2 * X.509 certificate parsing and verification
4 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
6 * This file is part of mbed TLS (https://tls.mbed.org)
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 * The ITU-T X.509 standard defines a certificate format for PKI.
25 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
26 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
27 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
29 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
30 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
33 #if !defined(POLARSSL_CONFIG_FILE)
34 #include "polarssl/config.h"
36 #include POLARSSL_CONFIG_FILE
39 #if defined(POLARSSL_X509_CRT_PARSE_C)
41 #include "polarssl/x509_crt.h"
42 #include "polarssl/oid.h"
47 #if defined(POLARSSL_PEM_PARSE_C)
48 #include "polarssl/pem.h"
51 #if defined(POLARSSL_PLATFORM_C)
52 #include "polarssl/platform.h"
55 #define polarssl_free free
56 #define polarssl_malloc malloc
57 #define polarssl_snprintf snprintf
60 #if defined(POLARSSL_THREADING_C)
61 #include "polarssl/threading.h"
64 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
70 #if defined(POLARSSL_FS_IO)
72 #if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
73 #include <sys/types.h>
76 #endif /* !_WIN32 || EFIX64 || EFI32 */
79 /* Implementation that should never be optimized out by the compiler */
80 static void polarssl_zeroize( void *v
, size_t n
) {
81 volatile unsigned char *p
= v
; while( n
-- ) *p
++ = 0;
85 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
87 static int x509_get_version( unsigned char **p
,
88 const unsigned char *end
,
94 if( ( ret
= asn1_get_tag( p
, end
, &len
,
95 ASN1_CONTEXT_SPECIFIC
| ASN1_CONSTRUCTED
| 0 ) ) != 0 )
97 if( ret
== POLARSSL_ERR_ASN1_UNEXPECTED_TAG
)
108 if( ( ret
= asn1_get_int( p
, end
, ver
) ) != 0 )
109 return( POLARSSL_ERR_X509_INVALID_VERSION
+ ret
);
112 return( POLARSSL_ERR_X509_INVALID_VERSION
+
113 POLARSSL_ERR_ASN1_LENGTH_MISMATCH
);
119 * Validity ::= SEQUENCE {
123 static int x509_get_dates( unsigned char **p
,
124 const unsigned char *end
,
131 if( ( ret
= asn1_get_tag( p
, end
, &len
,
132 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
133 return( POLARSSL_ERR_X509_INVALID_DATE
+ ret
);
137 if( ( ret
= x509_get_time( p
, end
, from
) ) != 0 )
140 if( ( ret
= x509_get_time( p
, end
, to
) ) != 0 )
144 return( POLARSSL_ERR_X509_INVALID_DATE
+
145 POLARSSL_ERR_ASN1_LENGTH_MISMATCH
);
151 * X.509 v2/v3 unique identifier (not parsed)
153 static int x509_get_uid( unsigned char **p
,
154 const unsigned char *end
,
155 x509_buf
*uid
, int n
)
164 if( ( ret
= asn1_get_tag( p
, end
, &uid
->len
,
165 ASN1_CONTEXT_SPECIFIC
| ASN1_CONSTRUCTED
| n
) ) != 0 )
167 if( ret
== POLARSSL_ERR_ASN1_UNEXPECTED_TAG
)
179 static int x509_get_basic_constraints( unsigned char **p
,
180 const unsigned char *end
,
188 * BasicConstraints ::= SEQUENCE {
189 * cA BOOLEAN DEFAULT FALSE,
190 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
192 *ca_istrue
= 0; /* DEFAULT FALSE */
193 *max_pathlen
= 0; /* endless */
195 if( ( ret
= asn1_get_tag( p
, end
, &len
,
196 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
197 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+ ret
);
202 if( ( ret
= asn1_get_bool( p
, end
, ca_istrue
) ) != 0 )
204 if( ret
== POLARSSL_ERR_ASN1_UNEXPECTED_TAG
)
205 ret
= asn1_get_int( p
, end
, ca_istrue
);
208 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+ ret
);
210 if( *ca_istrue
!= 0 )
217 if( ( ret
= asn1_get_int( p
, end
, max_pathlen
) ) != 0 )
218 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+ ret
);
221 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
222 POLARSSL_ERR_ASN1_LENGTH_MISMATCH
);
229 static int x509_get_ns_cert_type( unsigned char **p
,
230 const unsigned char *end
,
231 unsigned char *ns_cert_type
)
234 x509_bitstring bs
= { 0, 0, NULL
};
236 if( ( ret
= asn1_get_bitstring( p
, end
, &bs
) ) != 0 )
237 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+ ret
);
240 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
241 POLARSSL_ERR_ASN1_INVALID_LENGTH
);
243 /* Get actual bitstring */
244 *ns_cert_type
= *bs
.p
;
248 static int x509_get_key_usage( unsigned char **p
,
249 const unsigned char *end
,
250 unsigned char *key_usage
)
253 x509_bitstring bs
= { 0, 0, NULL
};
255 if( ( ret
= asn1_get_bitstring( p
, end
, &bs
) ) != 0 )
256 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+ ret
);
259 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
260 POLARSSL_ERR_ASN1_INVALID_LENGTH
);
262 /* Get actual bitstring */
268 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
270 * KeyPurposeId ::= OBJECT IDENTIFIER
272 static int x509_get_ext_key_usage( unsigned char **p
,
273 const unsigned char *end
,
274 x509_sequence
*ext_key_usage
)
278 if( ( ret
= asn1_get_sequence_of( p
, end
, ext_key_usage
, ASN1_OID
) ) != 0 )
279 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+ ret
);
281 /* Sequence length must be >= 1 */
282 if( ext_key_usage
->buf
.p
== NULL
)
283 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
284 POLARSSL_ERR_ASN1_INVALID_LENGTH
);
290 * SubjectAltName ::= GeneralNames
292 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
294 * GeneralName ::= CHOICE {
295 * otherName [0] OtherName,
296 * rfc822Name [1] IA5String,
297 * dNSName [2] IA5String,
298 * x400Address [3] ORAddress,
299 * directoryName [4] Name,
300 * ediPartyName [5] EDIPartyName,
301 * uniformResourceIdentifier [6] IA5String,
302 * iPAddress [7] OCTET STRING,
303 * registeredID [8] OBJECT IDENTIFIER }
305 * OtherName ::= SEQUENCE {
306 * type-id OBJECT IDENTIFIER,
307 * value [0] EXPLICIT ANY DEFINED BY type-id }
309 * EDIPartyName ::= SEQUENCE {
310 * nameAssigner [0] DirectoryString OPTIONAL,
311 * partyName [1] DirectoryString }
313 * NOTE: we only parse and use dNSName at this point.
315 static int x509_get_subject_alt_name( unsigned char **p
,
316 const unsigned char *end
,
317 x509_sequence
*subject_alt_name
)
323 asn1_sequence
*cur
= subject_alt_name
;
325 /* Get main sequence tag */
326 if( ( ret
= asn1_get_tag( p
, end
, &len
,
327 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
328 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+ ret
);
330 if( *p
+ len
!= end
)
331 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
332 POLARSSL_ERR_ASN1_LENGTH_MISMATCH
);
336 if( ( end
- *p
) < 1 )
337 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
338 POLARSSL_ERR_ASN1_OUT_OF_DATA
);
342 if( ( ret
= asn1_get_len( p
, end
, &tag_len
) ) != 0 )
343 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+ ret
);
345 if( ( tag
& ASN1_CONTEXT_SPECIFIC
) != ASN1_CONTEXT_SPECIFIC
)
346 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
347 POLARSSL_ERR_ASN1_UNEXPECTED_TAG
);
349 /* Skip everything but DNS name */
350 if( tag
!= ( ASN1_CONTEXT_SPECIFIC
| 2 ) )
356 /* Allocate and assign next pointer */
357 if( cur
->buf
.p
!= NULL
)
359 if( cur
->next
!= NULL
)
360 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
);
362 cur
->next
= polarssl_malloc( sizeof( asn1_sequence
) );
364 if( cur
->next
== NULL
)
365 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
366 POLARSSL_ERR_ASN1_MALLOC_FAILED
);
368 memset( cur
->next
, 0, sizeof( asn1_sequence
) );
379 /* Set final sequence entry's next pointer to NULL */
383 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
384 POLARSSL_ERR_ASN1_LENGTH_MISMATCH
);
390 * X.509 v3 extensions
392 * TODO: Perform all of the basic constraints tests required by the RFC
393 * TODO: Set values for undetected extensions to a sane default?
396 static int x509_get_crt_ext( unsigned char **p
,
397 const unsigned char *end
,
402 unsigned char *end_ext_data
, *end_ext_octet
;
404 if( ( ret
= x509_get_ext( p
, end
, &crt
->v3_ext
, 3 ) ) != 0 )
406 if( ret
== POLARSSL_ERR_ASN1_UNEXPECTED_TAG
)
415 * Extension ::= SEQUENCE {
416 * extnID OBJECT IDENTIFIER,
417 * critical BOOLEAN DEFAULT FALSE,
418 * extnValue OCTET STRING }
420 x509_buf extn_oid
= {0, 0, NULL
};
421 int is_critical
= 0; /* DEFAULT FALSE */
424 if( ( ret
= asn1_get_tag( p
, end
, &len
,
425 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
426 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+ ret
);
428 end_ext_data
= *p
+ len
;
430 /* Get extension ID */
433 if( ( ret
= asn1_get_tag( p
, end
, &extn_oid
.len
, ASN1_OID
) ) != 0 )
434 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+ ret
);
439 if( ( end
- *p
) < 1 )
440 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
441 POLARSSL_ERR_ASN1_OUT_OF_DATA
);
443 /* Get optional critical */
444 if( ( ret
= asn1_get_bool( p
, end_ext_data
, &is_critical
) ) != 0 &&
445 ( ret
!= POLARSSL_ERR_ASN1_UNEXPECTED_TAG
) )
446 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+ ret
);
448 /* Data should be octet string type */
449 if( ( ret
= asn1_get_tag( p
, end_ext_data
, &len
,
450 ASN1_OCTET_STRING
) ) != 0 )
451 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+ ret
);
453 end_ext_octet
= *p
+ len
;
455 if( end_ext_octet
!= end_ext_data
)
456 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
457 POLARSSL_ERR_ASN1_LENGTH_MISMATCH
);
460 * Detect supported extensions
462 ret
= oid_get_x509_ext_type( &extn_oid
, &ext_type
);
466 /* No parser found, skip extension */
469 #if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
472 /* Data is marked as critical: fail */
473 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
474 POLARSSL_ERR_ASN1_UNEXPECTED_TAG
);
480 /* Forbid repeated extensions */
481 if( ( crt
->ext_types
& ext_type
) != 0 )
482 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
);
484 crt
->ext_types
|= ext_type
;
488 case EXT_BASIC_CONSTRAINTS
:
489 /* Parse basic constraints */
490 if( ( ret
= x509_get_basic_constraints( p
, end_ext_octet
,
491 &crt
->ca_istrue
, &crt
->max_pathlen
) ) != 0 )
496 /* Parse key usage */
497 if( ( ret
= x509_get_key_usage( p
, end_ext_octet
,
498 &crt
->key_usage
) ) != 0 )
502 case EXT_EXTENDED_KEY_USAGE
:
503 /* Parse extended key usage */
504 if( ( ret
= x509_get_ext_key_usage( p
, end_ext_octet
,
505 &crt
->ext_key_usage
) ) != 0 )
509 case EXT_SUBJECT_ALT_NAME
:
510 /* Parse subject alt name */
511 if( ( ret
= x509_get_subject_alt_name( p
, end_ext_octet
,
512 &crt
->subject_alt_names
) ) != 0 )
516 case EXT_NS_CERT_TYPE
:
517 /* Parse netscape certificate type */
518 if( ( ret
= x509_get_ns_cert_type( p
, end_ext_octet
,
519 &crt
->ns_cert_type
) ) != 0 )
524 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE
);
529 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS
+
530 POLARSSL_ERR_ASN1_LENGTH_MISMATCH
);
536 * Parse and fill a single X.509 certificate in DER format
538 static int x509_crt_parse_der_core( x509_crt
*crt
, const unsigned char *buf
,
543 unsigned char *p
, *end
, *crt_end
;
544 x509_buf sig_params1
, sig_params2
;
546 memset( &sig_params1
, 0, sizeof( x509_buf
) );
547 memset( &sig_params2
, 0, sizeof( x509_buf
) );
550 * Check for valid input
552 if( crt
== NULL
|| buf
== NULL
)
553 return( POLARSSL_ERR_X509_BAD_INPUT_DATA
);
555 p
= polarssl_malloc( len
= buflen
);
558 return( POLARSSL_ERR_X509_MALLOC_FAILED
);
560 memcpy( p
, buf
, buflen
);
567 * Certificate ::= SEQUENCE {
568 * tbsCertificate TBSCertificate,
569 * signatureAlgorithm AlgorithmIdentifier,
570 * signatureValue BIT STRING }
572 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
573 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
575 x509_crt_free( crt
);
576 return( POLARSSL_ERR_X509_INVALID_FORMAT
);
579 if( len
> (size_t) ( end
- p
) )
581 x509_crt_free( crt
);
582 return( POLARSSL_ERR_X509_INVALID_FORMAT
+
583 POLARSSL_ERR_ASN1_LENGTH_MISMATCH
);
588 * TBSCertificate ::= SEQUENCE {
592 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
593 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
595 x509_crt_free( crt
);
596 return( POLARSSL_ERR_X509_INVALID_FORMAT
+ ret
);
600 crt
->tbs
.len
= end
- crt
->tbs
.p
;
603 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
605 * CertificateSerialNumber ::= INTEGER
607 * signature AlgorithmIdentifier
609 if( ( ret
= x509_get_version( &p
, end
, &crt
->version
) ) != 0 ||
610 ( ret
= x509_get_serial( &p
, end
, &crt
->serial
) ) != 0 ||
611 ( ret
= x509_get_alg( &p
, end
, &crt
->sig_oid1
,
612 &sig_params1
) ) != 0 )
614 x509_crt_free( crt
);
620 if( crt
->version
> 3 )
622 x509_crt_free( crt
);
623 return( POLARSSL_ERR_X509_UNKNOWN_VERSION
);
626 if( ( ret
= x509_get_sig_alg( &crt
->sig_oid1
, &sig_params1
,
627 &crt
->sig_md
, &crt
->sig_pk
,
628 &crt
->sig_opts
) ) != 0 )
630 x509_crt_free( crt
);
637 crt
->issuer_raw
.p
= p
;
639 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
640 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
642 x509_crt_free( crt
);
643 return( POLARSSL_ERR_X509_INVALID_FORMAT
+ ret
);
646 if( ( ret
= x509_get_name( &p
, p
+ len
, &crt
->issuer
) ) != 0 )
648 x509_crt_free( crt
);
652 crt
->issuer_raw
.len
= p
- crt
->issuer_raw
.p
;
655 * Validity ::= SEQUENCE {
660 if( ( ret
= x509_get_dates( &p
, end
, &crt
->valid_from
,
661 &crt
->valid_to
) ) != 0 )
663 x509_crt_free( crt
);
670 crt
->subject_raw
.p
= p
;
672 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
673 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
675 x509_crt_free( crt
);
676 return( POLARSSL_ERR_X509_INVALID_FORMAT
+ ret
);
679 if( len
&& ( ret
= x509_get_name( &p
, p
+ len
, &crt
->subject
) ) != 0 )
681 x509_crt_free( crt
);
685 crt
->subject_raw
.len
= p
- crt
->subject_raw
.p
;
688 * SubjectPublicKeyInfo
690 if( ( ret
= pk_parse_subpubkey( &p
, end
, &crt
->pk
) ) != 0 )
692 x509_crt_free( crt
);
697 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
698 * -- If present, version shall be v2 or v3
699 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
700 * -- If present, version shall be v2 or v3
701 * extensions [3] EXPLICIT Extensions OPTIONAL
702 * -- If present, version shall be v3
704 if( crt
->version
== 2 || crt
->version
== 3 )
706 ret
= x509_get_uid( &p
, end
, &crt
->issuer_id
, 1 );
709 x509_crt_free( crt
);
714 if( crt
->version
== 2 || crt
->version
== 3 )
716 ret
= x509_get_uid( &p
, end
, &crt
->subject_id
, 2 );
719 x509_crt_free( crt
);
724 #if !defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3)
725 if( crt
->version
== 3 )
728 ret
= x509_get_crt_ext( &p
, end
, crt
);
731 x509_crt_free( crt
);
734 #if !defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3)
740 x509_crt_free( crt
);
741 return( POLARSSL_ERR_X509_INVALID_FORMAT
+
742 POLARSSL_ERR_ASN1_LENGTH_MISMATCH
);
749 * -- end of TBSCertificate
751 * signatureAlgorithm AlgorithmIdentifier,
752 * signatureValue BIT STRING
754 if( ( ret
= x509_get_alg( &p
, end
, &crt
->sig_oid2
, &sig_params2
) ) != 0 )
756 x509_crt_free( crt
);
760 if( crt
->sig_oid1
.len
!= crt
->sig_oid2
.len
||
761 memcmp( crt
->sig_oid1
.p
, crt
->sig_oid2
.p
, crt
->sig_oid1
.len
) != 0 ||
762 sig_params1
.len
!= sig_params2
.len
||
763 ( sig_params1
.len
!= 0 &&
764 memcmp( sig_params1
.p
, sig_params2
.p
, sig_params1
.len
) != 0 ) )
766 x509_crt_free( crt
);
767 return( POLARSSL_ERR_X509_SIG_MISMATCH
);
770 if( ( ret
= x509_get_sig( &p
, end
, &crt
->sig
) ) != 0 )
772 x509_crt_free( crt
);
778 x509_crt_free( crt
);
779 return( POLARSSL_ERR_X509_INVALID_FORMAT
+
780 POLARSSL_ERR_ASN1_LENGTH_MISMATCH
);
787 * Parse one X.509 certificate in DER format from a buffer and add them to a
790 int x509_crt_parse_der( x509_crt
*chain
, const unsigned char *buf
,
794 x509_crt
*crt
= chain
, *prev
= NULL
;
797 * Check for valid input
799 if( crt
== NULL
|| buf
== NULL
)
800 return( POLARSSL_ERR_X509_BAD_INPUT_DATA
);
802 while( crt
->version
!= 0 && crt
->next
!= NULL
)
809 * Add new certificate on the end of the chain if needed.
811 if( crt
->version
!= 0 && crt
->next
== NULL
)
813 crt
->next
= polarssl_malloc( sizeof( x509_crt
) );
815 if( crt
->next
== NULL
)
816 return( POLARSSL_ERR_X509_MALLOC_FAILED
);
819 x509_crt_init( crt
->next
);
823 if( ( ret
= x509_crt_parse_der_core( crt
, buf
, buflen
) ) != 0 )
829 polarssl_free( crt
);
838 * Parse one or more PEM certificates from a buffer and add them to the chained
841 int x509_crt_parse( x509_crt
*chain
, const unsigned char *buf
, size_t buflen
)
843 int success
= 0, first_error
= 0, total_failed
= 0;
844 int buf_format
= X509_FORMAT_DER
;
847 * Check for valid input
849 if( chain
== NULL
|| buf
== NULL
)
850 return( POLARSSL_ERR_X509_BAD_INPUT_DATA
);
853 * Determine buffer content. Buffer contains either one DER certificate or
854 * one or more PEM certificates.
856 #if defined(POLARSSL_PEM_PARSE_C)
857 if( strstr( (const char *) buf
, "-----BEGIN CERTIFICATE-----" ) != NULL
)
858 buf_format
= X509_FORMAT_PEM
;
861 if( buf_format
== X509_FORMAT_DER
)
862 return x509_crt_parse_der( chain
, buf
, buflen
);
864 #if defined(POLARSSL_PEM_PARSE_C)
865 if( buf_format
== X509_FORMAT_PEM
)
875 ret
= pem_read_buffer( &pem
,
876 "-----BEGIN CERTIFICATE-----",
877 "-----END CERTIFICATE-----",
878 buf
, NULL
, 0, &use_len
);
888 else if( ret
== POLARSSL_ERR_PEM_BAD_INPUT_DATA
)
892 else if( ret
!= POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT
)
897 * PEM header and footer were found
902 if( first_error
== 0 )
911 ret
= x509_crt_parse_der( chain
, pem
.buf
, pem
.buflen
);
918 * Quit parsing on a memory error
920 if( ret
== POLARSSL_ERR_X509_MALLOC_FAILED
)
923 if( first_error
== 0 )
933 #endif /* POLARSSL_PEM_PARSE_C */
936 return( total_failed
);
937 else if( first_error
)
938 return( first_error
);
940 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT
);
943 #if defined(POLARSSL_FS_IO)
945 * Load one or more certificates and add them to the chained list
947 int x509_crt_parse_file( x509_crt
*chain
, const char *path
)
953 if( ( ret
= pk_load_file( path
, &buf
, &n
) ) != 0 )
956 ret
= x509_crt_parse( chain
, buf
, n
);
958 polarssl_zeroize( buf
, n
+ 1 );
959 polarssl_free( buf
);
964 #if defined(POLARSSL_THREADING_PTHREAD)
965 static threading_mutex_t readdir_mutex
= PTHREAD_MUTEX_INITIALIZER
;
968 int x509_crt_parse_path( x509_crt
*chain
, const char *path
)
971 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
973 WCHAR szDir
[MAX_PATH
];
974 char filename
[MAX_PATH
];
976 int len
= (int) strlen( path
);
978 WIN32_FIND_DATAW file_data
;
981 if( len
> MAX_PATH
- 3 )
982 return( POLARSSL_ERR_X509_BAD_INPUT_DATA
);
984 memset( szDir
, 0, sizeof(szDir
) );
985 memset( filename
, 0, MAX_PATH
);
986 memcpy( filename
, path
, len
);
987 filename
[len
++] = '\\';
989 filename
[len
++] = '*';
991 w_ret
= MultiByteToWideChar( CP_ACP
, 0, filename
, len
, szDir
,
994 return( POLARSSL_ERR_X509_BAD_INPUT_DATA
);
996 hFind
= FindFirstFileW( szDir
, &file_data
);
997 if( hFind
== INVALID_HANDLE_VALUE
)
998 return( POLARSSL_ERR_X509_FILE_IO_ERROR
);
1000 len
= MAX_PATH
- len
;
1003 memset( p
, 0, len
);
1005 if( file_data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
1008 w_ret
= WideCharToMultiByte( CP_ACP
, 0, file_data
.cFileName
,
1009 lstrlenW( file_data
.cFileName
),
1013 return( POLARSSL_ERR_X509_FILE_IO_ERROR
);
1015 w_ret
= x509_crt_parse_file( chain
, filename
);
1021 while( FindNextFileW( hFind
, &file_data
) != 0 );
1023 if( GetLastError() != ERROR_NO_MORE_FILES
)
1024 ret
= POLARSSL_ERR_X509_FILE_IO_ERROR
;
1030 struct dirent
*entry
;
1031 char entry_name
[255];
1032 DIR *dir
= opendir( path
);
1035 return( POLARSSL_ERR_X509_FILE_IO_ERROR
);
1037 #if defined(POLARSSL_THREADING_PTHREAD)
1038 if( ( ret
= polarssl_mutex_lock( &readdir_mutex
) ) != 0 )
1042 while( ( entry
= readdir( dir
) ) != NULL
)
1044 polarssl_snprintf( entry_name
, sizeof entry_name
, "%s/%s", path
, entry
->d_name
);
1046 if( stat( entry_name
, &sb
) == -1 )
1049 ret
= POLARSSL_ERR_X509_FILE_IO_ERROR
;
1053 if( !S_ISREG( sb
.st_mode
) )
1056 // Ignore parse errors
1058 t_ret
= x509_crt_parse_file( chain
, entry_name
);
1067 #if defined(POLARSSL_THREADING_PTHREAD)
1068 if( polarssl_mutex_unlock( &readdir_mutex
) != 0 )
1069 ret
= POLARSSL_ERR_THREADING_MUTEX_ERROR
;
1076 #endif /* POLARSSL_FS_IO */
1078 #if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
1082 #if !defined vsnprintf
1083 #define vsnprintf _vsnprintf
1087 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
1088 * Result value is not size of buffer needed, but -1 if no fit is possible.
1090 * This fuction tries to 'fix' this by at least suggesting enlarging the
1093 static int compat_snprintf( char *str
, size_t size
, const char *format
, ... )
1098 va_start( ap
, format
);
1100 res
= vsnprintf( str
, size
, format
, ap
);
1104 // No quick fix possible
1106 return( (int) size
+ 20 );
1111 #define snprintf compat_snprintf
1112 #endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */
1114 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
1116 #define SAFE_SNPRINTF() \
1121 if( (unsigned int) ret > n ) { \
1123 return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \
1126 n -= (unsigned int) ret; \
1127 p += (unsigned int) ret; \
1130 static int x509_info_subject_alt_name( char **buf
, size_t *size
,
1131 const x509_sequence
*subject_alt_name
)
1136 const x509_sequence
*cur
= subject_alt_name
;
1137 const char *sep
= "";
1140 while( cur
!= NULL
)
1142 if( cur
->buf
.len
+ sep_len
>= n
)
1145 return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL
);
1148 n
-= cur
->buf
.len
+ sep_len
;
1149 for( i
= 0; i
< sep_len
; i
++ )
1151 for( i
= 0; i
< cur
->buf
.len
; i
++ )
1152 *p
++ = cur
->buf
.p
[i
];
1168 #define PRINT_ITEM(i) \
1170 ret = polarssl_snprintf( p, n, "%s" i, sep ); \
1175 #define CERT_TYPE(type,name) \
1176 if( ns_cert_type & type ) \
1179 static int x509_info_cert_type( char **buf
, size_t *size
,
1180 unsigned char ns_cert_type
)
1185 const char *sep
= "";
1187 CERT_TYPE( NS_CERT_TYPE_SSL_CLIENT
, "SSL Client" );
1188 CERT_TYPE( NS_CERT_TYPE_SSL_SERVER
, "SSL Server" );
1189 CERT_TYPE( NS_CERT_TYPE_EMAIL
, "Email" );
1190 CERT_TYPE( NS_CERT_TYPE_OBJECT_SIGNING
, "Object Signing" );
1191 CERT_TYPE( NS_CERT_TYPE_RESERVED
, "Reserved" );
1192 CERT_TYPE( NS_CERT_TYPE_SSL_CA
, "SSL CA" );
1193 CERT_TYPE( NS_CERT_TYPE_EMAIL_CA
, "Email CA" );
1194 CERT_TYPE( NS_CERT_TYPE_OBJECT_SIGNING_CA
, "Object Signing CA" );
1202 #define KEY_USAGE(code,name) \
1203 if( key_usage & code ) \
1206 static int x509_info_key_usage( char **buf
, size_t *size
,
1207 unsigned char key_usage
)
1212 const char *sep
= "";
1214 KEY_USAGE( KU_DIGITAL_SIGNATURE
, "Digital Signature" );
1215 KEY_USAGE( KU_NON_REPUDIATION
, "Non Repudiation" );
1216 KEY_USAGE( KU_KEY_ENCIPHERMENT
, "Key Encipherment" );
1217 KEY_USAGE( KU_DATA_ENCIPHERMENT
, "Data Encipherment" );
1218 KEY_USAGE( KU_KEY_AGREEMENT
, "Key Agreement" );
1219 KEY_USAGE( KU_KEY_CERT_SIGN
, "Key Cert Sign" );
1220 KEY_USAGE( KU_CRL_SIGN
, "CRL Sign" );
1228 static int x509_info_ext_key_usage( char **buf
, size_t *size
,
1229 const x509_sequence
*extended_key_usage
)
1235 const x509_sequence
*cur
= extended_key_usage
;
1236 const char *sep
= "";
1238 while( cur
!= NULL
)
1240 if( oid_get_extended_key_usage( &cur
->buf
, &desc
) != 0 )
1243 ret
= polarssl_snprintf( p
, n
, "%s%s", sep
, desc
);
1258 * Return an informational string about the certificate.
1260 #define BEFORE_COLON 18
1262 int x509_crt_info( char *buf
, size_t size
, const char *prefix
,
1263 const x509_crt
*crt
)
1268 char key_size_str
[BEFORE_COLON
];
1273 ret
= polarssl_snprintf( p
, n
, "%scert. version : %d\n",
1274 prefix
, crt
->version
);
1276 ret
= polarssl_snprintf( p
, n
, "%sserial number : ",
1280 ret
= x509_serial_gets( p
, n
, &crt
->serial
);
1283 ret
= polarssl_snprintf( p
, n
, "\n%sissuer name : ", prefix
);
1285 ret
= x509_dn_gets( p
, n
, &crt
->issuer
);
1288 ret
= polarssl_snprintf( p
, n
, "\n%ssubject name : ", prefix
);
1290 ret
= x509_dn_gets( p
, n
, &crt
->subject
);
1293 ret
= polarssl_snprintf( p
, n
, "\n%sissued on : " \
1294 "%04d-%02d-%02d %02d:%02d:%02d", prefix
,
1295 crt
->valid_from
.year
, crt
->valid_from
.mon
,
1296 crt
->valid_from
.day
, crt
->valid_from
.hour
,
1297 crt
->valid_from
.min
, crt
->valid_from
.sec
);
1300 ret
= polarssl_snprintf( p
, n
, "\n%sexpires on : " \
1301 "%04d-%02d-%02d %02d:%02d:%02d", prefix
,
1302 crt
->valid_to
.year
, crt
->valid_to
.mon
,
1303 crt
->valid_to
.day
, crt
->valid_to
.hour
,
1304 crt
->valid_to
.min
, crt
->valid_to
.sec
);
1307 ret
= polarssl_snprintf( p
, n
, "\n%ssigned using : ", prefix
);
1310 ret
= x509_sig_alg_gets( p
, n
, &crt
->sig_oid1
, crt
->sig_pk
,
1311 crt
->sig_md
, crt
->sig_opts
);
1315 if( ( ret
= x509_key_size_helper( key_size_str
, BEFORE_COLON
,
1316 pk_get_name( &crt
->pk
) ) ) != 0 )
1321 ret
= polarssl_snprintf( p
, n
, "\n%s%-" BC
"s: %d bits", prefix
, key_size_str
,
1322 (int) pk_get_size( &crt
->pk
) );
1326 * Optional extensions
1329 if( crt
->ext_types
& EXT_BASIC_CONSTRAINTS
)
1331 ret
= polarssl_snprintf( p
, n
, "\n%sbasic constraints : CA=%s", prefix
,
1332 crt
->ca_istrue
? "true" : "false" );
1335 if( crt
->max_pathlen
> 0 )
1337 ret
= polarssl_snprintf( p
, n
, ", max_pathlen=%d", crt
->max_pathlen
- 1 );
1342 if( crt
->ext_types
& EXT_SUBJECT_ALT_NAME
)
1344 ret
= polarssl_snprintf( p
, n
, "\n%ssubject alt name : ", prefix
);
1347 if( ( ret
= x509_info_subject_alt_name( &p
, &n
,
1348 &crt
->subject_alt_names
) ) != 0 )
1352 if( crt
->ext_types
& EXT_NS_CERT_TYPE
)
1354 ret
= polarssl_snprintf( p
, n
, "\n%scert. type : ", prefix
);
1357 if( ( ret
= x509_info_cert_type( &p
, &n
, crt
->ns_cert_type
) ) != 0 )
1361 if( crt
->ext_types
& EXT_KEY_USAGE
)
1363 ret
= polarssl_snprintf( p
, n
, "\n%skey usage : ", prefix
);
1366 if( ( ret
= x509_info_key_usage( &p
, &n
, crt
->key_usage
) ) != 0 )
1370 if( crt
->ext_types
& EXT_EXTENDED_KEY_USAGE
)
1372 ret
= polarssl_snprintf( p
, n
, "\n%sext key usage : ", prefix
);
1375 if( ( ret
= x509_info_ext_key_usage( &p
, &n
,
1376 &crt
->ext_key_usage
) ) != 0 )
1380 ret
= polarssl_snprintf( p
, n
, "\n" );
1383 return( (int) ( size
- n
) );
1386 struct x509_crt_verify_string
{
1391 static const struct x509_crt_verify_string x509_crt_verify_strings
[] = {
1392 { BADCERT_EXPIRED
, "The certificate validity has expired" },
1393 { BADCERT_REVOKED
, "The certificate has been revoked (is on a CRL)" },
1394 { BADCERT_CN_MISMATCH
, "The certificate Common Name (CN) does not match with the expected CN" },
1395 { BADCERT_NOT_TRUSTED
, "The certificate is not correctly signed by the trusted CA" },
1396 { BADCRL_NOT_TRUSTED
, "The CRL is not correctly signed by the trusted CA" },
1397 { BADCRL_EXPIRED
, "The CRL is expired" },
1398 { BADCERT_MISSING
, "Certificate was missing" },
1399 { BADCERT_SKIP_VERIFY
, "Certificate verification was skipped" },
1400 { BADCERT_OTHER
, "Other reason (can be used by verify callback)" },
1401 { BADCERT_FUTURE
, "The certificate validity starts in the future" },
1402 { BADCRL_FUTURE
, "The CRL is from the future" },
1403 { BADCERT_KEY_USAGE
, "Usage does not match the keyUsage extension" },
1404 { BADCERT_EXT_KEY_USAGE
, "Usage does not match the extendedKeyUsage extension" },
1405 { BADCERT_NS_CERT_TYPE
, "Usage does not match the nsCertType extension" },
1409 int x509_crt_verify_info( char *buf
, size_t size
, const char *prefix
,
1413 const struct x509_crt_verify_string
*cur
;
1417 for( cur
= x509_crt_verify_strings
; cur
->string
!= NULL
; cur
++ )
1419 if( ( flags
& cur
->code
) == 0 )
1422 ret
= polarssl_snprintf( p
, n
, "%s%s\n", prefix
, cur
->string
);
1429 ret
= polarssl_snprintf( p
, n
, "%sUnknown reason "
1430 "(this should not happen)\n", prefix
);
1434 return( (int) ( size
- n
) );
1437 #if defined(POLARSSL_X509_CHECK_KEY_USAGE)
1438 int x509_crt_check_key_usage( const x509_crt
*crt
, int usage
)
1440 if( ( crt
->ext_types
& EXT_KEY_USAGE
) != 0 &&
1441 ( crt
->key_usage
& usage
) != usage
)
1442 return( POLARSSL_ERR_X509_BAD_INPUT_DATA
);
1448 #if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE)
1449 int x509_crt_check_extended_key_usage( const x509_crt
*crt
,
1450 const char *usage_oid
,
1453 const x509_sequence
*cur
;
1455 /* Extension is not mandatory, absent means no restriction */
1456 if( ( crt
->ext_types
& EXT_EXTENDED_KEY_USAGE
) == 0 )
1460 * Look for the requested usage (or wildcard ANY) in our list
1462 for( cur
= &crt
->ext_key_usage
; cur
!= NULL
; cur
= cur
->next
)
1464 const x509_buf
*cur_oid
= &cur
->buf
;
1466 if( cur_oid
->len
== usage_len
&&
1467 memcmp( cur_oid
->p
, usage_oid
, usage_len
) == 0 )
1472 if( OID_CMP( OID_ANY_EXTENDED_KEY_USAGE
, cur_oid
) )
1476 return( POLARSSL_ERR_X509_BAD_INPUT_DATA
);
1478 #endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE */
1480 #if defined(POLARSSL_X509_CRL_PARSE_C)
1482 * Return 1 if the certificate is revoked, or 0 otherwise.
1484 int x509_crt_revoked( const x509_crt
*crt
, const x509_crl
*crl
)
1486 const x509_crl_entry
*cur
= &crl
->entry
;
1488 while( cur
!= NULL
&& cur
->serial
.len
!= 0 )
1490 if( crt
->serial
.len
== cur
->serial
.len
&&
1491 memcmp( crt
->serial
.p
, cur
->serial
.p
, crt
->serial
.len
) == 0 )
1493 if( x509_time_expired( &cur
->revocation_date
) )
1504 * Check that the given certificate is valid according to the CRL.
1506 static int x509_crt_verifycrl( x509_crt
*crt
, x509_crt
*ca
,
1510 unsigned char hash
[POLARSSL_MD_MAX_SIZE
];
1511 const md_info_t
*md_info
;
1517 * TODO: What happens if no CRL is present?
1518 * Suggestion: Revocation state should be unknown if no CRL is present.
1519 * For backwards compatibility this is not yet implemented.
1522 while( crl_list
!= NULL
)
1524 if( crl_list
->version
== 0 ||
1525 crl_list
->issuer_raw
.len
!= ca
->subject_raw
.len
||
1526 memcmp( crl_list
->issuer_raw
.p
, ca
->subject_raw
.p
,
1527 crl_list
->issuer_raw
.len
) != 0 )
1529 crl_list
= crl_list
->next
;
1534 * Check if the CA is configured to sign CRLs
1536 #if defined(POLARSSL_X509_CHECK_KEY_USAGE)
1537 if( x509_crt_check_key_usage( ca
, KU_CRL_SIGN
) != 0 )
1539 flags
|= BADCRL_NOT_TRUSTED
;
1545 * Check if CRL is correctly signed by the trusted CA
1547 md_info
= md_info_from_type( crl_list
->sig_md
);
1548 if( md_info
== NULL
)
1551 * Cannot check 'unknown' hash
1553 flags
|= BADCRL_NOT_TRUSTED
;
1557 md( md_info
, crl_list
->tbs
.p
, crl_list
->tbs
.len
, hash
);
1559 if( pk_verify_ext( crl_list
->sig_pk
, crl_list
->sig_opts
, &ca
->pk
,
1560 crl_list
->sig_md
, hash
, md_info
->size
,
1561 crl_list
->sig
.p
, crl_list
->sig
.len
) != 0 )
1563 flags
|= BADCRL_NOT_TRUSTED
;
1568 * Check for validity of CRL (Do not drop out)
1570 if( x509_time_expired( &crl_list
->next_update
) )
1571 flags
|= BADCRL_EXPIRED
;
1573 if( x509_time_future( &crl_list
->this_update
) )
1574 flags
|= BADCRL_FUTURE
;
1577 * Check if certificate is revoked
1579 if( x509_crt_revoked( crt
, crl_list
) )
1581 flags
|= BADCERT_REVOKED
;
1585 crl_list
= crl_list
->next
;
1589 #endif /* POLARSSL_X509_CRL_PARSE_C */
1592 * Like memcmp, but case-insensitive and always returns -1 if different
1594 static int x509_memcasecmp( const void *s1
, const void *s2
, size_t len
)
1598 const unsigned char *n1
= s1
, *n2
= s2
;
1600 for( i
= 0; i
< len
; i
++ )
1602 diff
= n1
[i
] ^ n2
[i
];
1608 ( ( n1
[i
] >= 'a' && n1
[i
] <= 'z' ) ||
1609 ( n1
[i
] >= 'A' && n1
[i
] <= 'Z' ) ) )
1621 * Return 1 if match, 0 if not
1622 * TODO: inverted return value!
1624 static int x509_wildcard_verify( const char *cn
, x509_buf
*name
)
1627 size_t cn_idx
= 0, cn_len
= strlen( cn
);
1629 if( name
->len
< 3 || name
->p
[0] != '*' || name
->p
[1] != '.' )
1632 for( i
= 0; i
< cn_len
; ++i
)
1644 if( cn_len
- cn_idx
== name
->len
- 1 &&
1645 x509_memcasecmp( name
->p
+ 1, cn
+ cn_idx
, name
->len
- 1 ) == 0 )
1654 * Compare two X.509 strings, case-insensitive, and allowing for some encoding
1655 * variations (but not all).
1657 * Return 0 if equal, -1 otherwise.
1659 static int x509_string_cmp( const x509_buf
*a
, const x509_buf
*b
)
1661 if( a
->tag
== b
->tag
&&
1663 memcmp( a
->p
, b
->p
, b
->len
) == 0 )
1668 if( ( a
->tag
== ASN1_UTF8_STRING
|| a
->tag
== ASN1_PRINTABLE_STRING
) &&
1669 ( b
->tag
== ASN1_UTF8_STRING
|| b
->tag
== ASN1_PRINTABLE_STRING
) &&
1671 x509_memcasecmp( a
->p
, b
->p
, b
->len
) == 0 )
1680 * Compare two X.509 Names (aka rdnSequence).
1682 * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
1683 * we sometimes return unequal when the full algorithm would return equal,
1684 * but never the other way. (In particular, we don't do Unicode normalisation
1685 * or space folding.)
1687 * Return 0 if equal, -1 otherwise.
1689 static int x509_name_cmp( const x509_name
*a
, const x509_name
*b
)
1691 /* Avoid recursion, it might not be optimised by the compiler */
1692 while( a
!= NULL
|| b
!= NULL
)
1694 if( a
== NULL
|| b
== NULL
)
1698 if( a
->oid
.tag
!= b
->oid
.tag
||
1699 a
->oid
.len
!= b
->oid
.len
||
1700 memcmp( a
->oid
.p
, b
->oid
.p
, b
->oid
.len
) != 0 )
1706 if( x509_string_cmp( &a
->val
, &b
->val
) != 0 )
1709 /* structure of the list of sets */
1710 if( a
->next_merged
!= b
->next_merged
)
1717 /* a == NULL == b */
1722 * Check if 'parent' is a suitable parent (signing CA) for 'child'.
1723 * Return 0 if yes, -1 if not.
1725 * top means parent is a locally-trusted certificate
1726 * bottom means child is the end entity cert
1728 static int x509_crt_check_parent( const x509_crt
*child
,
1729 const x509_crt
*parent
,
1730 int top
, int bottom
)
1734 /* Parent must be the issuer */
1735 if( x509_name_cmp( &child
->issuer
, &parent
->subject
) != 0 )
1738 /* Parent must have the basicConstraints CA bit set as a general rule */
1741 /* Exception: v1/v2 certificates that are locally trusted. */
1742 if( top
&& parent
->version
< 3 )
1745 /* Exception: self-signed end-entity certs that are locally trusted. */
1746 if( top
&& bottom
&&
1747 child
->raw
.len
== parent
->raw
.len
&&
1748 memcmp( child
->raw
.p
, parent
->raw
.p
, child
->raw
.len
) == 0 )
1753 if( need_ca_bit
&& ! parent
->ca_istrue
)
1756 #if defined(POLARSSL_X509_CHECK_KEY_USAGE)
1758 x509_crt_check_key_usage( parent
, KU_KEY_CERT_SIGN
) != 0 )
1767 static int x509_crt_verify_top(
1768 x509_crt
*child
, x509_crt
*trust_ca
,
1769 x509_crl
*ca_crl
, int path_cnt
, int *flags
,
1770 int (*f_vrfy
)(void *, x509_crt
*, int, int *),
1774 int ca_flags
= 0, check_path_cnt
;
1775 unsigned char hash
[POLARSSL_MD_MAX_SIZE
];
1776 const md_info_t
*md_info
;
1778 if( x509_time_expired( &child
->valid_to
) )
1779 *flags
|= BADCERT_EXPIRED
;
1781 if( x509_time_future( &child
->valid_from
) )
1782 *flags
|= BADCERT_FUTURE
;
1785 * Child is the top of the chain. Check against the trust_ca list.
1787 *flags
|= BADCERT_NOT_TRUSTED
;
1789 md_info
= md_info_from_type( child
->sig_md
);
1790 if( md_info
== NULL
)
1793 * Cannot check 'unknown', no need to try any CA
1798 md( md_info
, child
->tbs
.p
, child
->tbs
.len
, hash
);
1800 for( /* trust_ca */ ; trust_ca
!= NULL
; trust_ca
= trust_ca
->next
)
1802 if( x509_crt_check_parent( child
, trust_ca
, 1, path_cnt
== 0 ) != 0 )
1805 check_path_cnt
= path_cnt
+ 1;
1808 * Reduce check_path_cnt to check against if top of the chain is
1809 * the same as the trusted CA
1811 if( child
->subject_raw
.len
== trust_ca
->subject_raw
.len
&&
1812 memcmp( child
->subject_raw
.p
, trust_ca
->subject_raw
.p
,
1813 child
->issuer_raw
.len
) == 0 )
1818 if( trust_ca
->max_pathlen
> 0 &&
1819 trust_ca
->max_pathlen
< check_path_cnt
)
1824 if( pk_verify_ext( child
->sig_pk
, child
->sig_opts
, &trust_ca
->pk
,
1825 child
->sig_md
, hash
, md_info
->size
,
1826 child
->sig
.p
, child
->sig
.len
) != 0 )
1832 * Top of chain is signed by a trusted CA
1834 *flags
&= ~BADCERT_NOT_TRUSTED
;
1839 * If top of chain is not the same as the trusted CA send a verify request
1840 * to the callback for any issues with validity and CRL presence for the
1841 * trusted CA certificate.
1843 if( trust_ca
!= NULL
&&
1844 ( child
->subject_raw
.len
!= trust_ca
->subject_raw
.len
||
1845 memcmp( child
->subject_raw
.p
, trust_ca
->subject_raw
.p
,
1846 child
->issuer_raw
.len
) != 0 ) )
1848 #if defined(POLARSSL_X509_CRL_PARSE_C)
1849 /* Check trusted CA's CRL for the chain's top crt */
1850 *flags
|= x509_crt_verifycrl( child
, trust_ca
, ca_crl
);
1855 if( x509_time_expired( &trust_ca
->valid_to
) )
1856 ca_flags
|= BADCERT_EXPIRED
;
1858 if( x509_time_future( &trust_ca
->valid_from
) )
1859 ca_flags
|= BADCERT_FUTURE
;
1861 if( NULL
!= f_vrfy
)
1863 if( ( ret
= f_vrfy( p_vrfy
, trust_ca
, path_cnt
+ 1,
1864 &ca_flags
) ) != 0 )
1871 /* Call callback on top cert */
1872 if( NULL
!= f_vrfy
)
1874 if( ( ret
= f_vrfy( p_vrfy
, child
, path_cnt
, flags
) ) != 0 )
1883 static int x509_crt_verify_child(
1884 x509_crt
*child
, x509_crt
*parent
, x509_crt
*trust_ca
,
1885 x509_crl
*ca_crl
, int path_cnt
, int *flags
,
1886 int (*f_vrfy
)(void *, x509_crt
*, int, int *),
1890 int parent_flags
= 0;
1891 unsigned char hash
[POLARSSL_MD_MAX_SIZE
];
1892 x509_crt
*grandparent
;
1893 const md_info_t
*md_info
;
1895 /* path_cnt is 0 for the first intermediate CA */
1896 if( 1 + path_cnt
> POLARSSL_X509_MAX_INTERMEDIATE_CA
)
1898 *flags
|= BADCERT_NOT_TRUSTED
;
1899 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED
);
1902 if( x509_time_expired( &child
->valid_to
) )
1903 *flags
|= BADCERT_EXPIRED
;
1905 if( x509_time_future( &child
->valid_from
) )
1906 *flags
|= BADCERT_FUTURE
;
1908 md_info
= md_info_from_type( child
->sig_md
);
1909 if( md_info
== NULL
)
1912 * Cannot check 'unknown' hash
1914 *flags
|= BADCERT_NOT_TRUSTED
;
1918 md( md_info
, child
->tbs
.p
, child
->tbs
.len
, hash
);
1920 if( pk_verify_ext( child
->sig_pk
, child
->sig_opts
, &parent
->pk
,
1921 child
->sig_md
, hash
, md_info
->size
,
1922 child
->sig
.p
, child
->sig
.len
) != 0 )
1924 *flags
|= BADCERT_NOT_TRUSTED
;
1928 #if defined(POLARSSL_X509_CRL_PARSE_C)
1929 /* Check trusted CA's CRL for the given crt */
1930 *flags
|= x509_crt_verifycrl(child
, parent
, ca_crl
);
1933 /* Look for a grandparent upwards the chain */
1934 for( grandparent
= parent
->next
;
1935 grandparent
!= NULL
;
1936 grandparent
= grandparent
->next
)
1938 if( x509_crt_check_parent( parent
, grandparent
,
1939 0, path_cnt
== 0 ) == 0 )
1943 /* Is our parent part of the chain or at the top? */
1944 if( grandparent
!= NULL
)
1946 ret
= x509_crt_verify_child( parent
, grandparent
, trust_ca
, ca_crl
,
1947 path_cnt
+ 1, &parent_flags
, f_vrfy
, p_vrfy
);
1953 ret
= x509_crt_verify_top( parent
, trust_ca
, ca_crl
,
1954 path_cnt
+ 1, &parent_flags
, f_vrfy
, p_vrfy
);
1959 /* child is verified to be a child of the parent, call verify callback */
1960 if( NULL
!= f_vrfy
)
1961 if( ( ret
= f_vrfy( p_vrfy
, child
, path_cnt
, flags
) ) != 0 )
1964 *flags
|= parent_flags
;
1970 * Verify the certificate validity
1972 int x509_crt_verify( x509_crt
*crt
,
1975 const char *cn
, int *flags
,
1976 int (*f_vrfy
)(void *, x509_crt
*, int, int *),
1984 x509_sequence
*cur
= NULL
;
1990 name
= &crt
->subject
;
1991 cn_len
= strlen( cn
);
1993 if( crt
->ext_types
& EXT_SUBJECT_ALT_NAME
)
1995 cur
= &crt
->subject_alt_names
;
1997 while( cur
!= NULL
)
1999 if( cur
->buf
.len
== cn_len
&&
2000 x509_memcasecmp( cn
, cur
->buf
.p
, cn_len
) == 0 )
2003 if( cur
->buf
.len
> 2 &&
2004 memcmp( cur
->buf
.p
, "*.", 2 ) == 0 &&
2005 x509_wildcard_verify( cn
, &cur
->buf
) )
2012 *flags
|= BADCERT_CN_MISMATCH
;
2016 while( name
!= NULL
)
2018 if( OID_CMP( OID_AT_CN
, &name
->oid
) )
2020 if( name
->val
.len
== cn_len
&&
2021 x509_memcasecmp( name
->val
.p
, cn
, cn_len
) == 0 )
2024 if( name
->val
.len
> 2 &&
2025 memcmp( name
->val
.p
, "*.", 2 ) == 0 &&
2026 x509_wildcard_verify( cn
, &name
->val
) )
2034 *flags
|= BADCERT_CN_MISMATCH
;
2038 /* Look for a parent upwards the chain */
2039 for( parent
= crt
->next
; parent
!= NULL
; parent
= parent
->next
)
2041 if( x509_crt_check_parent( crt
, parent
, 0, pathlen
== 0 ) == 0 )
2045 /* Are we part of the chain or at the top? */
2046 if( parent
!= NULL
)
2048 ret
= x509_crt_verify_child( crt
, parent
, trust_ca
, ca_crl
,
2049 pathlen
, flags
, f_vrfy
, p_vrfy
);
2055 ret
= x509_crt_verify_top( crt
, trust_ca
, ca_crl
,
2056 pathlen
, flags
, f_vrfy
, p_vrfy
);
2062 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED
);
2068 * Initialize a certificate chain
2070 void x509_crt_init( x509_crt
*crt
)
2072 memset( crt
, 0, sizeof(x509_crt
) );
2076 * Unallocate all certificate data
2078 void x509_crt_free( x509_crt
*crt
)
2080 x509_crt
*cert_cur
= crt
;
2082 x509_name
*name_cur
;
2083 x509_name
*name_prv
;
2084 x509_sequence
*seq_cur
;
2085 x509_sequence
*seq_prv
;
2092 pk_free( &cert_cur
->pk
);
2094 #if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
2095 polarssl_free( cert_cur
->sig_opts
);
2098 name_cur
= cert_cur
->issuer
.next
;
2099 while( name_cur
!= NULL
)
2101 name_prv
= name_cur
;
2102 name_cur
= name_cur
->next
;
2103 polarssl_zeroize( name_prv
, sizeof( x509_name
) );
2104 polarssl_free( name_prv
);
2107 name_cur
= cert_cur
->subject
.next
;
2108 while( name_cur
!= NULL
)
2110 name_prv
= name_cur
;
2111 name_cur
= name_cur
->next
;
2112 polarssl_zeroize( name_prv
, sizeof( x509_name
) );
2113 polarssl_free( name_prv
);
2116 seq_cur
= cert_cur
->ext_key_usage
.next
;
2117 while( seq_cur
!= NULL
)
2120 seq_cur
= seq_cur
->next
;
2121 polarssl_zeroize( seq_prv
, sizeof( x509_sequence
) );
2122 polarssl_free( seq_prv
);
2125 seq_cur
= cert_cur
->subject_alt_names
.next
;
2126 while( seq_cur
!= NULL
)
2129 seq_cur
= seq_cur
->next
;
2130 polarssl_zeroize( seq_prv
, sizeof( x509_sequence
) );
2131 polarssl_free( seq_prv
);
2134 if( cert_cur
->raw
.p
!= NULL
)
2136 polarssl_zeroize( cert_cur
->raw
.p
, cert_cur
->raw
.len
);
2137 polarssl_free( cert_cur
->raw
.p
);
2140 cert_cur
= cert_cur
->next
;
2142 while( cert_cur
!= NULL
);
2147 cert_prv
= cert_cur
;
2148 cert_cur
= cert_cur
->next
;
2150 polarssl_zeroize( cert_prv
, sizeof( x509_crt
) );
2151 if( cert_prv
!= crt
)
2152 polarssl_free( cert_prv
);
2154 while( cert_cur
!= NULL
);
2157 #endif /* POLARSSL_X509_CRT_PARSE_C */