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