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
33 * [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf
36 #if !defined(MBEDTLS_CONFIG_FILE)
37 #include "mbedtls/config.h"
39 #include MBEDTLS_CONFIG_FILE
42 #if defined(MBEDTLS_X509_CRT_PARSE_C)
44 #include "mbedtls/x509_crt.h"
45 #include "mbedtls/oid.h"
46 #include "mbedtls/platform_util.h"
51 #if defined(MBEDTLS_PEM_PARSE_C)
52 #include "mbedtls/pem.h"
55 #if defined(MBEDTLS_PLATFORM_C)
56 #include "mbedtls/platform.h"
59 #define mbedtls_free free
60 #define mbedtls_calloc calloc
61 #define mbedtls_snprintf snprintf
64 #if defined(MBEDTLS_THREADING_C)
65 #include "mbedtls/threading.h"
68 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
74 #if defined(MBEDTLS_FS_IO)
76 #if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
77 #include <sys/types.h>
80 #endif /* !_WIN32 || EFIX64 || EFI32 */
84 * Item in a verification chain: cert and flags for it
87 mbedtls_x509_crt
*crt
;
89 } x509_crt_verify_chain_item
;
92 * Max size of verification chain: end-entity + intermediates + trusted root
94 #define X509_MAX_VERIFY_CHAIN_SIZE ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 )
99 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default
=
101 #if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES)
102 /* Allow SHA-1 (weak, but still safe in controlled environments) */
103 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1
) |
105 /* Only SHA-2 hashes */
106 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224
) |
107 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256
) |
108 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384
) |
109 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512
),
110 0xFFFFFFF, /* Any PK alg */
111 0xFFFFFFF, /* Any curve */
116 * Next-default profile
118 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next
=
120 /* Hashes from SHA-256 and above */
121 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256
) |
122 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384
) |
123 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512
),
124 0xFFFFFFF, /* Any PK alg */
125 #if defined(MBEDTLS_ECP_C)
126 /* Curves at or above 128-bit security level */
127 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1
) |
128 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1
) |
129 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1
) |
130 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1
) |
131 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1
) |
132 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1
) |
133 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1
),
141 * NSA Suite B Profile
143 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb
=
145 /* Only SHA-256 and 384 */
146 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256
) |
147 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384
),
149 MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA
) |
150 MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY
),
151 #if defined(MBEDTLS_ECP_C)
152 /* Only NIST P-256 and P-384 */
153 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1
) |
154 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1
),
162 * Check md_alg against profile
163 * Return 0 if md_alg is acceptable for this profile, -1 otherwise
165 static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile
*profile
,
166 mbedtls_md_type_t md_alg
)
168 if( md_alg
== MBEDTLS_MD_NONE
)
171 if( ( profile
->allowed_mds
& MBEDTLS_X509_ID_FLAG( md_alg
) ) != 0 )
178 * Check pk_alg against profile
179 * Return 0 if pk_alg is acceptable for this profile, -1 otherwise
181 static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile
*profile
,
182 mbedtls_pk_type_t pk_alg
)
184 if( pk_alg
== MBEDTLS_PK_NONE
)
187 if( ( profile
->allowed_pks
& MBEDTLS_X509_ID_FLAG( pk_alg
) ) != 0 )
194 * Check key against profile
195 * Return 0 if pk is acceptable for this profile, -1 otherwise
197 static int x509_profile_check_key( const mbedtls_x509_crt_profile
*profile
,
198 const mbedtls_pk_context
*pk
)
200 const mbedtls_pk_type_t pk_alg
= mbedtls_pk_get_type( pk
);
202 #if defined(MBEDTLS_RSA_C)
203 if( pk_alg
== MBEDTLS_PK_RSA
|| pk_alg
== MBEDTLS_PK_RSASSA_PSS
)
205 if( mbedtls_pk_get_bitlen( pk
) >= profile
->rsa_min_bitlen
)
212 #if defined(MBEDTLS_ECP_C)
213 if( pk_alg
== MBEDTLS_PK_ECDSA
||
214 pk_alg
== MBEDTLS_PK_ECKEY
||
215 pk_alg
== MBEDTLS_PK_ECKEY_DH
)
217 const mbedtls_ecp_group_id gid
= mbedtls_pk_ec( *pk
)->grp
.id
;
219 if( gid
== MBEDTLS_ECP_DP_NONE
)
222 if( ( profile
->allowed_curves
& MBEDTLS_X509_ID_FLAG( gid
) ) != 0 )
233 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
235 static int x509_get_version( unsigned char **p
,
236 const unsigned char *end
,
242 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
243 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| 0 ) ) != 0 )
245 if( ret
== MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)
256 if( ( ret
= mbedtls_asn1_get_int( p
, end
, ver
) ) != 0 )
257 return( MBEDTLS_ERR_X509_INVALID_VERSION
+ ret
);
260 return( MBEDTLS_ERR_X509_INVALID_VERSION
+
261 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
267 * Validity ::= SEQUENCE {
271 static int x509_get_dates( unsigned char **p
,
272 const unsigned char *end
,
273 mbedtls_x509_time
*from
,
274 mbedtls_x509_time
*to
)
279 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
280 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
281 return( MBEDTLS_ERR_X509_INVALID_DATE
+ ret
);
285 if( ( ret
= mbedtls_x509_get_time( p
, end
, from
) ) != 0 )
288 if( ( ret
= mbedtls_x509_get_time( p
, end
, to
) ) != 0 )
292 return( MBEDTLS_ERR_X509_INVALID_DATE
+
293 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
299 * X.509 v2/v3 unique identifier (not parsed)
301 static int x509_get_uid( unsigned char **p
,
302 const unsigned char *end
,
303 mbedtls_x509_buf
*uid
, int n
)
312 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &uid
->len
,
313 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| n
) ) != 0 )
315 if( ret
== MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)
327 static int x509_get_basic_constraints( unsigned char **p
,
328 const unsigned char *end
,
336 * BasicConstraints ::= SEQUENCE {
337 * cA BOOLEAN DEFAULT FALSE,
338 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
340 *ca_istrue
= 0; /* DEFAULT FALSE */
341 *max_pathlen
= 0; /* endless */
343 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
344 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
345 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
350 if( ( ret
= mbedtls_asn1_get_bool( p
, end
, ca_istrue
) ) != 0 )
352 if( ret
== MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)
353 ret
= mbedtls_asn1_get_int( p
, end
, ca_istrue
);
356 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
358 if( *ca_istrue
!= 0 )
365 if( ( ret
= mbedtls_asn1_get_int( p
, end
, max_pathlen
) ) != 0 )
366 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
369 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
370 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
377 static int x509_get_ns_cert_type( unsigned char **p
,
378 const unsigned char *end
,
379 unsigned char *ns_cert_type
)
382 mbedtls_x509_bitstring bs
= { 0, 0, NULL
};
384 if( ( ret
= mbedtls_asn1_get_bitstring( p
, end
, &bs
) ) != 0 )
385 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
388 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
389 MBEDTLS_ERR_ASN1_INVALID_LENGTH
);
391 /* Get actual bitstring */
392 *ns_cert_type
= *bs
.p
;
396 static int x509_get_key_usage( unsigned char **p
,
397 const unsigned char *end
,
398 unsigned int *key_usage
)
402 mbedtls_x509_bitstring bs
= { 0, 0, NULL
};
404 if( ( ret
= mbedtls_asn1_get_bitstring( p
, end
, &bs
) ) != 0 )
405 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
408 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
409 MBEDTLS_ERR_ASN1_INVALID_LENGTH
);
411 /* Get actual bitstring */
413 for( i
= 0; i
< bs
.len
&& i
< sizeof( unsigned int ); i
++ )
415 *key_usage
|= (unsigned int) bs
.p
[i
] << (8*i
);
422 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
424 * KeyPurposeId ::= OBJECT IDENTIFIER
426 static int x509_get_ext_key_usage( unsigned char **p
,
427 const unsigned char *end
,
428 mbedtls_x509_sequence
*ext_key_usage
)
432 if( ( ret
= mbedtls_asn1_get_sequence_of( p
, end
, ext_key_usage
, MBEDTLS_ASN1_OID
) ) != 0 )
433 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
435 /* Sequence length must be >= 1 */
436 if( ext_key_usage
->buf
.p
== NULL
)
437 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
438 MBEDTLS_ERR_ASN1_INVALID_LENGTH
);
444 * SubjectAltName ::= GeneralNames
446 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
448 * GeneralName ::= CHOICE {
449 * otherName [0] OtherName,
450 * rfc822Name [1] IA5String,
451 * dNSName [2] IA5String,
452 * x400Address [3] ORAddress,
453 * directoryName [4] Name,
454 * ediPartyName [5] EDIPartyName,
455 * uniformResourceIdentifier [6] IA5String,
456 * iPAddress [7] OCTET STRING,
457 * registeredID [8] OBJECT IDENTIFIER }
459 * OtherName ::= SEQUENCE {
460 * type-id OBJECT IDENTIFIER,
461 * value [0] EXPLICIT ANY DEFINED BY type-id }
463 * EDIPartyName ::= SEQUENCE {
464 * nameAssigner [0] DirectoryString OPTIONAL,
465 * partyName [1] DirectoryString }
467 * NOTE: we only parse and use dNSName at this point.
469 static int x509_get_subject_alt_name( unsigned char **p
,
470 const unsigned char *end
,
471 mbedtls_x509_sequence
*subject_alt_name
)
475 mbedtls_asn1_buf
*buf
;
477 mbedtls_asn1_sequence
*cur
= subject_alt_name
;
479 /* Get main sequence tag */
480 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
481 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
482 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
484 if( *p
+ len
!= end
)
485 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
486 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
490 if( ( end
- *p
) < 1 )
491 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
492 MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
496 if( ( ret
= mbedtls_asn1_get_len( p
, end
, &tag_len
) ) != 0 )
497 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
499 if( ( tag
& MBEDTLS_ASN1_TAG_CLASS_MASK
) !=
500 MBEDTLS_ASN1_CONTEXT_SPECIFIC
)
502 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
503 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
506 /* Skip everything but DNS name */
507 if( tag
!= ( MBEDTLS_ASN1_CONTEXT_SPECIFIC
| 2 ) )
513 /* Allocate and assign next pointer */
514 if( cur
->buf
.p
!= NULL
)
516 if( cur
->next
!= NULL
)
517 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
);
519 cur
->next
= mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence
) );
521 if( cur
->next
== NULL
)
522 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
523 MBEDTLS_ERR_ASN1_ALLOC_FAILED
);
535 /* Set final sequence entry's next pointer to NULL */
539 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
540 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
546 * X.509 v3 extensions
549 static int x509_get_crt_ext( unsigned char **p
,
550 const unsigned char *end
,
551 mbedtls_x509_crt
*crt
)
555 unsigned char *end_ext_data
, *end_ext_octet
;
557 if( ( ret
= mbedtls_x509_get_ext( p
, end
, &crt
->v3_ext
, 3 ) ) != 0 )
559 if( ret
== MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)
568 * Extension ::= SEQUENCE {
569 * extnID OBJECT IDENTIFIER,
570 * critical BOOLEAN DEFAULT FALSE,
571 * extnValue OCTET STRING }
573 mbedtls_x509_buf extn_oid
= {0, 0, NULL
};
574 int is_critical
= 0; /* DEFAULT FALSE */
577 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
578 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
579 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
581 end_ext_data
= *p
+ len
;
583 /* Get extension ID */
584 if( ( ret
= mbedtls_asn1_get_tag( p
, end_ext_data
, &extn_oid
.len
,
585 MBEDTLS_ASN1_OID
) ) != 0 )
586 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
588 extn_oid
.tag
= MBEDTLS_ASN1_OID
;
592 /* Get optional critical */
593 if( ( ret
= mbedtls_asn1_get_bool( p
, end_ext_data
, &is_critical
) ) != 0 &&
594 ( ret
!= MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
) )
595 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
597 /* Data should be octet string type */
598 if( ( ret
= mbedtls_asn1_get_tag( p
, end_ext_data
, &len
,
599 MBEDTLS_ASN1_OCTET_STRING
) ) != 0 )
600 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
602 end_ext_octet
= *p
+ len
;
604 if( end_ext_octet
!= end_ext_data
)
605 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
606 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
609 * Detect supported extensions
611 ret
= mbedtls_oid_get_x509_ext_type( &extn_oid
, &ext_type
);
615 /* No parser found, skip extension */
618 #if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
621 /* Data is marked as critical: fail */
622 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
623 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
629 /* Forbid repeated extensions */
630 if( ( crt
->ext_types
& ext_type
) != 0 )
631 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
);
633 crt
->ext_types
|= ext_type
;
637 case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS
:
638 /* Parse basic constraints */
639 if( ( ret
= x509_get_basic_constraints( p
, end_ext_octet
,
640 &crt
->ca_istrue
, &crt
->max_pathlen
) ) != 0 )
644 case MBEDTLS_X509_EXT_KEY_USAGE
:
645 /* Parse key usage */
646 if( ( ret
= x509_get_key_usage( p
, end_ext_octet
,
647 &crt
->key_usage
) ) != 0 )
651 case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE
:
652 /* Parse extended key usage */
653 if( ( ret
= x509_get_ext_key_usage( p
, end_ext_octet
,
654 &crt
->ext_key_usage
) ) != 0 )
658 case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME
:
659 /* Parse subject alt name */
660 if( ( ret
= x509_get_subject_alt_name( p
, end_ext_octet
,
661 &crt
->subject_alt_names
) ) != 0 )
665 case MBEDTLS_X509_EXT_NS_CERT_TYPE
:
666 /* Parse netscape certificate type */
667 if( ( ret
= x509_get_ns_cert_type( p
, end_ext_octet
,
668 &crt
->ns_cert_type
) ) != 0 )
673 return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE
);
678 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
679 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
685 * Parse and fill a single X.509 certificate in DER format
687 static int x509_crt_parse_der_core( mbedtls_x509_crt
*crt
, const unsigned char *buf
,
692 unsigned char *p
, *end
, *crt_end
;
693 mbedtls_x509_buf sig_params1
, sig_params2
, sig_oid2
;
695 memset( &sig_params1
, 0, sizeof( mbedtls_x509_buf
) );
696 memset( &sig_params2
, 0, sizeof( mbedtls_x509_buf
) );
697 memset( &sig_oid2
, 0, sizeof( mbedtls_x509_buf
) );
700 * Check for valid input
702 if( crt
== NULL
|| buf
== NULL
)
703 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
705 // Use the original buffer until we figure out actual length
706 p
= (unsigned char*) buf
;
711 * Certificate ::= SEQUENCE {
712 * tbsCertificate TBSCertificate,
713 * signatureAlgorithm AlgorithmIdentifier,
714 * signatureValue BIT STRING }
716 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
717 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
719 mbedtls_x509_crt_free( crt
);
720 return( MBEDTLS_ERR_X509_INVALID_FORMAT
);
723 if( len
> (size_t) ( end
- p
) )
725 mbedtls_x509_crt_free( crt
);
726 return( MBEDTLS_ERR_X509_INVALID_FORMAT
+
727 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
731 // Create and populate a new buffer for the raw field
732 crt
->raw
.len
= crt_end
- buf
;
733 crt
->raw
.p
= p
= mbedtls_calloc( 1, crt
->raw
.len
);
735 return( MBEDTLS_ERR_X509_ALLOC_FAILED
);
737 memcpy( p
, buf
, crt
->raw
.len
);
739 // Direct pointers to the new buffer
740 p
+= crt
->raw
.len
- len
;
741 end
= crt_end
= p
+ len
;
744 * TBSCertificate ::= SEQUENCE {
748 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
749 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
751 mbedtls_x509_crt_free( crt
);
752 return( MBEDTLS_ERR_X509_INVALID_FORMAT
+ ret
);
756 crt
->tbs
.len
= end
- crt
->tbs
.p
;
759 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
761 * CertificateSerialNumber ::= INTEGER
763 * signature AlgorithmIdentifier
765 if( ( ret
= x509_get_version( &p
, end
, &crt
->version
) ) != 0 ||
766 ( ret
= mbedtls_x509_get_serial( &p
, end
, &crt
->serial
) ) != 0 ||
767 ( ret
= mbedtls_x509_get_alg( &p
, end
, &crt
->sig_oid
,
768 &sig_params1
) ) != 0 )
770 mbedtls_x509_crt_free( crt
);
774 if( crt
->version
< 0 || crt
->version
> 2 )
776 mbedtls_x509_crt_free( crt
);
777 return( MBEDTLS_ERR_X509_UNKNOWN_VERSION
);
782 if( ( ret
= mbedtls_x509_get_sig_alg( &crt
->sig_oid
, &sig_params1
,
783 &crt
->sig_md
, &crt
->sig_pk
,
784 &crt
->sig_opts
) ) != 0 )
786 mbedtls_x509_crt_free( crt
);
793 crt
->issuer_raw
.p
= p
;
795 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
796 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
798 mbedtls_x509_crt_free( crt
);
799 return( MBEDTLS_ERR_X509_INVALID_FORMAT
+ ret
);
802 if( ( ret
= mbedtls_x509_get_name( &p
, p
+ len
, &crt
->issuer
) ) != 0 )
804 mbedtls_x509_crt_free( crt
);
808 crt
->issuer_raw
.len
= p
- crt
->issuer_raw
.p
;
811 * Validity ::= SEQUENCE {
816 if( ( ret
= x509_get_dates( &p
, end
, &crt
->valid_from
,
817 &crt
->valid_to
) ) != 0 )
819 mbedtls_x509_crt_free( crt
);
826 crt
->subject_raw
.p
= p
;
828 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
829 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
831 mbedtls_x509_crt_free( crt
);
832 return( MBEDTLS_ERR_X509_INVALID_FORMAT
+ ret
);
835 if( len
&& ( ret
= mbedtls_x509_get_name( &p
, p
+ len
, &crt
->subject
) ) != 0 )
837 mbedtls_x509_crt_free( crt
);
841 crt
->subject_raw
.len
= p
- crt
->subject_raw
.p
;
844 * SubjectPublicKeyInfo
846 if( ( ret
= mbedtls_pk_parse_subpubkey( &p
, end
, &crt
->pk
) ) != 0 )
848 mbedtls_x509_crt_free( crt
);
853 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
854 * -- If present, version shall be v2 or v3
855 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
856 * -- If present, version shall be v2 or v3
857 * extensions [3] EXPLICIT Extensions OPTIONAL
858 * -- If present, version shall be v3
860 if( crt
->version
== 2 || crt
->version
== 3 )
862 ret
= x509_get_uid( &p
, end
, &crt
->issuer_id
, 1 );
865 mbedtls_x509_crt_free( crt
);
870 if( crt
->version
== 2 || crt
->version
== 3 )
872 ret
= x509_get_uid( &p
, end
, &crt
->subject_id
, 2 );
875 mbedtls_x509_crt_free( crt
);
880 #if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
881 if( crt
->version
== 3 )
884 ret
= x509_get_crt_ext( &p
, end
, crt
);
887 mbedtls_x509_crt_free( crt
);
894 mbedtls_x509_crt_free( crt
);
895 return( MBEDTLS_ERR_X509_INVALID_FORMAT
+
896 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
903 * -- end of TBSCertificate
905 * signatureAlgorithm AlgorithmIdentifier,
906 * signatureValue BIT STRING
908 if( ( ret
= mbedtls_x509_get_alg( &p
, end
, &sig_oid2
, &sig_params2
) ) != 0 )
910 mbedtls_x509_crt_free( crt
);
914 if( crt
->sig_oid
.len
!= sig_oid2
.len
||
915 memcmp( crt
->sig_oid
.p
, sig_oid2
.p
, crt
->sig_oid
.len
) != 0 ||
916 sig_params1
.len
!= sig_params2
.len
||
917 ( sig_params1
.len
!= 0 &&
918 memcmp( sig_params1
.p
, sig_params2
.p
, sig_params1
.len
) != 0 ) )
920 mbedtls_x509_crt_free( crt
);
921 return( MBEDTLS_ERR_X509_SIG_MISMATCH
);
924 if( ( ret
= mbedtls_x509_get_sig( &p
, end
, &crt
->sig
) ) != 0 )
926 mbedtls_x509_crt_free( crt
);
932 mbedtls_x509_crt_free( crt
);
933 return( MBEDTLS_ERR_X509_INVALID_FORMAT
+
934 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
941 * Parse one X.509 certificate in DER format from a buffer and add them to a
944 int mbedtls_x509_crt_parse_der( mbedtls_x509_crt
*chain
, const unsigned char *buf
,
948 mbedtls_x509_crt
*crt
= chain
, *prev
= NULL
;
951 * Check for valid input
953 if( crt
== NULL
|| buf
== NULL
)
954 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
956 while( crt
->version
!= 0 && crt
->next
!= NULL
)
963 * Add new certificate on the end of the chain if needed.
965 if( crt
->version
!= 0 && crt
->next
== NULL
)
967 crt
->next
= mbedtls_calloc( 1, sizeof( mbedtls_x509_crt
) );
969 if( crt
->next
== NULL
)
970 return( MBEDTLS_ERR_X509_ALLOC_FAILED
);
973 mbedtls_x509_crt_init( crt
->next
);
977 if( ( ret
= x509_crt_parse_der_core( crt
, buf
, buflen
) ) != 0 )
992 * Parse one or more PEM certificates from a buffer and add them to the chained
995 int mbedtls_x509_crt_parse( mbedtls_x509_crt
*chain
, const unsigned char *buf
, size_t buflen
)
997 #if defined(MBEDTLS_PEM_PARSE_C)
998 int success
= 0, first_error
= 0, total_failed
= 0;
999 int buf_format
= MBEDTLS_X509_FORMAT_DER
;
1003 * Check for valid input
1005 if( chain
== NULL
|| buf
== NULL
)
1006 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
1009 * Determine buffer content. Buffer contains either one DER certificate or
1010 * one or more PEM certificates.
1012 #if defined(MBEDTLS_PEM_PARSE_C)
1013 if( buflen
!= 0 && buf
[buflen
- 1] == '\0' &&
1014 strstr( (const char *) buf
, "-----BEGIN CERTIFICATE-----" ) != NULL
)
1016 buf_format
= MBEDTLS_X509_FORMAT_PEM
;
1019 if( buf_format
== MBEDTLS_X509_FORMAT_DER
)
1020 return mbedtls_x509_crt_parse_der( chain
, buf
, buflen
);
1022 return mbedtls_x509_crt_parse_der( chain
, buf
, buflen
);
1025 #if defined(MBEDTLS_PEM_PARSE_C)
1026 if( buf_format
== MBEDTLS_X509_FORMAT_PEM
)
1029 mbedtls_pem_context pem
;
1031 /* 1 rather than 0 since the terminating NULL byte is counted in */
1035 mbedtls_pem_init( &pem
);
1037 /* If we get there, we know the string is null-terminated */
1038 ret
= mbedtls_pem_read_buffer( &pem
,
1039 "-----BEGIN CERTIFICATE-----",
1040 "-----END CERTIFICATE-----",
1041 buf
, NULL
, 0, &use_len
);
1051 else if( ret
== MBEDTLS_ERR_PEM_BAD_INPUT_DATA
)
1055 else if( ret
!= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
)
1057 mbedtls_pem_free( &pem
);
1060 * PEM header and footer were found
1065 if( first_error
== 0 )
1074 ret
= mbedtls_x509_crt_parse_der( chain
, pem
.buf
, pem
.buflen
);
1076 mbedtls_pem_free( &pem
);
1081 * Quit parsing on a memory error
1083 if( ret
== MBEDTLS_ERR_X509_ALLOC_FAILED
)
1086 if( first_error
== 0 )
1098 return( total_failed
);
1099 else if( first_error
)
1100 return( first_error
);
1102 return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT
);
1103 #endif /* MBEDTLS_PEM_PARSE_C */
1106 #if defined(MBEDTLS_FS_IO)
1108 * Load one or more certificates and add them to the chained list
1110 int mbedtls_x509_crt_parse_file( mbedtls_x509_crt
*chain
, const char *path
)
1116 if( ( ret
= mbedtls_pk_load_file( path
, &buf
, &n
) ) != 0 )
1119 ret
= mbedtls_x509_crt_parse( chain
, buf
, n
);
1121 mbedtls_platform_zeroize( buf
, n
);
1122 mbedtls_free( buf
);
1127 int mbedtls_x509_crt_parse_path( mbedtls_x509_crt
*chain
, const char *path
)
1130 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
1132 WCHAR szDir
[MAX_PATH
];
1133 char filename
[MAX_PATH
];
1135 size_t len
= strlen( path
);
1137 WIN32_FIND_DATAW file_data
;
1140 if( len
> MAX_PATH
- 3 )
1141 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
1143 memset( szDir
, 0, sizeof(szDir
) );
1144 memset( filename
, 0, MAX_PATH
);
1145 memcpy( filename
, path
, len
);
1146 filename
[len
++] = '\\';
1148 filename
[len
++] = '*';
1150 w_ret
= MultiByteToWideChar( CP_ACP
, 0, filename
, (int)len
, szDir
,
1153 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
1155 hFind
= FindFirstFileW( szDir
, &file_data
);
1156 if( hFind
== INVALID_HANDLE_VALUE
)
1157 return( MBEDTLS_ERR_X509_FILE_IO_ERROR
);
1159 len
= MAX_PATH
- len
;
1162 memset( p
, 0, len
);
1164 if( file_data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
1167 w_ret
= WideCharToMultiByte( CP_ACP
, 0, file_data
.cFileName
,
1168 lstrlenW( file_data
.cFileName
),
1173 ret
= MBEDTLS_ERR_X509_FILE_IO_ERROR
;
1177 w_ret
= mbedtls_x509_crt_parse_file( chain
, filename
);
1183 while( FindNextFileW( hFind
, &file_data
) != 0 );
1185 if( GetLastError() != ERROR_NO_MORE_FILES
)
1186 ret
= MBEDTLS_ERR_X509_FILE_IO_ERROR
;
1194 struct dirent
*entry
;
1195 char entry_name
[MBEDTLS_X509_MAX_FILE_PATH_LEN
];
1196 DIR *dir
= opendir( path
);
1199 return( MBEDTLS_ERR_X509_FILE_IO_ERROR
);
1201 #if defined(MBEDTLS_THREADING_C)
1202 if( ( ret
= mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex
) ) != 0 )
1207 #endif /* MBEDTLS_THREADING_C */
1209 while( ( entry
= readdir( dir
) ) != NULL
)
1211 snp_ret
= mbedtls_snprintf( entry_name
, sizeof entry_name
,
1212 "%s/%s", path
, entry
->d_name
);
1214 if( snp_ret
< 0 || (size_t)snp_ret
>= sizeof entry_name
)
1216 ret
= MBEDTLS_ERR_X509_BUFFER_TOO_SMALL
;
1219 else if( stat( entry_name
, &sb
) == -1 )
1221 ret
= MBEDTLS_ERR_X509_FILE_IO_ERROR
;
1225 if( !S_ISREG( sb
.st_mode
) )
1228 // Ignore parse errors
1230 t_ret
= mbedtls_x509_crt_parse_file( chain
, entry_name
);
1240 #if defined(MBEDTLS_THREADING_C)
1241 if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex
) != 0 )
1242 ret
= MBEDTLS_ERR_THREADING_MUTEX_ERROR
;
1243 #endif /* MBEDTLS_THREADING_C */
1249 #endif /* MBEDTLS_FS_IO */
1251 static int x509_info_subject_alt_name( char **buf
, size_t *size
,
1252 const mbedtls_x509_sequence
*subject_alt_name
)
1257 const mbedtls_x509_sequence
*cur
= subject_alt_name
;
1258 const char *sep
= "";
1261 while( cur
!= NULL
)
1263 if( cur
->buf
.len
+ sep_len
>= n
)
1266 return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL
);
1269 n
-= cur
->buf
.len
+ sep_len
;
1270 for( i
= 0; i
< sep_len
; i
++ )
1272 for( i
= 0; i
< cur
->buf
.len
; i
++ )
1273 *p
++ = cur
->buf
.p
[i
];
1289 #define PRINT_ITEM(i) \
1291 ret = mbedtls_snprintf( p, n, "%s" i, sep ); \
1292 MBEDTLS_X509_SAFE_SNPRINTF; \
1296 #define CERT_TYPE(type,name) \
1297 if( ns_cert_type & type ) \
1300 static int x509_info_cert_type( char **buf
, size_t *size
,
1301 unsigned char ns_cert_type
)
1306 const char *sep
= "";
1308 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT
, "SSL Client" );
1309 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER
, "SSL Server" );
1310 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL
, "Email" );
1311 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING
, "Object Signing" );
1312 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED
, "Reserved" );
1313 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA
, "SSL CA" );
1314 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA
, "Email CA" );
1315 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA
, "Object Signing CA" );
1323 #define KEY_USAGE(code,name) \
1324 if( key_usage & code ) \
1327 static int x509_info_key_usage( char **buf
, size_t *size
,
1328 unsigned int key_usage
)
1333 const char *sep
= "";
1335 KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE
, "Digital Signature" );
1336 KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION
, "Non Repudiation" );
1337 KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT
, "Key Encipherment" );
1338 KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT
, "Data Encipherment" );
1339 KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT
, "Key Agreement" );
1340 KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN
, "Key Cert Sign" );
1341 KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN
, "CRL Sign" );
1342 KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY
, "Encipher Only" );
1343 KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY
, "Decipher Only" );
1351 static int x509_info_ext_key_usage( char **buf
, size_t *size
,
1352 const mbedtls_x509_sequence
*extended_key_usage
)
1358 const mbedtls_x509_sequence
*cur
= extended_key_usage
;
1359 const char *sep
= "";
1361 while( cur
!= NULL
)
1363 if( mbedtls_oid_get_extended_key_usage( &cur
->buf
, &desc
) != 0 )
1366 ret
= mbedtls_snprintf( p
, n
, "%s%s", sep
, desc
);
1367 MBEDTLS_X509_SAFE_SNPRINTF
;
1381 * Return an informational string about the certificate.
1383 #define BEFORE_COLON 18
1385 int mbedtls_x509_crt_info( char *buf
, size_t size
, const char *prefix
,
1386 const mbedtls_x509_crt
*crt
)
1391 char key_size_str
[BEFORE_COLON
];
1398 ret
= mbedtls_snprintf( p
, n
, "\nCertificate is uninitialised!\n" );
1399 MBEDTLS_X509_SAFE_SNPRINTF
;
1401 return( (int) ( size
- n
) );
1404 ret
= mbedtls_snprintf( p
, n
, "%scert. version : %d\n",
1405 prefix
, crt
->version
);
1406 MBEDTLS_X509_SAFE_SNPRINTF
;
1407 ret
= mbedtls_snprintf( p
, n
, "%sserial number : ",
1409 MBEDTLS_X509_SAFE_SNPRINTF
;
1411 ret
= mbedtls_x509_serial_gets( p
, n
, &crt
->serial
);
1412 MBEDTLS_X509_SAFE_SNPRINTF
;
1414 ret
= mbedtls_snprintf( p
, n
, "\n%sissuer name : ", prefix
);
1415 MBEDTLS_X509_SAFE_SNPRINTF
;
1416 ret
= mbedtls_x509_dn_gets( p
, n
, &crt
->issuer
);
1417 MBEDTLS_X509_SAFE_SNPRINTF
;
1419 ret
= mbedtls_snprintf( p
, n
, "\n%ssubject name : ", prefix
);
1420 MBEDTLS_X509_SAFE_SNPRINTF
;
1421 ret
= mbedtls_x509_dn_gets( p
, n
, &crt
->subject
);
1422 MBEDTLS_X509_SAFE_SNPRINTF
;
1424 ret
= mbedtls_snprintf( p
, n
, "\n%sissued on : " \
1425 "%04d-%02d-%02d %02d:%02d:%02d", prefix
,
1426 crt
->valid_from
.year
, crt
->valid_from
.mon
,
1427 crt
->valid_from
.day
, crt
->valid_from
.hour
,
1428 crt
->valid_from
.min
, crt
->valid_from
.sec
);
1429 MBEDTLS_X509_SAFE_SNPRINTF
;
1431 ret
= mbedtls_snprintf( p
, n
, "\n%sexpires on : " \
1432 "%04d-%02d-%02d %02d:%02d:%02d", prefix
,
1433 crt
->valid_to
.year
, crt
->valid_to
.mon
,
1434 crt
->valid_to
.day
, crt
->valid_to
.hour
,
1435 crt
->valid_to
.min
, crt
->valid_to
.sec
);
1436 MBEDTLS_X509_SAFE_SNPRINTF
;
1438 ret
= mbedtls_snprintf( p
, n
, "\n%ssigned using : ", prefix
);
1439 MBEDTLS_X509_SAFE_SNPRINTF
;
1441 ret
= mbedtls_x509_sig_alg_gets( p
, n
, &crt
->sig_oid
, crt
->sig_pk
,
1442 crt
->sig_md
, crt
->sig_opts
);
1443 MBEDTLS_X509_SAFE_SNPRINTF
;
1446 if( ( ret
= mbedtls_x509_key_size_helper( key_size_str
, BEFORE_COLON
,
1447 mbedtls_pk_get_name( &crt
->pk
) ) ) != 0 )
1452 ret
= mbedtls_snprintf( p
, n
, "\n%s%-" BC
"s: %d bits", prefix
, key_size_str
,
1453 (int) mbedtls_pk_get_bitlen( &crt
->pk
) );
1454 MBEDTLS_X509_SAFE_SNPRINTF
;
1457 * Optional extensions
1460 if( crt
->ext_types
& MBEDTLS_X509_EXT_BASIC_CONSTRAINTS
)
1462 ret
= mbedtls_snprintf( p
, n
, "\n%sbasic constraints : CA=%s", prefix
,
1463 crt
->ca_istrue
? "true" : "false" );
1464 MBEDTLS_X509_SAFE_SNPRINTF
;
1466 if( crt
->max_pathlen
> 0 )
1468 ret
= mbedtls_snprintf( p
, n
, ", max_pathlen=%d", crt
->max_pathlen
- 1 );
1469 MBEDTLS_X509_SAFE_SNPRINTF
;
1473 if( crt
->ext_types
& MBEDTLS_X509_EXT_SUBJECT_ALT_NAME
)
1475 ret
= mbedtls_snprintf( p
, n
, "\n%ssubject alt name : ", prefix
);
1476 MBEDTLS_X509_SAFE_SNPRINTF
;
1478 if( ( ret
= x509_info_subject_alt_name( &p
, &n
,
1479 &crt
->subject_alt_names
) ) != 0 )
1483 if( crt
->ext_types
& MBEDTLS_X509_EXT_NS_CERT_TYPE
)
1485 ret
= mbedtls_snprintf( p
, n
, "\n%scert. type : ", prefix
);
1486 MBEDTLS_X509_SAFE_SNPRINTF
;
1488 if( ( ret
= x509_info_cert_type( &p
, &n
, crt
->ns_cert_type
) ) != 0 )
1492 if( crt
->ext_types
& MBEDTLS_X509_EXT_KEY_USAGE
)
1494 ret
= mbedtls_snprintf( p
, n
, "\n%skey usage : ", prefix
);
1495 MBEDTLS_X509_SAFE_SNPRINTF
;
1497 if( ( ret
= x509_info_key_usage( &p
, &n
, crt
->key_usage
) ) != 0 )
1501 if( crt
->ext_types
& MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE
)
1503 ret
= mbedtls_snprintf( p
, n
, "\n%sext key usage : ", prefix
);
1504 MBEDTLS_X509_SAFE_SNPRINTF
;
1506 if( ( ret
= x509_info_ext_key_usage( &p
, &n
,
1507 &crt
->ext_key_usage
) ) != 0 )
1511 ret
= mbedtls_snprintf( p
, n
, "\n" );
1512 MBEDTLS_X509_SAFE_SNPRINTF
;
1514 return( (int) ( size
- n
) );
1517 struct x509_crt_verify_string
{
1522 static const struct x509_crt_verify_string x509_crt_verify_strings
[] = {
1523 { MBEDTLS_X509_BADCERT_EXPIRED
, "The certificate validity has expired" },
1524 { MBEDTLS_X509_BADCERT_REVOKED
, "The certificate has been revoked (is on a CRL)" },
1525 { MBEDTLS_X509_BADCERT_CN_MISMATCH
, "The certificate Common Name (CN) does not match with the expected CN" },
1526 { MBEDTLS_X509_BADCERT_NOT_TRUSTED
, "The certificate is not correctly signed by the trusted CA" },
1527 { MBEDTLS_X509_BADCRL_NOT_TRUSTED
, "The CRL is not correctly signed by the trusted CA" },
1528 { MBEDTLS_X509_BADCRL_EXPIRED
, "The CRL is expired" },
1529 { MBEDTLS_X509_BADCERT_MISSING
, "Certificate was missing" },
1530 { MBEDTLS_X509_BADCERT_SKIP_VERIFY
, "Certificate verification was skipped" },
1531 { MBEDTLS_X509_BADCERT_OTHER
, "Other reason (can be used by verify callback)" },
1532 { MBEDTLS_X509_BADCERT_FUTURE
, "The certificate validity starts in the future" },
1533 { MBEDTLS_X509_BADCRL_FUTURE
, "The CRL is from the future" },
1534 { MBEDTLS_X509_BADCERT_KEY_USAGE
, "Usage does not match the keyUsage extension" },
1535 { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE
, "Usage does not match the extendedKeyUsage extension" },
1536 { MBEDTLS_X509_BADCERT_NS_CERT_TYPE
, "Usage does not match the nsCertType extension" },
1537 { MBEDTLS_X509_BADCERT_BAD_MD
, "The certificate is signed with an unacceptable hash." },
1538 { MBEDTLS_X509_BADCERT_BAD_PK
, "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
1539 { MBEDTLS_X509_BADCERT_BAD_KEY
, "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." },
1540 { MBEDTLS_X509_BADCRL_BAD_MD
, "The CRL is signed with an unacceptable hash." },
1541 { MBEDTLS_X509_BADCRL_BAD_PK
, "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
1542 { MBEDTLS_X509_BADCRL_BAD_KEY
, "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." },
1546 int mbedtls_x509_crt_verify_info( char *buf
, size_t size
, const char *prefix
,
1550 const struct x509_crt_verify_string
*cur
;
1554 for( cur
= x509_crt_verify_strings
; cur
->string
!= NULL
; cur
++ )
1556 if( ( flags
& cur
->code
) == 0 )
1559 ret
= mbedtls_snprintf( p
, n
, "%s%s\n", prefix
, cur
->string
);
1560 MBEDTLS_X509_SAFE_SNPRINTF
;
1566 ret
= mbedtls_snprintf( p
, n
, "%sUnknown reason "
1567 "(this should not happen)\n", prefix
);
1568 MBEDTLS_X509_SAFE_SNPRINTF
;
1571 return( (int) ( size
- n
) );
1574 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
1575 int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt
*crt
,
1576 unsigned int usage
)
1578 unsigned int usage_must
, usage_may
;
1579 unsigned int may_mask
= MBEDTLS_X509_KU_ENCIPHER_ONLY
1580 | MBEDTLS_X509_KU_DECIPHER_ONLY
;
1582 if( ( crt
->ext_types
& MBEDTLS_X509_EXT_KEY_USAGE
) == 0 )
1585 usage_must
= usage
& ~may_mask
;
1587 if( ( ( crt
->key_usage
& ~may_mask
) & usage_must
) != usage_must
)
1588 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
1590 usage_may
= usage
& may_mask
;
1592 if( ( ( crt
->key_usage
& may_mask
) | usage_may
) != usage_may
)
1593 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
1599 #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
1600 int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt
*crt
,
1601 const char *usage_oid
,
1604 const mbedtls_x509_sequence
*cur
;
1606 /* Extension is not mandatory, absent means no restriction */
1607 if( ( crt
->ext_types
& MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE
) == 0 )
1611 * Look for the requested usage (or wildcard ANY) in our list
1613 for( cur
= &crt
->ext_key_usage
; cur
!= NULL
; cur
= cur
->next
)
1615 const mbedtls_x509_buf
*cur_oid
= &cur
->buf
;
1617 if( cur_oid
->len
== usage_len
&&
1618 memcmp( cur_oid
->p
, usage_oid
, usage_len
) == 0 )
1623 if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE
, cur_oid
) == 0 )
1627 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
1629 #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
1631 #if defined(MBEDTLS_X509_CRL_PARSE_C)
1633 * Return 1 if the certificate is revoked, or 0 otherwise.
1635 int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt
*crt
, const mbedtls_x509_crl
*crl
)
1637 const mbedtls_x509_crl_entry
*cur
= &crl
->entry
;
1639 while( cur
!= NULL
&& cur
->serial
.len
!= 0 )
1641 if( crt
->serial
.len
== cur
->serial
.len
&&
1642 memcmp( crt
->serial
.p
, cur
->serial
.p
, crt
->serial
.len
) == 0 )
1644 if( mbedtls_x509_time_is_past( &cur
->revocation_date
) )
1655 * Check that the given certificate is not revoked according to the CRL.
1656 * Skip validation if no CRL for the given CA is present.
1658 static int x509_crt_verifycrl( mbedtls_x509_crt
*crt
, mbedtls_x509_crt
*ca
,
1659 mbedtls_x509_crl
*crl_list
,
1660 const mbedtls_x509_crt_profile
*profile
)
1663 unsigned char hash
[MBEDTLS_MD_MAX_SIZE
];
1664 const mbedtls_md_info_t
*md_info
;
1669 while( crl_list
!= NULL
)
1671 if( crl_list
->version
== 0 ||
1672 crl_list
->issuer_raw
.len
!= ca
->subject_raw
.len
||
1673 memcmp( crl_list
->issuer_raw
.p
, ca
->subject_raw
.p
,
1674 crl_list
->issuer_raw
.len
) != 0 )
1676 crl_list
= crl_list
->next
;
1681 * Check if the CA is configured to sign CRLs
1683 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
1684 if( mbedtls_x509_crt_check_key_usage( ca
, MBEDTLS_X509_KU_CRL_SIGN
) != 0 )
1686 flags
|= MBEDTLS_X509_BADCRL_NOT_TRUSTED
;
1692 * Check if CRL is correctly signed by the trusted CA
1694 if( x509_profile_check_md_alg( profile
, crl_list
->sig_md
) != 0 )
1695 flags
|= MBEDTLS_X509_BADCRL_BAD_MD
;
1697 if( x509_profile_check_pk_alg( profile
, crl_list
->sig_pk
) != 0 )
1698 flags
|= MBEDTLS_X509_BADCRL_BAD_PK
;
1700 md_info
= mbedtls_md_info_from_type( crl_list
->sig_md
);
1701 if( mbedtls_md( md_info
, crl_list
->tbs
.p
, crl_list
->tbs
.len
, hash
) != 0 )
1703 /* Note: this can't happen except after an internal error */
1704 flags
|= MBEDTLS_X509_BADCRL_NOT_TRUSTED
;
1708 if( x509_profile_check_key( profile
, &ca
->pk
) != 0 )
1709 flags
|= MBEDTLS_X509_BADCERT_BAD_KEY
;
1711 if( mbedtls_pk_verify_ext( crl_list
->sig_pk
, crl_list
->sig_opts
, &ca
->pk
,
1712 crl_list
->sig_md
, hash
, mbedtls_md_get_size( md_info
),
1713 crl_list
->sig
.p
, crl_list
->sig
.len
) != 0 )
1715 flags
|= MBEDTLS_X509_BADCRL_NOT_TRUSTED
;
1720 * Check for validity of CRL (Do not drop out)
1722 if( mbedtls_x509_time_is_past( &crl_list
->next_update
) )
1723 flags
|= MBEDTLS_X509_BADCRL_EXPIRED
;
1725 if( mbedtls_x509_time_is_future( &crl_list
->this_update
) )
1726 flags
|= MBEDTLS_X509_BADCRL_FUTURE
;
1729 * Check if certificate is revoked
1731 if( mbedtls_x509_crt_is_revoked( crt
, crl_list
) )
1733 flags
|= MBEDTLS_X509_BADCERT_REVOKED
;
1737 crl_list
= crl_list
->next
;
1742 #endif /* MBEDTLS_X509_CRL_PARSE_C */
1745 * Like memcmp, but case-insensitive and always returns -1 if different
1747 static int x509_memcasecmp( const void *s1
, const void *s2
, size_t len
)
1751 const unsigned char *n1
= s1
, *n2
= s2
;
1753 for( i
= 0; i
< len
; i
++ )
1755 diff
= n1
[i
] ^ n2
[i
];
1761 ( ( n1
[i
] >= 'a' && n1
[i
] <= 'z' ) ||
1762 ( n1
[i
] >= 'A' && n1
[i
] <= 'Z' ) ) )
1774 * Return 0 if name matches wildcard, -1 otherwise
1776 static int x509_check_wildcard( const char *cn
, const mbedtls_x509_buf
*name
)
1779 size_t cn_idx
= 0, cn_len
= strlen( cn
);
1781 /* We can't have a match if there is no wildcard to match */
1782 if( name
->len
< 3 || name
->p
[0] != '*' || name
->p
[1] != '.' )
1785 for( i
= 0; i
< cn_len
; ++i
)
1797 if( cn_len
- cn_idx
== name
->len
- 1 &&
1798 x509_memcasecmp( name
->p
+ 1, cn
+ cn_idx
, name
->len
- 1 ) == 0 )
1807 * Compare two X.509 strings, case-insensitive, and allowing for some encoding
1808 * variations (but not all).
1810 * Return 0 if equal, -1 otherwise.
1812 static int x509_string_cmp( const mbedtls_x509_buf
*a
, const mbedtls_x509_buf
*b
)
1814 if( a
->tag
== b
->tag
&&
1816 memcmp( a
->p
, b
->p
, b
->len
) == 0 )
1821 if( ( a
->tag
== MBEDTLS_ASN1_UTF8_STRING
|| a
->tag
== MBEDTLS_ASN1_PRINTABLE_STRING
) &&
1822 ( b
->tag
== MBEDTLS_ASN1_UTF8_STRING
|| b
->tag
== MBEDTLS_ASN1_PRINTABLE_STRING
) &&
1824 x509_memcasecmp( a
->p
, b
->p
, b
->len
) == 0 )
1833 * Compare two X.509 Names (aka rdnSequence).
1835 * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
1836 * we sometimes return unequal when the full algorithm would return equal,
1837 * but never the other way. (In particular, we don't do Unicode normalisation
1838 * or space folding.)
1840 * Return 0 if equal, -1 otherwise.
1842 static int x509_name_cmp( const mbedtls_x509_name
*a
, const mbedtls_x509_name
*b
)
1844 /* Avoid recursion, it might not be optimised by the compiler */
1845 while( a
!= NULL
|| b
!= NULL
)
1847 if( a
== NULL
|| b
== NULL
)
1851 if( a
->oid
.tag
!= b
->oid
.tag
||
1852 a
->oid
.len
!= b
->oid
.len
||
1853 memcmp( a
->oid
.p
, b
->oid
.p
, b
->oid
.len
) != 0 )
1859 if( x509_string_cmp( &a
->val
, &b
->val
) != 0 )
1862 /* structure of the list of sets */
1863 if( a
->next_merged
!= b
->next_merged
)
1870 /* a == NULL == b */
1875 * Check the signature of a certificate by its parent
1877 static int x509_crt_check_signature( const mbedtls_x509_crt
*child
,
1878 mbedtls_x509_crt
*parent
)
1880 const mbedtls_md_info_t
*md_info
;
1881 unsigned char hash
[MBEDTLS_MD_MAX_SIZE
];
1883 md_info
= mbedtls_md_info_from_type( child
->sig_md
);
1884 if( mbedtls_md( md_info
, child
->tbs
.p
, child
->tbs
.len
, hash
) != 0 )
1886 /* Note: this can't happen except after an internal error */
1890 if( mbedtls_pk_verify_ext( child
->sig_pk
, child
->sig_opts
, &parent
->pk
,
1891 child
->sig_md
, hash
, mbedtls_md_get_size( md_info
),
1892 child
->sig
.p
, child
->sig
.len
) != 0 )
1901 * Check if 'parent' is a suitable parent (signing CA) for 'child'.
1902 * Return 0 if yes, -1 if not.
1904 * top means parent is a locally-trusted certificate
1906 static int x509_crt_check_parent( const mbedtls_x509_crt
*child
,
1907 const mbedtls_x509_crt
*parent
,
1912 /* Parent must be the issuer */
1913 if( x509_name_cmp( &child
->issuer
, &parent
->subject
) != 0 )
1916 /* Parent must have the basicConstraints CA bit set as a general rule */
1919 /* Exception: v1/v2 certificates that are locally trusted. */
1920 if( top
&& parent
->version
< 3 )
1923 if( need_ca_bit
&& ! parent
->ca_istrue
)
1926 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
1928 mbedtls_x509_crt_check_key_usage( parent
, MBEDTLS_X509_KU_KEY_CERT_SIGN
) != 0 )
1938 * Find a suitable parent for child in candidates, or return NULL.
1940 * Here suitable is defined as:
1941 * 1. subject name matches child's issuer
1942 * 2. if necessary, the CA bit is set and key usage allows signing certs
1943 * 3. for trusted roots, the signature is correct
1944 * 4. pathlen constraints are satisfied
1946 * If there's a suitable candidate which is also time-valid, return the first
1947 * such. Otherwise, return the first suitable candidate (or NULL if there is
1950 * The rationale for this rule is that someone could have a list of trusted
1951 * roots with two versions on the same root with different validity periods.
1952 * (At least one user reported having such a list and wanted it to just work.)
1953 * The reason we don't just require time-validity is that generally there is
1954 * only one version, and if it's expired we want the flags to state that
1955 * rather than NOT_TRUSTED, as would be the case if we required it here.
1957 * The rationale for rule 3 (signature for trusted roots) is that users might
1958 * have two versions of the same CA with different keys in their list, and the
1959 * way we select the correct one is by checking the signature (as we don't
1960 * rely on key identifier extensions). (This is one way users might choose to
1961 * handle key rollover, another relies on self-issued certs, see [SIRO].)
1964 * - [in] child: certificate for which we're looking for a parent
1965 * - [in] candidates: chained list of potential parents
1966 * - [in] top: 1 if candidates consists of trusted roots, ie we're at the top
1967 * of the chain, 0 otherwise
1968 * - [in] path_cnt: number of intermediates seen so far
1969 * - [in] self_cnt: number of self-signed intermediates seen so far
1970 * (will never be greater than path_cnt)
1973 * - the first suitable parent found (see above regarding time-validity)
1974 * - NULL if no suitable parent was found
1976 static mbedtls_x509_crt
*x509_crt_find_parent_in( mbedtls_x509_crt
*child
,
1977 mbedtls_x509_crt
*candidates
,
1982 mbedtls_x509_crt
*parent
, *badtime_parent
= NULL
;
1984 for( parent
= candidates
; parent
!= NULL
; parent
= parent
->next
)
1986 /* basic parenting skills (name, CA bit, key usage) */
1987 if( x509_crt_check_parent( child
, parent
, top
) != 0 )
1990 /* +1 because stored max_pathlen is 1 higher that the actual value */
1991 if( parent
->max_pathlen
> 0 &&
1992 (size_t) parent
->max_pathlen
< 1 + path_cnt
- self_cnt
)
1998 if( top
&& x509_crt_check_signature( child
, parent
) != 0 )
2003 /* optional time check */
2004 if( mbedtls_x509_time_is_past( &parent
->valid_to
) ||
2005 mbedtls_x509_time_is_future( &parent
->valid_from
) )
2007 if( badtime_parent
== NULL
)
2008 badtime_parent
= parent
;
2016 if( parent
== NULL
)
2017 parent
= badtime_parent
;
2023 * Find a parent in trusted CAs or the provided chain, or return NULL.
2025 * Searches in trusted CAs first, and return the first suitable parent found
2026 * (see find_parent_in() for definition of suitable).
2029 * - [in] child: certificate for which we're looking for a parent, followed
2030 * by a chain of possible intermediates
2031 * - [in] trust_ca: locally trusted CAs
2032 * - [out] 1 if parent was found in trust_ca, 0 if found in provided chain
2033 * - [in] path_cnt: number of intermediates seen so far
2034 * - [in] self_cnt: number of self-signed intermediates seen so far
2035 * (will always be no greater than path_cnt)
2038 * - the first suitable parent found (see find_parent_in() for "suitable")
2039 * - NULL if no suitable parent was found
2041 static mbedtls_x509_crt
*x509_crt_find_parent( mbedtls_x509_crt
*child
,
2042 mbedtls_x509_crt
*trust_ca
,
2043 int *parent_is_trusted
,
2047 mbedtls_x509_crt
*parent
;
2049 /* Look for a parent in trusted CAs */
2050 *parent_is_trusted
= 1;
2051 parent
= x509_crt_find_parent_in( child
, trust_ca
, 1, path_cnt
, self_cnt
);
2053 if( parent
!= NULL
)
2056 /* Look for a parent upwards the chain */
2057 *parent_is_trusted
= 0;
2058 return( x509_crt_find_parent_in( child
, child
->next
, 0, path_cnt
, self_cnt
) );
2062 * Check if an end-entity certificate is locally trusted
2064 * Currently we require such certificates to be self-signed (actually only
2065 * check for self-issued as self-signatures are not checked)
2067 static int x509_crt_check_ee_locally_trusted(
2068 mbedtls_x509_crt
*crt
,
2069 mbedtls_x509_crt
*trust_ca
)
2071 mbedtls_x509_crt
*cur
;
2073 /* must be self-issued */
2074 if( x509_name_cmp( &crt
->issuer
, &crt
->subject
) != 0 )
2077 /* look for an exact match with trusted cert */
2078 for( cur
= trust_ca
; cur
!= NULL
; cur
= cur
->next
)
2080 if( crt
->raw
.len
== cur
->raw
.len
&&
2081 memcmp( crt
->raw
.p
, cur
->raw
.p
, crt
->raw
.len
) == 0 )
2092 * Build and verify a certificate chain
2094 * Given a peer-provided list of certificates EE, C1, ..., Cn and
2095 * a list of trusted certs R1, ... Rp, try to build and verify a chain
2096 * EE, Ci1, ... Ciq [, Rj]
2097 * such that every cert in the chain is a child of the next one,
2098 * jumping to a trusted root as early as possible.
2100 * Verify that chain and return it with flags for all issues found.
2103 * - EE == Rj -> return a one-element list containing it
2104 * - EE, Ci1, ..., Ciq cannot be continued with a trusted root
2105 * -> return that chain with NOT_TRUSTED set on Ciq
2108 * - [in] crt: the cert list EE, C1, ..., Cn
2109 * - [in] trust_ca: the trusted list R1, ..., Rp
2110 * - [in] ca_crl, profile: as in verify_with_profile()
2111 * - [out] ver_chain, chain_len: the built and verified chain
2114 * - non-zero if the chain could not be fully built and examined
2115 * - 0 is the chain was successfully built and examined,
2116 * even if it was found to be invalid
2118 static int x509_crt_verify_chain(
2119 mbedtls_x509_crt
*crt
,
2120 mbedtls_x509_crt
*trust_ca
,
2121 mbedtls_x509_crl
*ca_crl
,
2122 const mbedtls_x509_crt_profile
*profile
,
2123 x509_crt_verify_chain_item ver_chain
[X509_MAX_VERIFY_CHAIN_SIZE
],
2127 mbedtls_x509_crt
*child
;
2128 mbedtls_x509_crt
*parent
;
2129 int parent_is_trusted
= 0;
2130 int child_is_trusted
= 0;
2131 size_t self_cnt
= 0;
2137 /* Add certificate to the verification chain */
2138 ver_chain
[*chain_len
].crt
= child
;
2139 flags
= &ver_chain
[*chain_len
].flags
;
2142 /* Check time-validity (all certificates) */
2143 if( mbedtls_x509_time_is_past( &child
->valid_to
) )
2144 *flags
|= MBEDTLS_X509_BADCERT_EXPIRED
;
2146 if( mbedtls_x509_time_is_future( &child
->valid_from
) )
2147 *flags
|= MBEDTLS_X509_BADCERT_FUTURE
;
2149 /* Stop here for trusted roots (but not for trusted EE certs) */
2150 if( child_is_trusted
)
2153 /* Check signature algorithm: MD & PK algs */
2154 if( x509_profile_check_md_alg( profile
, child
->sig_md
) != 0 )
2155 *flags
|= MBEDTLS_X509_BADCERT_BAD_MD
;
2157 if( x509_profile_check_pk_alg( profile
, child
->sig_pk
) != 0 )
2158 *flags
|= MBEDTLS_X509_BADCERT_BAD_PK
;
2160 /* Special case: EE certs that are locally trusted */
2161 if( *chain_len
== 1 &&
2162 x509_crt_check_ee_locally_trusted( child
, trust_ca
) == 0 )
2167 /* Look for a parent in trusted CAs or up the chain */
2168 parent
= x509_crt_find_parent( child
, trust_ca
, &parent_is_trusted
,
2169 *chain_len
- 1, self_cnt
);
2171 /* No parent? We're done here */
2172 if( parent
== NULL
)
2174 *flags
|= MBEDTLS_X509_BADCERT_NOT_TRUSTED
;
2178 /* Count intermediate self-issued (not necessarily self-signed) certs.
2179 * These can occur with some strategies for key rollover, see [SIRO],
2180 * and should be excluded from max_pathlen checks. */
2181 if( *chain_len
!= 1 &&
2182 x509_name_cmp( &child
->issuer
, &child
->subject
) == 0 )
2187 /* path_cnt is 0 for the first intermediate CA,
2188 * and if parent is trusted it's not an intermediate CA */
2189 if( ! parent_is_trusted
&&
2190 *chain_len
> MBEDTLS_X509_MAX_INTERMEDIATE_CA
)
2192 /* return immediately to avoid overflow the chain array */
2193 return( MBEDTLS_ERR_X509_FATAL_ERROR
);
2196 /* if parent is trusted, the signature was checked by find_parent() */
2197 if( ! parent_is_trusted
&& x509_crt_check_signature( child
, parent
) != 0 )
2198 *flags
|= MBEDTLS_X509_BADCERT_NOT_TRUSTED
;
2200 /* check size of signing key */
2201 if( x509_profile_check_key( profile
, &parent
->pk
) != 0 )
2202 *flags
|= MBEDTLS_X509_BADCERT_BAD_KEY
;
2204 #if defined(MBEDTLS_X509_CRL_PARSE_C)
2205 /* Check trusted CA's CRL for the given crt */
2206 *flags
|= x509_crt_verifycrl( child
, parent
, ca_crl
, profile
);
2211 /* prepare for next iteration */
2214 child_is_trusted
= parent_is_trusted
;
2219 * Check for CN match
2221 static int x509_crt_check_cn( const mbedtls_x509_buf
*name
,
2222 const char *cn
, size_t cn_len
)
2224 /* try exact match */
2225 if( name
->len
== cn_len
&&
2226 x509_memcasecmp( cn
, name
->p
, cn_len
) == 0 )
2231 /* try wildcard match */
2232 if( x509_check_wildcard( cn
, name
) == 0 )
2241 * Verify the requested CN - only call this if cn is not NULL!
2243 static void x509_crt_verify_name( const mbedtls_x509_crt
*crt
,
2247 const mbedtls_x509_name
*name
;
2248 const mbedtls_x509_sequence
*cur
;
2249 size_t cn_len
= strlen( cn
);
2251 if( crt
->ext_types
& MBEDTLS_X509_EXT_SUBJECT_ALT_NAME
)
2253 for( cur
= &crt
->subject_alt_names
; cur
!= NULL
; cur
= cur
->next
)
2255 if( x509_crt_check_cn( &cur
->buf
, cn
, cn_len
) == 0 )
2260 *flags
|= MBEDTLS_X509_BADCERT_CN_MISMATCH
;
2264 for( name
= &crt
->subject
; name
!= NULL
; name
= name
->next
)
2266 if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN
, &name
->oid
) == 0 &&
2267 x509_crt_check_cn( &name
->val
, cn
, cn_len
) == 0 )
2274 *flags
|= MBEDTLS_X509_BADCERT_CN_MISMATCH
;
2279 * Merge the flags for all certs in the chain, after calling callback
2281 static int x509_crt_merge_flags_with_cb(
2283 x509_crt_verify_chain_item ver_chain
[X509_MAX_VERIFY_CHAIN_SIZE
],
2285 int (*f_vrfy
)(void *, mbedtls_x509_crt
*, int, uint32_t *),
2292 for( i
= chain_len
; i
!= 0; --i
)
2294 cur_flags
= ver_chain
[i
-1].flags
;
2296 if( NULL
!= f_vrfy
)
2297 if( ( ret
= f_vrfy( p_vrfy
, ver_chain
[i
-1].crt
, (int) i
-1, &cur_flags
) ) != 0 )
2300 *flags
|= cur_flags
;
2307 * Verify the certificate validity
2309 int mbedtls_x509_crt_verify( mbedtls_x509_crt
*crt
,
2310 mbedtls_x509_crt
*trust_ca
,
2311 mbedtls_x509_crl
*ca_crl
,
2312 const char *cn
, uint32_t *flags
,
2313 int (*f_vrfy
)(void *, mbedtls_x509_crt
*, int, uint32_t *),
2316 return( mbedtls_x509_crt_verify_with_profile( crt
, trust_ca
, ca_crl
,
2317 &mbedtls_x509_crt_profile_default
, cn
, flags
, f_vrfy
, p_vrfy
) );
2321 * Verify the certificate validity, with profile
2324 * - checks the requested CN (if any)
2325 * - checks the type and size of the EE cert's key,
2326 * as that isn't done as part of chain building/verification currently
2327 * - builds and verifies the chain
2328 * - then calls the callback and merges the flags
2330 int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt
*crt
,
2331 mbedtls_x509_crt
*trust_ca
,
2332 mbedtls_x509_crl
*ca_crl
,
2333 const mbedtls_x509_crt_profile
*profile
,
2334 const char *cn
, uint32_t *flags
,
2335 int (*f_vrfy
)(void *, mbedtls_x509_crt
*, int, uint32_t *),
2339 mbedtls_pk_type_t pk_type
;
2340 x509_crt_verify_chain_item ver_chain
[X509_MAX_VERIFY_CHAIN_SIZE
];
2342 uint32_t *ee_flags
= &ver_chain
[0].flags
;
2345 memset( ver_chain
, 0, sizeof( ver_chain
) );
2348 if( profile
== NULL
)
2350 ret
= MBEDTLS_ERR_X509_BAD_INPUT_DATA
;
2354 /* check name if requested */
2356 x509_crt_verify_name( crt
, cn
, ee_flags
);
2358 /* Check the type and size of the key */
2359 pk_type
= mbedtls_pk_get_type( &crt
->pk
);
2361 if( x509_profile_check_pk_alg( profile
, pk_type
) != 0 )
2362 *ee_flags
|= MBEDTLS_X509_BADCERT_BAD_PK
;
2364 if( x509_profile_check_key( profile
, &crt
->pk
) != 0 )
2365 *ee_flags
|= MBEDTLS_X509_BADCERT_BAD_KEY
;
2367 /* Check the chain */
2368 ret
= x509_crt_verify_chain( crt
, trust_ca
, ca_crl
, profile
,
2369 ver_chain
, &chain_len
);
2373 /* Build final flags, calling callback on the way if any */
2374 ret
= x509_crt_merge_flags_with_cb( flags
,
2375 ver_chain
, chain_len
, f_vrfy
, p_vrfy
);
2378 /* prevent misuse of the vrfy callback - VERIFY_FAILED would be ignored by
2379 * the SSL module for authmode optional, but non-zero return from the
2380 * callback means a fatal error so it shouldn't be ignored */
2381 if( ret
== MBEDTLS_ERR_X509_CERT_VERIFY_FAILED
)
2382 ret
= MBEDTLS_ERR_X509_FATAL_ERROR
;
2386 *flags
= (uint32_t) -1;
2391 return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED
);
2397 * Initialize a certificate chain
2399 void mbedtls_x509_crt_init( mbedtls_x509_crt
*crt
)
2401 memset( crt
, 0, sizeof(mbedtls_x509_crt
) );
2405 * Unallocate all certificate data
2407 void mbedtls_x509_crt_free( mbedtls_x509_crt
*crt
)
2409 mbedtls_x509_crt
*cert_cur
= crt
;
2410 mbedtls_x509_crt
*cert_prv
;
2411 mbedtls_x509_name
*name_cur
;
2412 mbedtls_x509_name
*name_prv
;
2413 mbedtls_x509_sequence
*seq_cur
;
2414 mbedtls_x509_sequence
*seq_prv
;
2421 mbedtls_pk_free( &cert_cur
->pk
);
2423 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
2424 mbedtls_free( cert_cur
->sig_opts
);
2427 name_cur
= cert_cur
->issuer
.next
;
2428 while( name_cur
!= NULL
)
2430 name_prv
= name_cur
;
2431 name_cur
= name_cur
->next
;
2432 mbedtls_platform_zeroize( name_prv
, sizeof( mbedtls_x509_name
) );
2433 mbedtls_free( name_prv
);
2436 name_cur
= cert_cur
->subject
.next
;
2437 while( name_cur
!= NULL
)
2439 name_prv
= name_cur
;
2440 name_cur
= name_cur
->next
;
2441 mbedtls_platform_zeroize( name_prv
, sizeof( mbedtls_x509_name
) );
2442 mbedtls_free( name_prv
);
2445 seq_cur
= cert_cur
->ext_key_usage
.next
;
2446 while( seq_cur
!= NULL
)
2449 seq_cur
= seq_cur
->next
;
2450 mbedtls_platform_zeroize( seq_prv
,
2451 sizeof( mbedtls_x509_sequence
) );
2452 mbedtls_free( seq_prv
);
2455 seq_cur
= cert_cur
->subject_alt_names
.next
;
2456 while( seq_cur
!= NULL
)
2459 seq_cur
= seq_cur
->next
;
2460 mbedtls_platform_zeroize( seq_prv
,
2461 sizeof( mbedtls_x509_sequence
) );
2462 mbedtls_free( seq_prv
);
2465 if( cert_cur
->raw
.p
!= NULL
)
2467 mbedtls_platform_zeroize( cert_cur
->raw
.p
, cert_cur
->raw
.len
);
2468 mbedtls_free( cert_cur
->raw
.p
);
2471 cert_cur
= cert_cur
->next
;
2473 while( cert_cur
!= NULL
);
2478 cert_prv
= cert_cur
;
2479 cert_cur
= cert_cur
->next
;
2481 mbedtls_platform_zeroize( cert_prv
, sizeof( mbedtls_x509_crt
) );
2482 if( cert_prv
!= crt
)
2483 mbedtls_free( cert_prv
);
2485 while( cert_cur
!= NULL
);
2488 #endif /* MBEDTLS_X509_CRT_PARSE_C */