Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
x509.c
00001 /* 00002 * X.509 common functions for parsing and verification 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 /* 00022 * The ITU-T X.509 standard defines a certificate format for PKI. 00023 * 00024 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) 00025 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) 00026 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) 00027 * 00028 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf 00029 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf 00030 */ 00031 00032 #if !defined(MBEDTLS_CONFIG_FILE) 00033 #include "mbedtls/config.h" 00034 #else 00035 #include MBEDTLS_CONFIG_FILE 00036 #endif 00037 00038 #if defined(MBEDTLS_X509_USE_C) 00039 00040 #include "mbedtls/x509.h" 00041 #include "mbedtls/asn1.h" 00042 #include "mbedtls/oid.h" 00043 00044 #include <stdio.h> 00045 #include <string.h> 00046 00047 #if defined(MBEDTLS_PEM_PARSE_C) 00048 #include "mbedtls/pem.h" 00049 #endif 00050 00051 #if defined(MBEDTLS_PLATFORM_C) 00052 #include "mbedtls/platform.h" 00053 #else 00054 #include <stdio.h> 00055 #include <stdlib.h> 00056 #define mbedtls_free free 00057 #define mbedtls_calloc calloc 00058 #define mbedtls_printf printf 00059 #define mbedtls_snprintf snprintf 00060 #endif 00061 00062 00063 #if defined(MBEDTLS_HAVE_TIME) 00064 #include "mbedtls/platform_time.h" 00065 #endif 00066 00067 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 00068 #include <windows.h> 00069 #else 00070 #include <time.h> 00071 #endif 00072 00073 #if defined(MBEDTLS_FS_IO) 00074 #include <stdio.h> 00075 #if !defined(_WIN32) 00076 #include <sys/types.h> 00077 #include <sys/stat.h> 00078 #include <dirent.h> 00079 #endif 00080 #endif 00081 00082 #define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); } 00083 #define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); } 00084 00085 /* 00086 * CertificateSerialNumber ::= INTEGER 00087 */ 00088 int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, 00089 mbedtls_x509_buf *serial ) 00090 { 00091 int ret; 00092 00093 if( ( end - *p ) < 1 ) 00094 return( MBEDTLS_ERR_X509_INVALID_SERIAL + 00095 MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00096 00097 if( **p != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2 ) && 00098 **p != MBEDTLS_ASN1_INTEGER ) 00099 return( MBEDTLS_ERR_X509_INVALID_SERIAL + 00100 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 00101 00102 serial->tag = *(*p)++; 00103 00104 if( ( ret = mbedtls_asn1_get_len( p, end, &serial->len ) ) != 0 ) 00105 return( MBEDTLS_ERR_X509_INVALID_SERIAL + ret ); 00106 00107 serial->p = *p; 00108 *p += serial->len; 00109 00110 return( 0 ); 00111 } 00112 00113 /* Get an algorithm identifier without parameters (eg for signatures) 00114 * 00115 * AlgorithmIdentifier ::= SEQUENCE { 00116 * algorithm OBJECT IDENTIFIER, 00117 * parameters ANY DEFINED BY algorithm OPTIONAL } 00118 */ 00119 int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, 00120 mbedtls_x509_buf *alg ) 00121 { 00122 int ret; 00123 00124 if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 ) 00125 return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); 00126 00127 return( 0 ); 00128 } 00129 00130 /* 00131 * Parse an algorithm identifier with (optional) paramaters 00132 */ 00133 int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, 00134 mbedtls_x509_buf *alg, mbedtls_x509_buf *params ) 00135 { 00136 int ret; 00137 00138 if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 ) 00139 return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); 00140 00141 return( 0 ); 00142 } 00143 00144 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 00145 /* 00146 * HashAlgorithm ::= AlgorithmIdentifier 00147 * 00148 * AlgorithmIdentifier ::= SEQUENCE { 00149 * algorithm OBJECT IDENTIFIER, 00150 * parameters ANY DEFINED BY algorithm OPTIONAL } 00151 * 00152 * For HashAlgorithm, parameters MUST be NULL or absent. 00153 */ 00154 static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg ) 00155 { 00156 int ret; 00157 unsigned char *p; 00158 const unsigned char *end; 00159 mbedtls_x509_buf md_oid; 00160 size_t len; 00161 00162 /* Make sure we got a SEQUENCE and setup bounds */ 00163 if( alg->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) 00164 return( MBEDTLS_ERR_X509_INVALID_ALG + 00165 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 00166 00167 p = (unsigned char *) alg->p; 00168 end = p + alg->len; 00169 00170 if( p >= end ) 00171 return( MBEDTLS_ERR_X509_INVALID_ALG + 00172 MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00173 00174 /* Parse md_oid */ 00175 md_oid.tag = *p; 00176 00177 if( ( ret = mbedtls_asn1_get_tag( &p, end, &md_oid.len, MBEDTLS_ASN1_OID ) ) != 0 ) 00178 return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); 00179 00180 md_oid.p = p; 00181 p += md_oid.len; 00182 00183 /* Get md_alg from md_oid */ 00184 if( ( ret = mbedtls_oid_get_md_alg( &md_oid, md_alg ) ) != 0 ) 00185 return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); 00186 00187 /* Make sure params is absent of NULL */ 00188 if( p == end ) 00189 return( 0 ); 00190 00191 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_NULL ) ) != 0 || len != 0 ) 00192 return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); 00193 00194 if( p != end ) 00195 return( MBEDTLS_ERR_X509_INVALID_ALG + 00196 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00197 00198 return( 0 ); 00199 } 00200 00201 /* 00202 * RSASSA-PSS-params ::= SEQUENCE { 00203 * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier, 00204 * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier, 00205 * saltLength [2] INTEGER DEFAULT 20, 00206 * trailerField [3] INTEGER DEFAULT 1 } 00207 * -- Note that the tags in this Sequence are explicit. 00208 * 00209 * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value 00210 * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other 00211 * option. Enfore this at parsing time. 00212 */ 00213 int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, 00214 mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, 00215 int *salt_len ) 00216 { 00217 int ret; 00218 unsigned char *p; 00219 const unsigned char *end, *end2; 00220 size_t len; 00221 mbedtls_x509_buf alg_id, alg_params; 00222 00223 /* First set everything to defaults */ 00224 *md_alg = MBEDTLS_MD_SHA1; 00225 *mgf_md = MBEDTLS_MD_SHA1; 00226 *salt_len = 20; 00227 00228 /* Make sure params is a SEQUENCE and setup bounds */ 00229 if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) 00230 return( MBEDTLS_ERR_X509_INVALID_ALG + 00231 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 00232 00233 p = (unsigned char *) params->p; 00234 end = p + params->len; 00235 00236 if( p == end ) 00237 return( 0 ); 00238 00239 /* 00240 * HashAlgorithm 00241 */ 00242 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00243 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 ) 00244 { 00245 end2 = p + len; 00246 00247 /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */ 00248 if( ( ret = mbedtls_x509_get_alg_null( &p, end2, &alg_id ) ) != 0 ) 00249 return( ret ); 00250 00251 if( ( ret = mbedtls_oid_get_md_alg( &alg_id, md_alg ) ) != 0 ) 00252 return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); 00253 00254 if( p != end2 ) 00255 return( MBEDTLS_ERR_X509_INVALID_ALG + 00256 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00257 } 00258 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 00259 return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); 00260 00261 if( p == end ) 00262 return( 0 ); 00263 00264 /* 00265 * MaskGenAlgorithm 00266 */ 00267 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00268 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 ) 00269 { 00270 end2 = p + len; 00271 00272 /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */ 00273 if( ( ret = mbedtls_x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 ) 00274 return( ret ); 00275 00276 /* Only MFG1 is recognised for now */ 00277 if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1, &alg_id ) != 0 ) 00278 return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE + 00279 MBEDTLS_ERR_OID_NOT_FOUND ); 00280 00281 /* Parse HashAlgorithm */ 00282 if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 ) 00283 return( ret ); 00284 00285 if( p != end2 ) 00286 return( MBEDTLS_ERR_X509_INVALID_ALG + 00287 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00288 } 00289 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 00290 return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); 00291 00292 if( p == end ) 00293 return( 0 ); 00294 00295 /* 00296 * salt_len 00297 */ 00298 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00299 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 2 ) ) == 0 ) 00300 { 00301 end2 = p + len; 00302 00303 if( ( ret = mbedtls_asn1_get_int( &p, end2, salt_len ) ) != 0 ) 00304 return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); 00305 00306 if( p != end2 ) 00307 return( MBEDTLS_ERR_X509_INVALID_ALG + 00308 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00309 } 00310 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 00311 return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); 00312 00313 if( p == end ) 00314 return( 0 ); 00315 00316 /* 00317 * trailer_field (if present, must be 1) 00318 */ 00319 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00320 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 3 ) ) == 0 ) 00321 { 00322 int trailer_field; 00323 00324 end2 = p + len; 00325 00326 if( ( ret = mbedtls_asn1_get_int( &p, end2, &trailer_field ) ) != 0 ) 00327 return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); 00328 00329 if( p != end2 ) 00330 return( MBEDTLS_ERR_X509_INVALID_ALG + 00331 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00332 00333 if( trailer_field != 1 ) 00334 return( MBEDTLS_ERR_X509_INVALID_ALG ); 00335 } 00336 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 00337 return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); 00338 00339 if( p != end ) 00340 return( MBEDTLS_ERR_X509_INVALID_ALG + 00341 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00342 00343 return( 0 ); 00344 } 00345 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 00346 00347 /* 00348 * AttributeTypeAndValue ::= SEQUENCE { 00349 * type AttributeType, 00350 * value AttributeValue } 00351 * 00352 * AttributeType ::= OBJECT IDENTIFIER 00353 * 00354 * AttributeValue ::= ANY DEFINED BY AttributeType 00355 */ 00356 static int x509_get_attr_type_value( unsigned char **p, 00357 const unsigned char *end, 00358 mbedtls_x509_name *cur ) 00359 { 00360 int ret; 00361 size_t len; 00362 mbedtls_x509_buf *oid; 00363 mbedtls_x509_buf *val; 00364 00365 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00366 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00367 return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); 00368 00369 if( ( end - *p ) < 1 ) 00370 return( MBEDTLS_ERR_X509_INVALID_NAME + 00371 MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00372 00373 oid = &cur->oid; 00374 oid->tag = **p; 00375 00376 if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 ) 00377 return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); 00378 00379 oid->p = *p; 00380 *p += oid->len; 00381 00382 if( ( end - *p ) < 1 ) 00383 return( MBEDTLS_ERR_X509_INVALID_NAME + 00384 MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00385 00386 if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING && 00387 **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING && 00388 **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING && 00389 **p != MBEDTLS_ASN1_BIT_STRING ) 00390 return( MBEDTLS_ERR_X509_INVALID_NAME + 00391 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 00392 00393 val = &cur->val; 00394 val->tag = *(*p)++; 00395 00396 if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 ) 00397 return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); 00398 00399 val->p = *p; 00400 *p += val->len; 00401 00402 cur->next = NULL; 00403 00404 return( 0 ); 00405 } 00406 00407 /* 00408 * Name ::= CHOICE { -- only one possibility for now -- 00409 * rdnSequence RDNSequence } 00410 * 00411 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName 00412 * 00413 * RelativeDistinguishedName ::= 00414 * SET OF AttributeTypeAndValue 00415 * 00416 * AttributeTypeAndValue ::= SEQUENCE { 00417 * type AttributeType, 00418 * value AttributeValue } 00419 * 00420 * AttributeType ::= OBJECT IDENTIFIER 00421 * 00422 * AttributeValue ::= ANY DEFINED BY AttributeType 00423 * 00424 * The data structure is optimized for the common case where each RDN has only 00425 * one element, which is represented as a list of AttributeTypeAndValue. 00426 * For the general case we still use a flat list, but we mark elements of the 00427 * same set so that they are "merged" together in the functions that consume 00428 * this list, eg mbedtls_x509_dn_gets(). 00429 */ 00430 int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, 00431 mbedtls_x509_name *cur ) 00432 { 00433 int ret; 00434 size_t set_len; 00435 const unsigned char *end_set; 00436 00437 /* don't use recursion, we'd risk stack overflow if not optimized */ 00438 while( 1 ) 00439 { 00440 /* 00441 * parse SET 00442 */ 00443 if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len, 00444 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 ) 00445 return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); 00446 00447 end_set = *p + set_len; 00448 00449 while( 1 ) 00450 { 00451 if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 ) 00452 return( ret ); 00453 00454 if( *p == end_set ) 00455 break; 00456 00457 /* Mark this item as being no the only one in a set */ 00458 cur->next_merged = 1; 00459 00460 cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); 00461 00462 if( cur->next == NULL ) 00463 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 00464 00465 cur = cur->next; 00466 } 00467 00468 /* 00469 * continue until end of SEQUENCE is reached 00470 */ 00471 if( *p == end ) 00472 return( 0 ); 00473 00474 cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); 00475 00476 if( cur->next == NULL ) 00477 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 00478 00479 cur = cur->next; 00480 } 00481 } 00482 00483 static int x509_parse_int( unsigned char **p, size_t n, int *res ) 00484 { 00485 *res = 0; 00486 00487 for( ; n > 0; --n ) 00488 { 00489 if( ( **p < '0') || ( **p > '9' ) ) 00490 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 00491 00492 *res *= 10; 00493 *res += ( *(*p)++ - '0' ); 00494 } 00495 00496 return( 0 ); 00497 } 00498 00499 static int x509_date_is_valid(const mbedtls_x509_time *t ) 00500 { 00501 int ret = MBEDTLS_ERR_X509_INVALID_DATE; 00502 int month_len; 00503 00504 CHECK_RANGE( 0, 9999, t->year ); 00505 CHECK_RANGE( 0, 23, t->hour ); 00506 CHECK_RANGE( 0, 59, t->min ); 00507 CHECK_RANGE( 0, 59, t->sec ); 00508 00509 switch( t->mon ) 00510 { 00511 case 1: case 3: case 5: case 7: case 8: case 10: case 12: 00512 month_len = 31; 00513 break; 00514 case 4: case 6: case 9: case 11: 00515 month_len = 30; 00516 break; 00517 case 2: 00518 if( ( !( t->year % 4 ) && t->year % 100 ) || 00519 !( t->year % 400 ) ) 00520 month_len = 29; 00521 else 00522 month_len = 28; 00523 break; 00524 default: 00525 return( ret ); 00526 } 00527 CHECK_RANGE( 1, month_len, t->day ); 00528 00529 return( 0 ); 00530 } 00531 00532 /* 00533 * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4) 00534 * field. 00535 */ 00536 static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen, 00537 mbedtls_x509_time *tm ) 00538 { 00539 int ret; 00540 00541 /* 00542 * Minimum length is 10 or 12 depending on yearlen 00543 */ 00544 if ( len < yearlen + 8 ) 00545 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 00546 len -= yearlen + 8; 00547 00548 /* 00549 * Parse year, month, day, hour, minute 00550 */ 00551 CHECK( x509_parse_int( p, yearlen, &tm->year ) ); 00552 if ( 2 == yearlen ) 00553 { 00554 if ( tm->year < 50 ) 00555 tm->year += 100; 00556 00557 tm->year += 1900; 00558 } 00559 00560 CHECK( x509_parse_int( p, 2, &tm->mon ) ); 00561 CHECK( x509_parse_int( p, 2, &tm->day ) ); 00562 CHECK( x509_parse_int( p, 2, &tm->hour ) ); 00563 CHECK( x509_parse_int( p, 2, &tm->min ) ); 00564 00565 /* 00566 * Parse seconds if present 00567 */ 00568 if ( len >= 2 ) 00569 { 00570 CHECK( x509_parse_int( p, 2, &tm->sec ) ); 00571 len -= 2; 00572 } 00573 else 00574 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 00575 00576 /* 00577 * Parse trailing 'Z' if present 00578 */ 00579 if ( 1 == len && 'Z' == **p ) 00580 { 00581 (*p)++; 00582 len--; 00583 } 00584 00585 /* 00586 * We should have parsed all characters at this point 00587 */ 00588 if ( 0 != len ) 00589 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 00590 00591 CHECK( x509_date_is_valid( tm ) ); 00592 00593 return ( 0 ); 00594 } 00595 00596 /* 00597 * Time ::= CHOICE { 00598 * utcTime UTCTime, 00599 * generalTime GeneralizedTime } 00600 */ 00601 int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, 00602 mbedtls_x509_time *tm ) 00603 { 00604 int ret; 00605 size_t len, year_len; 00606 unsigned char tag; 00607 00608 if( ( end - *p ) < 1 ) 00609 return( MBEDTLS_ERR_X509_INVALID_DATE + 00610 MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00611 00612 tag = **p; 00613 00614 if( tag == MBEDTLS_ASN1_UTC_TIME ) 00615 year_len = 2; 00616 else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME ) 00617 year_len = 4; 00618 else 00619 return( MBEDTLS_ERR_X509_INVALID_DATE + 00620 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 00621 00622 (*p)++; 00623 ret = mbedtls_asn1_get_len( p, end, &len ); 00624 00625 if( ret != 0 ) 00626 return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); 00627 00628 return x509_parse_time( p, len, year_len, tm ); 00629 } 00630 00631 int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ) 00632 { 00633 int ret; 00634 size_t len; 00635 int tag_type; 00636 00637 if( ( end - *p ) < 1 ) 00638 return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + 00639 MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00640 00641 tag_type = **p; 00642 00643 if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) 00644 return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret ); 00645 00646 sig->tag = tag_type; 00647 sig->len = len; 00648 sig->p = *p; 00649 00650 *p += len; 00651 00652 return( 0 ); 00653 } 00654 00655 /* 00656 * Get signature algorithm from alg OID and optional parameters 00657 */ 00658 int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, 00659 mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, 00660 void **sig_opts ) 00661 { 00662 int ret; 00663 00664 if( *sig_opts != NULL ) 00665 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 00666 00667 if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 ) 00668 return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret ); 00669 00670 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 00671 if( *pk_alg == MBEDTLS_PK_RSASSA_PSS ) 00672 { 00673 mbedtls_pk_rsassa_pss_options *pss_opts; 00674 00675 pss_opts = mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options ) ); 00676 if( pss_opts == NULL ) 00677 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 00678 00679 ret = mbedtls_x509_get_rsassa_pss_params( sig_params, 00680 md_alg, 00681 &pss_opts->mgf1_hash_id, 00682 &pss_opts->expected_salt_len ); 00683 if( ret != 0 ) 00684 { 00685 mbedtls_free( pss_opts ); 00686 return( ret ); 00687 } 00688 00689 *sig_opts = (void *) pss_opts; 00690 } 00691 else 00692 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 00693 { 00694 /* Make sure parameters are absent or NULL */ 00695 if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) || 00696 sig_params->len != 0 ) 00697 return( MBEDTLS_ERR_X509_INVALID_ALG ); 00698 } 00699 00700 return( 0 ); 00701 } 00702 00703 /* 00704 * X.509 Extensions (No parsing of extensions, pointer should 00705 * be either manually updated or extensions should be parsed!) 00706 */ 00707 int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, 00708 mbedtls_x509_buf *ext, int tag ) 00709 { 00710 int ret; 00711 size_t len; 00712 00713 if( *p == end ) 00714 return( 0 ); 00715 00716 ext->tag = **p; 00717 00718 if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len, 00719 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ) ) != 0 ) 00720 return( ret ); 00721 00722 ext->p = *p; 00723 end = *p + ext->len; 00724 00725 /* 00726 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 00727 * 00728 * Extension ::= SEQUENCE { 00729 * extnID OBJECT IDENTIFIER, 00730 * critical BOOLEAN DEFAULT FALSE, 00731 * extnValue OCTET STRING } 00732 */ 00733 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00734 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00735 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00736 00737 if( end != *p + len ) 00738 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00739 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00740 00741 return( 0 ); 00742 } 00743 00744 /* 00745 * Store the name in printable form into buf; no more 00746 * than size characters will be written 00747 */ 00748 int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn ) 00749 { 00750 int ret; 00751 size_t i, n; 00752 unsigned char c, merge = 0; 00753 const mbedtls_x509_name *name; 00754 const char *short_name = NULL; 00755 char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p; 00756 00757 memset( s, 0, sizeof( s ) ); 00758 00759 name = dn; 00760 p = buf; 00761 n = size; 00762 00763 while( name != NULL ) 00764 { 00765 if( !name->oid.p ) 00766 { 00767 name = name->next; 00768 continue; 00769 } 00770 00771 if( name != dn ) 00772 { 00773 ret = mbedtls_snprintf( p, n, merge ? " + " : ", " ); 00774 MBEDTLS_X509_SAFE_SNPRINTF; 00775 } 00776 00777 ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name ); 00778 00779 if( ret == 0 ) 00780 ret = mbedtls_snprintf( p, n, "%s=", short_name ); 00781 else 00782 ret = mbedtls_snprintf( p, n, "\?\?=" ); 00783 MBEDTLS_X509_SAFE_SNPRINTF; 00784 00785 for( i = 0; i < name->val.len; i++ ) 00786 { 00787 if( i >= sizeof( s ) - 1 ) 00788 break; 00789 00790 c = name->val.p[i]; 00791 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) 00792 s[i] = '?'; 00793 else s[i] = c; 00794 } 00795 s[i] = '\0'; 00796 ret = mbedtls_snprintf( p, n, "%s", s ); 00797 MBEDTLS_X509_SAFE_SNPRINTF; 00798 00799 merge = name->next_merged; 00800 name = name->next; 00801 } 00802 00803 return( (int) ( size - n ) ); 00804 } 00805 00806 /* 00807 * Store the serial in printable form into buf; no more 00808 * than size characters will be written 00809 */ 00810 int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial ) 00811 { 00812 int ret; 00813 size_t i, n, nr; 00814 char *p; 00815 00816 p = buf; 00817 n = size; 00818 00819 nr = ( serial->len <= 32 ) 00820 ? serial->len : 28; 00821 00822 for( i = 0; i < nr; i++ ) 00823 { 00824 if( i == 0 && nr > 1 && serial->p[i] == 0x0 ) 00825 continue; 00826 00827 ret = mbedtls_snprintf( p, n, "%02X%s", 00828 serial->p[i], ( i < nr - 1 ) ? ":" : "" ); 00829 MBEDTLS_X509_SAFE_SNPRINTF; 00830 } 00831 00832 if( nr != serial->len ) 00833 { 00834 ret = mbedtls_snprintf( p, n, "...." ); 00835 MBEDTLS_X509_SAFE_SNPRINTF; 00836 } 00837 00838 return( (int) ( size - n ) ); 00839 } 00840 00841 /* 00842 * Helper for writing signature algorithms 00843 */ 00844 int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, 00845 mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, 00846 const void *sig_opts ) 00847 { 00848 int ret; 00849 char *p = buf; 00850 size_t n = size; 00851 const char *desc = NULL; 00852 00853 ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc ); 00854 if( ret != 0 ) 00855 ret = mbedtls_snprintf( p, n, "???" ); 00856 else 00857 ret = mbedtls_snprintf( p, n, "%s", desc ); 00858 MBEDTLS_X509_SAFE_SNPRINTF; 00859 00860 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 00861 if( pk_alg == MBEDTLS_PK_RSASSA_PSS ) 00862 { 00863 const mbedtls_pk_rsassa_pss_options *pss_opts; 00864 const mbedtls_md_info_t *md_info, *mgf_md_info; 00865 00866 pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts; 00867 00868 md_info = mbedtls_md_info_from_type( md_alg ); 00869 mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id ); 00870 00871 ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)", 00872 md_info ? mbedtls_md_get_name( md_info ) : "???", 00873 mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???", 00874 pss_opts->expected_salt_len ); 00875 MBEDTLS_X509_SAFE_SNPRINTF; 00876 } 00877 #else 00878 ((void) pk_alg); 00879 ((void) md_alg); 00880 ((void) sig_opts); 00881 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 00882 00883 return( (int)( size - n ) ); 00884 } 00885 00886 /* 00887 * Helper for writing "RSA key size", "EC key size", etc 00888 */ 00889 int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ) 00890 { 00891 char *p = buf; 00892 size_t n = buf_size; 00893 int ret; 00894 00895 ret = mbedtls_snprintf( p, n, "%s key size", name ); 00896 MBEDTLS_X509_SAFE_SNPRINTF; 00897 00898 return( 0 ); 00899 } 00900 00901 #if defined(MBEDTLS_HAVE_TIME_DATE) 00902 /* 00903 * Set the time structure to the current time. 00904 * Return 0 on success, non-zero on failure. 00905 */ 00906 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 00907 static int x509_get_current_time( mbedtls_x509_time *now ) 00908 { 00909 SYSTEMTIME st; 00910 00911 GetSystemTime( &st ); 00912 00913 now->year = st.wYear; 00914 now->mon = st.wMonth; 00915 now->day = st.wDay; 00916 now->hour = st.wHour; 00917 now->min = st.wMinute; 00918 now->sec = st.wSecond; 00919 00920 return( 0 ); 00921 } 00922 #else 00923 static int x509_get_current_time( mbedtls_x509_time *now ) 00924 { 00925 struct tm *lt; 00926 mbedtls_time_t tt; 00927 int ret = 0; 00928 00929 #if defined(MBEDTLS_THREADING_C) 00930 if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 ) 00931 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 00932 #endif 00933 00934 tt = mbedtls_time( NULL ); 00935 lt = gmtime( &tt ); 00936 00937 if( lt == NULL ) 00938 ret = -1; 00939 else 00940 { 00941 now->year = lt->tm_year + 1900; 00942 now->mon = lt->tm_mon + 1; 00943 now->day = lt->tm_mday; 00944 now->hour = lt->tm_hour; 00945 now->min = lt->tm_min; 00946 now->sec = lt->tm_sec; 00947 } 00948 00949 #if defined(MBEDTLS_THREADING_C) 00950 if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 ) 00951 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 00952 #endif 00953 00954 return( ret ); 00955 } 00956 #endif /* _WIN32 && !EFIX64 && !EFI32 */ 00957 00958 /* 00959 * Return 0 if before <= after, 1 otherwise 00960 */ 00961 static int x509_check_time( const mbedtls_x509_time *before, const mbedtls_x509_time *after ) 00962 { 00963 if( before->year > after->year ) 00964 return( 1 ); 00965 00966 if( before->year == after->year && 00967 before->mon > after->mon ) 00968 return( 1 ); 00969 00970 if( before->year == after->year && 00971 before->mon == after->mon && 00972 before->day > after->day ) 00973 return( 1 ); 00974 00975 if( before->year == after->year && 00976 before->mon == after->mon && 00977 before->day == after->day && 00978 before->hour > after->hour ) 00979 return( 1 ); 00980 00981 if( before->year == after->year && 00982 before->mon == after->mon && 00983 before->day == after->day && 00984 before->hour == after->hour && 00985 before->min > after->min ) 00986 return( 1 ); 00987 00988 if( before->year == after->year && 00989 before->mon == after->mon && 00990 before->day == after->day && 00991 before->hour == after->hour && 00992 before->min == after->min && 00993 before->sec > after->sec ) 00994 return( 1 ); 00995 00996 return( 0 ); 00997 } 00998 00999 int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) 01000 { 01001 mbedtls_x509_time now; 01002 01003 if( x509_get_current_time( &now ) != 0 ) 01004 return( 1 ); 01005 01006 return( x509_check_time( &now, to ) ); 01007 } 01008 01009 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) 01010 { 01011 mbedtls_x509_time now; 01012 01013 if( x509_get_current_time( &now ) != 0 ) 01014 return( 1 ); 01015 01016 return( x509_check_time( from, &now ) ); 01017 } 01018 01019 #else /* MBEDTLS_HAVE_TIME_DATE */ 01020 01021 int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) 01022 { 01023 ((void) to); 01024 return( 0 ); 01025 } 01026 01027 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) 01028 { 01029 ((void) from); 01030 return( 0 ); 01031 } 01032 #endif /* MBEDTLS_HAVE_TIME_DATE */ 01033 01034 #if defined(MBEDTLS_SELF_TEST) 01035 01036 #include "mbedtls/x509_crt.h" 01037 #include "mbedtls/certs.h" 01038 01039 /* 01040 * Checkup routine 01041 */ 01042 int mbedtls_x509_self_test( int verbose ) 01043 { 01044 #if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C) 01045 int ret; 01046 uint32_t flags; 01047 mbedtls_x509_crt cacert; 01048 mbedtls_x509_crt clicert; 01049 01050 if( verbose != 0 ) 01051 mbedtls_printf( " X.509 certificate load: " ); 01052 01053 mbedtls_x509_crt_init( &clicert ); 01054 01055 ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt, 01056 mbedtls_test_cli_crt_len ); 01057 if( ret != 0 ) 01058 { 01059 if( verbose != 0 ) 01060 mbedtls_printf( "failed\n" ); 01061 01062 return( ret ); 01063 } 01064 01065 mbedtls_x509_crt_init( &cacert ); 01066 01067 ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt, 01068 mbedtls_test_ca_crt_len ); 01069 if( ret != 0 ) 01070 { 01071 if( verbose != 0 ) 01072 mbedtls_printf( "failed\n" ); 01073 01074 return( ret ); 01075 } 01076 01077 if( verbose != 0 ) 01078 mbedtls_printf( "passed\n X.509 signature verify: "); 01079 01080 ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL ); 01081 if( ret != 0 ) 01082 { 01083 if( verbose != 0 ) 01084 mbedtls_printf( "failed\n" ); 01085 01086 return( ret ); 01087 } 01088 01089 if( verbose != 0 ) 01090 mbedtls_printf( "passed\n\n"); 01091 01092 mbedtls_x509_crt_free( &cacert ); 01093 mbedtls_x509_crt_free( &clicert ); 01094 01095 return( 0 ); 01096 #else 01097 ((void) verbose); 01098 return( 0 ); 01099 #endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */ 01100 } 01101 01102 #endif /* MBEDTLS_SELF_TEST */ 01103 01104 #endif /* MBEDTLS_X509_USE_C */
Generated on Tue Jul 12 2022 12:46:19 by
