2 * X.509 certificate parsing and verification
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * This file is part of mbed TLS (https://tls.mbed.org)
24 * The ITU-T X.509 standard defines a certificate format for PKI.
26 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
27 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
28 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
30 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
31 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
34 #if !defined(MBEDTLS_CONFIG_FILE)
35 #include "mbedtls/config.h"
37 #include MBEDTLS_CONFIG_FILE
40 #if defined(MBEDTLS_X509_CRT_PARSE_C)
42 #include "mbedtls/x509_crt.h"
43 #include "mbedtls/oid.h"
48 #if defined(MBEDTLS_PEM_PARSE_C)
49 #include "mbedtls/pem.h"
52 #if defined(MBEDTLS_PLATFORM_C)
53 #include "mbedtls/platform.h"
56 #define mbedtls_free free
57 #define mbedtls_calloc calloc
58 #define mbedtls_snprintf snprintf
61 #if defined(MBEDTLS_THREADING_C)
62 #include "mbedtls/threading.h"
65 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
71 #if defined(MBEDTLS_FS_IO)
73 #if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
74 #include <sys/types.h>
77 #endif /* !_WIN32 || EFIX64 || EFI32 */
80 /* Implementation that should never be optimized out by the compiler */
81 static void mbedtls_zeroize( void *v
, size_t n
) {
82 volatile unsigned char *p
= v
; while( n
-- ) *p
++ = 0;
88 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default
=
90 /* Hashes from SHA-1 and above */
91 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1
) |
92 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160
) |
93 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224
) |
94 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256
) |
95 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384
) |
96 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512
),
97 0xFFFFFFF, /* Any PK alg */
98 0xFFFFFFF, /* Any curve */
103 * Next-default profile
105 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next
=
107 /* Hashes from SHA-256 and above */
108 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256
) |
109 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384
) |
110 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512
),
111 0xFFFFFFF, /* Any PK alg */
112 #if defined(MBEDTLS_ECP_C)
113 /* Curves at or above 128-bit security level */
114 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1
) |
115 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1
) |
116 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1
) |
117 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1
) |
118 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1
) |
119 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1
) |
120 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1
),
128 * NSA Suite B Profile
130 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb
=
132 /* Only SHA-256 and 384 */
133 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256
) |
134 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384
),
136 MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA
),
137 #if defined(MBEDTLS_ECP_C)
138 /* Only NIST P-256 and P-384 */
139 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1
) |
140 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1
),
148 * Check md_alg against profile
149 * Return 0 if md_alg acceptable for this profile, -1 otherwise
151 static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile
*profile
,
152 mbedtls_md_type_t md_alg
)
154 if( ( profile
->allowed_mds
& MBEDTLS_X509_ID_FLAG( md_alg
) ) != 0 )
161 * Check pk_alg against profile
162 * Return 0 if pk_alg acceptable for this profile, -1 otherwise
164 static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile
*profile
,
165 mbedtls_pk_type_t pk_alg
)
167 if( ( profile
->allowed_pks
& MBEDTLS_X509_ID_FLAG( pk_alg
) ) != 0 )
174 * Check key against profile
175 * Return 0 if pk_alg acceptable for this profile, -1 otherwise
177 static int x509_profile_check_key( const mbedtls_x509_crt_profile
*profile
,
178 mbedtls_pk_type_t pk_alg
,
179 const mbedtls_pk_context
*pk
)
181 #if defined(MBEDTLS_RSA_C)
182 if( pk_alg
== MBEDTLS_PK_RSA
|| pk_alg
== MBEDTLS_PK_RSASSA_PSS
)
184 if( mbedtls_pk_get_bitlen( pk
) >= profile
->rsa_min_bitlen
)
191 #if defined(MBEDTLS_ECP_C)
192 if( pk_alg
== MBEDTLS_PK_ECDSA
||
193 pk_alg
== MBEDTLS_PK_ECKEY
||
194 pk_alg
== MBEDTLS_PK_ECKEY_DH
)
196 mbedtls_ecp_group_id gid
= mbedtls_pk_ec( *pk
)->grp
.id
;
198 if( ( profile
->allowed_curves
& MBEDTLS_X509_ID_FLAG( gid
) ) != 0 )
209 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
211 static int x509_get_version( unsigned char **p
,
212 const unsigned char *end
,
218 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
219 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| 0 ) ) != 0 )
221 if( ret
== MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)
232 if( ( ret
= mbedtls_asn1_get_int( p
, end
, ver
) ) != 0 )
233 return( MBEDTLS_ERR_X509_INVALID_VERSION
+ ret
);
236 return( MBEDTLS_ERR_X509_INVALID_VERSION
+
237 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
243 * Validity ::= SEQUENCE {
247 static int x509_get_dates( unsigned char **p
,
248 const unsigned char *end
,
249 mbedtls_x509_time
*from
,
250 mbedtls_x509_time
*to
)
255 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
256 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
257 return( MBEDTLS_ERR_X509_INVALID_DATE
+ ret
);
261 if( ( ret
= mbedtls_x509_get_time( p
, end
, from
) ) != 0 )
264 if( ( ret
= mbedtls_x509_get_time( p
, end
, to
) ) != 0 )
268 return( MBEDTLS_ERR_X509_INVALID_DATE
+
269 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
275 * X.509 v2/v3 unique identifier (not parsed)
277 static int x509_get_uid( unsigned char **p
,
278 const unsigned char *end
,
279 mbedtls_x509_buf
*uid
, int n
)
288 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &uid
->len
,
289 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| n
) ) != 0 )
291 if( ret
== MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)
303 static int x509_get_basic_constraints( unsigned char **p
,
304 const unsigned char *end
,
312 * BasicConstraints ::= SEQUENCE {
313 * cA BOOLEAN DEFAULT FALSE,
314 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
316 *ca_istrue
= 0; /* DEFAULT FALSE */
317 *max_pathlen
= 0; /* endless */
319 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
320 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
321 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
326 if( ( ret
= mbedtls_asn1_get_bool( p
, end
, ca_istrue
) ) != 0 )
328 if( ret
== MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)
329 ret
= mbedtls_asn1_get_int( p
, end
, ca_istrue
);
332 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
334 if( *ca_istrue
!= 0 )
341 if( ( ret
= mbedtls_asn1_get_int( p
, end
, max_pathlen
) ) != 0 )
342 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
345 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
346 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
353 static int x509_get_ns_cert_type( unsigned char **p
,
354 const unsigned char *end
,
355 unsigned char *ns_cert_type
)
358 mbedtls_x509_bitstring bs
= { 0, 0, NULL
};
360 if( ( ret
= mbedtls_asn1_get_bitstring( p
, end
, &bs
) ) != 0 )
361 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
364 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
365 MBEDTLS_ERR_ASN1_INVALID_LENGTH
);
367 /* Get actual bitstring */
368 *ns_cert_type
= *bs
.p
;
372 static int x509_get_key_usage( unsigned char **p
,
373 const unsigned char *end
,
374 unsigned int *key_usage
)
378 mbedtls_x509_bitstring bs
= { 0, 0, NULL
};
380 if( ( ret
= mbedtls_asn1_get_bitstring( p
, end
, &bs
) ) != 0 )
381 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
384 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
385 MBEDTLS_ERR_ASN1_INVALID_LENGTH
);
387 /* Get actual bitstring */
389 for( i
= 0; i
< bs
.len
&& i
< sizeof( unsigned int ); i
++ )
391 *key_usage
|= (unsigned int) bs
.p
[i
] << (8*i
);
398 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
400 * KeyPurposeId ::= OBJECT IDENTIFIER
402 static int x509_get_ext_key_usage( unsigned char **p
,
403 const unsigned char *end
,
404 mbedtls_x509_sequence
*ext_key_usage
)
408 if( ( ret
= mbedtls_asn1_get_sequence_of( p
, end
, ext_key_usage
, MBEDTLS_ASN1_OID
) ) != 0 )
409 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
411 /* Sequence length must be >= 1 */
412 if( ext_key_usage
->buf
.p
== NULL
)
413 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
414 MBEDTLS_ERR_ASN1_INVALID_LENGTH
);
420 * SubjectAltName ::= GeneralNames
422 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
424 * GeneralName ::= CHOICE {
425 * otherName [0] OtherName,
426 * rfc822Name [1] IA5String,
427 * dNSName [2] IA5String,
428 * x400Address [3] ORAddress,
429 * directoryName [4] Name,
430 * ediPartyName [5] EDIPartyName,
431 * uniformResourceIdentifier [6] IA5String,
432 * iPAddress [7] OCTET STRING,
433 * registeredID [8] OBJECT IDENTIFIER }
435 * OtherName ::= SEQUENCE {
436 * type-id OBJECT IDENTIFIER,
437 * value [0] EXPLICIT ANY DEFINED BY type-id }
439 * EDIPartyName ::= SEQUENCE {
440 * nameAssigner [0] DirectoryString OPTIONAL,
441 * partyName [1] DirectoryString }
443 * NOTE: we only parse and use dNSName at this point.
445 static int x509_get_subject_alt_name( unsigned char **p
,
446 const unsigned char *end
,
447 mbedtls_x509_sequence
*subject_alt_name
)
451 mbedtls_asn1_buf
*buf
;
453 mbedtls_asn1_sequence
*cur
= subject_alt_name
;
455 /* Get main sequence tag */
456 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
457 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
458 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
460 if( *p
+ len
!= end
)
461 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
462 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
466 if( ( end
- *p
) < 1 )
467 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
468 MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
472 if( ( ret
= mbedtls_asn1_get_len( p
, end
, &tag_len
) ) != 0 )
473 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
475 if( ( tag
& MBEDTLS_ASN1_CONTEXT_SPECIFIC
) != MBEDTLS_ASN1_CONTEXT_SPECIFIC
)
476 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
477 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
479 /* Skip everything but DNS name */
480 if( tag
!= ( MBEDTLS_ASN1_CONTEXT_SPECIFIC
| 2 ) )
486 /* Allocate and assign next pointer */
487 if( cur
->buf
.p
!= NULL
)
489 if( cur
->next
!= NULL
)
490 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
);
492 cur
->next
= mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence
) );
494 if( cur
->next
== NULL
)
495 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
496 MBEDTLS_ERR_ASN1_ALLOC_FAILED
);
508 /* Set final sequence entry's next pointer to NULL */
512 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
513 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
519 * X.509 v3 extensions
522 static int x509_get_crt_ext( unsigned char **p
,
523 const unsigned char *end
,
524 mbedtls_x509_crt
*crt
)
528 unsigned char *end_ext_data
, *end_ext_octet
;
530 if( ( ret
= mbedtls_x509_get_ext( p
, end
, &crt
->v3_ext
, 3 ) ) != 0 )
532 if( ret
== MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)
541 * Extension ::= SEQUENCE {
542 * extnID OBJECT IDENTIFIER,
543 * critical BOOLEAN DEFAULT FALSE,
544 * extnValue OCTET STRING }
546 mbedtls_x509_buf extn_oid
= {0, 0, NULL
};
547 int is_critical
= 0; /* DEFAULT FALSE */
550 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
551 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
552 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
554 end_ext_data
= *p
+ len
;
556 /* Get extension ID */
559 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &extn_oid
.len
, MBEDTLS_ASN1_OID
) ) != 0 )
560 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
565 if( ( end
- *p
) < 1 )
566 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
567 MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
569 /* Get optional critical */
570 if( ( ret
= mbedtls_asn1_get_bool( p
, end_ext_data
, &is_critical
) ) != 0 &&
571 ( ret
!= MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
) )
572 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
574 /* Data should be octet string type */
575 if( ( ret
= mbedtls_asn1_get_tag( p
, end_ext_data
, &len
,
576 MBEDTLS_ASN1_OCTET_STRING
) ) != 0 )
577 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
579 end_ext_octet
= *p
+ len
;
581 if( end_ext_octet
!= end_ext_data
)
582 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
583 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
586 * Detect supported extensions
588 ret
= mbedtls_oid_get_x509_ext_type( &extn_oid
, &ext_type
);
592 /* No parser found, skip extension */
595 #if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
598 /* Data is marked as critical: fail */
599 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
600 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
606 /* Forbid repeated extensions */
607 if( ( crt
->ext_types
& ext_type
) != 0 )
608 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
);
610 crt
->ext_types
|= ext_type
;
614 case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS
:
615 /* Parse basic constraints */
616 if( ( ret
= x509_get_basic_constraints( p
, end_ext_octet
,
617 &crt
->ca_istrue
, &crt
->max_pathlen
) ) != 0 )
621 case MBEDTLS_X509_EXT_KEY_USAGE
:
622 /* Parse key usage */
623 if( ( ret
= x509_get_key_usage( p
, end_ext_octet
,
624 &crt
->key_usage
) ) != 0 )
628 case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE
:
629 /* Parse extended key usage */
630 if( ( ret
= x509_get_ext_key_usage( p
, end_ext_octet
,
631 &crt
->ext_key_usage
) ) != 0 )
635 case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME
:
636 /* Parse subject alt name */
637 if( ( ret
= x509_get_subject_alt_name( p
, end_ext_octet
,
638 &crt
->subject_alt_names
) ) != 0 )
642 case MBEDTLS_X509_EXT_NS_CERT_TYPE
:
643 /* Parse netscape certificate type */
644 if( ( ret
= x509_get_ns_cert_type( p
, end_ext_octet
,
645 &crt
->ns_cert_type
) ) != 0 )
650 return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE
);
655 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
656 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
662 * Parse and fill a single X.509 certificate in DER format
664 static int x509_crt_parse_der_core( mbedtls_x509_crt
*crt
, const unsigned char *buf
,
669 unsigned char *p
, *end
, *crt_end
;
670 mbedtls_x509_buf sig_params1
, sig_params2
, sig_oid2
;
672 memset( &sig_params1
, 0, sizeof( mbedtls_x509_buf
) );
673 memset( &sig_params2
, 0, sizeof( mbedtls_x509_buf
) );
674 memset( &sig_oid2
, 0, sizeof( mbedtls_x509_buf
) );
677 * Check for valid input
679 if( crt
== NULL
|| buf
== NULL
)
680 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
682 // Use the original buffer until we figure out actual length
683 p
= (unsigned char*) buf
;
688 * Certificate ::= SEQUENCE {
689 * tbsCertificate TBSCertificate,
690 * signatureAlgorithm AlgorithmIdentifier,
691 * signatureValue BIT STRING }
693 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
694 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
696 mbedtls_x509_crt_free( crt
);
697 return( MBEDTLS_ERR_X509_INVALID_FORMAT
);
700 if( len
> (size_t) ( end
- p
) )
702 mbedtls_x509_crt_free( crt
);
703 return( MBEDTLS_ERR_X509_INVALID_FORMAT
+
704 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
708 // Create and populate a new buffer for the raw field
709 crt
->raw
.len
= crt_end
- buf
;
710 crt
->raw
.p
= p
= mbedtls_calloc( 1, crt
->raw
.len
);
712 return( MBEDTLS_ERR_X509_ALLOC_FAILED
);
714 memcpy( p
, buf
, crt
->raw
.len
);
716 // Direct pointers to the new buffer
717 p
+= crt
->raw
.len
- len
;
718 end
= crt_end
= p
+ len
;
721 * TBSCertificate ::= SEQUENCE {
725 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
726 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
728 mbedtls_x509_crt_free( crt
);
729 return( MBEDTLS_ERR_X509_INVALID_FORMAT
+ ret
);
733 crt
->tbs
.len
= end
- crt
->tbs
.p
;
736 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
738 * CertificateSerialNumber ::= INTEGER
740 * signature AlgorithmIdentifier
742 if( ( ret
= x509_get_version( &p
, end
, &crt
->version
) ) != 0 ||
743 ( ret
= mbedtls_x509_get_serial( &p
, end
, &crt
->serial
) ) != 0 ||
744 ( ret
= mbedtls_x509_get_alg( &p
, end
, &crt
->sig_oid
,
745 &sig_params1
) ) != 0 )
747 mbedtls_x509_crt_free( crt
);
753 if( crt
->version
> 3 )
755 mbedtls_x509_crt_free( crt
);
756 return( MBEDTLS_ERR_X509_UNKNOWN_VERSION
);
759 if( ( ret
= mbedtls_x509_get_sig_alg( &crt
->sig_oid
, &sig_params1
,
760 &crt
->sig_md
, &crt
->sig_pk
,
761 &crt
->sig_opts
) ) != 0 )
763 mbedtls_x509_crt_free( crt
);
770 crt
->issuer_raw
.p
= p
;
772 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
773 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
775 mbedtls_x509_crt_free( crt
);
776 return( MBEDTLS_ERR_X509_INVALID_FORMAT
+ ret
);
779 if( ( ret
= mbedtls_x509_get_name( &p
, p
+ len
, &crt
->issuer
) ) != 0 )
781 mbedtls_x509_crt_free( crt
);
785 crt
->issuer_raw
.len
= p
- crt
->issuer_raw
.p
;
788 * Validity ::= SEQUENCE {
793 if( ( ret
= x509_get_dates( &p
, end
, &crt
->valid_from
,
794 &crt
->valid_to
) ) != 0 )
796 mbedtls_x509_crt_free( crt
);
803 crt
->subject_raw
.p
= p
;
805 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
806 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
808 mbedtls_x509_crt_free( crt
);
809 return( MBEDTLS_ERR_X509_INVALID_FORMAT
+ ret
);
812 if( len
&& ( ret
= mbedtls_x509_get_name( &p
, p
+ len
, &crt
->subject
) ) != 0 )
814 mbedtls_x509_crt_free( crt
);
818 crt
->subject_raw
.len
= p
- crt
->subject_raw
.p
;
821 * SubjectPublicKeyInfo
823 if( ( ret
= mbedtls_pk_parse_subpubkey( &p
, end
, &crt
->pk
) ) != 0 )
825 mbedtls_x509_crt_free( crt
);
830 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
831 * -- If present, version shall be v2 or v3
832 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
833 * -- If present, version shall be v2 or v3
834 * extensions [3] EXPLICIT Extensions OPTIONAL
835 * -- If present, version shall be v3
837 if( crt
->version
== 2 || crt
->version
== 3 )
839 ret
= x509_get_uid( &p
, end
, &crt
->issuer_id
, 1 );
842 mbedtls_x509_crt_free( crt
);
847 if( crt
->version
== 2 || crt
->version
== 3 )
849 ret
= x509_get_uid( &p
, end
, &crt
->subject_id
, 2 );
852 mbedtls_x509_crt_free( crt
);
857 #if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
858 if( crt
->version
== 3 )
861 ret
= x509_get_crt_ext( &p
, end
, crt
);
864 mbedtls_x509_crt_free( crt
);
871 mbedtls_x509_crt_free( crt
);
872 return( MBEDTLS_ERR_X509_INVALID_FORMAT
+
873 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
880 * -- end of TBSCertificate
882 * signatureAlgorithm AlgorithmIdentifier,
883 * signatureValue BIT STRING
885 if( ( ret
= mbedtls_x509_get_alg( &p
, end
, &sig_oid2
, &sig_params2
) ) != 0 )
887 mbedtls_x509_crt_free( crt
);
891 if( crt
->sig_oid
.len
!= sig_oid2
.len
||
892 memcmp( crt
->sig_oid
.p
, sig_oid2
.p
, crt
->sig_oid
.len
) != 0 ||
893 sig_params1
.len
!= sig_params2
.len
||
894 ( sig_params1
.len
!= 0 &&
895 memcmp( sig_params1
.p
, sig_params2
.p
, sig_params1
.len
) != 0 ) )
897 mbedtls_x509_crt_free( crt
);
898 return( MBEDTLS_ERR_X509_SIG_MISMATCH
);
901 if( ( ret
= mbedtls_x509_get_sig( &p
, end
, &crt
->sig
) ) != 0 )
903 mbedtls_x509_crt_free( crt
);
909 mbedtls_x509_crt_free( crt
);
910 return( MBEDTLS_ERR_X509_INVALID_FORMAT
+
911 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
918 * Parse one X.509 certificate in DER format from a buffer and add them to a
921 int mbedtls_x509_crt_parse_der( mbedtls_x509_crt
*chain
, const unsigned char *buf
,
925 mbedtls_x509_crt
*crt
= chain
, *prev
= NULL
;
928 * Check for valid input
930 if( crt
== NULL
|| buf
== NULL
)
931 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
933 while( crt
->version
!= 0 && crt
->next
!= NULL
)
940 * Add new certificate on the end of the chain if needed.
942 if( crt
->version
!= 0 && crt
->next
== NULL
)
944 crt
->next
= mbedtls_calloc( 1, sizeof( mbedtls_x509_crt
) );
946 if( crt
->next
== NULL
)
947 return( MBEDTLS_ERR_X509_ALLOC_FAILED
);
950 mbedtls_x509_crt_init( crt
->next
);
954 if( ( ret
= x509_crt_parse_der_core( crt
, buf
, buflen
) ) != 0 )
969 * Parse one or more PEM certificates from a buffer and add them to the chained
972 int mbedtls_x509_crt_parse( mbedtls_x509_crt
*chain
, const unsigned char *buf
, size_t buflen
)
975 int success
= 0, first_error
= 0, total_failed
= 0;
977 #if defined(MBEDTLS_PEM_PARSE_C)
978 int buf_format
= MBEDTLS_X509_FORMAT_DER
;
982 * Check for valid input
984 if( chain
== NULL
|| buf
== NULL
)
985 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
988 * Determine buffer content. Buffer contains either one DER certificate or
989 * one or more PEM certificates.
991 #if defined(MBEDTLS_PEM_PARSE_C)
992 if( buflen
!= 0 && buf
[buflen
- 1] == '\0' &&
993 strstr( (const char *) buf
, "-----BEGIN CERTIFICATE-----" ) != NULL
)
995 buf_format
= MBEDTLS_X509_FORMAT_PEM
;
998 if( buf_format
== MBEDTLS_X509_FORMAT_DER
)
999 return mbedtls_x509_crt_parse_der( chain
, buf
, buflen
);
1001 return mbedtls_x509_crt_parse_der( chain
, buf
, buflen
);
1004 #if defined(MBEDTLS_PEM_PARSE_C)
1005 if( buf_format
== MBEDTLS_X509_FORMAT_PEM
)
1008 mbedtls_pem_context pem
;
1010 /* 1 rather than 0 since the terminating NULL byte is counted in */
1014 mbedtls_pem_init( &pem
);
1016 /* If we get there, we know the string is null-terminated */
1017 ret
= mbedtls_pem_read_buffer( &pem
,
1018 "-----BEGIN CERTIFICATE-----",
1019 "-----END CERTIFICATE-----",
1020 buf
, NULL
, 0, &use_len
);
1030 else if( ret
== MBEDTLS_ERR_PEM_BAD_INPUT_DATA
)
1034 else if( ret
!= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
)
1036 mbedtls_pem_free( &pem
);
1039 * PEM header and footer were found
1044 if( first_error
== 0 )
1053 ret
= mbedtls_x509_crt_parse_der( chain
, pem
.buf
, pem
.buflen
);
1055 mbedtls_pem_free( &pem
);
1060 * Quit parsing on a memory error
1062 if( ret
== MBEDTLS_ERR_X509_ALLOC_FAILED
)
1065 if( first_error
== 0 )
1077 return( total_failed
);
1078 else if( first_error
)
1079 return( first_error
);
1081 return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT
);
1082 #endif /* MBEDTLS_PEM_PARSE_C */
1085 #if defined(MBEDTLS_FS_IO)
1087 * Load one or more certificates and add them to the chained list
1089 int mbedtls_x509_crt_parse_file( mbedtls_x509_crt
*chain
, const char *path
)
1095 if( ( ret
= mbedtls_pk_load_file( path
, &buf
, &n
) ) != 0 )
1098 ret
= mbedtls_x509_crt_parse( chain
, buf
, n
);
1100 mbedtls_zeroize( buf
, n
);
1101 mbedtls_free( buf
);
1106 int mbedtls_x509_crt_parse_path( mbedtls_x509_crt
*chain
, const char *path
)
1109 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
1111 WCHAR szDir
[MAX_PATH
];
1112 char filename
[MAX_PATH
];
1114 size_t len
= strlen( path
);
1116 WIN32_FIND_DATAW file_data
;
1119 if( len
> MAX_PATH
- 3 )
1120 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
1122 memset( szDir
, 0, sizeof(szDir
) );
1123 memset( filename
, 0, MAX_PATH
);
1124 memcpy( filename
, path
, len
);
1125 filename
[len
++] = '\\';
1127 filename
[len
++] = '*';
1129 w_ret
= MultiByteToWideChar( CP_ACP
, 0, filename
, len
, szDir
,
1132 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
1134 hFind
= FindFirstFileW( szDir
, &file_data
);
1135 if( hFind
== INVALID_HANDLE_VALUE
)
1136 return( MBEDTLS_ERR_X509_FILE_IO_ERROR
);
1138 len
= MAX_PATH
- len
;
1141 memset( p
, 0, len
);
1143 if( file_data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
1146 w_ret
= WideCharToMultiByte( CP_ACP
, 0, file_data
.cFileName
,
1147 lstrlenW( file_data
.cFileName
),
1151 return( MBEDTLS_ERR_X509_FILE_IO_ERROR
);
1153 w_ret
= mbedtls_x509_crt_parse_file( chain
, filename
);
1159 while( FindNextFileW( hFind
, &file_data
) != 0 );
1161 if( GetLastError() != ERROR_NO_MORE_FILES
)
1162 ret
= MBEDTLS_ERR_X509_FILE_IO_ERROR
;
1169 struct dirent
*entry
;
1170 char entry_name
[MBEDTLS_X509_MAX_FILE_PATH_LEN
];
1171 DIR *dir
= opendir( path
);
1174 return( MBEDTLS_ERR_X509_FILE_IO_ERROR
);
1176 #if defined(MBEDTLS_THREADING_PTHREAD)
1177 if( ( ret
= mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex
) ) != 0 )
1184 while( ( entry
= readdir( dir
) ) != NULL
)
1186 snp_ret
= mbedtls_snprintf( entry_name
, sizeof entry_name
,
1187 "%s/%s", path
, entry
->d_name
);
1189 if( snp_ret
< 0 || (size_t)snp_ret
>= sizeof entry_name
)
1191 ret
= MBEDTLS_ERR_X509_BUFFER_TOO_SMALL
;
1194 else if( stat( entry_name
, &sb
) == -1 )
1196 ret
= MBEDTLS_ERR_X509_FILE_IO_ERROR
;
1200 if( !S_ISREG( sb
.st_mode
) )
1203 // Ignore parse errors
1205 t_ret
= mbedtls_x509_crt_parse_file( chain
, entry_name
);
1215 #if defined(MBEDTLS_THREADING_PTHREAD)
1216 if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex
) != 0 )
1217 ret
= MBEDTLS_ERR_THREADING_MUTEX_ERROR
;
1224 #endif /* MBEDTLS_FS_IO */
1226 static int x509_info_subject_alt_name( char **buf
, size_t *size
,
1227 const mbedtls_x509_sequence
*subject_alt_name
)
1232 const mbedtls_x509_sequence
*cur
= subject_alt_name
;
1233 const char *sep
= "";
1236 while( cur
!= NULL
)
1238 if( cur
->buf
.len
+ sep_len
>= n
)
1241 return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL
);
1244 n
-= cur
->buf
.len
+ sep_len
;
1245 for( i
= 0; i
< sep_len
; i
++ )
1247 for( i
= 0; i
< cur
->buf
.len
; i
++ )
1248 *p
++ = cur
->buf
.p
[i
];
1264 #define PRINT_ITEM(i) \
1266 ret = mbedtls_snprintf( p, n, "%s" i, sep ); \
1267 MBEDTLS_X509_SAFE_SNPRINTF; \
1271 #define CERT_TYPE(type,name) \
1272 if( ns_cert_type & type ) \
1275 static int x509_info_cert_type( char **buf
, size_t *size
,
1276 unsigned char ns_cert_type
)
1281 const char *sep
= "";
1283 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT
, "SSL Client" );
1284 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER
, "SSL Server" );
1285 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL
, "Email" );
1286 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING
, "Object Signing" );
1287 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED
, "Reserved" );
1288 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA
, "SSL CA" );
1289 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA
, "Email CA" );
1290 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA
, "Object Signing CA" );
1298 #define KEY_USAGE(code,name) \
1299 if( key_usage & code ) \
1302 static int x509_info_key_usage( char **buf
, size_t *size
,
1303 unsigned int key_usage
)
1308 const char *sep
= "";
1310 KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE
, "Digital Signature" );
1311 KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION
, "Non Repudiation" );
1312 KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT
, "Key Encipherment" );
1313 KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT
, "Data Encipherment" );
1314 KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT
, "Key Agreement" );
1315 KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN
, "Key Cert Sign" );
1316 KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN
, "CRL Sign" );
1317 KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY
, "Encipher Only" );
1318 KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY
, "Decipher Only" );
1326 static int x509_info_ext_key_usage( char **buf
, size_t *size
,
1327 const mbedtls_x509_sequence
*extended_key_usage
)
1333 const mbedtls_x509_sequence
*cur
= extended_key_usage
;
1334 const char *sep
= "";
1336 while( cur
!= NULL
)
1338 if( mbedtls_oid_get_extended_key_usage( &cur
->buf
, &desc
) != 0 )
1341 ret
= mbedtls_snprintf( p
, n
, "%s%s", sep
, desc
);
1342 MBEDTLS_X509_SAFE_SNPRINTF
;
1356 * Return an informational string about the certificate.
1358 #define BEFORE_COLON 18
1360 int mbedtls_x509_crt_info( char *buf
, size_t size
, const char *prefix
,
1361 const mbedtls_x509_crt
*crt
)
1366 char key_size_str
[BEFORE_COLON
];
1373 ret
= mbedtls_snprintf( p
, n
, "\nCertificate is uninitialised!\n" );
1374 MBEDTLS_X509_SAFE_SNPRINTF
;
1376 return( (int) ( size
- n
) );
1379 ret
= mbedtls_snprintf( p
, n
, "%scert. version : %d\n",
1380 prefix
, crt
->version
);
1381 MBEDTLS_X509_SAFE_SNPRINTF
;
1382 ret
= mbedtls_snprintf( p
, n
, "%sserial number : ",
1384 MBEDTLS_X509_SAFE_SNPRINTF
;
1386 ret
= mbedtls_x509_serial_gets( p
, n
, &crt
->serial
);
1387 MBEDTLS_X509_SAFE_SNPRINTF
;
1389 ret
= mbedtls_snprintf( p
, n
, "\n%sissuer name : ", prefix
);
1390 MBEDTLS_X509_SAFE_SNPRINTF
;
1391 ret
= mbedtls_x509_dn_gets( p
, n
, &crt
->issuer
);
1392 MBEDTLS_X509_SAFE_SNPRINTF
;
1394 ret
= mbedtls_snprintf( p
, n
, "\n%ssubject name : ", prefix
);
1395 MBEDTLS_X509_SAFE_SNPRINTF
;
1396 ret
= mbedtls_x509_dn_gets( p
, n
, &crt
->subject
);
1397 MBEDTLS_X509_SAFE_SNPRINTF
;
1399 ret
= mbedtls_snprintf( p
, n
, "\n%sissued on : " \
1400 "%04d-%02d-%02d %02d:%02d:%02d", prefix
,
1401 crt
->valid_from
.year
, crt
->valid_from
.mon
,
1402 crt
->valid_from
.day
, crt
->valid_from
.hour
,
1403 crt
->valid_from
.min
, crt
->valid_from
.sec
);
1404 MBEDTLS_X509_SAFE_SNPRINTF
;
1406 ret
= mbedtls_snprintf( p
, n
, "\n%sexpires on : " \
1407 "%04d-%02d-%02d %02d:%02d:%02d", prefix
,
1408 crt
->valid_to
.year
, crt
->valid_to
.mon
,
1409 crt
->valid_to
.day
, crt
->valid_to
.hour
,
1410 crt
->valid_to
.min
, crt
->valid_to
.sec
);
1411 MBEDTLS_X509_SAFE_SNPRINTF
;
1413 ret
= mbedtls_snprintf( p
, n
, "\n%ssigned using : ", prefix
);
1414 MBEDTLS_X509_SAFE_SNPRINTF
;
1416 ret
= mbedtls_x509_sig_alg_gets( p
, n
, &crt
->sig_oid
, crt
->sig_pk
,
1417 crt
->sig_md
, crt
->sig_opts
);
1418 MBEDTLS_X509_SAFE_SNPRINTF
;
1421 if( ( ret
= mbedtls_x509_key_size_helper( key_size_str
, BEFORE_COLON
,
1422 mbedtls_pk_get_name( &crt
->pk
) ) ) != 0 )
1427 ret
= mbedtls_snprintf( p
, n
, "\n%s%-" BC
"s: %d bits", prefix
, key_size_str
,
1428 (int) mbedtls_pk_get_bitlen( &crt
->pk
) );
1429 MBEDTLS_X509_SAFE_SNPRINTF
;
1432 * Optional extensions
1435 if( crt
->ext_types
& MBEDTLS_X509_EXT_BASIC_CONSTRAINTS
)
1437 ret
= mbedtls_snprintf( p
, n
, "\n%sbasic constraints : CA=%s", prefix
,
1438 crt
->ca_istrue
? "true" : "false" );
1439 MBEDTLS_X509_SAFE_SNPRINTF
;
1441 if( crt
->max_pathlen
> 0 )
1443 ret
= mbedtls_snprintf( p
, n
, ", max_pathlen=%d", crt
->max_pathlen
- 1 );
1444 MBEDTLS_X509_SAFE_SNPRINTF
;
1448 if( crt
->ext_types
& MBEDTLS_X509_EXT_SUBJECT_ALT_NAME
)
1450 ret
= mbedtls_snprintf( p
, n
, "\n%ssubject alt name : ", prefix
);
1451 MBEDTLS_X509_SAFE_SNPRINTF
;
1453 if( ( ret
= x509_info_subject_alt_name( &p
, &n
,
1454 &crt
->subject_alt_names
) ) != 0 )
1458 if( crt
->ext_types
& MBEDTLS_X509_EXT_NS_CERT_TYPE
)
1460 ret
= mbedtls_snprintf( p
, n
, "\n%scert. type : ", prefix
);
1461 MBEDTLS_X509_SAFE_SNPRINTF
;
1463 if( ( ret
= x509_info_cert_type( &p
, &n
, crt
->ns_cert_type
) ) != 0 )
1467 if( crt
->ext_types
& MBEDTLS_X509_EXT_KEY_USAGE
)
1469 ret
= mbedtls_snprintf( p
, n
, "\n%skey usage : ", prefix
);
1470 MBEDTLS_X509_SAFE_SNPRINTF
;
1472 if( ( ret
= x509_info_key_usage( &p
, &n
, crt
->key_usage
) ) != 0 )
1476 if( crt
->ext_types
& MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE
)
1478 ret
= mbedtls_snprintf( p
, n
, "\n%sext key usage : ", prefix
);
1479 MBEDTLS_X509_SAFE_SNPRINTF
;
1481 if( ( ret
= x509_info_ext_key_usage( &p
, &n
,
1482 &crt
->ext_key_usage
) ) != 0 )
1486 ret
= mbedtls_snprintf( p
, n
, "\n" );
1487 MBEDTLS_X509_SAFE_SNPRINTF
;
1489 return( (int) ( size
- n
) );
1492 struct x509_crt_verify_string
{
1497 static const struct x509_crt_verify_string x509_crt_verify_strings
[] = {
1498 { MBEDTLS_X509_BADCERT_EXPIRED
, "The certificate validity has expired" },
1499 { MBEDTLS_X509_BADCERT_REVOKED
, "The certificate has been revoked (is on a CRL)" },
1500 { MBEDTLS_X509_BADCERT_CN_MISMATCH
, "The certificate Common Name (CN) does not match with the expected CN" },
1501 { MBEDTLS_X509_BADCERT_NOT_TRUSTED
, "The certificate is not correctly signed by the trusted CA" },
1502 { MBEDTLS_X509_BADCRL_NOT_TRUSTED
, "The CRL is not correctly signed by the trusted CA" },
1503 { MBEDTLS_X509_BADCRL_EXPIRED
, "The CRL is expired" },
1504 { MBEDTLS_X509_BADCERT_MISSING
, "Certificate was missing" },
1505 { MBEDTLS_X509_BADCERT_SKIP_VERIFY
, "Certificate verification was skipped" },
1506 { MBEDTLS_X509_BADCERT_OTHER
, "Other reason (can be used by verify callback)" },
1507 { MBEDTLS_X509_BADCERT_FUTURE
, "The certificate validity starts in the future" },
1508 { MBEDTLS_X509_BADCRL_FUTURE
, "The CRL is from the future" },
1509 { MBEDTLS_X509_BADCERT_KEY_USAGE
, "Usage does not match the keyUsage extension" },
1510 { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE
, "Usage does not match the extendedKeyUsage extension" },
1511 { MBEDTLS_X509_BADCERT_NS_CERT_TYPE
, "Usage does not match the nsCertType extension" },
1512 { MBEDTLS_X509_BADCERT_BAD_MD
, "The certificate is signed with an unacceptable hash." },
1513 { MBEDTLS_X509_BADCERT_BAD_PK
, "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
1514 { MBEDTLS_X509_BADCERT_BAD_KEY
, "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." },
1515 { MBEDTLS_X509_BADCRL_BAD_MD
, "The CRL is signed with an unacceptable hash." },
1516 { MBEDTLS_X509_BADCRL_BAD_PK
, "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
1517 { MBEDTLS_X509_BADCRL_BAD_KEY
, "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." },
1521 int mbedtls_x509_crt_verify_info( char *buf
, size_t size
, const char *prefix
,
1525 const struct x509_crt_verify_string
*cur
;
1529 for( cur
= x509_crt_verify_strings
; cur
->string
!= NULL
; cur
++ )
1531 if( ( flags
& cur
->code
) == 0 )
1534 ret
= mbedtls_snprintf( p
, n
, "%s%s\n", prefix
, cur
->string
);
1535 MBEDTLS_X509_SAFE_SNPRINTF
;
1541 ret
= mbedtls_snprintf( p
, n
, "%sUnknown reason "
1542 "(this should not happen)\n", prefix
);
1543 MBEDTLS_X509_SAFE_SNPRINTF
;
1546 return( (int) ( size
- n
) );
1549 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
1550 int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt
*crt
,
1551 unsigned int usage
)
1553 unsigned int usage_must
, usage_may
;
1554 unsigned int may_mask
= MBEDTLS_X509_KU_ENCIPHER_ONLY
1555 | MBEDTLS_X509_KU_DECIPHER_ONLY
;
1557 if( ( crt
->ext_types
& MBEDTLS_X509_EXT_KEY_USAGE
) == 0 )
1560 usage_must
= usage
& ~may_mask
;
1562 if( ( ( crt
->key_usage
& ~may_mask
) & usage_must
) != usage_must
)
1563 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
1565 usage_may
= usage
& may_mask
;
1567 if( ( ( crt
->key_usage
& may_mask
) | usage_may
) != usage_may
)
1568 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
1574 #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
1575 int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt
*crt
,
1576 const char *usage_oid
,
1579 const mbedtls_x509_sequence
*cur
;
1581 /* Extension is not mandatory, absent means no restriction */
1582 if( ( crt
->ext_types
& MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE
) == 0 )
1586 * Look for the requested usage (or wildcard ANY) in our list
1588 for( cur
= &crt
->ext_key_usage
; cur
!= NULL
; cur
= cur
->next
)
1590 const mbedtls_x509_buf
*cur_oid
= &cur
->buf
;
1592 if( cur_oid
->len
== usage_len
&&
1593 memcmp( cur_oid
->p
, usage_oid
, usage_len
) == 0 )
1598 if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE
, cur_oid
) == 0 )
1602 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
1604 #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
1606 #if defined(MBEDTLS_X509_CRL_PARSE_C)
1608 * Return 1 if the certificate is revoked, or 0 otherwise.
1610 int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt
*crt
, const mbedtls_x509_crl
*crl
)
1612 const mbedtls_x509_crl_entry
*cur
= &crl
->entry
;
1614 while( cur
!= NULL
&& cur
->serial
.len
!= 0 )
1616 if( crt
->serial
.len
== cur
->serial
.len
&&
1617 memcmp( crt
->serial
.p
, cur
->serial
.p
, crt
->serial
.len
) == 0 )
1619 if( mbedtls_x509_time_is_past( &cur
->revocation_date
) )
1630 * Check that the given certificate is not revoked according to the CRL.
1631 * Skip validation is no CRL for the given CA is present.
1633 static int x509_crt_verifycrl( mbedtls_x509_crt
*crt
, mbedtls_x509_crt
*ca
,
1634 mbedtls_x509_crl
*crl_list
,
1635 const mbedtls_x509_crt_profile
*profile
)
1638 unsigned char hash
[MBEDTLS_MD_MAX_SIZE
];
1639 const mbedtls_md_info_t
*md_info
;
1644 while( crl_list
!= NULL
)
1646 if( crl_list
->version
== 0 ||
1647 crl_list
->issuer_raw
.len
!= ca
->subject_raw
.len
||
1648 memcmp( crl_list
->issuer_raw
.p
, ca
->subject_raw
.p
,
1649 crl_list
->issuer_raw
.len
) != 0 )
1651 crl_list
= crl_list
->next
;
1656 * Check if the CA is configured to sign CRLs
1658 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
1659 if( mbedtls_x509_crt_check_key_usage( ca
, MBEDTLS_X509_KU_CRL_SIGN
) != 0 )
1661 flags
|= MBEDTLS_X509_BADCRL_NOT_TRUSTED
;
1667 * Check if CRL is correctly signed by the trusted CA
1669 if( x509_profile_check_md_alg( profile
, crl_list
->sig_md
) != 0 )
1670 flags
|= MBEDTLS_X509_BADCRL_BAD_MD
;
1672 if( x509_profile_check_pk_alg( profile
, crl_list
->sig_pk
) != 0 )
1673 flags
|= MBEDTLS_X509_BADCRL_BAD_PK
;
1675 md_info
= mbedtls_md_info_from_type( crl_list
->sig_md
);
1676 if( md_info
== NULL
)
1679 * Cannot check 'unknown' hash
1681 flags
|= MBEDTLS_X509_BADCRL_NOT_TRUSTED
;
1685 mbedtls_md( md_info
, crl_list
->tbs
.p
, crl_list
->tbs
.len
, hash
);
1687 if( x509_profile_check_key( profile
, crl_list
->sig_pk
, &ca
->pk
) != 0 )
1688 flags
|= MBEDTLS_X509_BADCERT_BAD_KEY
;
1690 if( mbedtls_pk_verify_ext( crl_list
->sig_pk
, crl_list
->sig_opts
, &ca
->pk
,
1691 crl_list
->sig_md
, hash
, mbedtls_md_get_size( md_info
),
1692 crl_list
->sig
.p
, crl_list
->sig
.len
) != 0 )
1694 flags
|= MBEDTLS_X509_BADCRL_NOT_TRUSTED
;
1699 * Check for validity of CRL (Do not drop out)
1701 if( mbedtls_x509_time_is_past( &crl_list
->next_update
) )
1702 flags
|= MBEDTLS_X509_BADCRL_EXPIRED
;
1704 if( mbedtls_x509_time_is_future( &crl_list
->this_update
) )
1705 flags
|= MBEDTLS_X509_BADCRL_FUTURE
;
1708 * Check if certificate is revoked
1710 if( mbedtls_x509_crt_is_revoked( crt
, crl_list
) )
1712 flags
|= MBEDTLS_X509_BADCERT_REVOKED
;
1716 crl_list
= crl_list
->next
;
1721 #endif /* MBEDTLS_X509_CRL_PARSE_C */
1724 * Like memcmp, but case-insensitive and always returns -1 if different
1726 static int x509_memcasecmp( const void *s1
, const void *s2
, size_t len
)
1730 const unsigned char *n1
= s1
, *n2
= s2
;
1732 for( i
= 0; i
< len
; i
++ )
1734 diff
= n1
[i
] ^ n2
[i
];
1740 ( ( n1
[i
] >= 'a' && n1
[i
] <= 'z' ) ||
1741 ( n1
[i
] >= 'A' && n1
[i
] <= 'Z' ) ) )
1753 * Return 0 if name matches wildcard, -1 otherwise
1755 static int x509_check_wildcard( const char *cn
, mbedtls_x509_buf
*name
)
1758 size_t cn_idx
= 0, cn_len
= strlen( cn
);
1760 if( name
->len
< 3 || name
->p
[0] != '*' || name
->p
[1] != '.' )
1763 for( i
= 0; i
< cn_len
; ++i
)
1775 if( cn_len
- cn_idx
== name
->len
- 1 &&
1776 x509_memcasecmp( name
->p
+ 1, cn
+ cn_idx
, name
->len
- 1 ) == 0 )
1785 * Compare two X.509 strings, case-insensitive, and allowing for some encoding
1786 * variations (but not all).
1788 * Return 0 if equal, -1 otherwise.
1790 static int x509_string_cmp( const mbedtls_x509_buf
*a
, const mbedtls_x509_buf
*b
)
1792 if( a
->tag
== b
->tag
&&
1794 memcmp( a
->p
, b
->p
, b
->len
) == 0 )
1799 if( ( a
->tag
== MBEDTLS_ASN1_UTF8_STRING
|| a
->tag
== MBEDTLS_ASN1_PRINTABLE_STRING
) &&
1800 ( b
->tag
== MBEDTLS_ASN1_UTF8_STRING
|| b
->tag
== MBEDTLS_ASN1_PRINTABLE_STRING
) &&
1802 x509_memcasecmp( a
->p
, b
->p
, b
->len
) == 0 )
1811 * Compare two X.509 Names (aka rdnSequence).
1813 * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
1814 * we sometimes return unequal when the full algorithm would return equal,
1815 * but never the other way. (In particular, we don't do Unicode normalisation
1816 * or space folding.)
1818 * Return 0 if equal, -1 otherwise.
1820 static int x509_name_cmp( const mbedtls_x509_name
*a
, const mbedtls_x509_name
*b
)
1822 /* Avoid recursion, it might not be optimised by the compiler */
1823 while( a
!= NULL
|| b
!= NULL
)
1825 if( a
== NULL
|| b
== NULL
)
1829 if( a
->oid
.tag
!= b
->oid
.tag
||
1830 a
->oid
.len
!= b
->oid
.len
||
1831 memcmp( a
->oid
.p
, b
->oid
.p
, b
->oid
.len
) != 0 )
1837 if( x509_string_cmp( &a
->val
, &b
->val
) != 0 )
1840 /* structure of the list of sets */
1841 if( a
->next_merged
!= b
->next_merged
)
1848 /* a == NULL == b */
1853 * Check if 'parent' is a suitable parent (signing CA) for 'child'.
1854 * Return 0 if yes, -1 if not.
1856 * top means parent is a locally-trusted certificate
1857 * bottom means child is the end entity cert
1859 static int x509_crt_check_parent( const mbedtls_x509_crt
*child
,
1860 const mbedtls_x509_crt
*parent
,
1861 int top
, int bottom
)
1865 /* Parent must be the issuer */
1866 if( x509_name_cmp( &child
->issuer
, &parent
->subject
) != 0 )
1869 /* Parent must have the basicConstraints CA bit set as a general rule */
1872 /* Exception: v1/v2 certificates that are locally trusted. */
1873 if( top
&& parent
->version
< 3 )
1876 /* Exception: self-signed end-entity certs that are locally trusted. */
1877 if( top
&& bottom
&&
1878 child
->raw
.len
== parent
->raw
.len
&&
1879 memcmp( child
->raw
.p
, parent
->raw
.p
, child
->raw
.len
) == 0 )
1884 if( need_ca_bit
&& ! parent
->ca_istrue
)
1887 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
1889 mbedtls_x509_crt_check_key_usage( parent
, MBEDTLS_X509_KU_KEY_CERT_SIGN
) != 0 )
1898 static int x509_crt_verify_top(
1899 mbedtls_x509_crt
*child
, mbedtls_x509_crt
*trust_ca
,
1900 mbedtls_x509_crl
*ca_crl
,
1901 const mbedtls_x509_crt_profile
*profile
,
1902 int path_cnt
, int self_cnt
, uint32_t *flags
,
1903 int (*f_vrfy
)(void *, mbedtls_x509_crt
*, int, uint32_t *),
1907 uint32_t ca_flags
= 0;
1909 unsigned char hash
[MBEDTLS_MD_MAX_SIZE
];
1910 const mbedtls_md_info_t
*md_info
;
1912 if( mbedtls_x509_time_is_past( &child
->valid_to
) )
1913 *flags
|= MBEDTLS_X509_BADCERT_EXPIRED
;
1915 if( mbedtls_x509_time_is_future( &child
->valid_from
) )
1916 *flags
|= MBEDTLS_X509_BADCERT_FUTURE
;
1918 if( x509_profile_check_md_alg( profile
, child
->sig_md
) != 0 )
1919 *flags
|= MBEDTLS_X509_BADCERT_BAD_MD
;
1921 if( x509_profile_check_pk_alg( profile
, child
->sig_pk
) != 0 )
1922 *flags
|= MBEDTLS_X509_BADCERT_BAD_PK
;
1925 * Child is the top of the chain. Check against the trust_ca list.
1927 *flags
|= MBEDTLS_X509_BADCERT_NOT_TRUSTED
;
1929 md_info
= mbedtls_md_info_from_type( child
->sig_md
);
1930 if( md_info
== NULL
)
1933 * Cannot check 'unknown', no need to try any CA
1938 mbedtls_md( md_info
, child
->tbs
.p
, child
->tbs
.len
, hash
);
1940 for( /* trust_ca */ ; trust_ca
!= NULL
; trust_ca
= trust_ca
->next
)
1942 if( x509_crt_check_parent( child
, trust_ca
, 1, path_cnt
== 0 ) != 0 )
1945 check_path_cnt
= path_cnt
+ 1;
1948 * Reduce check_path_cnt to check against if top of the chain is
1949 * the same as the trusted CA
1951 if( child
->subject_raw
.len
== trust_ca
->subject_raw
.len
&&
1952 memcmp( child
->subject_raw
.p
, trust_ca
->subject_raw
.p
,
1953 child
->issuer_raw
.len
) == 0 )
1958 /* Self signed certificates do not count towards the limit */
1959 if( trust_ca
->max_pathlen
> 0 &&
1960 trust_ca
->max_pathlen
< check_path_cnt
- self_cnt
)
1965 if( mbedtls_x509_time_is_past( &trust_ca
->valid_to
) )
1970 if( mbedtls_x509_time_is_future( &trust_ca
->valid_from
) )
1975 if( mbedtls_pk_verify_ext( child
->sig_pk
, child
->sig_opts
, &trust_ca
->pk
,
1976 child
->sig_md
, hash
, mbedtls_md_get_size( md_info
),
1977 child
->sig
.p
, child
->sig
.len
) != 0 )
1983 * Top of chain is signed by a trusted CA
1985 *flags
&= ~MBEDTLS_X509_BADCERT_NOT_TRUSTED
;
1987 if( x509_profile_check_key( profile
, child
->sig_pk
, &trust_ca
->pk
) != 0 )
1988 *flags
|= MBEDTLS_X509_BADCERT_BAD_KEY
;
1994 * If top of chain is not the same as the trusted CA send a verify request
1995 * to the callback for any issues with validity and CRL presence for the
1996 * trusted CA certificate.
1998 if( trust_ca
!= NULL
&&
1999 ( child
->subject_raw
.len
!= trust_ca
->subject_raw
.len
||
2000 memcmp( child
->subject_raw
.p
, trust_ca
->subject_raw
.p
,
2001 child
->issuer_raw
.len
) != 0 ) )
2003 #if defined(MBEDTLS_X509_CRL_PARSE_C)
2004 /* Check trusted CA's CRL for the chain's top crt */
2005 *flags
|= x509_crt_verifycrl( child
, trust_ca
, ca_crl
, profile
);
2010 if( NULL
!= f_vrfy
)
2012 if( ( ret
= f_vrfy( p_vrfy
, trust_ca
, path_cnt
+ 1,
2013 &ca_flags
) ) != 0 )
2020 /* Call callback on top cert */
2021 if( NULL
!= f_vrfy
)
2023 if( ( ret
= f_vrfy( p_vrfy
, child
, path_cnt
, flags
) ) != 0 )
2032 static int x509_crt_verify_child(
2033 mbedtls_x509_crt
*child
, mbedtls_x509_crt
*parent
,
2034 mbedtls_x509_crt
*trust_ca
, mbedtls_x509_crl
*ca_crl
,
2035 const mbedtls_x509_crt_profile
*profile
,
2036 int path_cnt
, int self_cnt
, uint32_t *flags
,
2037 int (*f_vrfy
)(void *, mbedtls_x509_crt
*, int, uint32_t *),
2041 uint32_t parent_flags
= 0;
2042 unsigned char hash
[MBEDTLS_MD_MAX_SIZE
];
2043 mbedtls_x509_crt
*grandparent
;
2044 const mbedtls_md_info_t
*md_info
;
2046 /* Counting intermediate self signed certificates */
2047 if( ( path_cnt
!= 0 ) && x509_name_cmp( &child
->issuer
, &child
->subject
) == 0 )
2050 /* path_cnt is 0 for the first intermediate CA */
2051 if( 1 + path_cnt
> MBEDTLS_X509_MAX_INTERMEDIATE_CA
)
2053 *flags
|= MBEDTLS_X509_BADCERT_NOT_TRUSTED
;
2054 return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED
);
2057 if( mbedtls_x509_time_is_past( &child
->valid_to
) )
2058 *flags
|= MBEDTLS_X509_BADCERT_EXPIRED
;
2060 if( mbedtls_x509_time_is_future( &child
->valid_from
) )
2061 *flags
|= MBEDTLS_X509_BADCERT_FUTURE
;
2063 if( x509_profile_check_md_alg( profile
, child
->sig_md
) != 0 )
2064 *flags
|= MBEDTLS_X509_BADCERT_BAD_MD
;
2066 if( x509_profile_check_pk_alg( profile
, child
->sig_pk
) != 0 )
2067 *flags
|= MBEDTLS_X509_BADCERT_BAD_PK
;
2069 md_info
= mbedtls_md_info_from_type( child
->sig_md
);
2070 if( md_info
== NULL
)
2073 * Cannot check 'unknown' hash
2075 *flags
|= MBEDTLS_X509_BADCERT_NOT_TRUSTED
;
2079 mbedtls_md( md_info
, child
->tbs
.p
, child
->tbs
.len
, hash
);
2081 if( x509_profile_check_key( profile
, child
->sig_pk
, &parent
->pk
) != 0 )
2082 *flags
|= MBEDTLS_X509_BADCERT_BAD_KEY
;
2084 if( mbedtls_pk_verify_ext( child
->sig_pk
, child
->sig_opts
, &parent
->pk
,
2085 child
->sig_md
, hash
, mbedtls_md_get_size( md_info
),
2086 child
->sig
.p
, child
->sig
.len
) != 0 )
2088 *flags
|= MBEDTLS_X509_BADCERT_NOT_TRUSTED
;
2092 #if defined(MBEDTLS_X509_CRL_PARSE_C)
2093 /* Check trusted CA's CRL for the given crt */
2094 *flags
|= x509_crt_verifycrl(child
, parent
, ca_crl
, profile
);
2097 /* Look for a grandparent in trusted CAs */
2098 for( grandparent
= trust_ca
;
2099 grandparent
!= NULL
;
2100 grandparent
= grandparent
->next
)
2102 if( x509_crt_check_parent( parent
, grandparent
,
2103 0, path_cnt
== 0 ) == 0 )
2107 if( grandparent
!= NULL
)
2109 ret
= x509_crt_verify_top( parent
, grandparent
, ca_crl
, profile
,
2110 path_cnt
+ 1, self_cnt
, &parent_flags
, f_vrfy
, p_vrfy
);
2116 /* Look for a grandparent upwards the chain */
2117 for( grandparent
= parent
->next
;
2118 grandparent
!= NULL
;
2119 grandparent
= grandparent
->next
)
2121 /* +2 because the current step is not yet accounted for
2122 * and because max_pathlen is one higher than it should be.
2123 * Also self signed certificates do not count to the limit. */
2124 if( grandparent
->max_pathlen
> 0 &&
2125 grandparent
->max_pathlen
< 2 + path_cnt
- self_cnt
)
2130 if( x509_crt_check_parent( parent
, grandparent
,
2131 0, path_cnt
== 0 ) == 0 )
2135 /* Is our parent part of the chain or at the top? */
2136 if( grandparent
!= NULL
)
2138 ret
= x509_crt_verify_child( parent
, grandparent
, trust_ca
, ca_crl
,
2139 profile
, path_cnt
+ 1, self_cnt
, &parent_flags
,
2146 ret
= x509_crt_verify_top( parent
, trust_ca
, ca_crl
, profile
,
2147 path_cnt
+ 1, self_cnt
, &parent_flags
,
2154 /* child is verified to be a child of the parent, call verify callback */
2155 if( NULL
!= f_vrfy
)
2156 if( ( ret
= f_vrfy( p_vrfy
, child
, path_cnt
, flags
) ) != 0 )
2159 *flags
|= parent_flags
;
2165 * Verify the certificate validity
2167 int mbedtls_x509_crt_verify( mbedtls_x509_crt
*crt
,
2168 mbedtls_x509_crt
*trust_ca
,
2169 mbedtls_x509_crl
*ca_crl
,
2170 const char *cn
, uint32_t *flags
,
2171 int (*f_vrfy
)(void *, mbedtls_x509_crt
*, int, uint32_t *),
2174 return( mbedtls_x509_crt_verify_with_profile( crt
, trust_ca
, ca_crl
,
2175 &mbedtls_x509_crt_profile_default
, cn
, flags
, f_vrfy
, p_vrfy
) );
2180 * Verify the certificate validity, with profile
2182 int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt
*crt
,
2183 mbedtls_x509_crt
*trust_ca
,
2184 mbedtls_x509_crl
*ca_crl
,
2185 const mbedtls_x509_crt_profile
*profile
,
2186 const char *cn
, uint32_t *flags
,
2187 int (*f_vrfy
)(void *, mbedtls_x509_crt
*, int, uint32_t *),
2192 int pathlen
= 0, selfsigned
= 0;
2193 mbedtls_x509_crt
*parent
;
2194 mbedtls_x509_name
*name
;
2195 mbedtls_x509_sequence
*cur
= NULL
;
2196 mbedtls_pk_type_t pk_type
;
2198 if( profile
== NULL
)
2199 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
2205 name
= &crt
->subject
;
2206 cn_len
= strlen( cn
);
2208 if( crt
->ext_types
& MBEDTLS_X509_EXT_SUBJECT_ALT_NAME
)
2210 cur
= &crt
->subject_alt_names
;
2212 while( cur
!= NULL
)
2214 if( cur
->buf
.len
== cn_len
&&
2215 x509_memcasecmp( cn
, cur
->buf
.p
, cn_len
) == 0 )
2218 if( cur
->buf
.len
> 2 &&
2219 memcmp( cur
->buf
.p
, "*.", 2 ) == 0 &&
2220 x509_check_wildcard( cn
, &cur
->buf
) == 0 )
2229 *flags
|= MBEDTLS_X509_BADCERT_CN_MISMATCH
;
2233 while( name
!= NULL
)
2235 if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN
, &name
->oid
) == 0 )
2237 if( name
->val
.len
== cn_len
&&
2238 x509_memcasecmp( name
->val
.p
, cn
, cn_len
) == 0 )
2241 if( name
->val
.len
> 2 &&
2242 memcmp( name
->val
.p
, "*.", 2 ) == 0 &&
2243 x509_check_wildcard( cn
, &name
->val
) == 0 )
2251 *flags
|= MBEDTLS_X509_BADCERT_CN_MISMATCH
;
2255 /* Check the type and size of the key */
2256 pk_type
= mbedtls_pk_get_type( &crt
->pk
);
2258 if( x509_profile_check_pk_alg( profile
, pk_type
) != 0 )
2259 *flags
|= MBEDTLS_X509_BADCERT_BAD_PK
;
2261 if( x509_profile_check_key( profile
, pk_type
, &crt
->pk
) != 0 )
2262 *flags
|= MBEDTLS_X509_BADCERT_BAD_KEY
;
2264 /* Look for a parent in trusted CAs */
2265 for( parent
= trust_ca
; parent
!= NULL
; parent
= parent
->next
)
2267 if( x509_crt_check_parent( crt
, parent
, 0, pathlen
== 0 ) == 0 )
2271 if( parent
!= NULL
)
2273 ret
= x509_crt_verify_top( crt
, parent
, ca_crl
, profile
,
2274 pathlen
, selfsigned
, flags
, f_vrfy
, p_vrfy
);
2280 /* Look for a parent upwards the chain */
2281 for( parent
= crt
->next
; parent
!= NULL
; parent
= parent
->next
)
2282 if( x509_crt_check_parent( crt
, parent
, 0, pathlen
== 0 ) == 0 )
2285 /* Are we part of the chain or at the top? */
2286 if( parent
!= NULL
)
2288 ret
= x509_crt_verify_child( crt
, parent
, trust_ca
, ca_crl
, profile
,
2289 pathlen
, selfsigned
, flags
, f_vrfy
, p_vrfy
);
2295 ret
= x509_crt_verify_top( crt
, trust_ca
, ca_crl
, profile
,
2296 pathlen
, selfsigned
, flags
, f_vrfy
, p_vrfy
);
2303 return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED
);
2309 * Initialize a certificate chain
2311 void mbedtls_x509_crt_init( mbedtls_x509_crt
*crt
)
2313 memset( crt
, 0, sizeof(mbedtls_x509_crt
) );
2317 * Unallocate all certificate data
2319 void mbedtls_x509_crt_free( mbedtls_x509_crt
*crt
)
2321 mbedtls_x509_crt
*cert_cur
= crt
;
2322 mbedtls_x509_crt
*cert_prv
;
2323 mbedtls_x509_name
*name_cur
;
2324 mbedtls_x509_name
*name_prv
;
2325 mbedtls_x509_sequence
*seq_cur
;
2326 mbedtls_x509_sequence
*seq_prv
;
2333 mbedtls_pk_free( &cert_cur
->pk
);
2335 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
2336 mbedtls_free( cert_cur
->sig_opts
);
2339 name_cur
= cert_cur
->issuer
.next
;
2340 while( name_cur
!= NULL
)
2342 name_prv
= name_cur
;
2343 name_cur
= name_cur
->next
;
2344 mbedtls_zeroize( name_prv
, sizeof( mbedtls_x509_name
) );
2345 mbedtls_free( name_prv
);
2348 name_cur
= cert_cur
->subject
.next
;
2349 while( name_cur
!= NULL
)
2351 name_prv
= name_cur
;
2352 name_cur
= name_cur
->next
;
2353 mbedtls_zeroize( name_prv
, sizeof( mbedtls_x509_name
) );
2354 mbedtls_free( name_prv
);
2357 seq_cur
= cert_cur
->ext_key_usage
.next
;
2358 while( seq_cur
!= NULL
)
2361 seq_cur
= seq_cur
->next
;
2362 mbedtls_zeroize( seq_prv
, sizeof( mbedtls_x509_sequence
) );
2363 mbedtls_free( seq_prv
);
2366 seq_cur
= cert_cur
->subject_alt_names
.next
;
2367 while( seq_cur
!= NULL
)
2370 seq_cur
= seq_cur
->next
;
2371 mbedtls_zeroize( seq_prv
, sizeof( mbedtls_x509_sequence
) );
2372 mbedtls_free( seq_prv
);
2375 if( cert_cur
->raw
.p
!= NULL
)
2377 mbedtls_zeroize( cert_cur
->raw
.p
, cert_cur
->raw
.len
);
2378 mbedtls_free( cert_cur
->raw
.p
);
2381 cert_cur
= cert_cur
->next
;
2383 while( cert_cur
!= NULL
);
2388 cert_prv
= cert_cur
;
2389 cert_cur
= cert_cur
->next
;
2391 mbedtls_zeroize( cert_prv
, sizeof( mbedtls_x509_crt
) );
2392 if( cert_prv
!= crt
)
2393 mbedtls_free( cert_prv
);
2395 while( cert_cur
!= NULL
);
2398 #endif /* MBEDTLS_X509_CRT_PARSE_C */