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 /* Ensure gmtime_r is available even with -std=c99; must be included before 
  35  * config.h, which pulls in glibc's features.h. Harmless on other platforms. */ 
  36 #define _POSIX_C_SOURCE 200112L 
  38 #if !defined(MBEDTLS_CONFIG_FILE) 
  39 #include "mbedtls/config.h" 
  41 #include MBEDTLS_CONFIG_FILE 
  44 #if defined(MBEDTLS_X509_USE_C) 
  46 #include "mbedtls/x509.h" 
  47 #include "mbedtls/asn1.h" 
  48 #include "mbedtls/oid.h" 
  53 #if defined(MBEDTLS_PEM_PARSE_C) 
  54 #include "mbedtls/pem.h" 
  57 #if defined(MBEDTLS_PLATFORM_C) 
  58 #include "mbedtls/platform.h" 
  62 #define mbedtls_free      free 
  63 #define mbedtls_calloc    calloc 
  64 #define mbedtls_printf    printf 
  65 #define mbedtls_snprintf  snprintf 
  68 #if defined(MBEDTLS_HAVE_TIME) 
  69 #include "mbedtls/platform_time.h" 
  71 #if defined(MBEDTLS_HAVE_TIME_DATE) 
  75 #define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); } 
  76 #define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); } 
  79  *  CertificateSerialNumber  ::=  INTEGER 
  81 int mbedtls_x509_get_serial( unsigned char **p
, const unsigned char *end
, 
  82                      mbedtls_x509_buf 
*serial 
) 
  86     if( ( end 
- *p 
) < 1 ) 
  87         return( MBEDTLS_ERR_X509_INVALID_SERIAL 
+ 
  88                 MBEDTLS_ERR_ASN1_OUT_OF_DATA 
); 
  90     if( **p 
!= ( MBEDTLS_ASN1_CONTEXT_SPECIFIC 
| MBEDTLS_ASN1_PRIMITIVE 
| 2 ) && 
  91         **p 
!=   MBEDTLS_ASN1_INTEGER 
) 
  92         return( MBEDTLS_ERR_X509_INVALID_SERIAL 
+ 
  93                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG 
); 
  95     serial
->tag 
= *(*p
)++; 
  97     if( ( ret 
= mbedtls_asn1_get_len( p
, end
, &serial
->len 
) ) != 0 ) 
  98         return( MBEDTLS_ERR_X509_INVALID_SERIAL 
+ ret 
); 
 106 /* Get an algorithm identifier without parameters (eg for signatures) 
 108  *  AlgorithmIdentifier  ::=  SEQUENCE  { 
 109  *       algorithm               OBJECT IDENTIFIER, 
 110  *       parameters              ANY DEFINED BY algorithm OPTIONAL  } 
 112 int mbedtls_x509_get_alg_null( unsigned char **p
, const unsigned char *end
, 
 113                        mbedtls_x509_buf 
*alg 
) 
 117     if( ( ret 
= mbedtls_asn1_get_alg_null( p
, end
, alg 
) ) != 0 ) 
 118         return( MBEDTLS_ERR_X509_INVALID_ALG 
+ ret 
); 
 124  * Parse an algorithm identifier with (optional) paramaters 
 126 int mbedtls_x509_get_alg( unsigned char **p
, const unsigned char *end
, 
 127                   mbedtls_x509_buf 
*alg
, mbedtls_x509_buf 
*params 
) 
 131     if( ( ret 
= mbedtls_asn1_get_alg( p
, end
, alg
, params 
) ) != 0 ) 
 132         return( MBEDTLS_ERR_X509_INVALID_ALG 
+ ret 
); 
 137 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 
 139  * HashAlgorithm ::= AlgorithmIdentifier 
 141  * AlgorithmIdentifier  ::=  SEQUENCE  { 
 142  *      algorithm               OBJECT IDENTIFIER, 
 143  *      parameters              ANY DEFINED BY algorithm OPTIONAL  } 
 145  * For HashAlgorithm, parameters MUST be NULL or absent. 
 147 static int x509_get_hash_alg( const mbedtls_x509_buf 
*alg
, mbedtls_md_type_t 
*md_alg 
) 
 151     const unsigned char *end
; 
 152     mbedtls_x509_buf md_oid
; 
 155     /* Make sure we got a SEQUENCE and setup bounds */ 
 156     if( alg
->tag 
!= ( MBEDTLS_ASN1_CONSTRUCTED 
| MBEDTLS_ASN1_SEQUENCE 
) ) 
 157         return( MBEDTLS_ERR_X509_INVALID_ALG 
+ 
 158                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG 
); 
 160     p 
= (unsigned char *) alg
->p
; 
 164         return( MBEDTLS_ERR_X509_INVALID_ALG 
+ 
 165                 MBEDTLS_ERR_ASN1_OUT_OF_DATA 
); 
 170     if( ( ret 
= mbedtls_asn1_get_tag( &p
, end
, &md_oid
.len
, MBEDTLS_ASN1_OID 
) ) != 0 ) 
 171         return( MBEDTLS_ERR_X509_INVALID_ALG 
+ ret 
); 
 176     /* Get md_alg from md_oid */ 
 177     if( ( ret 
= mbedtls_oid_get_md_alg( &md_oid
, md_alg 
) ) != 0 ) 
 178         return( MBEDTLS_ERR_X509_INVALID_ALG 
+ ret 
); 
 180     /* Make sure params is absent of NULL */ 
 184     if( ( ret 
= mbedtls_asn1_get_tag( &p
, end
, &len
, MBEDTLS_ASN1_NULL 
) ) != 0 || len 
!= 0 ) 
 185         return( MBEDTLS_ERR_X509_INVALID_ALG 
+ ret 
); 
 188         return( MBEDTLS_ERR_X509_INVALID_ALG 
+ 
 189                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH 
); 
 195  *    RSASSA-PSS-params  ::=  SEQUENCE  { 
 196  *       hashAlgorithm     [0] HashAlgorithm DEFAULT sha1Identifier, 
 197  *       maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier, 
 198  *       saltLength        [2] INTEGER DEFAULT 20, 
 199  *       trailerField      [3] INTEGER DEFAULT 1  } 
 200  *    -- Note that the tags in this Sequence are explicit. 
 202  * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value 
 203  * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other 
 204  * option. Enfore this at parsing time. 
 206 int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf 
*params
, 
 207                                 mbedtls_md_type_t 
*md_alg
, mbedtls_md_type_t 
*mgf_md
, 
 212     const unsigned char *end
, *end2
; 
 214     mbedtls_x509_buf alg_id
, alg_params
; 
 216     /* First set everything to defaults */ 
 217     *md_alg 
= MBEDTLS_MD_SHA1
; 
 218     *mgf_md 
= MBEDTLS_MD_SHA1
; 
 221     /* Make sure params is a SEQUENCE and setup bounds */ 
 222     if( params
->tag 
!= ( MBEDTLS_ASN1_CONSTRUCTED 
| MBEDTLS_ASN1_SEQUENCE 
) ) 
 223         return( MBEDTLS_ERR_X509_INVALID_ALG 
+ 
 224                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG 
); 
 226     p 
= (unsigned char *) params
->p
; 
 227     end 
= p 
+ params
->len
; 
 235     if( ( ret 
= mbedtls_asn1_get_tag( &p
, end
, &len
, 
 236                     MBEDTLS_ASN1_CONTEXT_SPECIFIC 
| MBEDTLS_ASN1_CONSTRUCTED 
| 0 ) ) == 0 ) 
 240         /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */ 
 241         if( ( ret 
= mbedtls_x509_get_alg_null( &p
, end2
, &alg_id 
) ) != 0 ) 
 244         if( ( ret 
= mbedtls_oid_get_md_alg( &alg_id
, md_alg 
) ) != 0 ) 
 245             return( MBEDTLS_ERR_X509_INVALID_ALG 
+ ret 
); 
 248             return( MBEDTLS_ERR_X509_INVALID_ALG 
+ 
 249                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH 
); 
 251     else if( ret 
!= MBEDTLS_ERR_ASN1_UNEXPECTED_TAG 
) 
 252         return( MBEDTLS_ERR_X509_INVALID_ALG 
+ ret 
); 
 260     if( ( ret 
= mbedtls_asn1_get_tag( &p
, end
, &len
, 
 261                     MBEDTLS_ASN1_CONTEXT_SPECIFIC 
| MBEDTLS_ASN1_CONSTRUCTED 
| 1 ) ) == 0 ) 
 265         /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */ 
 266         if( ( ret 
= mbedtls_x509_get_alg( &p
, end2
, &alg_id
, &alg_params 
) ) != 0 ) 
 269         /* Only MFG1 is recognised for now */ 
 270         if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1
, &alg_id 
) != 0 ) 
 271             return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE 
+ 
 272                     MBEDTLS_ERR_OID_NOT_FOUND 
); 
 274         /* Parse HashAlgorithm */ 
 275         if( ( ret 
= x509_get_hash_alg( &alg_params
, mgf_md 
) ) != 0 ) 
 279             return( MBEDTLS_ERR_X509_INVALID_ALG 
+ 
 280                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH 
); 
 282     else if( ret 
!= MBEDTLS_ERR_ASN1_UNEXPECTED_TAG 
) 
 283         return( MBEDTLS_ERR_X509_INVALID_ALG 
+ ret 
); 
 291     if( ( ret 
= mbedtls_asn1_get_tag( &p
, end
, &len
, 
 292                     MBEDTLS_ASN1_CONTEXT_SPECIFIC 
| MBEDTLS_ASN1_CONSTRUCTED 
| 2 ) ) == 0 ) 
 296         if( ( ret 
= mbedtls_asn1_get_int( &p
, end2
, salt_len 
) ) != 0 ) 
 297             return( MBEDTLS_ERR_X509_INVALID_ALG 
+ ret 
); 
 300             return( MBEDTLS_ERR_X509_INVALID_ALG 
+ 
 301                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH 
); 
 303     else if( ret 
!= MBEDTLS_ERR_ASN1_UNEXPECTED_TAG 
) 
 304         return( MBEDTLS_ERR_X509_INVALID_ALG 
+ ret 
); 
 310      * trailer_field (if present, must be 1) 
 312     if( ( ret 
= mbedtls_asn1_get_tag( &p
, end
, &len
, 
 313                     MBEDTLS_ASN1_CONTEXT_SPECIFIC 
| MBEDTLS_ASN1_CONSTRUCTED 
| 3 ) ) == 0 ) 
 319         if( ( ret 
= mbedtls_asn1_get_int( &p
, end2
, &trailer_field 
) ) != 0 ) 
 320             return( MBEDTLS_ERR_X509_INVALID_ALG 
+ ret 
); 
 323             return( MBEDTLS_ERR_X509_INVALID_ALG 
+ 
 324                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH 
); 
 326         if( trailer_field 
!= 1 ) 
 327             return( MBEDTLS_ERR_X509_INVALID_ALG 
); 
 329     else if( ret 
!= MBEDTLS_ERR_ASN1_UNEXPECTED_TAG 
) 
 330         return( MBEDTLS_ERR_X509_INVALID_ALG 
+ ret 
); 
 333         return( MBEDTLS_ERR_X509_INVALID_ALG 
+ 
 334                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH 
); 
 338 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 
 341  *  AttributeTypeAndValue ::= SEQUENCE { 
 342  *    type     AttributeType, 
 343  *    value    AttributeValue } 
 345  *  AttributeType ::= OBJECT IDENTIFIER 
 347  *  AttributeValue ::= ANY DEFINED BY AttributeType 
 349 static int x509_get_attr_type_value( unsigned char **p
, 
 350                                      const unsigned char *end
, 
 351                                      mbedtls_x509_name 
*cur 
) 
 355     mbedtls_x509_buf 
*oid
; 
 356     mbedtls_x509_buf 
*val
; 
 358     if( ( ret 
= mbedtls_asn1_get_tag( p
, end
, &len
, 
 359             MBEDTLS_ASN1_CONSTRUCTED 
| MBEDTLS_ASN1_SEQUENCE 
) ) != 0 ) 
 360         return( MBEDTLS_ERR_X509_INVALID_NAME 
+ ret 
); 
 362     if( ( end 
- *p 
) < 1 ) 
 363         return( MBEDTLS_ERR_X509_INVALID_NAME 
+ 
 364                 MBEDTLS_ERR_ASN1_OUT_OF_DATA 
); 
 369     if( ( ret 
= mbedtls_asn1_get_tag( p
, end
, &oid
->len
, MBEDTLS_ASN1_OID 
) ) != 0 ) 
 370         return( MBEDTLS_ERR_X509_INVALID_NAME 
+ ret 
); 
 375     if( ( end 
- *p 
) < 1 ) 
 376         return( MBEDTLS_ERR_X509_INVALID_NAME 
+ 
 377                 MBEDTLS_ERR_ASN1_OUT_OF_DATA 
); 
 379     if( **p 
!= MBEDTLS_ASN1_BMP_STRING 
&& **p 
!= MBEDTLS_ASN1_UTF8_STRING      
&& 
 380         **p 
!= MBEDTLS_ASN1_T61_STRING 
&& **p 
!= MBEDTLS_ASN1_PRINTABLE_STRING 
&& 
 381         **p 
!= MBEDTLS_ASN1_IA5_STRING 
&& **p 
!= MBEDTLS_ASN1_UNIVERSAL_STRING 
&& 
 382         **p 
!= MBEDTLS_ASN1_BIT_STRING 
) 
 383         return( MBEDTLS_ERR_X509_INVALID_NAME 
+ 
 384                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG 
); 
 389     if( ( ret 
= mbedtls_asn1_get_len( p
, end
, &val
->len 
) ) != 0 ) 
 390         return( MBEDTLS_ERR_X509_INVALID_NAME 
+ ret 
); 
 401  *  Name ::= CHOICE { -- only one possibility for now -- 
 402  *       rdnSequence  RDNSequence } 
 404  *  RDNSequence ::= SEQUENCE OF RelativeDistinguishedName 
 406  *  RelativeDistinguishedName ::= 
 407  *    SET OF AttributeTypeAndValue 
 409  *  AttributeTypeAndValue ::= SEQUENCE { 
 410  *    type     AttributeType, 
 411  *    value    AttributeValue } 
 413  *  AttributeType ::= OBJECT IDENTIFIER 
 415  *  AttributeValue ::= ANY DEFINED BY AttributeType 
 417  * The data structure is optimized for the common case where each RDN has only 
 418  * one element, which is represented as a list of AttributeTypeAndValue. 
 419  * For the general case we still use a flat list, but we mark elements of the 
 420  * same set so that they are "merged" together in the functions that consume 
 421  * this list, eg mbedtls_x509_dn_gets(). 
 423 int mbedtls_x509_get_name( unsigned char **p
, const unsigned char *end
, 
 424                    mbedtls_x509_name 
*cur 
) 
 428     const unsigned char *end_set
; 
 430     /* don't use recursion, we'd risk stack overflow if not optimized */ 
 436         if( ( ret 
= mbedtls_asn1_get_tag( p
, end
, &set_len
, 
 437                 MBEDTLS_ASN1_CONSTRUCTED 
| MBEDTLS_ASN1_SET 
) ) != 0 ) 
 438             return( MBEDTLS_ERR_X509_INVALID_NAME 
+ ret 
); 
 440         end_set  
= *p 
+ set_len
; 
 444             if( ( ret 
= x509_get_attr_type_value( p
, end_set
, cur 
) ) != 0 ) 
 450             /* Mark this item as being no the only one in a set */ 
 451             cur
->next_merged 
= 1; 
 453             cur
->next 
= mbedtls_calloc( 1, sizeof( mbedtls_x509_name 
) ); 
 455             if( cur
->next 
== NULL 
) 
 456                 return( MBEDTLS_ERR_X509_ALLOC_FAILED 
); 
 462          * continue until end of SEQUENCE is reached 
 467         cur
->next 
= mbedtls_calloc( 1, sizeof( mbedtls_x509_name 
) ); 
 469         if( cur
->next 
== NULL 
) 
 470             return( MBEDTLS_ERR_X509_ALLOC_FAILED 
); 
 476 static int x509_parse_int( unsigned char **p
, size_t n
, int *res 
) 
 482         if( ( **p 
< '0') || ( **p 
> '9' ) ) 
 483             return ( MBEDTLS_ERR_X509_INVALID_DATE 
); 
 486         *res 
+= ( *(*p
)++ - '0' ); 
 492 static int x509_date_is_valid(const mbedtls_x509_time 
*t 
) 
 494     int ret 
= MBEDTLS_ERR_X509_INVALID_DATE
; 
 497     CHECK_RANGE( 0, 9999, t
->year 
); 
 498     CHECK_RANGE( 0, 23,   t
->hour 
); 
 499     CHECK_RANGE( 0, 59,   t
->min  
); 
 500     CHECK_RANGE( 0, 59,   t
->sec  
); 
 504         case 1: case 3: case 5: case 7: case 8: case 10: case 12: 
 507         case 4: case 6: case 9: case 11: 
 511             if( ( !( t
->year 
% 4 ) && t
->year 
% 100 ) || 
 520     CHECK_RANGE( 1, month_len
, t
->day 
); 
 526  * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4) 
 529 static int x509_parse_time( unsigned char **p
, size_t len
, size_t yearlen
, 
 530                             mbedtls_x509_time 
*tm 
) 
 535      * Minimum length is 10 or 12 depending on yearlen 
 537     if ( len 
< yearlen 
+ 8 ) 
 538         return ( MBEDTLS_ERR_X509_INVALID_DATE 
); 
 542      * Parse year, month, day, hour, minute 
 544     CHECK( x509_parse_int( p
, yearlen
, &tm
->year 
) ); 
 553     CHECK( x509_parse_int( p
, 2, &tm
->mon 
) ); 
 554     CHECK( x509_parse_int( p
, 2, &tm
->day 
) ); 
 555     CHECK( x509_parse_int( p
, 2, &tm
->hour 
) ); 
 556     CHECK( x509_parse_int( p
, 2, &tm
->min 
) ); 
 559      * Parse seconds if present 
 563         CHECK( x509_parse_int( p
, 2, &tm
->sec 
) ); 
 567         return ( MBEDTLS_ERR_X509_INVALID_DATE 
); 
 570      * Parse trailing 'Z' if present 
 572     if ( 1 == len 
&& 'Z' == **p 
) 
 579      * We should have parsed all characters at this point 
 582         return ( MBEDTLS_ERR_X509_INVALID_DATE 
); 
 584     CHECK( x509_date_is_valid( tm 
) ); 
 592  *       generalTime    GeneralizedTime } 
 594 int mbedtls_x509_get_time( unsigned char **p
, const unsigned char *end
, 
 595                            mbedtls_x509_time 
*tm 
) 
 598     size_t len
, year_len
; 
 601     if( ( end 
- *p 
) < 1 ) 
 602         return( MBEDTLS_ERR_X509_INVALID_DATE 
+ 
 603                 MBEDTLS_ERR_ASN1_OUT_OF_DATA 
); 
 607     if( tag 
== MBEDTLS_ASN1_UTC_TIME 
) 
 609     else if( tag 
== MBEDTLS_ASN1_GENERALIZED_TIME 
) 
 612         return( MBEDTLS_ERR_X509_INVALID_DATE 
+ 
 613                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG 
); 
 616     ret 
= mbedtls_asn1_get_len( p
, end
, &len 
); 
 619         return( MBEDTLS_ERR_X509_INVALID_DATE 
+ ret 
); 
 621     return x509_parse_time( p
, len
, year_len
, tm 
); 
 624 int mbedtls_x509_get_sig( unsigned char **p
, const unsigned char *end
, mbedtls_x509_buf 
*sig 
) 
 630     if( ( end 
- *p 
) < 1 ) 
 631         return( MBEDTLS_ERR_X509_INVALID_SIGNATURE 
+ 
 632                 MBEDTLS_ERR_ASN1_OUT_OF_DATA 
); 
 636     if( ( ret 
= mbedtls_asn1_get_bitstring_null( p
, end
, &len 
) ) != 0 ) 
 637         return( MBEDTLS_ERR_X509_INVALID_SIGNATURE 
+ ret 
); 
 649  * Get signature algorithm from alg OID and optional parameters 
 651 int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf 
*sig_oid
, const mbedtls_x509_buf 
*sig_params
, 
 652                       mbedtls_md_type_t 
*md_alg
, mbedtls_pk_type_t 
*pk_alg
, 
 657     if( *sig_opts 
!= NULL 
) 
 658         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA 
); 
 660     if( ( ret 
= mbedtls_oid_get_sig_alg( sig_oid
, md_alg
, pk_alg 
) ) != 0 ) 
 661         return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG 
+ ret 
); 
 663 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 
 664     if( *pk_alg 
== MBEDTLS_PK_RSASSA_PSS 
) 
 666         mbedtls_pk_rsassa_pss_options 
*pss_opts
; 
 668         pss_opts 
= mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options 
) ); 
 669         if( pss_opts 
== NULL 
) 
 670             return( MBEDTLS_ERR_X509_ALLOC_FAILED 
); 
 672         ret 
= mbedtls_x509_get_rsassa_pss_params( sig_params
, 
 674                                           &pss_opts
->mgf1_hash_id
, 
 675                                           &pss_opts
->expected_salt_len 
); 
 678             mbedtls_free( pss_opts 
); 
 682         *sig_opts 
= (void *) pss_opts
; 
 685 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 
 687         /* Make sure parameters are absent or NULL */ 
 688         if( ( sig_params
->tag 
!= MBEDTLS_ASN1_NULL 
&& sig_params
->tag 
!= 0 ) || 
 689               sig_params
->len 
!= 0 ) 
 690         return( MBEDTLS_ERR_X509_INVALID_ALG 
); 
 697  * X.509 Extensions (No parsing of extensions, pointer should 
 698  * be either manually updated or extensions should be parsed!) 
 700 int mbedtls_x509_get_ext( unsigned char **p
, const unsigned char *end
, 
 701                   mbedtls_x509_buf 
*ext
, int tag 
) 
 711     if( ( ret 
= mbedtls_asn1_get_tag( p
, end
, &ext
->len
, 
 712             MBEDTLS_ASN1_CONTEXT_SPECIFIC 
| MBEDTLS_ASN1_CONSTRUCTED 
| tag 
) ) != 0 ) 
 719      * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension 
 721      * Extension  ::=  SEQUENCE  { 
 722      *      extnID      OBJECT IDENTIFIER, 
 723      *      critical    BOOLEAN DEFAULT FALSE, 
 724      *      extnValue   OCTET STRING  } 
 726     if( ( ret 
= mbedtls_asn1_get_tag( p
, end
, &len
, 
 727             MBEDTLS_ASN1_CONSTRUCTED 
| MBEDTLS_ASN1_SEQUENCE 
) ) != 0 ) 
 728         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS 
+ ret 
); 
 730     if( end 
!= *p 
+ len 
) 
 731         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS 
+ 
 732                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH 
); 
 738  * Store the name in printable form into buf; no more 
 739  * than size characters will be written 
 741 int mbedtls_x509_dn_gets( char *buf
, size_t size
, const mbedtls_x509_name 
*dn 
) 
 745     unsigned char c
, merge 
= 0; 
 746     const mbedtls_x509_name 
*name
; 
 747     const char *short_name 
= NULL
; 
 748     char s
[MBEDTLS_X509_MAX_DN_NAME_SIZE
], *p
; 
 750     memset( s
, 0, sizeof( s 
) ); 
 756     while( name 
!= NULL 
) 
 766             ret 
= mbedtls_snprintf( p
, n
, merge 
? " + " : ", " ); 
 767             MBEDTLS_X509_SAFE_SNPRINTF
; 
 770         ret 
= mbedtls_oid_get_attr_short_name( &name
->oid
, &short_name 
); 
 773             ret 
= mbedtls_snprintf( p
, n
, "%s=", short_name 
); 
 775             ret 
= mbedtls_snprintf( p
, n
, "\?\?=" ); 
 776         MBEDTLS_X509_SAFE_SNPRINTF
; 
 778         for( i 
= 0; i 
< name
->val
.len
; i
++ ) 
 780             if( i 
>= sizeof( s 
) - 1 ) 
 784             if( c 
< 32 || c 
== 127 || ( c 
> 128 && c 
< 160 ) ) 
 789         ret 
= mbedtls_snprintf( p
, n
, "%s", s 
); 
 790         MBEDTLS_X509_SAFE_SNPRINTF
; 
 792         merge 
= name
->next_merged
; 
 796     return( (int) ( size 
- n 
) ); 
 800  * Store the serial in printable form into buf; no more 
 801  * than size characters will be written 
 803 int mbedtls_x509_serial_gets( char *buf
, size_t size
, const mbedtls_x509_buf 
*serial 
) 
 812     nr 
= ( serial
->len 
<= 32 ) 
 815     for( i 
= 0; i 
< nr
; i
++ ) 
 817         if( i 
== 0 && nr 
> 1 && serial
->p
[i
] == 0x0 ) 
 820         ret 
= mbedtls_snprintf( p
, n
, "%02X%s", 
 821                 serial
->p
[i
], ( i 
< nr 
- 1 ) ? ":" : "" ); 
 822         MBEDTLS_X509_SAFE_SNPRINTF
; 
 825     if( nr 
!= serial
->len 
) 
 827         ret 
= mbedtls_snprintf( p
, n
, "...." ); 
 828         MBEDTLS_X509_SAFE_SNPRINTF
; 
 831     return( (int) ( size 
- n 
) ); 
 835  * Helper for writing signature algorithms 
 837 int mbedtls_x509_sig_alg_gets( char *buf
, size_t size
, const mbedtls_x509_buf 
*sig_oid
, 
 838                        mbedtls_pk_type_t pk_alg
, mbedtls_md_type_t md_alg
, 
 839                        const void *sig_opts 
) 
 844     const char *desc 
= NULL
; 
 846     ret 
= mbedtls_oid_get_sig_alg_desc( sig_oid
, &desc 
); 
 848         ret 
= mbedtls_snprintf( p
, n
, "???"  ); 
 850         ret 
= mbedtls_snprintf( p
, n
, "%s", desc 
); 
 851     MBEDTLS_X509_SAFE_SNPRINTF
; 
 853 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 
 854     if( pk_alg 
== MBEDTLS_PK_RSASSA_PSS 
) 
 856         const mbedtls_pk_rsassa_pss_options 
*pss_opts
; 
 857         const mbedtls_md_info_t 
*md_info
, *mgf_md_info
; 
 859         pss_opts 
= (const mbedtls_pk_rsassa_pss_options 
*) sig_opts
; 
 861         md_info 
= mbedtls_md_info_from_type( md_alg 
); 
 862         mgf_md_info 
= mbedtls_md_info_from_type( pss_opts
->mgf1_hash_id 
); 
 864         ret 
= mbedtls_snprintf( p
, n
, " (%s, MGF1-%s, 0x%02X)", 
 865                               md_info 
? mbedtls_md_get_name( md_info 
) : "???", 
 866                               mgf_md_info 
? mbedtls_md_get_name( mgf_md_info 
) : "???", 
 867                               pss_opts
->expected_salt_len 
); 
 868         MBEDTLS_X509_SAFE_SNPRINTF
; 
 874 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 
 876     return( (int)( size 
- n 
) ); 
 880  * Helper for writing "RSA key size", "EC key size", etc 
 882 int mbedtls_x509_key_size_helper( char *buf
, size_t buf_size
, const char *name 
) 
 888     ret 
= mbedtls_snprintf( p
, n
, "%s key size", name 
); 
 889     MBEDTLS_X509_SAFE_SNPRINTF
; 
 894 #if defined(MBEDTLS_HAVE_TIME_DATE) 
 896  * Set the time structure to the current time. 
 897  * Return 0 on success, non-zero on failure. 
 899 static int x509_get_current_time( mbedtls_x509_time 
*now 
) 
 901     struct tm 
*lt
, tm_buf
; 
 905     tt 
= mbedtls_time( NULL 
); 
 906 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 
 907     lt 
= gmtime_s( &tm_buf
, &tt 
) == 0 ? &tm_buf 
: NULL
; 
 909     lt 
= gmtime_r( &tt
, &tm_buf 
); 
 916         now
->year 
= lt
->tm_year 
+ 1900; 
 917         now
->mon  
= lt
->tm_mon  
+ 1; 
 918         now
->day  
= lt
->tm_mday
; 
 919         now
->hour 
= lt
->tm_hour
; 
 920         now
->min  
= lt
->tm_min
; 
 921         now
->sec  
= lt
->tm_sec
; 
 928  * Return 0 if before <= after, 1 otherwise 
 930 static int x509_check_time( const mbedtls_x509_time 
*before
, const mbedtls_x509_time 
*after 
) 
 932     if( before
->year  
> after
->year 
) 
 935     if( before
->year 
== after
->year 
&& 
 936         before
->mon   
> after
->mon 
) 
 939     if( before
->year 
== after
->year 
&& 
 940         before
->mon  
== after
->mon  
&& 
 941         before
->day   
> after
->day 
) 
 944     if( before
->year 
== after
->year 
&& 
 945         before
->mon  
== after
->mon  
&& 
 946         before
->day  
== after
->day  
&& 
 947         before
->hour  
> after
->hour 
) 
 950     if( before
->year 
== after
->year 
&& 
 951         before
->mon  
== after
->mon  
&& 
 952         before
->day  
== after
->day  
&& 
 953         before
->hour 
== after
->hour 
&& 
 954         before
->min   
> after
->min  
) 
 957     if( before
->year 
== after
->year 
&& 
 958         before
->mon  
== after
->mon  
&& 
 959         before
->day  
== after
->day  
&& 
 960         before
->hour 
== after
->hour 
&& 
 961         before
->min  
== after
->min  
&& 
 962         before
->sec   
> after
->sec  
) 
 968 int mbedtls_x509_time_is_past( const mbedtls_x509_time 
*to 
) 
 970     mbedtls_x509_time now
; 
 972     if( x509_get_current_time( &now 
) != 0 ) 
 975     return( x509_check_time( &now
, to 
) ); 
 978 int mbedtls_x509_time_is_future( const mbedtls_x509_time 
*from 
) 
 980     mbedtls_x509_time now
; 
 982     if( x509_get_current_time( &now 
) != 0 ) 
 985     return( x509_check_time( from
, &now 
) ); 
 988 #else  /* MBEDTLS_HAVE_TIME_DATE */ 
 990 int mbedtls_x509_time_is_past( const mbedtls_x509_time 
*to 
) 
 996 int mbedtls_x509_time_is_future( const mbedtls_x509_time 
*from 
) 
1001 #endif /* MBEDTLS_HAVE_TIME_DATE */ 
1003 #if defined(MBEDTLS_SELF_TEST) 
1005 #include "mbedtls/x509_crt.h" 
1006 #include "mbedtls/certs.h" 
1011 int mbedtls_x509_self_test( int verbose 
) 
1013 #if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C) 
1016     mbedtls_x509_crt cacert
; 
1017     mbedtls_x509_crt clicert
; 
1020         mbedtls_printf( "  X.509 certificate load: " ); 
1022     mbedtls_x509_crt_init( &clicert 
); 
1024     ret 
= mbedtls_x509_crt_parse( &clicert
, (const unsigned char *) mbedtls_test_cli_crt
, 
1025                            mbedtls_test_cli_crt_len 
); 
1029             mbedtls_printf( "failed\n" ); 
1034     mbedtls_x509_crt_init( &cacert 
); 
1036     ret 
= mbedtls_x509_crt_parse( &cacert
, (const unsigned char *) mbedtls_test_ca_crt
, 
1037                           mbedtls_test_ca_crt_len 
); 
1041             mbedtls_printf( "failed\n" ); 
1047         mbedtls_printf( "passed\n  X.509 signature verify: "); 
1049     ret 
= mbedtls_x509_crt_verify( &clicert
, &cacert
, NULL
, NULL
, &flags
, NULL
, NULL 
); 
1053             mbedtls_printf( "failed\n" ); 
1059         mbedtls_printf( "passed\n\n"); 
1061     mbedtls_x509_crt_free( &cacert  
); 
1062     mbedtls_x509_crt_free( &clicert 
); 
1068 #endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */ 
1071 #endif /* MBEDTLS_SELF_TEST */ 
1073 #endif /* MBEDTLS_X509_USE_C */