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