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 #include <stdlib.h>
33 #define mbedtls_snprintf        snprintf
34 #define mbedtls_printf          printf
35 #define mbedtls_exit            exit
36 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
37 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
38 #endif /* MBEDTLS_PLATFORM_C */
39 
40 #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_X509_CRT_PARSE_C) && \
41     defined(MBEDTLS_FS_IO) && defined(MBEDTLS_X509_CRL_PARSE_C)
42 #include "mbedtls/certs.h"
43 #include "mbedtls/x509_crt.h"
44 
45 #include <stdio.h>
46 #include <string.h>
47 #endif
48 
49 #define MAX_CLIENT_CERTS    8
50 
51 #if !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
52     !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_X509_CRL_PARSE_C)
main(void)53 int main( void )
54 {
55     mbedtls_printf("MBEDTLS_RSA_C and/or MBEDTLS_X509_CRT_PARSE_C "
56            "MBEDTLS_FS_IO and/or MBEDTLS_X509_CRL_PARSE_C "
57            "not defined.\n");
58     return( 0 );
59 }
60 #else
61 const char *client_certificates[MAX_CLIENT_CERTS] =
62 {
63     "client1.crt",
64     "client2.crt",
65     "server1.crt",
66     "server2.crt",
67     "cert_sha224.crt",
68     "cert_sha256.crt",
69     "cert_sha384.crt",
70     "cert_sha512.crt"
71 };
72 
73 const char *client_private_keys[MAX_CLIENT_CERTS] =
74 {
75     "client1.key",
76     "client2.key",
77     "server1.key",
78     "server2.key",
79     "cert_digest.key",
80     "cert_digest.key",
81     "cert_digest.key",
82     "cert_digest.key"
83 };
84 
85 #if defined(MBEDTLS_CHECK_PARAMS)
86 #include "mbedtls/platform_util.h"
mbedtls_param_failed(const char * failure_condition,const char * file,int line)87 void mbedtls_param_failed( const char *failure_condition,
88                            const char *file,
89                            int line )
90 {
91     mbedtls_printf( "%s:%i: Input param failed - %s\n",
92                     file, line, failure_condition );
93     mbedtls_exit( MBEDTLS_EXIT_FAILURE );
94 }
95 #endif
96 
main(void)97 int main( void )
98 {
99     int ret = 1, i;
100     int exit_code = MBEDTLS_EXIT_FAILURE;
101     mbedtls_x509_crt cacert;
102     mbedtls_x509_crl crl;
103     char buf[10240];
104 
105     mbedtls_x509_crt_init( &cacert );
106     mbedtls_x509_crl_init( &crl );
107 
108     /*
109      * 1.1. Load the trusted CA
110      */
111     mbedtls_printf( "\n  . Loading the CA root certificate ..." );
112     fflush( stdout );
113 
114     /*
115      * Alternatively, you may load the CA certificates from a .pem or
116      * .crt file by calling mbedtls_x509_crt_parse_file( &cacert, "myca.crt" ).
117      */
118     ret = mbedtls_x509_crt_parse_file( &cacert, "ssl/test-ca/test-ca.crt" );
119     if( ret != 0 )
120     {
121         mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse_file returned %d\n\n", ret );
122         goto exit;
123     }
124 
125     mbedtls_printf( " ok\n" );
126 
127     mbedtls_x509_crt_info( buf, 1024, "CRT: ", &cacert );
128     mbedtls_printf("%s\n", buf );
129 
130     /*
131      * 1.2. Load the CRL
132      */
133     mbedtls_printf( "  . Loading the CRL ..." );
134     fflush( stdout );
135 
136     ret = mbedtls_x509_crl_parse_file( &crl, "ssl/test-ca/crl.pem" );
137     if( ret != 0 )
138     {
139         mbedtls_printf( " failed\n  !  mbedtls_x509_crl_parse_file returned %d\n\n", ret );
140         goto exit;
141     }
142 
143     mbedtls_printf( " ok\n" );
144 
145     mbedtls_x509_crl_info( buf, 1024, "CRL: ", &crl );
146     mbedtls_printf("%s\n", buf );
147 
148     for( i = 0; i < MAX_CLIENT_CERTS; i++ )
149     {
150         /*
151          * 1.3. Load own certificate
152          */
153         char    name[512];
154         uint32_t flags;
155         mbedtls_x509_crt clicert;
156         mbedtls_pk_context pk;
157 
158         mbedtls_x509_crt_init( &clicert );
159         mbedtls_pk_init( &pk );
160 
161         mbedtls_snprintf(name, 512, "ssl/test-ca/%s", client_certificates[i]);
162 
163         mbedtls_printf( "  . Loading the client certificate %s...", name );
164         fflush( stdout );
165 
166         ret = mbedtls_x509_crt_parse_file( &clicert, name );
167         if( ret != 0 )
168         {
169             mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse_file returned %d\n\n", ret );
170             goto exit;
171         }
172 
173         mbedtls_printf( " ok\n" );
174 
175         /*
176          * 1.4. Verify certificate validity with CA certificate
177          */
178         mbedtls_printf( "  . Verify the client certificate with CA certificate..." );
179         fflush( stdout );
180 
181         ret = mbedtls_x509_crt_verify( &clicert, &cacert, &crl, NULL, &flags, NULL,
182                                NULL );
183         if( ret != 0 )
184         {
185             if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
186             {
187                  char vrfy_buf[512];
188 
189                  mbedtls_printf( " failed\n" );
190                  mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", flags );
191                  mbedtls_printf( "%s\n", vrfy_buf );
192              }
193              else
194              {
195                 mbedtls_printf( " failed\n  !  mbedtls_x509_crt_verify returned %d\n\n", ret );
196                 goto exit;
197             }
198         }
199 
200         mbedtls_printf( " ok\n" );
201 
202         /*
203          * 1.5. Load own private key
204          */
205         mbedtls_snprintf(name, 512, "ssl/test-ca/%s", client_private_keys[i]);
206 
207         mbedtls_printf( "  . Loading the client private key %s...", name );
208         fflush( stdout );
209 
210         ret = mbedtls_pk_parse_keyfile( &pk, name, NULL );
211         if( ret != 0 )
212         {
213             mbedtls_printf( " failed\n  !  mbedtls_pk_parse_keyfile returned %d\n\n", ret );
214             goto exit;
215         }
216 
217         mbedtls_printf( " ok\n" );
218 
219         /*
220          * 1.6. Verify certificate validity with private key
221          */
222         mbedtls_printf( "  . Verify the client certificate with private key..." );
223         fflush( stdout );
224 
225 
226         /* EC NOT IMPLEMENTED YET */
227         if( ! mbedtls_pk_can_do( &clicert.pk, MBEDTLS_PK_RSA ) )
228         {
229             mbedtls_printf( " failed\n  !  certificate's key is not RSA\n\n" );
230             goto exit;
231         }
232 
233         ret = mbedtls_mpi_cmp_mpi(&mbedtls_pk_rsa( pk )->N, &mbedtls_pk_rsa( clicert.pk )->N);
234         if( ret != 0 )
235         {
236             mbedtls_printf( " failed\n  !  mbedtls_mpi_cmp_mpi for N returned %d\n\n", ret );
237             goto exit;
238         }
239 
240         ret = mbedtls_mpi_cmp_mpi(&mbedtls_pk_rsa( pk )->E, &mbedtls_pk_rsa( clicert.pk )->E);
241         if( ret != 0 )
242         {
243             mbedtls_printf( " failed\n  !  mbedtls_mpi_cmp_mpi for E returned %d\n\n", ret );
244             goto exit;
245         }
246 
247         ret = mbedtls_rsa_check_privkey( mbedtls_pk_rsa( pk ) );
248         if( ret != 0 )
249         {
250             mbedtls_printf( " failed\n  !  mbedtls_rsa_check_privkey returned %d\n\n", ret );
251             goto exit;
252         }
253 
254         mbedtls_printf( " ok\n" );
255 
256         mbedtls_x509_crt_free( &clicert );
257         mbedtls_pk_free( &pk );
258     }
259 
260     exit_code = MBEDTLS_EXIT_SUCCESS;
261 
262 exit:
263     mbedtls_x509_crt_free( &cacert );
264     mbedtls_x509_crl_free( &crl );
265 
266 #if defined(_WIN32)
267     mbedtls_printf( "  + Press Enter to exit this program.\n" );
268     fflush( stdout ); getchar();
269 #endif
270 
271     return( exit_code );
272 }
273 #endif /* MBEDTLS_RSA_C && MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_FS_IO &&
274           MBEDTLS_X509_CRL_PARSE_C */
275