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