1 /*
2  *  X.509 certificate parsing and verification
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  *  The ITU-T X.509 standard defines a certificate format for PKI.
23  *
24  *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
25  *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
26  *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
27  *
28  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
29  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
30  */
31 
32 #if !defined(MBEDTLS_CONFIG_FILE)
33 #include "mbedtls/config.h"
34 #else
35 #include MBEDTLS_CONFIG_FILE
36 #endif
37 
38 #if defined(MBEDTLS_X509_CRT_PARSE_C)
39 
40 #include "mbedtls/x509_crt.h"
41 #include "mbedtls/oid.h"
42 
43 #include <stdio.h>
44 #include <string.h>
45 
46 #if defined(MBEDTLS_PEM_PARSE_C)
47 #include "mbedtls/pem.h"
48 #endif
49 
50 #if defined(MBEDTLS_PLATFORM_C)
51 #include "mbedtls/platform.h"
52 #else
53 #include <stdlib.h>
54 #define mbedtls_free       free
55 #define mbedtls_calloc    calloc
56 #define mbedtls_snprintf   snprintf
57 #endif
58 
59 #if defined(MBEDTLS_THREADING_C)
60 #include "mbedtls/threading.h"
61 #endif
62 
63 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
64 #include <windows.h>
65 #else
66 #include <time.h>
67 #endif
68 
69 #if defined(MBEDTLS_FS_IO)
70 #include <stdio.h>
71 #if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
72 #include <sys/types.h>
73 #include <sys/stat.h>
74 #include <dirent.h>
75 #endif /* !_WIN32 || EFIX64 || EFI32 */
76 #endif
77 
78 /* Implementation that should never be optimized out by the compiler */
mbedtls_zeroize(void * v,size_t n)79 static void mbedtls_zeroize( void *v, size_t n ) {
80     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
81 }
82 
83 /*
84  * Default profile
85  */
86 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
87 {
88     /* Hashes from SHA-1 and above */
89     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
90     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) |
91     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
92     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
93     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
94     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
95     0xFFFFFFF, /* Any PK alg    */
96     0xFFFFFFF, /* Any curve     */
97     2048,
98 };
99 
100 /*
101  * Next-default profile
102  */
103 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next =
104 {
105     /* Hashes from SHA-256 and above */
106     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
107     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
108     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
109     0xFFFFFFF, /* Any PK alg    */
110 #if defined(MBEDTLS_ECP_C)
111     /* Curves at or above 128-bit security level */
112     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
113     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) |
114     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) |
115     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1 ) |
116     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1 ) |
117     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1 ) |
118     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1 ),
119 #else
120     0,
121 #endif
122     2048,
123 };
124 
125 /*
126  * NSA Suite B Profile
127  */
128 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb =
129 {
130     /* Only SHA-256 and 384 */
131     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
132     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ),
133     /* Only ECDSA */
134     MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ),
135 #if defined(MBEDTLS_ECP_C)
136     /* Only NIST P-256 and P-384 */
137     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
138     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ),
139 #else
140     0,
141 #endif
142     0,
143 };
144 
145 /*
146  * Check md_alg against profile
147  * Return 0 if md_alg acceptable for this profile, -1 otherwise
148  */
x509_profile_check_md_alg(const mbedtls_x509_crt_profile * profile,mbedtls_md_type_t md_alg)149 static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile,
150                                       mbedtls_md_type_t md_alg )
151 {
152     if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 )
153         return( 0 );
154 
155     return( -1 );
156 }
157 
158 /*
159  * Check pk_alg against profile
160  * Return 0 if pk_alg acceptable for this profile, -1 otherwise
161  */
x509_profile_check_pk_alg(const mbedtls_x509_crt_profile * profile,mbedtls_pk_type_t pk_alg)162 static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile,
163                                       mbedtls_pk_type_t pk_alg )
164 {
165     if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 )
166         return( 0 );
167 
168     return( -1 );
169 }
170 
171 /*
172  * Check key against profile
173  * Return 0 if pk_alg acceptable for this profile, -1 otherwise
174  */
x509_profile_check_key(const mbedtls_x509_crt_profile * profile,mbedtls_pk_type_t pk_alg,const mbedtls_pk_context * pk)175 static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile,
176                                    mbedtls_pk_type_t pk_alg,
177                                    const mbedtls_pk_context *pk )
178 {
179 #if defined(MBEDTLS_RSA_C)
180     if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS )
181     {
182         if( mbedtls_pk_get_bitlen( pk ) >= profile->rsa_min_bitlen )
183             return( 0 );
184 
185         return( -1 );
186     }
187 #endif
188 
189 #if defined(MBEDTLS_ECP_C)
190     if( pk_alg == MBEDTLS_PK_ECDSA ||
191         pk_alg == MBEDTLS_PK_ECKEY ||
192         pk_alg == MBEDTLS_PK_ECKEY_DH )
193     {
194         mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id;
195 
196         if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 )
197             return( 0 );
198 
199         return( -1 );
200     }
201 #endif
202 
203     return( -1 );
204 }
205 
206 /*
207  *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
208  */
x509_get_version(unsigned char ** p,const unsigned char * end,int * ver)209 static int x509_get_version( unsigned char **p,
210                              const unsigned char *end,
211                              int *ver )
212 {
213     int ret;
214     size_t len;
215 
216     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
217             MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) != 0 )
218     {
219         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
220         {
221             *ver = 0;
222             return( 0 );
223         }
224 
225         return( ret );
226     }
227 
228     end = *p + len;
229 
230     if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
231         return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
232 
233     if( *p != end )
234         return( MBEDTLS_ERR_X509_INVALID_VERSION +
235                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
236 
237     return( 0 );
238 }
239 
240 /*
241  *  Validity ::= SEQUENCE {
242  *       notBefore      Time,
243  *       notAfter       Time }
244  */
x509_get_dates(unsigned char ** p,const unsigned char * end,mbedtls_x509_time * from,mbedtls_x509_time * to)245 static int x509_get_dates( unsigned char **p,
246                            const unsigned char *end,
247                            mbedtls_x509_time *from,
248                            mbedtls_x509_time *to )
249 {
250     int ret;
251     size_t len;
252 
253     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
254             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
255         return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
256 
257     end = *p + len;
258 
259     if( ( ret = mbedtls_x509_get_time( p, end, from ) ) != 0 )
260         return( ret );
261 
262     if( ( ret = mbedtls_x509_get_time( p, end, to ) ) != 0 )
263         return( ret );
264 
265     if( *p != end )
266         return( MBEDTLS_ERR_X509_INVALID_DATE +
267                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
268 
269     return( 0 );
270 }
271 
272 /*
273  * X.509 v2/v3 unique identifier (not parsed)
274  */
x509_get_uid(unsigned char ** p,const unsigned char * end,mbedtls_x509_buf * uid,int n)275 static int x509_get_uid( unsigned char **p,
276                          const unsigned char *end,
277                          mbedtls_x509_buf *uid, int n )
278 {
279     int ret;
280 
281     if( *p == end )
282         return( 0 );
283 
284     uid->tag = **p;
285 
286     if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len,
287             MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 )
288     {
289         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
290             return( 0 );
291 
292         return( ret );
293     }
294 
295     uid->p = *p;
296     *p += uid->len;
297 
298     return( 0 );
299 }
300 
x509_get_basic_constraints(unsigned char ** p,const unsigned char * end,int * ca_istrue,int * max_pathlen)301 static int x509_get_basic_constraints( unsigned char **p,
302                                        const unsigned char *end,
303                                        int *ca_istrue,
304                                        int *max_pathlen )
305 {
306     int ret;
307     size_t len;
308 
309     /*
310      * BasicConstraints ::= SEQUENCE {
311      *      cA                      BOOLEAN DEFAULT FALSE,
312      *      pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
313      */
314     *ca_istrue = 0; /* DEFAULT FALSE */
315     *max_pathlen = 0; /* endless */
316 
317     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
318             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
319         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
320 
321     if( *p == end )
322         return( 0 );
323 
324     if( ( ret = mbedtls_asn1_get_bool( p, end, ca_istrue ) ) != 0 )
325     {
326         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
327             ret = mbedtls_asn1_get_int( p, end, ca_istrue );
328 
329         if( ret != 0 )
330             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
331 
332         if( *ca_istrue != 0 )
333             *ca_istrue = 1;
334     }
335 
336     if( *p == end )
337         return( 0 );
338 
339     if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 )
340         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
341 
342     if( *p != end )
343         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
344                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
345 
346     (*max_pathlen)++;
347 
348     return( 0 );
349 }
350 
x509_get_ns_cert_type(unsigned char ** p,const unsigned char * end,unsigned char * ns_cert_type)351 static int x509_get_ns_cert_type( unsigned char **p,
352                                        const unsigned char *end,
353                                        unsigned char *ns_cert_type)
354 {
355     int ret;
356     mbedtls_x509_bitstring bs = { 0, 0, NULL };
357 
358     if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
359         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
360 
361     if( bs.len != 1 )
362         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
363                 MBEDTLS_ERR_ASN1_INVALID_LENGTH );
364 
365     /* Get actual bitstring */
366     *ns_cert_type = *bs.p;
367     return( 0 );
368 }
369 
x509_get_key_usage(unsigned char ** p,const unsigned char * end,unsigned int * key_usage)370 static int x509_get_key_usage( unsigned char **p,
371                                const unsigned char *end,
372                                unsigned int *key_usage)
373 {
374     int ret;
375     size_t i;
376     mbedtls_x509_bitstring bs = { 0, 0, NULL };
377 
378     if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
379         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
380 
381     if( bs.len < 1 )
382         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
383                 MBEDTLS_ERR_ASN1_INVALID_LENGTH );
384 
385     /* Get actual bitstring */
386     *key_usage = 0;
387     for( i = 0; i < bs.len && i < sizeof( unsigned int ); i++ )
388     {
389         *key_usage |= (unsigned int) bs.p[i] << (8*i);
390     }
391 
392     return( 0 );
393 }
394 
395 /*
396  * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
397  *
398  * KeyPurposeId ::= OBJECT IDENTIFIER
399  */
x509_get_ext_key_usage(unsigned char ** p,const unsigned char * end,mbedtls_x509_sequence * ext_key_usage)400 static int x509_get_ext_key_usage( unsigned char **p,
401                                const unsigned char *end,
402                                mbedtls_x509_sequence *ext_key_usage)
403 {
404     int ret;
405 
406     if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 )
407         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
408 
409     /* Sequence length must be >= 1 */
410     if( ext_key_usage->buf.p == NULL )
411         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
412                 MBEDTLS_ERR_ASN1_INVALID_LENGTH );
413 
414     return( 0 );
415 }
416 
417 /*
418  * SubjectAltName ::= GeneralNames
419  *
420  * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
421  *
422  * GeneralName ::= CHOICE {
423  *      otherName                       [0]     OtherName,
424  *      rfc822Name                      [1]     IA5String,
425  *      dNSName                         [2]     IA5String,
426  *      x400Address                     [3]     ORAddress,
427  *      directoryName                   [4]     Name,
428  *      ediPartyName                    [5]     EDIPartyName,
429  *      uniformResourceIdentifier       [6]     IA5String,
430  *      iPAddress                       [7]     OCTET STRING,
431  *      registeredID                    [8]     OBJECT IDENTIFIER }
432  *
433  * OtherName ::= SEQUENCE {
434  *      type-id    OBJECT IDENTIFIER,
435  *      value      [0] EXPLICIT ANY DEFINED BY type-id }
436  *
437  * EDIPartyName ::= SEQUENCE {
438  *      nameAssigner            [0]     DirectoryString OPTIONAL,
439  *      partyName               [1]     DirectoryString }
440  *
441  * NOTE: we only parse and use dNSName at this point.
442  */
x509_get_subject_alt_name(unsigned char ** p,const unsigned char * end,mbedtls_x509_sequence * subject_alt_name)443 static int x509_get_subject_alt_name( unsigned char **p,
444                                       const unsigned char *end,
445                                       mbedtls_x509_sequence *subject_alt_name )
446 {
447     int ret;
448     size_t len, tag_len;
449     mbedtls_asn1_buf *buf;
450     unsigned char tag;
451     mbedtls_asn1_sequence *cur = subject_alt_name;
452 
453     /* Get main sequence tag */
454     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
455             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
456         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
457 
458     if( *p + len != end )
459         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
460                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
461 
462     while( *p < end )
463     {
464         if( ( end - *p ) < 1 )
465             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
466                     MBEDTLS_ERR_ASN1_OUT_OF_DATA );
467 
468         tag = **p;
469         (*p)++;
470         if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 )
471             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
472 
473         if( ( tag & MBEDTLS_ASN1_CONTEXT_SPECIFIC ) != MBEDTLS_ASN1_CONTEXT_SPECIFIC )
474             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
475                     MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
476 
477         /* Skip everything but DNS name */
478         if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) )
479         {
480             *p += tag_len;
481             continue;
482         }
483 
484         /* Allocate and assign next pointer */
485         if( cur->buf.p != NULL )
486         {
487             if( cur->next != NULL )
488                 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
489 
490             cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
491 
492             if( cur->next == NULL )
493                 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
494                         MBEDTLS_ERR_ASN1_ALLOC_FAILED );
495 
496             cur = cur->next;
497         }
498 
499         buf = &(cur->buf);
500         buf->tag = tag;
501         buf->p = *p;
502         buf->len = tag_len;
503         *p += buf->len;
504     }
505 
506     /* Set final sequence entry's next pointer to NULL */
507     cur->next = NULL;
508 
509     if( *p != end )
510         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
511                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
512 
513     return( 0 );
514 }
515 
516 /*
517  * X.509 v3 extensions
518  *
519  */
x509_get_crt_ext(unsigned char ** p,const unsigned char * end,mbedtls_x509_crt * crt)520 static int x509_get_crt_ext( unsigned char **p,
521                              const unsigned char *end,
522                              mbedtls_x509_crt *crt )
523 {
524     int ret;
525     size_t len;
526     unsigned char *end_ext_data, *end_ext_octet;
527 
528     if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
529     {
530         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
531             return( 0 );
532 
533         return( ret );
534     }
535 
536     while( *p < end )
537     {
538         /*
539          * Extension  ::=  SEQUENCE  {
540          *      extnID      OBJECT IDENTIFIER,
541          *      critical    BOOLEAN DEFAULT FALSE,
542          *      extnValue   OCTET STRING  }
543          */
544         mbedtls_x509_buf extn_oid = {0, 0, NULL};
545         int is_critical = 0; /* DEFAULT FALSE */
546         int ext_type = 0;
547 
548         if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
549                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
550             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
551 
552         end_ext_data = *p + len;
553 
554         /* Get extension ID */
555         extn_oid.tag = **p;
556 
557         if( ( ret = mbedtls_asn1_get_tag( p, end, &extn_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
558             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
559 
560         extn_oid.p = *p;
561         *p += extn_oid.len;
562 
563         if( ( end - *p ) < 1 )
564             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
565                     MBEDTLS_ERR_ASN1_OUT_OF_DATA );
566 
567         /* Get optional critical */
568         if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
569             ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
570             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
571 
572         /* Data should be octet string type */
573         if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
574                 MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
575             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
576 
577         end_ext_octet = *p + len;
578 
579         if( end_ext_octet != end_ext_data )
580             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
581                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
582 
583         /*
584          * Detect supported extensions
585          */
586         ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type );
587 
588         if( ret != 0 )
589         {
590             /* No parser found, skip extension */
591             *p = end_ext_octet;
592 
593 #if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
594             if( is_critical )
595             {
596                 /* Data is marked as critical: fail */
597                 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
598                         MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
599             }
600 #endif
601             continue;
602         }
603 
604         /* Forbid repeated extensions */
605         if( ( crt->ext_types & ext_type ) != 0 )
606             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
607 
608         crt->ext_types |= ext_type;
609 
610         switch( ext_type )
611         {
612         case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS:
613             /* Parse basic constraints */
614             if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
615                     &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
616                 return( ret );
617             break;
618 
619         case MBEDTLS_X509_EXT_KEY_USAGE:
620             /* Parse key usage */
621             if( ( ret = x509_get_key_usage( p, end_ext_octet,
622                     &crt->key_usage ) ) != 0 )
623                 return( ret );
624             break;
625 
626         case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE:
627             /* Parse extended key usage */
628             if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
629                     &crt->ext_key_usage ) ) != 0 )
630                 return( ret );
631             break;
632 
633         case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
634             /* Parse subject alt name */
635             if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
636                     &crt->subject_alt_names ) ) != 0 )
637                 return( ret );
638             break;
639 
640         case MBEDTLS_X509_EXT_NS_CERT_TYPE:
641             /* Parse netscape certificate type */
642             if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
643                     &crt->ns_cert_type ) ) != 0 )
644                 return( ret );
645             break;
646 
647         default:
648             return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
649         }
650     }
651 
652     if( *p != end )
653         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
654                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
655 
656     return( 0 );
657 }
658 
659 /*
660  * Parse and fill a single X.509 certificate in DER format
661  */
x509_crt_parse_der_core(mbedtls_x509_crt * crt,const unsigned char * buf,size_t buflen)662 static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf,
663                                     size_t buflen )
664 {
665     int ret;
666     size_t len;
667     unsigned char *p, *end, *crt_end;
668     mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
669 
670     memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) );
671     memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) );
672     memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) );
673 
674     /*
675      * Check for valid input
676      */
677     if( crt == NULL || buf == NULL )
678         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
679 
680     // Use the original buffer until we figure out actual length
681     p = (unsigned char*) buf;
682     len = buflen;
683     end = p + len;
684 
685     /*
686      * Certificate  ::=  SEQUENCE  {
687      *      tbsCertificate       TBSCertificate,
688      *      signatureAlgorithm   AlgorithmIdentifier,
689      *      signatureValue       BIT STRING  }
690      */
691     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
692             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
693     {
694         mbedtls_x509_crt_free( crt );
695         return( MBEDTLS_ERR_X509_INVALID_FORMAT );
696     }
697 
698     if( len > (size_t) ( end - p ) )
699     {
700         mbedtls_x509_crt_free( crt );
701         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
702                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
703     }
704     crt_end = p + len;
705 
706     // Create and populate a new buffer for the raw field
707     crt->raw.len = crt_end - buf;
708     crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len );
709     if( p == NULL )
710         return( MBEDTLS_ERR_X509_ALLOC_FAILED );
711 
712     memcpy( p, buf, crt->raw.len );
713 
714     // Direct pointers to the new buffer
715     p += crt->raw.len - len;
716     end = crt_end = p + len;
717 
718     /*
719      * TBSCertificate  ::=  SEQUENCE  {
720      */
721     crt->tbs.p = p;
722 
723     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
724             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
725     {
726         mbedtls_x509_crt_free( crt );
727         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
728     }
729 
730     end = p + len;
731     crt->tbs.len = end - crt->tbs.p;
732 
733     /*
734      * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
735      *
736      * CertificateSerialNumber  ::=  INTEGER
737      *
738      * signature            AlgorithmIdentifier
739      */
740     if( ( ret = x509_get_version(  &p, end, &crt->version  ) ) != 0 ||
741         ( ret = mbedtls_x509_get_serial(   &p, end, &crt->serial   ) ) != 0 ||
742         ( ret = mbedtls_x509_get_alg(      &p, end, &crt->sig_oid,
743                                             &sig_params1 ) ) != 0 )
744     {
745         mbedtls_x509_crt_free( crt );
746         return( ret );
747     }
748 
749     crt->version++;
750 
751     if( crt->version > 3 )
752     {
753         mbedtls_x509_crt_free( crt );
754         return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
755     }
756 
757     if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1,
758                                   &crt->sig_md, &crt->sig_pk,
759                                   &crt->sig_opts ) ) != 0 )
760     {
761         mbedtls_x509_crt_free( crt );
762         return( ret );
763     }
764 
765     /*
766      * issuer               Name
767      */
768     crt->issuer_raw.p = p;
769 
770     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
771             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
772     {
773         mbedtls_x509_crt_free( crt );
774         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
775     }
776 
777     if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
778     {
779         mbedtls_x509_crt_free( crt );
780         return( ret );
781     }
782 
783     crt->issuer_raw.len = p - crt->issuer_raw.p;
784 
785     /*
786      * Validity ::= SEQUENCE {
787      *      notBefore      Time,
788      *      notAfter       Time }
789      *
790      */
791     if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
792                                          &crt->valid_to ) ) != 0 )
793     {
794         mbedtls_x509_crt_free( crt );
795         return( ret );
796     }
797 
798     /*
799      * subject              Name
800      */
801     crt->subject_raw.p = p;
802 
803     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
804             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
805     {
806         mbedtls_x509_crt_free( crt );
807         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
808     }
809 
810     if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
811     {
812         mbedtls_x509_crt_free( crt );
813         return( ret );
814     }
815 
816     crt->subject_raw.len = p - crt->subject_raw.p;
817 
818     /*
819      * SubjectPublicKeyInfo
820      */
821     if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
822     {
823         mbedtls_x509_crt_free( crt );
824         return( ret );
825     }
826 
827     /*
828      *  issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
829      *                       -- If present, version shall be v2 or v3
830      *  subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
831      *                       -- If present, version shall be v2 or v3
832      *  extensions      [3]  EXPLICIT Extensions OPTIONAL
833      *                       -- If present, version shall be v3
834      */
835     if( crt->version == 2 || crt->version == 3 )
836     {
837         ret = x509_get_uid( &p, end, &crt->issuer_id,  1 );
838         if( ret != 0 )
839         {
840             mbedtls_x509_crt_free( crt );
841             return( ret );
842         }
843     }
844 
845     if( crt->version == 2 || crt->version == 3 )
846     {
847         ret = x509_get_uid( &p, end, &crt->subject_id,  2 );
848         if( ret != 0 )
849         {
850             mbedtls_x509_crt_free( crt );
851             return( ret );
852         }
853     }
854 
855 #if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
856     if( crt->version == 3 )
857 #endif
858     {
859         ret = x509_get_crt_ext( &p, end, crt );
860         if( ret != 0 )
861         {
862             mbedtls_x509_crt_free( crt );
863             return( ret );
864         }
865     }
866 
867     if( p != end )
868     {
869         mbedtls_x509_crt_free( crt );
870         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
871                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
872     }
873 
874     end = crt_end;
875 
876     /*
877      *  }
878      *  -- end of TBSCertificate
879      *
880      *  signatureAlgorithm   AlgorithmIdentifier,
881      *  signatureValue       BIT STRING
882      */
883     if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 )
884     {
885         mbedtls_x509_crt_free( crt );
886         return( ret );
887     }
888 
889     if( crt->sig_oid.len != sig_oid2.len ||
890         memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 ||
891         sig_params1.len != sig_params2.len ||
892         ( sig_params1.len != 0 &&
893           memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
894     {
895         mbedtls_x509_crt_free( crt );
896         return( MBEDTLS_ERR_X509_SIG_MISMATCH );
897     }
898 
899     if( ( ret = mbedtls_x509_get_sig( &p, end, &crt->sig ) ) != 0 )
900     {
901         mbedtls_x509_crt_free( crt );
902         return( ret );
903     }
904 
905     if( p != end )
906     {
907         mbedtls_x509_crt_free( crt );
908         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
909                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
910     }
911 
912     return( 0 );
913 }
914 
915 /*
916  * Parse one X.509 certificate in DER format from a buffer and add them to a
917  * chained list
918  */
mbedtls_x509_crt_parse_der(mbedtls_x509_crt * chain,const unsigned char * buf,size_t buflen)919 int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf,
920                         size_t buflen )
921 {
922     int ret;
923     mbedtls_x509_crt *crt = chain, *prev = NULL;
924 
925     /*
926      * Check for valid input
927      */
928     if( crt == NULL || buf == NULL )
929         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
930 
931     while( crt->version != 0 && crt->next != NULL )
932     {
933         prev = crt;
934         crt = crt->next;
935     }
936 
937     /*
938      * Add new certificate on the end of the chain if needed.
939      */
940     if( crt->version != 0 && crt->next == NULL )
941     {
942         crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
943 
944         if( crt->next == NULL )
945             return( MBEDTLS_ERR_X509_ALLOC_FAILED );
946 
947         prev = crt;
948         mbedtls_x509_crt_init( crt->next );
949         crt = crt->next;
950     }
951 
952     if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )
953     {
954         if( prev )
955             prev->next = NULL;
956 
957         if( crt != chain )
958             mbedtls_free( crt );
959 
960         return( ret );
961     }
962 
963     return( 0 );
964 }
965 
966 /*
967  * Parse one or more PEM certificates from a buffer and add them to the chained
968  * list
969  */
mbedtls_x509_crt_parse(mbedtls_x509_crt * chain,const unsigned char * buf,size_t buflen)970 int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen )
971 {
972     int success = 0, first_error = 0, total_failed = 0;
973 #if defined(MBEDTLS_PEM_PARSE_C)
974     int buf_format = MBEDTLS_X509_FORMAT_DER;
975 #endif
976 
977     /*
978      * Check for valid input
979      */
980     if( chain == NULL || buf == NULL )
981         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
982 
983     /*
984      * Determine buffer content. Buffer contains either one DER certificate or
985      * one or more PEM certificates.
986      */
987 #if defined(MBEDTLS_PEM_PARSE_C)
988     if( buflen != 0 && buf[buflen - 1] == '\0' &&
989         strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
990     {
991         buf_format = MBEDTLS_X509_FORMAT_PEM;
992     }
993 
994     if( buf_format == MBEDTLS_X509_FORMAT_DER )
995         return mbedtls_x509_crt_parse_der( chain, buf, buflen );
996 #else
997     return mbedtls_x509_crt_parse_der( chain, buf, buflen );
998 #endif
999 
1000 #if defined(MBEDTLS_PEM_PARSE_C)
1001     if( buf_format == MBEDTLS_X509_FORMAT_PEM )
1002     {
1003         int ret;
1004         mbedtls_pem_context pem;
1005 
1006         /* 1 rather than 0 since the terminating NULL byte is counted in */
1007         while( buflen > 1 )
1008         {
1009             size_t use_len;
1010             mbedtls_pem_init( &pem );
1011 
1012             /* If we get there, we know the string is null-terminated */
1013             ret = mbedtls_pem_read_buffer( &pem,
1014                            "-----BEGIN CERTIFICATE-----",
1015                            "-----END CERTIFICATE-----",
1016                            buf, NULL, 0, &use_len );
1017 
1018             if( ret == 0 )
1019             {
1020                 /*
1021                  * Was PEM encoded
1022                  */
1023                 buflen -= use_len;
1024                 buf += use_len;
1025             }
1026             else if( ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA )
1027             {
1028                 return( ret );
1029             }
1030             else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1031             {
1032                 mbedtls_pem_free( &pem );
1033 
1034                 /*
1035                  * PEM header and footer were found
1036                  */
1037                 buflen -= use_len;
1038                 buf += use_len;
1039 
1040                 if( first_error == 0 )
1041                     first_error = ret;
1042 
1043                 total_failed++;
1044                 continue;
1045             }
1046             else
1047                 break;
1048 
1049             ret = mbedtls_x509_crt_parse_der( chain, pem.buf, pem.buflen );
1050 
1051             mbedtls_pem_free( &pem );
1052 
1053             if( ret != 0 )
1054             {
1055                 /*
1056                  * Quit parsing on a memory error
1057                  */
1058                 if( ret == MBEDTLS_ERR_X509_ALLOC_FAILED )
1059                     return( ret );
1060 
1061                 if( first_error == 0 )
1062                     first_error = ret;
1063 
1064                 total_failed++;
1065                 continue;
1066             }
1067 
1068             success = 1;
1069         }
1070     }
1071 
1072     if( success )
1073         return( total_failed );
1074     else if( first_error )
1075         return( first_error );
1076     else
1077         return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT );
1078 #endif /* MBEDTLS_PEM_PARSE_C */
1079 }
1080 
1081 #if defined(MBEDTLS_FS_IO)
1082 /*
1083  * Load one or more certificates and add them to the chained list
1084  */
mbedtls_x509_crt_parse_file(mbedtls_x509_crt * chain,const char * path)1085 int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path )
1086 {
1087     int ret;
1088     size_t n;
1089     unsigned char *buf;
1090 
1091     if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
1092         return( ret );
1093 
1094     ret = mbedtls_x509_crt_parse( chain, buf, n );
1095 
1096     mbedtls_zeroize( buf, n );
1097     mbedtls_free( buf );
1098 
1099     return( ret );
1100 }
1101 
mbedtls_x509_crt_parse_path(mbedtls_x509_crt * chain,const char * path)1102 int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
1103 {
1104     int ret = 0;
1105 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
1106     int w_ret;
1107     WCHAR szDir[MAX_PATH];
1108     char filename[MAX_PATH];
1109     char *p;
1110     size_t len = strlen( path );
1111 
1112     WIN32_FIND_DATAW file_data;
1113     HANDLE hFind;
1114 
1115     if( len > MAX_PATH - 3 )
1116         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
1117 
1118     memset( szDir, 0, sizeof(szDir) );
1119     memset( filename, 0, MAX_PATH );
1120     memcpy( filename, path, len );
1121     filename[len++] = '\\';
1122     p = filename + len;
1123     filename[len++] = '*';
1124 
1125     w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir,
1126                                  MAX_PATH - 3 );
1127     if( w_ret == 0 )
1128         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
1129 
1130     hFind = FindFirstFileW( szDir, &file_data );
1131     if( hFind == INVALID_HANDLE_VALUE )
1132         return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
1133 
1134     len = MAX_PATH - len;
1135     do
1136     {
1137         memset( p, 0, len );
1138 
1139         if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
1140             continue;
1141 
1142         w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1143                                      lstrlenW( file_data.cFileName ),
1144                                      p, (int) len - 1,
1145                                      NULL, NULL );
1146         if( w_ret == 0 )
1147             return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
1148 
1149         w_ret = mbedtls_x509_crt_parse_file( chain, filename );
1150         if( w_ret < 0 )
1151             ret++;
1152         else
1153             ret += w_ret;
1154     }
1155     while( FindNextFileW( hFind, &file_data ) != 0 );
1156 
1157     if( GetLastError() != ERROR_NO_MORE_FILES )
1158         ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
1159 
1160     FindClose( hFind );
1161 #else /* _WIN32 */
1162     int t_ret;
1163     int snp_ret;
1164     struct stat sb;
1165     struct dirent *entry;
1166     char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN];
1167     DIR *dir = opendir( path );
1168 
1169     if( dir == NULL )
1170         return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
1171 
1172 #if defined(MBEDTLS_THREADING_PTHREAD)
1173     if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 )
1174     {
1175         closedir( dir );
1176         return( ret );
1177     }
1178 #endif
1179 
1180     while( ( entry = readdir( dir ) ) != NULL )
1181     {
1182         snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name,
1183                                     "%s/%s", path, entry->d_name );
1184 
1185         if( snp_ret < 0 || (size_t)snp_ret >= sizeof entry_name )
1186         {
1187             ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
1188             goto cleanup;
1189         }
1190         else if( stat( entry_name, &sb ) == -1 )
1191         {
1192             ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
1193             goto cleanup;
1194         }
1195 
1196         if( !S_ISREG( sb.st_mode ) )
1197             continue;
1198 
1199         // Ignore parse errors
1200         //
1201         t_ret = mbedtls_x509_crt_parse_file( chain, entry_name );
1202         if( t_ret < 0 )
1203             ret++;
1204         else
1205             ret += t_ret;
1206     }
1207 
1208 cleanup:
1209     closedir( dir );
1210 
1211 #if defined(MBEDTLS_THREADING_PTHREAD)
1212     if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 )
1213         ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
1214 #endif
1215 
1216 #endif /* _WIN32 */
1217 
1218     return( ret );
1219 }
1220 #endif /* MBEDTLS_FS_IO */
1221 
x509_info_subject_alt_name(char ** buf,size_t * size,const mbedtls_x509_sequence * subject_alt_name)1222 static int x509_info_subject_alt_name( char **buf, size_t *size,
1223                                        const mbedtls_x509_sequence *subject_alt_name )
1224 {
1225     size_t i;
1226     size_t n = *size;
1227     char *p = *buf;
1228     const mbedtls_x509_sequence *cur = subject_alt_name;
1229     const char *sep = "";
1230     size_t sep_len = 0;
1231 
1232     while( cur != NULL )
1233     {
1234         if( cur->buf.len + sep_len >= n )
1235         {
1236             *p = '\0';
1237             return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
1238         }
1239 
1240         n -= cur->buf.len + sep_len;
1241         for( i = 0; i < sep_len; i++ )
1242             *p++ = sep[i];
1243         for( i = 0; i < cur->buf.len; i++ )
1244             *p++ = cur->buf.p[i];
1245 
1246         sep = ", ";
1247         sep_len = 2;
1248 
1249         cur = cur->next;
1250     }
1251 
1252     *p = '\0';
1253 
1254     *size = n;
1255     *buf = p;
1256 
1257     return( 0 );
1258 }
1259 
1260 #define PRINT_ITEM(i)                           \
1261     {                                           \
1262         ret = mbedtls_snprintf( p, n, "%s" i, sep );    \
1263         MBEDTLS_X509_SAFE_SNPRINTF;                        \
1264         sep = ", ";                             \
1265     }
1266 
1267 #define CERT_TYPE(type,name)                    \
1268     if( ns_cert_type & type )                   \
1269         PRINT_ITEM( name );
1270 
x509_info_cert_type(char ** buf,size_t * size,unsigned char ns_cert_type)1271 static int x509_info_cert_type( char **buf, size_t *size,
1272                                 unsigned char ns_cert_type )
1273 {
1274     int ret;
1275     size_t n = *size;
1276     char *p = *buf;
1277     const char *sep = "";
1278 
1279     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT,         "SSL Client" );
1280     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER,         "SSL Server" );
1281     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL,              "Email" );
1282     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING,     "Object Signing" );
1283     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED,           "Reserved" );
1284     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA,             "SSL CA" );
1285     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA,           "Email CA" );
1286     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA,  "Object Signing CA" );
1287 
1288     *size = n;
1289     *buf = p;
1290 
1291     return( 0 );
1292 }
1293 
1294 #define KEY_USAGE(code,name)    \
1295     if( key_usage & code )      \
1296         PRINT_ITEM( name );
1297 
x509_info_key_usage(char ** buf,size_t * size,unsigned int key_usage)1298 static int x509_info_key_usage( char **buf, size_t *size,
1299                                 unsigned int key_usage )
1300 {
1301     int ret;
1302     size_t n = *size;
1303     char *p = *buf;
1304     const char *sep = "";
1305 
1306     KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE,    "Digital Signature" );
1307     KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION,      "Non Repudiation" );
1308     KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT,     "Key Encipherment" );
1309     KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT,    "Data Encipherment" );
1310     KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT,        "Key Agreement" );
1311     KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN,        "Key Cert Sign" );
1312     KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN,             "CRL Sign" );
1313     KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY,        "Encipher Only" );
1314     KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY,        "Decipher Only" );
1315 
1316     *size = n;
1317     *buf = p;
1318 
1319     return( 0 );
1320 }
1321 
x509_info_ext_key_usage(char ** buf,size_t * size,const mbedtls_x509_sequence * extended_key_usage)1322 static int x509_info_ext_key_usage( char **buf, size_t *size,
1323                                     const mbedtls_x509_sequence *extended_key_usage )
1324 {
1325     int ret;
1326     const char *desc;
1327     size_t n = *size;
1328     char *p = *buf;
1329     const mbedtls_x509_sequence *cur = extended_key_usage;
1330     const char *sep = "";
1331 
1332     while( cur != NULL )
1333     {
1334         if( mbedtls_oid_get_extended_key_usage( &cur->buf, &desc ) != 0 )
1335             desc = "???";
1336 
1337         ret = mbedtls_snprintf( p, n, "%s%s", sep, desc );
1338         MBEDTLS_X509_SAFE_SNPRINTF;
1339 
1340         sep = ", ";
1341 
1342         cur = cur->next;
1343     }
1344 
1345     *size = n;
1346     *buf = p;
1347 
1348     return( 0 );
1349 }
1350 
1351 /*
1352  * Return an informational string about the certificate.
1353  */
1354 #define BEFORE_COLON    18
1355 #define BC              "18"
mbedtls_x509_crt_info(char * buf,size_t size,const char * prefix,const mbedtls_x509_crt * crt)1356 int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
1357                    const mbedtls_x509_crt *crt )
1358 {
1359     int ret;
1360     size_t n;
1361     char *p;
1362     char key_size_str[BEFORE_COLON];
1363 
1364     p = buf;
1365     n = size;
1366 
1367     if( NULL == crt )
1368     {
1369         ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" );
1370         MBEDTLS_X509_SAFE_SNPRINTF;
1371 
1372         return( (int) ( size - n ) );
1373     }
1374 
1375     ret = mbedtls_snprintf( p, n, "%scert. version     : %d\n",
1376                                prefix, crt->version );
1377     MBEDTLS_X509_SAFE_SNPRINTF;
1378     ret = mbedtls_snprintf( p, n, "%sserial number     : ",
1379                                prefix );
1380     MBEDTLS_X509_SAFE_SNPRINTF;
1381 
1382     ret = mbedtls_x509_serial_gets( p, n, &crt->serial );
1383     MBEDTLS_X509_SAFE_SNPRINTF;
1384 
1385     ret = mbedtls_snprintf( p, n, "\n%sissuer name       : ", prefix );
1386     MBEDTLS_X509_SAFE_SNPRINTF;
1387     ret = mbedtls_x509_dn_gets( p, n, &crt->issuer  );
1388     MBEDTLS_X509_SAFE_SNPRINTF;
1389 
1390     ret = mbedtls_snprintf( p, n, "\n%ssubject name      : ", prefix );
1391     MBEDTLS_X509_SAFE_SNPRINTF;
1392     ret = mbedtls_x509_dn_gets( p, n, &crt->subject );
1393     MBEDTLS_X509_SAFE_SNPRINTF;
1394 
1395     ret = mbedtls_snprintf( p, n, "\n%sissued  on        : " \
1396                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1397                    crt->valid_from.year, crt->valid_from.mon,
1398                    crt->valid_from.day,  crt->valid_from.hour,
1399                    crt->valid_from.min,  crt->valid_from.sec );
1400     MBEDTLS_X509_SAFE_SNPRINTF;
1401 
1402     ret = mbedtls_snprintf( p, n, "\n%sexpires on        : " \
1403                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1404                    crt->valid_to.year, crt->valid_to.mon,
1405                    crt->valid_to.day,  crt->valid_to.hour,
1406                    crt->valid_to.min,  crt->valid_to.sec );
1407     MBEDTLS_X509_SAFE_SNPRINTF;
1408 
1409     ret = mbedtls_snprintf( p, n, "\n%ssigned using      : ", prefix );
1410     MBEDTLS_X509_SAFE_SNPRINTF;
1411 
1412     ret = mbedtls_x509_sig_alg_gets( p, n, &crt->sig_oid, crt->sig_pk,
1413                              crt->sig_md, crt->sig_opts );
1414     MBEDTLS_X509_SAFE_SNPRINTF;
1415 
1416     /* Key size */
1417     if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
1418                                       mbedtls_pk_get_name( &crt->pk ) ) ) != 0 )
1419     {
1420         return( ret );
1421     }
1422 
1423     ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str,
1424                           (int) mbedtls_pk_get_bitlen( &crt->pk ) );
1425     MBEDTLS_X509_SAFE_SNPRINTF;
1426 
1427     /*
1428      * Optional extensions
1429      */
1430 
1431     if( crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS )
1432     {
1433         ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix,
1434                         crt->ca_istrue ? "true" : "false" );
1435         MBEDTLS_X509_SAFE_SNPRINTF;
1436 
1437         if( crt->max_pathlen > 0 )
1438         {
1439             ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 );
1440             MBEDTLS_X509_SAFE_SNPRINTF;
1441         }
1442     }
1443 
1444     if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
1445     {
1446         ret = mbedtls_snprintf( p, n, "\n%ssubject alt name  : ", prefix );
1447         MBEDTLS_X509_SAFE_SNPRINTF;
1448 
1449         if( ( ret = x509_info_subject_alt_name( &p, &n,
1450                                             &crt->subject_alt_names ) ) != 0 )
1451             return( ret );
1452     }
1453 
1454     if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE )
1455     {
1456         ret = mbedtls_snprintf( p, n, "\n%scert. type        : ", prefix );
1457         MBEDTLS_X509_SAFE_SNPRINTF;
1458 
1459         if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 )
1460             return( ret );
1461     }
1462 
1463     if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE )
1464     {
1465         ret = mbedtls_snprintf( p, n, "\n%skey usage         : ", prefix );
1466         MBEDTLS_X509_SAFE_SNPRINTF;
1467 
1468         if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 )
1469             return( ret );
1470     }
1471 
1472     if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE )
1473     {
1474         ret = mbedtls_snprintf( p, n, "\n%sext key usage     : ", prefix );
1475         MBEDTLS_X509_SAFE_SNPRINTF;
1476 
1477         if( ( ret = x509_info_ext_key_usage( &p, &n,
1478                                              &crt->ext_key_usage ) ) != 0 )
1479             return( ret );
1480     }
1481 
1482     ret = mbedtls_snprintf( p, n, "\n" );
1483     MBEDTLS_X509_SAFE_SNPRINTF;
1484 
1485     return( (int) ( size - n ) );
1486 }
1487 
1488 struct x509_crt_verify_string {
1489     int code;
1490     const char *string;
1491 };
1492 
1493 static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
1494     { MBEDTLS_X509_BADCERT_EXPIRED,       "The certificate validity has expired" },
1495     { MBEDTLS_X509_BADCERT_REVOKED,       "The certificate has been revoked (is on a CRL)" },
1496     { MBEDTLS_X509_BADCERT_CN_MISMATCH,   "The certificate Common Name (CN) does not match with the expected CN" },
1497     { MBEDTLS_X509_BADCERT_NOT_TRUSTED,   "The certificate is not correctly signed by the trusted CA" },
1498     { MBEDTLS_X509_BADCRL_NOT_TRUSTED,    "The CRL is not correctly signed by the trusted CA" },
1499     { MBEDTLS_X509_BADCRL_EXPIRED,        "The CRL is expired" },
1500     { MBEDTLS_X509_BADCERT_MISSING,       "Certificate was missing" },
1501     { MBEDTLS_X509_BADCERT_SKIP_VERIFY,   "Certificate verification was skipped" },
1502     { MBEDTLS_X509_BADCERT_OTHER,         "Other reason (can be used by verify callback)" },
1503     { MBEDTLS_X509_BADCERT_FUTURE,        "The certificate validity starts in the future" },
1504     { MBEDTLS_X509_BADCRL_FUTURE,         "The CRL is from the future" },
1505     { MBEDTLS_X509_BADCERT_KEY_USAGE,     "Usage does not match the keyUsage extension" },
1506     { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" },
1507     { MBEDTLS_X509_BADCERT_NS_CERT_TYPE,  "Usage does not match the nsCertType extension" },
1508     { MBEDTLS_X509_BADCERT_BAD_MD,        "The certificate is signed with an unacceptable hash." },
1509     { MBEDTLS_X509_BADCERT_BAD_PK,        "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
1510     { MBEDTLS_X509_BADCERT_BAD_KEY,       "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." },
1511     { MBEDTLS_X509_BADCRL_BAD_MD,         "The CRL is signed with an unacceptable hash." },
1512     { MBEDTLS_X509_BADCRL_BAD_PK,         "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
1513     { MBEDTLS_X509_BADCRL_BAD_KEY,        "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." },
1514     { 0, NULL }
1515 };
1516 
mbedtls_x509_crt_verify_info(char * buf,size_t size,const char * prefix,uint32_t flags)1517 int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
1518                           uint32_t flags )
1519 {
1520     int ret;
1521     const struct x509_crt_verify_string *cur;
1522     char *p = buf;
1523     size_t n = size;
1524 
1525     for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ )
1526     {
1527         if( ( flags & cur->code ) == 0 )
1528             continue;
1529 
1530         ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string );
1531         MBEDTLS_X509_SAFE_SNPRINTF;
1532         flags ^= cur->code;
1533     }
1534 
1535     if( flags != 0 )
1536     {
1537         ret = mbedtls_snprintf( p, n, "%sUnknown reason "
1538                                        "(this should not happen)\n", prefix );
1539         MBEDTLS_X509_SAFE_SNPRINTF;
1540     }
1541 
1542     return( (int) ( size - n ) );
1543 }
1544 
1545 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
mbedtls_x509_crt_check_key_usage(const mbedtls_x509_crt * crt,unsigned int usage)1546 int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
1547                                       unsigned int usage )
1548 {
1549     unsigned int usage_must, usage_may;
1550     unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY
1551                           | MBEDTLS_X509_KU_DECIPHER_ONLY;
1552 
1553     if( ( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) == 0 )
1554         return( 0 );
1555 
1556     usage_must = usage & ~may_mask;
1557 
1558     if( ( ( crt->key_usage & ~may_mask ) & usage_must ) != usage_must )
1559         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
1560 
1561     usage_may = usage & may_mask;
1562 
1563     if( ( ( crt->key_usage & may_mask ) | usage_may ) != usage_may )
1564         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
1565 
1566     return( 0 );
1567 }
1568 #endif
1569 
1570 #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
mbedtls_x509_crt_check_extended_key_usage(const mbedtls_x509_crt * crt,const char * usage_oid,size_t usage_len)1571 int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
1572                                        const char *usage_oid,
1573                                        size_t usage_len )
1574 {
1575     const mbedtls_x509_sequence *cur;
1576 
1577     /* Extension is not mandatory, absent means no restriction */
1578     if( ( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 )
1579         return( 0 );
1580 
1581     /*
1582      * Look for the requested usage (or wildcard ANY) in our list
1583      */
1584     for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next )
1585     {
1586         const mbedtls_x509_buf *cur_oid = &cur->buf;
1587 
1588         if( cur_oid->len == usage_len &&
1589             memcmp( cur_oid->p, usage_oid, usage_len ) == 0 )
1590         {
1591             return( 0 );
1592         }
1593 
1594         if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) == 0 )
1595             return( 0 );
1596     }
1597 
1598     return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
1599 }
1600 #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
1601 
1602 #if defined(MBEDTLS_X509_CRL_PARSE_C)
1603 /*
1604  * Return 1 if the certificate is revoked, or 0 otherwise.
1605  */
mbedtls_x509_crt_is_revoked(const mbedtls_x509_crt * crt,const mbedtls_x509_crl * crl)1606 int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl )
1607 {
1608     const mbedtls_x509_crl_entry *cur = &crl->entry;
1609 
1610     while( cur != NULL && cur->serial.len != 0 )
1611     {
1612         if( crt->serial.len == cur->serial.len &&
1613             memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
1614         {
1615             if( mbedtls_x509_time_is_past( &cur->revocation_date ) )
1616                 return( 1 );
1617         }
1618 
1619         cur = cur->next;
1620     }
1621 
1622     return( 0 );
1623 }
1624 
1625 /*
1626  * Check that the given certificate is not revoked according to the CRL.
1627  * Skip validation is no CRL for the given CA is present.
1628  */
x509_crt_verifycrl(mbedtls_x509_crt * crt,mbedtls_x509_crt * ca,mbedtls_x509_crl * crl_list,const mbedtls_x509_crt_profile * profile)1629 static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
1630                                mbedtls_x509_crl *crl_list,
1631                                const mbedtls_x509_crt_profile *profile )
1632 {
1633     int flags = 0;
1634     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
1635     const mbedtls_md_info_t *md_info;
1636 
1637     if( ca == NULL )
1638         return( flags );
1639 
1640     while( crl_list != NULL )
1641     {
1642         if( crl_list->version == 0 ||
1643             crl_list->issuer_raw.len != ca->subject_raw.len ||
1644             memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
1645                     crl_list->issuer_raw.len ) != 0 )
1646         {
1647             crl_list = crl_list->next;
1648             continue;
1649         }
1650 
1651         /*
1652          * Check if the CA is configured to sign CRLs
1653          */
1654 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
1655         if( mbedtls_x509_crt_check_key_usage( ca, MBEDTLS_X509_KU_CRL_SIGN ) != 0 )
1656         {
1657             flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
1658             break;
1659         }
1660 #endif
1661 
1662         /*
1663          * Check if CRL is correctly signed by the trusted CA
1664          */
1665         if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 )
1666             flags |= MBEDTLS_X509_BADCRL_BAD_MD;
1667 
1668         if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 )
1669             flags |= MBEDTLS_X509_BADCRL_BAD_PK;
1670 
1671         md_info = mbedtls_md_info_from_type( crl_list->sig_md );
1672         if( md_info == NULL )
1673         {
1674             /*
1675              * Cannot check 'unknown' hash
1676              */
1677             flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
1678             break;
1679         }
1680 
1681         mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
1682 
1683         if( x509_profile_check_key( profile, crl_list->sig_pk, &ca->pk ) != 0 )
1684             flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
1685 
1686         if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk,
1687                            crl_list->sig_md, hash, mbedtls_md_get_size( md_info ),
1688                            crl_list->sig.p, crl_list->sig.len ) != 0 )
1689         {
1690             flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
1691             break;
1692         }
1693 
1694         /*
1695          * Check for validity of CRL (Do not drop out)
1696          */
1697         if( mbedtls_x509_time_is_past( &crl_list->next_update ) )
1698             flags |= MBEDTLS_X509_BADCRL_EXPIRED;
1699 
1700         if( mbedtls_x509_time_is_future( &crl_list->this_update ) )
1701             flags |= MBEDTLS_X509_BADCRL_FUTURE;
1702 
1703         /*
1704          * Check if certificate is revoked
1705          */
1706         if( mbedtls_x509_crt_is_revoked( crt, crl_list ) )
1707         {
1708             flags |= MBEDTLS_X509_BADCERT_REVOKED;
1709             break;
1710         }
1711 
1712         crl_list = crl_list->next;
1713     }
1714 
1715     return( flags );
1716 }
1717 #endif /* MBEDTLS_X509_CRL_PARSE_C */
1718 
1719 /*
1720  * Like memcmp, but case-insensitive and always returns -1 if different
1721  */
x509_memcasecmp(const void * s1,const void * s2,size_t len)1722 static int x509_memcasecmp( const void *s1, const void *s2, size_t len )
1723 {
1724     size_t i;
1725     unsigned char diff;
1726     const unsigned char *n1 = s1, *n2 = s2;
1727 
1728     for( i = 0; i < len; i++ )
1729     {
1730         diff = n1[i] ^ n2[i];
1731 
1732         if( diff == 0 )
1733             continue;
1734 
1735         if( diff == 32 &&
1736             ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
1737               ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
1738         {
1739             continue;
1740         }
1741 
1742         return( -1 );
1743     }
1744 
1745     return( 0 );
1746 }
1747 
1748 /*
1749  * Return 0 if name matches wildcard, -1 otherwise
1750  */
x509_check_wildcard(const char * cn,mbedtls_x509_buf * name)1751 static int x509_check_wildcard( const char *cn, mbedtls_x509_buf *name )
1752 {
1753     size_t i;
1754     size_t cn_idx = 0, cn_len = strlen( cn );
1755 
1756     if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
1757         return( 0 );
1758 
1759     for( i = 0; i < cn_len; ++i )
1760     {
1761         if( cn[i] == '.' )
1762         {
1763             cn_idx = i;
1764             break;
1765         }
1766     }
1767 
1768     if( cn_idx == 0 )
1769         return( -1 );
1770 
1771     if( cn_len - cn_idx == name->len - 1 &&
1772         x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
1773     {
1774         return( 0 );
1775     }
1776 
1777     return( -1 );
1778 }
1779 
1780 /*
1781  * Compare two X.509 strings, case-insensitive, and allowing for some encoding
1782  * variations (but not all).
1783  *
1784  * Return 0 if equal, -1 otherwise.
1785  */
x509_string_cmp(const mbedtls_x509_buf * a,const mbedtls_x509_buf * b)1786 static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b )
1787 {
1788     if( a->tag == b->tag &&
1789         a->len == b->len &&
1790         memcmp( a->p, b->p, b->len ) == 0 )
1791     {
1792         return( 0 );
1793     }
1794 
1795     if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
1796         ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
1797         a->len == b->len &&
1798         x509_memcasecmp( a->p, b->p, b->len ) == 0 )
1799     {
1800         return( 0 );
1801     }
1802 
1803     return( -1 );
1804 }
1805 
1806 /*
1807  * Compare two X.509 Names (aka rdnSequence).
1808  *
1809  * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
1810  * we sometimes return unequal when the full algorithm would return equal,
1811  * but never the other way. (In particular, we don't do Unicode normalisation
1812  * or space folding.)
1813  *
1814  * Return 0 if equal, -1 otherwise.
1815  */
x509_name_cmp(const mbedtls_x509_name * a,const mbedtls_x509_name * b)1816 static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b )
1817 {
1818     /* Avoid recursion, it might not be optimised by the compiler */
1819     while( a != NULL || b != NULL )
1820     {
1821         if( a == NULL || b == NULL )
1822             return( -1 );
1823 
1824         /* type */
1825         if( a->oid.tag != b->oid.tag ||
1826             a->oid.len != b->oid.len ||
1827             memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 )
1828         {
1829             return( -1 );
1830         }
1831 
1832         /* value */
1833         if( x509_string_cmp( &a->val, &b->val ) != 0 )
1834             return( -1 );
1835 
1836         /* structure of the list of sets */
1837         if( a->next_merged != b->next_merged )
1838             return( -1 );
1839 
1840         a = a->next;
1841         b = b->next;
1842     }
1843 
1844     /* a == NULL == b */
1845     return( 0 );
1846 }
1847 
1848 /*
1849  * Check if 'parent' is a suitable parent (signing CA) for 'child'.
1850  * Return 0 if yes, -1 if not.
1851  *
1852  * top means parent is a locally-trusted certificate
1853  * bottom means child is the end entity cert
1854  */
x509_crt_check_parent(const mbedtls_x509_crt * child,const mbedtls_x509_crt * parent,int top,int bottom)1855 static int x509_crt_check_parent( const mbedtls_x509_crt *child,
1856                                   const mbedtls_x509_crt *parent,
1857                                   int top, int bottom )
1858 {
1859     int need_ca_bit;
1860 
1861     /* Parent must be the issuer */
1862     if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 )
1863         return( -1 );
1864 
1865     /* Parent must have the basicConstraints CA bit set as a general rule */
1866     need_ca_bit = 1;
1867 
1868     /* Exception: v1/v2 certificates that are locally trusted. */
1869     if( top && parent->version < 3 )
1870         need_ca_bit = 0;
1871 
1872     /* Exception: self-signed end-entity certs that are locally trusted. */
1873     if( top && bottom &&
1874         child->raw.len == parent->raw.len &&
1875         memcmp( child->raw.p, parent->raw.p, child->raw.len ) == 0 )
1876     {
1877         need_ca_bit = 0;
1878     }
1879 
1880     if( need_ca_bit && ! parent->ca_istrue )
1881         return( -1 );
1882 
1883 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
1884     if( need_ca_bit &&
1885         mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 )
1886     {
1887         return( -1 );
1888     }
1889 #endif
1890 
1891     return( 0 );
1892 }
1893 
x509_crt_verify_top(mbedtls_x509_crt * child,mbedtls_x509_crt * trust_ca,mbedtls_x509_crl * ca_crl,const mbedtls_x509_crt_profile * profile,int path_cnt,int self_cnt,uint32_t * flags,int (* f_vrfy)(void *,mbedtls_x509_crt *,int,uint32_t *),void * p_vrfy)1894 static int x509_crt_verify_top(
1895                 mbedtls_x509_crt *child, mbedtls_x509_crt *trust_ca,
1896                 mbedtls_x509_crl *ca_crl,
1897                 const mbedtls_x509_crt_profile *profile,
1898                 int path_cnt, int self_cnt, uint32_t *flags,
1899                 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
1900                 void *p_vrfy )
1901 {
1902     int ret;
1903     uint32_t ca_flags = 0;
1904     int check_path_cnt;
1905     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
1906     const mbedtls_md_info_t *md_info;
1907 
1908     if( mbedtls_x509_time_is_past( &child->valid_to ) )
1909         *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
1910 
1911     if( mbedtls_x509_time_is_future( &child->valid_from ) )
1912         *flags |= MBEDTLS_X509_BADCERT_FUTURE;
1913 
1914     if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
1915         *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
1916 
1917     if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
1918         *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
1919 
1920     /*
1921      * Child is the top of the chain. Check against the trust_ca list.
1922      */
1923     *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
1924 
1925     md_info = mbedtls_md_info_from_type( child->sig_md );
1926     if( md_info == NULL )
1927     {
1928         /*
1929          * Cannot check 'unknown', no need to try any CA
1930          */
1931         trust_ca = NULL;
1932     }
1933     else
1934         mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash );
1935 
1936     for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next )
1937     {
1938         if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 )
1939             continue;
1940 
1941         check_path_cnt = path_cnt + 1;
1942 
1943         /*
1944          * Reduce check_path_cnt to check against if top of the chain is
1945          * the same as the trusted CA
1946          */
1947         if( child->subject_raw.len == trust_ca->subject_raw.len &&
1948             memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
1949                             child->issuer_raw.len ) == 0 )
1950         {
1951             check_path_cnt--;
1952         }
1953 
1954         /* Self signed certificates do not count towards the limit */
1955         if( trust_ca->max_pathlen > 0 &&
1956             trust_ca->max_pathlen < check_path_cnt - self_cnt )
1957         {
1958             continue;
1959         }
1960 
1961         if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) )
1962         {
1963             continue;
1964         }
1965 
1966         if( mbedtls_x509_time_is_future( &trust_ca->valid_from ) )
1967         {
1968             continue;
1969         }
1970 
1971         if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk,
1972                            child->sig_md, hash, mbedtls_md_get_size( md_info ),
1973                            child->sig.p, child->sig.len ) != 0 )
1974         {
1975             continue;
1976         }
1977 
1978         /*
1979          * Top of chain is signed by a trusted CA
1980          */
1981         *flags &= ~MBEDTLS_X509_BADCERT_NOT_TRUSTED;
1982 
1983         if( x509_profile_check_key( profile, child->sig_pk, &trust_ca->pk ) != 0 )
1984             *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
1985 
1986         break;
1987     }
1988 
1989     /*
1990      * If top of chain is not the same as the trusted CA send a verify request
1991      * to the callback for any issues with validity and CRL presence for the
1992      * trusted CA certificate.
1993      */
1994     if( trust_ca != NULL &&
1995         ( child->subject_raw.len != trust_ca->subject_raw.len ||
1996           memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
1997                             child->issuer_raw.len ) != 0 ) )
1998     {
1999 #if defined(MBEDTLS_X509_CRL_PARSE_C)
2000         /* Check trusted CA's CRL for the chain's top crt */
2001         *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl, profile );
2002 #else
2003         ((void) ca_crl);
2004 #endif
2005 
2006         if( NULL != f_vrfy )
2007         {
2008             if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1,
2009                                 &ca_flags ) ) != 0 )
2010             {
2011                 return( ret );
2012             }
2013         }
2014     }
2015 
2016     /* Call callback on top cert */
2017     if( NULL != f_vrfy )
2018     {
2019         if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
2020             return( ret );
2021     }
2022 
2023     *flags |= ca_flags;
2024 
2025     return( 0 );
2026 }
2027 
x509_crt_verify_child(mbedtls_x509_crt * child,mbedtls_x509_crt * parent,mbedtls_x509_crt * trust_ca,mbedtls_x509_crl * ca_crl,const mbedtls_x509_crt_profile * profile,int path_cnt,int self_cnt,uint32_t * flags,int (* f_vrfy)(void *,mbedtls_x509_crt *,int,uint32_t *),void * p_vrfy)2028 static int x509_crt_verify_child(
2029                 mbedtls_x509_crt *child, mbedtls_x509_crt *parent,
2030                 mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl,
2031                 const mbedtls_x509_crt_profile *profile,
2032                 int path_cnt, int self_cnt, uint32_t *flags,
2033                 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
2034                 void *p_vrfy )
2035 {
2036     int ret;
2037     uint32_t parent_flags = 0;
2038     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
2039     mbedtls_x509_crt *grandparent;
2040     const mbedtls_md_info_t *md_info;
2041 
2042     /* Counting intermediate self signed certificates */
2043     if( ( path_cnt != 0 ) && x509_name_cmp( &child->issuer, &child->subject ) == 0 )
2044         self_cnt++;
2045 
2046     /* path_cnt is 0 for the first intermediate CA */
2047     if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA )
2048     {
2049         *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
2050         return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
2051     }
2052 
2053     if( mbedtls_x509_time_is_past( &child->valid_to ) )
2054         *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
2055 
2056     if( mbedtls_x509_time_is_future( &child->valid_from ) )
2057         *flags |= MBEDTLS_X509_BADCERT_FUTURE;
2058 
2059     if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
2060         *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
2061 
2062     if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
2063         *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
2064 
2065     md_info = mbedtls_md_info_from_type( child->sig_md );
2066     if( md_info == NULL )
2067     {
2068         /*
2069          * Cannot check 'unknown' hash
2070          */
2071         *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
2072     }
2073     else
2074     {
2075         mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash );
2076 
2077         if( x509_profile_check_key( profile, child->sig_pk, &parent->pk ) != 0 )
2078             *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
2079 
2080         if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
2081                            child->sig_md, hash, mbedtls_md_get_size( md_info ),
2082                            child->sig.p, child->sig.len ) != 0 )
2083         {
2084             *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
2085         }
2086     }
2087 
2088 #if defined(MBEDTLS_X509_CRL_PARSE_C)
2089     /* Check trusted CA's CRL for the given crt */
2090     *flags |= x509_crt_verifycrl(child, parent, ca_crl, profile );
2091 #endif
2092 
2093     /* Look for a grandparent in trusted CAs */
2094     for( grandparent = trust_ca;
2095          grandparent != NULL;
2096          grandparent = grandparent->next )
2097     {
2098         if( x509_crt_check_parent( parent, grandparent,
2099                                    0, path_cnt == 0 ) == 0 )
2100             break;
2101     }
2102 
2103     if( grandparent != NULL )
2104     {
2105         ret = x509_crt_verify_top( parent, grandparent, ca_crl, profile,
2106                                 path_cnt + 1, self_cnt, &parent_flags, f_vrfy, p_vrfy );
2107         if( ret != 0 )
2108             return( ret );
2109     }
2110     else
2111     {
2112         /* Look for a grandparent upwards the chain */
2113         for( grandparent = parent->next;
2114              grandparent != NULL;
2115              grandparent = grandparent->next )
2116         {
2117             /* +2 because the current step is not yet accounted for
2118              * and because max_pathlen is one higher than it should be.
2119              * Also self signed certificates do not count to the limit. */
2120             if( grandparent->max_pathlen > 0 &&
2121                 grandparent->max_pathlen < 2 + path_cnt - self_cnt )
2122             {
2123                 continue;
2124             }
2125 
2126             if( x509_crt_check_parent( parent, grandparent,
2127                                        0, path_cnt == 0 ) == 0 )
2128                 break;
2129         }
2130 
2131         /* Is our parent part of the chain or at the top? */
2132         if( grandparent != NULL )
2133         {
2134             ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl,
2135                                          profile, path_cnt + 1, self_cnt, &parent_flags,
2136                                          f_vrfy, p_vrfy );
2137             if( ret != 0 )
2138                 return( ret );
2139         }
2140         else
2141         {
2142             ret = x509_crt_verify_top( parent, trust_ca, ca_crl, profile,
2143                                        path_cnt + 1, self_cnt, &parent_flags,
2144                                        f_vrfy, p_vrfy );
2145             if( ret != 0 )
2146                 return( ret );
2147         }
2148     }
2149 
2150     /* child is verified to be a child of the parent, call verify callback */
2151     if( NULL != f_vrfy )
2152         if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
2153             return( ret );
2154 
2155     *flags |= parent_flags;
2156 
2157     return( 0 );
2158 }
2159 
2160 /*
2161  * Verify the certificate validity
2162  */
mbedtls_x509_crt_verify(mbedtls_x509_crt * crt,mbedtls_x509_crt * trust_ca,mbedtls_x509_crl * ca_crl,const char * cn,uint32_t * flags,int (* f_vrfy)(void *,mbedtls_x509_crt *,int,uint32_t *),void * p_vrfy)2163 int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
2164                      mbedtls_x509_crt *trust_ca,
2165                      mbedtls_x509_crl *ca_crl,
2166                      const char *cn, uint32_t *flags,
2167                      int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
2168                      void *p_vrfy )
2169 {
2170     return( mbedtls_x509_crt_verify_with_profile( crt, trust_ca, ca_crl,
2171                 &mbedtls_x509_crt_profile_default, cn, flags, f_vrfy, p_vrfy ) );
2172 }
2173 
2174 
2175 /*
2176  * Verify the certificate validity, with profile
2177  */
mbedtls_x509_crt_verify_with_profile(mbedtls_x509_crt * crt,mbedtls_x509_crt * trust_ca,mbedtls_x509_crl * ca_crl,const mbedtls_x509_crt_profile * profile,const char * cn,uint32_t * flags,int (* f_vrfy)(void *,mbedtls_x509_crt *,int,uint32_t *),void * p_vrfy)2178 int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
2179                      mbedtls_x509_crt *trust_ca,
2180                      mbedtls_x509_crl *ca_crl,
2181                      const mbedtls_x509_crt_profile *profile,
2182                      const char *cn, uint32_t *flags,
2183                      int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
2184                      void *p_vrfy )
2185 {
2186     size_t cn_len;
2187     int ret;
2188     int pathlen = 0, selfsigned = 0;
2189     mbedtls_x509_crt *parent;
2190     mbedtls_x509_name *name;
2191     mbedtls_x509_sequence *cur = NULL;
2192     mbedtls_pk_type_t pk_type;
2193 
2194     if( profile == NULL )
2195         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
2196 
2197     *flags = 0;
2198 
2199     if( cn != NULL )
2200     {
2201         name = &crt->subject;
2202         cn_len = strlen( cn );
2203 
2204         if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
2205         {
2206             cur = &crt->subject_alt_names;
2207 
2208             while( cur != NULL )
2209             {
2210                 if( cur->buf.len == cn_len &&
2211                     x509_memcasecmp( cn, cur->buf.p, cn_len ) == 0 )
2212                     break;
2213 
2214                 if( cur->buf.len > 2 &&
2215                     memcmp( cur->buf.p, "*.", 2 ) == 0 &&
2216                     x509_check_wildcard( cn, &cur->buf ) == 0 )
2217                 {
2218                     break;
2219                 }
2220 
2221                 cur = cur->next;
2222             }
2223 
2224             if( cur == NULL )
2225                 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
2226         }
2227         else
2228         {
2229             while( name != NULL )
2230             {
2231                 if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 )
2232                 {
2233                     if( name->val.len == cn_len &&
2234                         x509_memcasecmp( name->val.p, cn, cn_len ) == 0 )
2235                         break;
2236 
2237                     if( name->val.len > 2 &&
2238                         memcmp( name->val.p, "*.", 2 ) == 0 &&
2239                         x509_check_wildcard( cn, &name->val ) == 0 )
2240                         break;
2241                 }
2242 
2243                 name = name->next;
2244             }
2245 
2246             if( name == NULL )
2247                 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
2248         }
2249     }
2250 
2251     /* Check the type and size of the key */
2252     pk_type = mbedtls_pk_get_type( &crt->pk );
2253 
2254     if( x509_profile_check_pk_alg( profile, pk_type ) != 0 )
2255         *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
2256 
2257     if( x509_profile_check_key( profile, pk_type, &crt->pk ) != 0 )
2258         *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
2259 
2260     /* Look for a parent in trusted CAs */
2261     for( parent = trust_ca; parent != NULL; parent = parent->next )
2262     {
2263         if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 )
2264             break;
2265     }
2266 
2267     if( parent != NULL )
2268     {
2269         ret = x509_crt_verify_top( crt, parent, ca_crl, profile,
2270                                    pathlen, selfsigned, flags, f_vrfy, p_vrfy );
2271         if( ret != 0 )
2272             return( ret );
2273     }
2274     else
2275     {
2276         /* Look for a parent upwards the chain */
2277         for( parent = crt->next; parent != NULL; parent = parent->next )
2278             if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 )
2279                 break;
2280 
2281         /* Are we part of the chain or at the top? */
2282         if( parent != NULL )
2283         {
2284             ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, profile,
2285                                          pathlen, selfsigned, flags, f_vrfy, p_vrfy );
2286             if( ret != 0 )
2287                 return( ret );
2288         }
2289         else
2290         {
2291             ret = x509_crt_verify_top( crt, trust_ca, ca_crl, profile,
2292                                        pathlen, selfsigned, flags, f_vrfy, p_vrfy );
2293             if( ret != 0 )
2294                 return( ret );
2295         }
2296     }
2297 
2298     if( *flags != 0 )
2299         return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
2300 
2301     return( 0 );
2302 }
2303 
2304 /*
2305  * Initialize a certificate chain
2306  */
mbedtls_x509_crt_init(mbedtls_x509_crt * crt)2307 void mbedtls_x509_crt_init( mbedtls_x509_crt *crt )
2308 {
2309     memset( crt, 0, sizeof(mbedtls_x509_crt) );
2310 }
2311 
2312 /*
2313  * Unallocate all certificate data
2314  */
mbedtls_x509_crt_free(mbedtls_x509_crt * crt)2315 void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
2316 {
2317     mbedtls_x509_crt *cert_cur = crt;
2318     mbedtls_x509_crt *cert_prv;
2319     mbedtls_x509_name *name_cur;
2320     mbedtls_x509_name *name_prv;
2321     mbedtls_x509_sequence *seq_cur;
2322     mbedtls_x509_sequence *seq_prv;
2323 
2324     if( crt == NULL )
2325         return;
2326 
2327     do
2328     {
2329         mbedtls_pk_free( &cert_cur->pk );
2330 
2331 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
2332         mbedtls_free( cert_cur->sig_opts );
2333 #endif
2334 
2335         name_cur = cert_cur->issuer.next;
2336         while( name_cur != NULL )
2337         {
2338             name_prv = name_cur;
2339             name_cur = name_cur->next;
2340             mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
2341             mbedtls_free( name_prv );
2342         }
2343 
2344         name_cur = cert_cur->subject.next;
2345         while( name_cur != NULL )
2346         {
2347             name_prv = name_cur;
2348             name_cur = name_cur->next;
2349             mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
2350             mbedtls_free( name_prv );
2351         }
2352 
2353         seq_cur = cert_cur->ext_key_usage.next;
2354         while( seq_cur != NULL )
2355         {
2356             seq_prv = seq_cur;
2357             seq_cur = seq_cur->next;
2358             mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
2359             mbedtls_free( seq_prv );
2360         }
2361 
2362         seq_cur = cert_cur->subject_alt_names.next;
2363         while( seq_cur != NULL )
2364         {
2365             seq_prv = seq_cur;
2366             seq_cur = seq_cur->next;
2367             mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
2368             mbedtls_free( seq_prv );
2369         }
2370 
2371         if( cert_cur->raw.p != NULL )
2372         {
2373             mbedtls_zeroize( cert_cur->raw.p, cert_cur->raw.len );
2374             mbedtls_free( cert_cur->raw.p );
2375         }
2376 
2377         cert_cur = cert_cur->next;
2378     }
2379     while( cert_cur != NULL );
2380 
2381     cert_cur = crt;
2382     do
2383     {
2384         cert_prv = cert_cur;
2385         cert_cur = cert_cur->next;
2386 
2387         mbedtls_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) );
2388         if( cert_prv != crt )
2389             mbedtls_free( cert_prv );
2390     }
2391     while( cert_cur != NULL );
2392 }
2393 
2394 #endif /* MBEDTLS_X509_CRT_PARSE_C */
2395