1 /*
2  *  SSL certificate functionality tests
3  *
4  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5  *  SPDX-License-Identifier: Apache-2.0
6  *
7  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
8  *  not use this file except in compliance with the License.
9  *  You may obtain a copy of the License at
10  *
11  *  http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *  Unless required by applicable law or agreed to in writing, software
14  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *  See the License for the specific language governing permissions and
17  *  limitations under the License.
18  *
19  *  This file is part of mbed TLS (https://tls.mbed.org)
20  */
21 
22 #if !defined(MBEDTLS_CONFIG_FILE)
23 #include "mbedtls/config.h"
24 #else
25 #include MBEDTLS_CONFIG_FILE
26 #endif
27 
28 #if defined(MBEDTLS_PLATFORM_C)
29 #include "mbedtls/platform.h"
30 #else
31 #include <stdio.h>
32 #define mbedtls_snprintf   snprintf
33 #define mbedtls_printf     printf
34 #endif
35 
36 #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_X509_CRT_PARSE_C) && \
37     defined(MBEDTLS_FS_IO) && defined(MBEDTLS_X509_CRL_PARSE_C)
38 #include "mbedtls/certs.h"
39 #include "mbedtls/x509_crt.h"
40 
41 #include <stdio.h>
42 #include <string.h>
43 #endif
44 
45 #define MAX_CLIENT_CERTS    8
46 
47 #if !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
48     !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_X509_CRL_PARSE_C)
main(void)49 int main( void )
50 {
51     mbedtls_printf("MBEDTLS_RSA_C and/or MBEDTLS_X509_CRT_PARSE_C "
52            "MBEDTLS_FS_IO and/or MBEDTLS_X509_CRL_PARSE_C "
53            "not defined.\n");
54     return( 0 );
55 }
56 #else
57 const char *client_certificates[MAX_CLIENT_CERTS] =
58 {
59     "client1.crt",
60     "client2.crt",
61     "server1.crt",
62     "server2.crt",
63     "cert_sha224.crt",
64     "cert_sha256.crt",
65     "cert_sha384.crt",
66     "cert_sha512.crt"
67 };
68 
69 const char *client_private_keys[MAX_CLIENT_CERTS] =
70 {
71     "client1.key",
72     "client2.key",
73     "server1.key",
74     "server2.key",
75     "cert_digest.key",
76     "cert_digest.key",
77     "cert_digest.key",
78     "cert_digest.key"
79 };
80 
main(void)81 int main( void )
82 {
83     int ret, i;
84     mbedtls_x509_crt cacert;
85     mbedtls_x509_crl crl;
86     char buf[10240];
87 
88     mbedtls_x509_crt_init( &cacert );
89     mbedtls_x509_crl_init( &crl );
90 
91     /*
92      * 1.1. Load the trusted CA
93      */
94     mbedtls_printf( "\n  . Loading the CA root certificate ..." );
95     fflush( stdout );
96 
97     /*
98      * Alternatively, you may load the CA certificates from a .pem or
99      * .crt file by calling mbedtls_x509_crt_parse_file( &cacert, "myca.crt" ).
100      */
101     ret = mbedtls_x509_crt_parse_file( &cacert, "ssl/test-ca/test-ca.crt" );
102     if( ret != 0 )
103     {
104         mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse_file returned %d\n\n", ret );
105         goto exit;
106     }
107 
108     mbedtls_printf( " ok\n" );
109 
110     mbedtls_x509_crt_info( buf, 1024, "CRT: ", &cacert );
111     mbedtls_printf("%s\n", buf );
112 
113     /*
114      * 1.2. Load the CRL
115      */
116     mbedtls_printf( "  . Loading the CRL ..." );
117     fflush( stdout );
118 
119     ret = mbedtls_x509_crl_parse_file( &crl, "ssl/test-ca/crl.pem" );
120     if( ret != 0 )
121     {
122         mbedtls_printf( " failed\n  !  mbedtls_x509_crl_parse_file returned %d\n\n", ret );
123         goto exit;
124     }
125 
126     mbedtls_printf( " ok\n" );
127 
128     mbedtls_x509_crl_info( buf, 1024, "CRL: ", &crl );
129     mbedtls_printf("%s\n", buf );
130 
131     for( i = 0; i < MAX_CLIENT_CERTS; i++ )
132     {
133         /*
134          * 1.3. Load own certificate
135          */
136         char    name[512];
137         uint32_t flags;
138         mbedtls_x509_crt clicert;
139         mbedtls_pk_context pk;
140 
141         mbedtls_x509_crt_init( &clicert );
142         mbedtls_pk_init( &pk );
143 
144         mbedtls_snprintf(name, 512, "ssl/test-ca/%s", client_certificates[i]);
145 
146         mbedtls_printf( "  . Loading the client certificate %s...", name );
147         fflush( stdout );
148 
149         ret = mbedtls_x509_crt_parse_file( &clicert, name );
150         if( ret != 0 )
151         {
152             mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse_file returned %d\n\n", ret );
153             goto exit;
154         }
155 
156         mbedtls_printf( " ok\n" );
157 
158         /*
159          * 1.4. Verify certificate validity with CA certificate
160          */
161         mbedtls_printf( "  . Verify the client certificate with CA certificate..." );
162         fflush( stdout );
163 
164         ret = mbedtls_x509_crt_verify( &clicert, &cacert, &crl, NULL, &flags, NULL,
165                                NULL );
166         if( ret != 0 )
167         {
168             if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
169             {
170                  char vrfy_buf[512];
171 
172                  mbedtls_printf( " failed\n" );
173                  mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", flags );
174                  mbedtls_printf( "%s\n", vrfy_buf );
175              }
176              else
177              {
178                 mbedtls_printf( " failed\n  !  mbedtls_x509_crt_verify returned %d\n\n", ret );
179                 goto exit;
180             }
181         }
182 
183         mbedtls_printf( " ok\n" );
184 
185         /*
186          * 1.5. Load own private key
187          */
188         mbedtls_snprintf(name, 512, "ssl/test-ca/%s", client_private_keys[i]);
189 
190         mbedtls_printf( "  . Loading the client private key %s...", name );
191         fflush( stdout );
192 
193         ret = mbedtls_pk_parse_keyfile( &pk, name, NULL );
194         if( ret != 0 )
195         {
196             mbedtls_printf( " failed\n  !  mbedtls_pk_parse_keyfile returned %d\n\n", ret );
197             goto exit;
198         }
199 
200         mbedtls_printf( " ok\n" );
201 
202         /*
203          * 1.6. Verify certificate validity with private key
204          */
205         mbedtls_printf( "  . Verify the client certificate with private key..." );
206         fflush( stdout );
207 
208 
209         /* EC NOT IMPLEMENTED YET */
210         if( ! mbedtls_pk_can_do( &clicert.pk, MBEDTLS_PK_RSA ) )
211         {
212             mbedtls_printf( " failed\n  !  certificate's key is not RSA\n\n" );
213             ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
214             goto exit;
215         }
216 
217         ret = mbedtls_mpi_cmp_mpi(&mbedtls_pk_rsa( pk )->N, &mbedtls_pk_rsa( clicert.pk )->N);
218         if( ret != 0 )
219         {
220             mbedtls_printf( " failed\n  !  mbedtls_mpi_cmp_mpi for N returned %d\n\n", ret );
221             goto exit;
222         }
223 
224         ret = mbedtls_mpi_cmp_mpi(&mbedtls_pk_rsa( pk )->E, &mbedtls_pk_rsa( clicert.pk )->E);
225         if( ret != 0 )
226         {
227             mbedtls_printf( " failed\n  !  mbedtls_mpi_cmp_mpi for E returned %d\n\n", ret );
228             goto exit;
229         }
230 
231         ret = mbedtls_rsa_check_privkey( mbedtls_pk_rsa( pk ) );
232         if( ret != 0 )
233         {
234             mbedtls_printf( " failed\n  !  mbedtls_rsa_check_privkey returned %d\n\n", ret );
235             goto exit;
236         }
237 
238         mbedtls_printf( " ok\n" );
239 
240         mbedtls_x509_crt_free( &clicert );
241         mbedtls_pk_free( &pk );
242     }
243 
244 exit:
245     mbedtls_x509_crt_free( &cacert );
246     mbedtls_x509_crl_free( &crl );
247 
248 #if defined(_WIN32)
249     mbedtls_printf( "  + Press Enter to exit this program.\n" );
250     fflush( stdout ); getchar();
251 #endif
252 
253     return( ret );
254 }
255 #endif /* MBEDTLS_RSA_C && MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_FS_IO &&
256           MBEDTLS_X509_CRL_PARSE_C */
257