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