2 * X.509 common functions for parsing and verification
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * This file is part of mbed TLS (https://tls.mbed.org)
24 * The ITU-T X.509 standard defines a certificate format for PKI.
26 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
27 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
28 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
30 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
31 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
34 #if !defined(MBEDTLS_CONFIG_FILE)
35 #include "mbedtls/config.h"
37 #include MBEDTLS_CONFIG_FILE
40 #if defined(MBEDTLS_X509_USE_C)
42 #include "mbedtls/x509.h"
43 #include "mbedtls/asn1.h"
44 #include "mbedtls/oid.h"
49 #if defined(MBEDTLS_PEM_PARSE_C)
50 #include "mbedtls/pem.h"
53 #if defined(MBEDTLS_PLATFORM_C)
54 #include "mbedtls/platform.h"
58 #define mbedtls_free free
59 #define mbedtls_calloc calloc
60 #define mbedtls_printf printf
61 #define mbedtls_snprintf snprintf
65 #if defined(MBEDTLS_HAVE_TIME)
66 #include "mbedtls/platform_time.h"
69 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
75 #if defined(MBEDTLS_FS_IO)
78 #include <sys/types.h>
84 #define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); }
85 #define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); }
88 * CertificateSerialNumber ::= INTEGER
90 int mbedtls_x509_get_serial( unsigned char **p
, const unsigned char *end
,
91 mbedtls_x509_buf
*serial
)
95 if( ( end
- *p
) < 1 )
96 return( MBEDTLS_ERR_X509_INVALID_SERIAL
+
97 MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
99 if( **p
!= ( MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_PRIMITIVE
| 2 ) &&
100 **p
!= MBEDTLS_ASN1_INTEGER
)
101 return( MBEDTLS_ERR_X509_INVALID_SERIAL
+
102 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
104 serial
->tag
= *(*p
)++;
106 if( ( ret
= mbedtls_asn1_get_len( p
, end
, &serial
->len
) ) != 0 )
107 return( MBEDTLS_ERR_X509_INVALID_SERIAL
+ ret
);
115 /* Get an algorithm identifier without parameters (eg for signatures)
117 * AlgorithmIdentifier ::= SEQUENCE {
118 * algorithm OBJECT IDENTIFIER,
119 * parameters ANY DEFINED BY algorithm OPTIONAL }
121 int mbedtls_x509_get_alg_null( unsigned char **p
, const unsigned char *end
,
122 mbedtls_x509_buf
*alg
)
126 if( ( ret
= mbedtls_asn1_get_alg_null( p
, end
, alg
) ) != 0 )
127 return( MBEDTLS_ERR_X509_INVALID_ALG
+ ret
);
133 * Parse an algorithm identifier with (optional) paramaters
135 int mbedtls_x509_get_alg( unsigned char **p
, const unsigned char *end
,
136 mbedtls_x509_buf
*alg
, mbedtls_x509_buf
*params
)
140 if( ( ret
= mbedtls_asn1_get_alg( p
, end
, alg
, params
) ) != 0 )
141 return( MBEDTLS_ERR_X509_INVALID_ALG
+ ret
);
146 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
148 * HashAlgorithm ::= AlgorithmIdentifier
150 * AlgorithmIdentifier ::= SEQUENCE {
151 * algorithm OBJECT IDENTIFIER,
152 * parameters ANY DEFINED BY algorithm OPTIONAL }
154 * For HashAlgorithm, parameters MUST be NULL or absent.
156 static int x509_get_hash_alg( const mbedtls_x509_buf
*alg
, mbedtls_md_type_t
*md_alg
)
160 const unsigned char *end
;
161 mbedtls_x509_buf md_oid
;
164 /* Make sure we got a SEQUENCE and setup bounds */
165 if( alg
->tag
!= ( MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) )
166 return( MBEDTLS_ERR_X509_INVALID_ALG
+
167 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
169 p
= (unsigned char *) alg
->p
;
173 return( MBEDTLS_ERR_X509_INVALID_ALG
+
174 MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
179 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &md_oid
.len
, MBEDTLS_ASN1_OID
) ) != 0 )
180 return( MBEDTLS_ERR_X509_INVALID_ALG
+ ret
);
185 /* Get md_alg from md_oid */
186 if( ( ret
= mbedtls_oid_get_md_alg( &md_oid
, md_alg
) ) != 0 )
187 return( MBEDTLS_ERR_X509_INVALID_ALG
+ ret
);
189 /* Make sure params is absent of NULL */
193 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
, MBEDTLS_ASN1_NULL
) ) != 0 || len
!= 0 )
194 return( MBEDTLS_ERR_X509_INVALID_ALG
+ ret
);
197 return( MBEDTLS_ERR_X509_INVALID_ALG
+
198 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
204 * RSASSA-PSS-params ::= SEQUENCE {
205 * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier,
206 * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
207 * saltLength [2] INTEGER DEFAULT 20,
208 * trailerField [3] INTEGER DEFAULT 1 }
209 * -- Note that the tags in this Sequence are explicit.
211 * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
212 * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
213 * option. Enfore this at parsing time.
215 int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf
*params
,
216 mbedtls_md_type_t
*md_alg
, mbedtls_md_type_t
*mgf_md
,
221 const unsigned char *end
, *end2
;
223 mbedtls_x509_buf alg_id
, alg_params
;
225 /* First set everything to defaults */
226 *md_alg
= MBEDTLS_MD_SHA1
;
227 *mgf_md
= MBEDTLS_MD_SHA1
;
230 /* Make sure params is a SEQUENCE and setup bounds */
231 if( params
->tag
!= ( MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) )
232 return( MBEDTLS_ERR_X509_INVALID_ALG
+
233 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
235 p
= (unsigned char *) params
->p
;
236 end
= p
+ params
->len
;
244 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
245 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| 0 ) ) == 0 )
249 /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
250 if( ( ret
= mbedtls_x509_get_alg_null( &p
, end2
, &alg_id
) ) != 0 )
253 if( ( ret
= mbedtls_oid_get_md_alg( &alg_id
, md_alg
) ) != 0 )
254 return( MBEDTLS_ERR_X509_INVALID_ALG
+ ret
);
257 return( MBEDTLS_ERR_X509_INVALID_ALG
+
258 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
260 else if( ret
!= MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)
261 return( MBEDTLS_ERR_X509_INVALID_ALG
+ ret
);
269 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
270 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| 1 ) ) == 0 )
274 /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
275 if( ( ret
= mbedtls_x509_get_alg( &p
, end2
, &alg_id
, &alg_params
) ) != 0 )
278 /* Only MFG1 is recognised for now */
279 if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1
, &alg_id
) != 0 )
280 return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE
+
281 MBEDTLS_ERR_OID_NOT_FOUND
);
283 /* Parse HashAlgorithm */
284 if( ( ret
= x509_get_hash_alg( &alg_params
, mgf_md
) ) != 0 )
288 return( MBEDTLS_ERR_X509_INVALID_ALG
+
289 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
291 else if( ret
!= MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)
292 return( MBEDTLS_ERR_X509_INVALID_ALG
+ ret
);
300 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
301 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| 2 ) ) == 0 )
305 if( ( ret
= mbedtls_asn1_get_int( &p
, end2
, salt_len
) ) != 0 )
306 return( MBEDTLS_ERR_X509_INVALID_ALG
+ ret
);
309 return( MBEDTLS_ERR_X509_INVALID_ALG
+
310 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
312 else if( ret
!= MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)
313 return( MBEDTLS_ERR_X509_INVALID_ALG
+ ret
);
319 * trailer_field (if present, must be 1)
321 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
322 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| 3 ) ) == 0 )
328 if( ( ret
= mbedtls_asn1_get_int( &p
, end2
, &trailer_field
) ) != 0 )
329 return( MBEDTLS_ERR_X509_INVALID_ALG
+ ret
);
332 return( MBEDTLS_ERR_X509_INVALID_ALG
+
333 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
335 if( trailer_field
!= 1 )
336 return( MBEDTLS_ERR_X509_INVALID_ALG
);
338 else if( ret
!= MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)
339 return( MBEDTLS_ERR_X509_INVALID_ALG
+ ret
);
342 return( MBEDTLS_ERR_X509_INVALID_ALG
+
343 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
347 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
350 * AttributeTypeAndValue ::= SEQUENCE {
351 * type AttributeType,
352 * value AttributeValue }
354 * AttributeType ::= OBJECT IDENTIFIER
356 * AttributeValue ::= ANY DEFINED BY AttributeType
358 static int x509_get_attr_type_value( unsigned char **p
,
359 const unsigned char *end
,
360 mbedtls_x509_name
*cur
)
364 mbedtls_x509_buf
*oid
;
365 mbedtls_x509_buf
*val
;
367 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
368 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
369 return( MBEDTLS_ERR_X509_INVALID_NAME
+ ret
);
371 if( ( end
- *p
) < 1 )
372 return( MBEDTLS_ERR_X509_INVALID_NAME
+
373 MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
378 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &oid
->len
, MBEDTLS_ASN1_OID
) ) != 0 )
379 return( MBEDTLS_ERR_X509_INVALID_NAME
+ ret
);
384 if( ( end
- *p
) < 1 )
385 return( MBEDTLS_ERR_X509_INVALID_NAME
+
386 MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
388 if( **p
!= MBEDTLS_ASN1_BMP_STRING
&& **p
!= MBEDTLS_ASN1_UTF8_STRING
&&
389 **p
!= MBEDTLS_ASN1_T61_STRING
&& **p
!= MBEDTLS_ASN1_PRINTABLE_STRING
&&
390 **p
!= MBEDTLS_ASN1_IA5_STRING
&& **p
!= MBEDTLS_ASN1_UNIVERSAL_STRING
&&
391 **p
!= MBEDTLS_ASN1_BIT_STRING
)
392 return( MBEDTLS_ERR_X509_INVALID_NAME
+
393 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
398 if( ( ret
= mbedtls_asn1_get_len( p
, end
, &val
->len
) ) != 0 )
399 return( MBEDTLS_ERR_X509_INVALID_NAME
+ ret
);
410 * Name ::= CHOICE { -- only one possibility for now --
411 * rdnSequence RDNSequence }
413 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
415 * RelativeDistinguishedName ::=
416 * SET OF AttributeTypeAndValue
418 * AttributeTypeAndValue ::= SEQUENCE {
419 * type AttributeType,
420 * value AttributeValue }
422 * AttributeType ::= OBJECT IDENTIFIER
424 * AttributeValue ::= ANY DEFINED BY AttributeType
426 * The data structure is optimized for the common case where each RDN has only
427 * one element, which is represented as a list of AttributeTypeAndValue.
428 * For the general case we still use a flat list, but we mark elements of the
429 * same set so that they are "merged" together in the functions that consume
430 * this list, eg mbedtls_x509_dn_gets().
432 int mbedtls_x509_get_name( unsigned char **p
, const unsigned char *end
,
433 mbedtls_x509_name
*cur
)
437 const unsigned char *end_set
;
439 /* don't use recursion, we'd risk stack overflow if not optimized */
445 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &set_len
,
446 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SET
) ) != 0 )
447 return( MBEDTLS_ERR_X509_INVALID_NAME
+ ret
);
449 end_set
= *p
+ set_len
;
453 if( ( ret
= x509_get_attr_type_value( p
, end_set
, cur
) ) != 0 )
459 /* Mark this item as being no the only one in a set */
460 cur
->next_merged
= 1;
462 cur
->next
= mbedtls_calloc( 1, sizeof( mbedtls_x509_name
) );
464 if( cur
->next
== NULL
)
465 return( MBEDTLS_ERR_X509_ALLOC_FAILED
);
471 * continue until end of SEQUENCE is reached
476 cur
->next
= mbedtls_calloc( 1, sizeof( mbedtls_x509_name
) );
478 if( cur
->next
== NULL
)
479 return( MBEDTLS_ERR_X509_ALLOC_FAILED
);
485 static int x509_parse_int( unsigned char **p
, size_t n
, int *res
)
491 if( ( **p
< '0') || ( **p
> '9' ) )
492 return ( MBEDTLS_ERR_X509_INVALID_DATE
);
495 *res
+= ( *(*p
)++ - '0' );
501 static int x509_date_is_valid(const mbedtls_x509_time
*t
)
503 int ret
= MBEDTLS_ERR_X509_INVALID_DATE
;
505 CHECK_RANGE( 0, 9999, t
->year
);
506 CHECK_RANGE( 0, 23, t
->hour
);
507 CHECK_RANGE( 0, 59, t
->min
);
508 CHECK_RANGE( 0, 59, t
->sec
);
512 case 1: case 3: case 5: case 7: case 8: case 10: case 12:
513 CHECK_RANGE( 1, 31, t
->day
);
515 case 4: case 6: case 9: case 11:
516 CHECK_RANGE( 1, 30, t
->day
);
519 CHECK_RANGE( 1, 28 + (t
->year
% 4 == 0), t
->day
);
529 * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4)
532 static int x509_parse_time( unsigned char **p
, size_t len
, size_t yearlen
,
533 mbedtls_x509_time
*tm
)
538 * Minimum length is 10 or 12 depending on yearlen
540 if ( len
< yearlen
+ 8 )
541 return ( MBEDTLS_ERR_X509_INVALID_DATE
);
545 * Parse year, month, day, hour, minute
547 CHECK( x509_parse_int( p
, yearlen
, &tm
->year
) );
556 CHECK( x509_parse_int( p
, 2, &tm
->mon
) );
557 CHECK( x509_parse_int( p
, 2, &tm
->day
) );
558 CHECK( x509_parse_int( p
, 2, &tm
->hour
) );
559 CHECK( x509_parse_int( p
, 2, &tm
->min
) );
562 * Parse seconds if present
566 CHECK( x509_parse_int( p
, 2, &tm
->sec
) );
570 return ( MBEDTLS_ERR_X509_INVALID_DATE
);
573 * Parse trailing 'Z' if present
575 if ( 1 == len
&& 'Z' == **p
)
582 * We should have parsed all characters at this point
585 return ( MBEDTLS_ERR_X509_INVALID_DATE
);
587 CHECK( x509_date_is_valid( tm
) );
595 * generalTime GeneralizedTime }
597 int mbedtls_x509_get_time( unsigned char **p
, const unsigned char *end
,
598 mbedtls_x509_time
*tm
)
601 size_t len
, year_len
;
604 if( ( end
- *p
) < 1 )
605 return( MBEDTLS_ERR_X509_INVALID_DATE
+
606 MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
610 if( tag
== MBEDTLS_ASN1_UTC_TIME
)
612 else if( tag
== MBEDTLS_ASN1_GENERALIZED_TIME
)
615 return( MBEDTLS_ERR_X509_INVALID_DATE
+
616 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
619 ret
= mbedtls_asn1_get_len( p
, end
, &len
);
622 return( MBEDTLS_ERR_X509_INVALID_DATE
+ ret
);
624 return x509_parse_time( p
, len
, year_len
, tm
);
627 int mbedtls_x509_get_sig( unsigned char **p
, const unsigned char *end
, mbedtls_x509_buf
*sig
)
633 if( ( end
- *p
) < 1 )
634 return( MBEDTLS_ERR_X509_INVALID_SIGNATURE
+
635 MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
639 if( ( ret
= mbedtls_asn1_get_bitstring_null( p
, end
, &len
) ) != 0 )
640 return( MBEDTLS_ERR_X509_INVALID_SIGNATURE
+ ret
);
652 * Get signature algorithm from alg OID and optional parameters
654 int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf
*sig_oid
, const mbedtls_x509_buf
*sig_params
,
655 mbedtls_md_type_t
*md_alg
, mbedtls_pk_type_t
*pk_alg
,
660 if( *sig_opts
!= NULL
)
661 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA
);
663 if( ( ret
= mbedtls_oid_get_sig_alg( sig_oid
, md_alg
, pk_alg
) ) != 0 )
664 return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG
+ ret
);
666 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
667 if( *pk_alg
== MBEDTLS_PK_RSASSA_PSS
)
669 mbedtls_pk_rsassa_pss_options
*pss_opts
;
671 pss_opts
= mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options
) );
672 if( pss_opts
== NULL
)
673 return( MBEDTLS_ERR_X509_ALLOC_FAILED
);
675 ret
= mbedtls_x509_get_rsassa_pss_params( sig_params
,
677 &pss_opts
->mgf1_hash_id
,
678 &pss_opts
->expected_salt_len
);
681 mbedtls_free( pss_opts
);
685 *sig_opts
= (void *) pss_opts
;
688 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
690 /* Make sure parameters are absent or NULL */
691 if( ( sig_params
->tag
!= MBEDTLS_ASN1_NULL
&& sig_params
->tag
!= 0 ) ||
692 sig_params
->len
!= 0 )
693 return( MBEDTLS_ERR_X509_INVALID_ALG
);
700 * X.509 Extensions (No parsing of extensions, pointer should
701 * be either manually updated or extensions should be parsed!)
703 int mbedtls_x509_get_ext( unsigned char **p
, const unsigned char *end
,
704 mbedtls_x509_buf
*ext
, int tag
)
714 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &ext
->len
,
715 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| tag
) ) != 0 )
722 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
724 * Extension ::= SEQUENCE {
725 * extnID OBJECT IDENTIFIER,
726 * critical BOOLEAN DEFAULT FALSE,
727 * extnValue OCTET STRING }
729 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
730 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
731 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+ ret
);
733 if( end
!= *p
+ len
)
734 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
735 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
741 * Store the name in printable form into buf; no more
742 * than size characters will be written
744 int mbedtls_x509_dn_gets( char *buf
, size_t size
, const mbedtls_x509_name
*dn
)
748 unsigned char c
, merge
= 0;
749 const mbedtls_x509_name
*name
;
750 const char *short_name
= NULL
;
751 char s
[MBEDTLS_X509_MAX_DN_NAME_SIZE
], *p
;
753 memset( s
, 0, sizeof( s
) );
759 while( name
!= NULL
)
769 ret
= mbedtls_snprintf( p
, n
, merge
? " + " : ", " );
770 MBEDTLS_X509_SAFE_SNPRINTF
;
773 ret
= mbedtls_oid_get_attr_short_name( &name
->oid
, &short_name
);
776 ret
= mbedtls_snprintf( p
, n
, "%s=", short_name
);
778 ret
= mbedtls_snprintf( p
, n
, "\?\?=" );
779 MBEDTLS_X509_SAFE_SNPRINTF
;
781 for( i
= 0; i
< name
->val
.len
; i
++ )
783 if( i
>= sizeof( s
) - 1 )
787 if( c
< 32 || c
== 127 || ( c
> 128 && c
< 160 ) )
792 ret
= mbedtls_snprintf( p
, n
, "%s", s
);
793 MBEDTLS_X509_SAFE_SNPRINTF
;
795 merge
= name
->next_merged
;
799 return( (int) ( size
- n
) );
803 * Store the serial in printable form into buf; no more
804 * than size characters will be written
806 int mbedtls_x509_serial_gets( char *buf
, size_t size
, const mbedtls_x509_buf
*serial
)
815 nr
= ( serial
->len
<= 32 )
818 for( i
= 0; i
< nr
; i
++ )
820 if( i
== 0 && nr
> 1 && serial
->p
[i
] == 0x0 )
823 ret
= mbedtls_snprintf( p
, n
, "%02X%s",
824 serial
->p
[i
], ( i
< nr
- 1 ) ? ":" : "" );
825 MBEDTLS_X509_SAFE_SNPRINTF
;
828 if( nr
!= serial
->len
)
830 ret
= mbedtls_snprintf( p
, n
, "...." );
831 MBEDTLS_X509_SAFE_SNPRINTF
;
834 return( (int) ( size
- n
) );
838 * Helper for writing signature algorithms
840 int mbedtls_x509_sig_alg_gets( char *buf
, size_t size
, const mbedtls_x509_buf
*sig_oid
,
841 mbedtls_pk_type_t pk_alg
, mbedtls_md_type_t md_alg
,
842 const void *sig_opts
)
847 const char *desc
= NULL
;
849 ret
= mbedtls_oid_get_sig_alg_desc( sig_oid
, &desc
);
851 ret
= mbedtls_snprintf( p
, n
, "???" );
853 ret
= mbedtls_snprintf( p
, n
, "%s", desc
);
854 MBEDTLS_X509_SAFE_SNPRINTF
;
856 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
857 if( pk_alg
== MBEDTLS_PK_RSASSA_PSS
)
859 const mbedtls_pk_rsassa_pss_options
*pss_opts
;
860 const mbedtls_md_info_t
*md_info
, *mgf_md_info
;
862 pss_opts
= (const mbedtls_pk_rsassa_pss_options
*) sig_opts
;
864 md_info
= mbedtls_md_info_from_type( md_alg
);
865 mgf_md_info
= mbedtls_md_info_from_type( pss_opts
->mgf1_hash_id
);
867 ret
= mbedtls_snprintf( p
, n
, " (%s, MGF1-%s, 0x%02X)",
868 md_info
? mbedtls_md_get_name( md_info
) : "???",
869 mgf_md_info
? mbedtls_md_get_name( mgf_md_info
) : "???",
870 pss_opts
->expected_salt_len
);
871 MBEDTLS_X509_SAFE_SNPRINTF
;
877 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
879 return( (int)( size
- n
) );
883 * Helper for writing "RSA key size", "EC key size", etc
885 int mbedtls_x509_key_size_helper( char *buf
, size_t buf_size
, const char *name
)
891 ret
= mbedtls_snprintf( p
, n
, "%s key size", name
);
892 MBEDTLS_X509_SAFE_SNPRINTF
;
897 #if defined(MBEDTLS_HAVE_TIME_DATE)
899 * Set the time structure to the current time.
900 * Return 0 on success, non-zero on failure.
902 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
903 static int x509_get_current_time( mbedtls_x509_time
*now
)
907 GetSystemTime( &st
);
909 now
->year
= st
.wYear
;
910 now
->mon
= st
.wMonth
;
912 now
->hour
= st
.wHour
;
913 now
->min
= st
.wMinute
;
914 now
->sec
= st
.wSecond
;
919 static int x509_get_current_time( mbedtls_x509_time
*now
)
925 #if defined(MBEDTLS_THREADING_C)
926 if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex
) != 0 )
927 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR
);
930 tt
= mbedtls_time( NULL
);
937 now
->year
= lt
->tm_year
+ 1900;
938 now
->mon
= lt
->tm_mon
+ 1;
939 now
->day
= lt
->tm_mday
;
940 now
->hour
= lt
->tm_hour
;
941 now
->min
= lt
->tm_min
;
942 now
->sec
= lt
->tm_sec
;
945 #if defined(MBEDTLS_THREADING_C)
946 if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex
) != 0 )
947 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR
);
952 #endif /* _WIN32 && !EFIX64 && !EFI32 */
955 * Return 0 if before <= after, 1 otherwise
957 static int x509_check_time( const mbedtls_x509_time
*before
, const mbedtls_x509_time
*after
)
959 if( before
->year
> after
->year
)
962 if( before
->year
== after
->year
&&
963 before
->mon
> after
->mon
)
966 if( before
->year
== after
->year
&&
967 before
->mon
== after
->mon
&&
968 before
->day
> after
->day
)
971 if( before
->year
== after
->year
&&
972 before
->mon
== after
->mon
&&
973 before
->day
== after
->day
&&
974 before
->hour
> after
->hour
)
977 if( before
->year
== after
->year
&&
978 before
->mon
== after
->mon
&&
979 before
->day
== after
->day
&&
980 before
->hour
== after
->hour
&&
981 before
->min
> after
->min
)
984 if( before
->year
== after
->year
&&
985 before
->mon
== after
->mon
&&
986 before
->day
== after
->day
&&
987 before
->hour
== after
->hour
&&
988 before
->min
== after
->min
&&
989 before
->sec
> after
->sec
)
995 int mbedtls_x509_time_is_past( const mbedtls_x509_time
*to
)
997 mbedtls_x509_time now
;
999 if( x509_get_current_time( &now
) != 0 )
1002 return( x509_check_time( &now
, to
) );
1005 int mbedtls_x509_time_is_future( const mbedtls_x509_time
*from
)
1007 mbedtls_x509_time now
;
1009 if( x509_get_current_time( &now
) != 0 )
1012 return( x509_check_time( from
, &now
) );
1015 #else /* MBEDTLS_HAVE_TIME_DATE */
1017 int mbedtls_x509_time_is_past( const mbedtls_x509_time
*to
)
1023 int mbedtls_x509_time_is_future( const mbedtls_x509_time
*from
)
1028 #endif /* MBEDTLS_HAVE_TIME_DATE */
1030 #if defined(MBEDTLS_SELF_TEST)
1032 #include "mbedtls/x509_crt.h"
1033 #include "mbedtls/certs.h"
1038 int mbedtls_x509_self_test( int verbose
)
1040 #if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C)
1043 mbedtls_x509_crt cacert
;
1044 mbedtls_x509_crt clicert
;
1047 mbedtls_printf( " X.509 certificate load: " );
1049 mbedtls_x509_crt_init( &clicert
);
1051 ret
= mbedtls_x509_crt_parse( &clicert
, (const unsigned char *) mbedtls_test_cli_crt
,
1052 mbedtls_test_cli_crt_len
);
1056 mbedtls_printf( "failed\n" );
1061 mbedtls_x509_crt_init( &cacert
);
1063 ret
= mbedtls_x509_crt_parse( &cacert
, (const unsigned char *) mbedtls_test_ca_crt
,
1064 mbedtls_test_ca_crt_len
);
1068 mbedtls_printf( "failed\n" );
1074 mbedtls_printf( "passed\n X.509 signature verify: ");
1076 ret
= mbedtls_x509_crt_verify( &clicert
, &cacert
, NULL
, NULL
, &flags
, NULL
, NULL
);
1080 mbedtls_printf( "failed\n" );
1086 mbedtls_printf( "passed\n\n");
1088 mbedtls_x509_crt_free( &cacert
);
1089 mbedtls_x509_crt_free( &clicert
);
1095 #endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */
1098 #endif /* MBEDTLS_SELF_TEST */
1100 #endif /* MBEDTLS_X509_USE_C */