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