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.
Fork of mbedtls by
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 00503 CHECK_RANGE( 0, 9999, t->year ); 00504 CHECK_RANGE( 0, 23, t->hour ); 00505 CHECK_RANGE( 0, 59, t->min ); 00506 CHECK_RANGE( 0, 59, t->sec ); 00507 00508 switch( t->mon ) 00509 { 00510 case 1: case 3: case 5: case 7: case 8: case 10: case 12: 00511 CHECK_RANGE( 1, 31, t->day ); 00512 break; 00513 case 4: case 6: case 9: case 11: 00514 CHECK_RANGE( 1, 30, t->day ); 00515 break; 00516 case 2: 00517 CHECK_RANGE( 1, 28 + (t->year % 4 == 0), t->day ); 00518 break; 00519 default: 00520 return( ret ); 00521 } 00522 00523 return( 0 ); 00524 } 00525 00526 /* 00527 * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4) 00528 * field. 00529 */ 00530 static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen, 00531 mbedtls_x509_time *tm ) 00532 { 00533 int ret; 00534 00535 /* 00536 * Minimum length is 10 or 12 depending on yearlen 00537 */ 00538 if ( len < yearlen + 8 ) 00539 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 00540 len -= yearlen + 8; 00541 00542 /* 00543 * Parse year, month, day, hour, minute 00544 */ 00545 CHECK( x509_parse_int( p, yearlen, &tm->year ) ); 00546 if ( 2 == yearlen ) 00547 { 00548 if ( tm->year < 50 ) 00549 tm->year += 100; 00550 00551 tm->year += 1900; 00552 } 00553 00554 CHECK( x509_parse_int( p, 2, &tm->mon ) ); 00555 CHECK( x509_parse_int( p, 2, &tm->day ) ); 00556 CHECK( x509_parse_int( p, 2, &tm->hour ) ); 00557 CHECK( x509_parse_int( p, 2, &tm->min ) ); 00558 00559 /* 00560 * Parse seconds if present 00561 */ 00562 if ( len >= 2 ) 00563 { 00564 CHECK( x509_parse_int( p, 2, &tm->sec ) ); 00565 len -= 2; 00566 } 00567 else 00568 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 00569 00570 /* 00571 * Parse trailing 'Z' if present 00572 */ 00573 if ( 1 == len && 'Z' == **p ) 00574 { 00575 (*p)++; 00576 len--; 00577 } 00578 00579 /* 00580 * We should have parsed all characters at this point 00581 */ 00582 if ( 0 != len ) 00583 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 00584 00585 CHECK( x509_date_is_valid( tm ) ); 00586 00587 return ( 0 ); 00588 } 00589 00590 /* 00591 * Time ::= CHOICE { 00592 * utcTime UTCTime, 00593 * generalTime GeneralizedTime } 00594 */ 00595 int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, 00596 mbedtls_x509_time *tm ) 00597 { 00598 int ret; 00599 size_t len, year_len; 00600 unsigned char tag; 00601 00602 if( ( end - *p ) < 1 ) 00603 return( MBEDTLS_ERR_X509_INVALID_DATE + 00604 MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00605 00606 tag = **p; 00607 00608 if( tag == MBEDTLS_ASN1_UTC_TIME ) 00609 year_len = 2; 00610 else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME ) 00611 year_len = 4; 00612 else 00613 return( MBEDTLS_ERR_X509_INVALID_DATE + 00614 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 00615 00616 (*p)++; 00617 ret = mbedtls_asn1_get_len( p, end, &len ); 00618 00619 if( ret != 0 ) 00620 return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); 00621 00622 return x509_parse_time( p, len, year_len, tm ); 00623 } 00624 00625 int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ) 00626 { 00627 int ret; 00628 size_t len; 00629 int tag_type; 00630 00631 if( ( end - *p ) < 1 ) 00632 return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + 00633 MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00634 00635 tag_type = **p; 00636 00637 if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) 00638 return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret ); 00639 00640 sig->tag = tag_type; 00641 sig->len = len; 00642 sig->p = *p; 00643 00644 *p += len; 00645 00646 return( 0 ); 00647 } 00648 00649 /* 00650 * Get signature algorithm from alg OID and optional parameters 00651 */ 00652 int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, 00653 mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, 00654 void **sig_opts ) 00655 { 00656 int ret; 00657 00658 if( *sig_opts != NULL ) 00659 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 00660 00661 if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 ) 00662 return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret ); 00663 00664 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 00665 if( *pk_alg == MBEDTLS_PK_RSASSA_PSS ) 00666 { 00667 mbedtls_pk_rsassa_pss_options *pss_opts; 00668 00669 pss_opts = mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options ) ); 00670 if( pss_opts == NULL ) 00671 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 00672 00673 ret = mbedtls_x509_get_rsassa_pss_params( sig_params, 00674 md_alg, 00675 &pss_opts->mgf1_hash_id, 00676 &pss_opts->expected_salt_len ); 00677 if( ret != 0 ) 00678 { 00679 mbedtls_free( pss_opts ); 00680 return( ret ); 00681 } 00682 00683 *sig_opts = (void *) pss_opts; 00684 } 00685 else 00686 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 00687 { 00688 /* Make sure parameters are absent or NULL */ 00689 if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) || 00690 sig_params->len != 0 ) 00691 return( MBEDTLS_ERR_X509_INVALID_ALG ); 00692 } 00693 00694 return( 0 ); 00695 } 00696 00697 /* 00698 * X.509 Extensions (No parsing of extensions, pointer should 00699 * be either manually updated or extensions should be parsed!) 00700 */ 00701 int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, 00702 mbedtls_x509_buf *ext, int tag ) 00703 { 00704 int ret; 00705 size_t len; 00706 00707 if( *p == end ) 00708 return( 0 ); 00709 00710 ext->tag = **p; 00711 00712 if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len, 00713 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ) ) != 0 ) 00714 return( ret ); 00715 00716 ext->p = *p; 00717 end = *p + ext->len; 00718 00719 /* 00720 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 00721 * 00722 * Extension ::= SEQUENCE { 00723 * extnID OBJECT IDENTIFIER, 00724 * critical BOOLEAN DEFAULT FALSE, 00725 * extnValue OCTET STRING } 00726 */ 00727 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00728 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00729 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00730 00731 if( end != *p + len ) 00732 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00733 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00734 00735 return( 0 ); 00736 } 00737 00738 /* 00739 * Store the name in printable form into buf; no more 00740 * than size characters will be written 00741 */ 00742 int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn ) 00743 { 00744 int ret; 00745 size_t i, n; 00746 unsigned char c, merge = 0; 00747 const mbedtls_x509_name *name; 00748 const char *short_name = NULL; 00749 char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p; 00750 00751 memset( s, 0, sizeof( s ) ); 00752 00753 name = dn; 00754 p = buf; 00755 n = size; 00756 00757 while( name != NULL ) 00758 { 00759 if( !name->oid.p ) 00760 { 00761 name = name->next; 00762 continue; 00763 } 00764 00765 if( name != dn ) 00766 { 00767 ret = mbedtls_snprintf( p, n, merge ? " + " : ", " ); 00768 MBEDTLS_X509_SAFE_SNPRINTF; 00769 } 00770 00771 ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name ); 00772 00773 if( ret == 0 ) 00774 ret = mbedtls_snprintf( p, n, "%s=", short_name ); 00775 else 00776 ret = mbedtls_snprintf( p, n, "\?\?=" ); 00777 MBEDTLS_X509_SAFE_SNPRINTF; 00778 00779 for( i = 0; i < name->val.len; i++ ) 00780 { 00781 if( i >= sizeof( s ) - 1 ) 00782 break; 00783 00784 c = name->val.p[i]; 00785 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) 00786 s[i] = '?'; 00787 else s[i] = c; 00788 } 00789 s[i] = '\0'; 00790 ret = mbedtls_snprintf( p, n, "%s", s ); 00791 MBEDTLS_X509_SAFE_SNPRINTF; 00792 00793 merge = name->next_merged; 00794 name = name->next; 00795 } 00796 00797 return( (int) ( size - n ) ); 00798 } 00799 00800 /* 00801 * Store the serial in printable form into buf; no more 00802 * than size characters will be written 00803 */ 00804 int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial ) 00805 { 00806 int ret; 00807 size_t i, n, nr; 00808 char *p; 00809 00810 p = buf; 00811 n = size; 00812 00813 nr = ( serial->len <= 32 ) 00814 ? serial->len : 28; 00815 00816 for( i = 0; i < nr; i++ ) 00817 { 00818 if( i == 0 && nr > 1 && serial->p[i] == 0x0 ) 00819 continue; 00820 00821 ret = mbedtls_snprintf( p, n, "%02X%s", 00822 serial->p[i], ( i < nr - 1 ) ? ":" : "" ); 00823 MBEDTLS_X509_SAFE_SNPRINTF; 00824 } 00825 00826 if( nr != serial->len ) 00827 { 00828 ret = mbedtls_snprintf( p, n, "...." ); 00829 MBEDTLS_X509_SAFE_SNPRINTF; 00830 } 00831 00832 return( (int) ( size - n ) ); 00833 } 00834 00835 /* 00836 * Helper for writing signature algorithms 00837 */ 00838 int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, 00839 mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, 00840 const void *sig_opts ) 00841 { 00842 int ret; 00843 char *p = buf; 00844 size_t n = size; 00845 const char *desc = NULL; 00846 00847 ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc ); 00848 if( ret != 0 ) 00849 ret = mbedtls_snprintf( p, n, "???" ); 00850 else 00851 ret = mbedtls_snprintf( p, n, "%s", desc ); 00852 MBEDTLS_X509_SAFE_SNPRINTF; 00853 00854 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 00855 if( pk_alg == MBEDTLS_PK_RSASSA_PSS ) 00856 { 00857 const mbedtls_pk_rsassa_pss_options *pss_opts; 00858 const mbedtls_md_info_t *md_info, *mgf_md_info; 00859 00860 pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts; 00861 00862 md_info = mbedtls_md_info_from_type( md_alg ); 00863 mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id ); 00864 00865 ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)", 00866 md_info ? mbedtls_md_get_name( md_info ) : "???", 00867 mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???", 00868 pss_opts->expected_salt_len ); 00869 MBEDTLS_X509_SAFE_SNPRINTF; 00870 } 00871 #else 00872 ((void) pk_alg); 00873 ((void) md_alg); 00874 ((void) sig_opts); 00875 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 00876 00877 return( (int)( size - n ) ); 00878 } 00879 00880 /* 00881 * Helper for writing "RSA key size", "EC key size", etc 00882 */ 00883 int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ) 00884 { 00885 char *p = buf; 00886 size_t n = buf_size; 00887 int ret; 00888 00889 ret = mbedtls_snprintf( p, n, "%s key size", name ); 00890 MBEDTLS_X509_SAFE_SNPRINTF; 00891 00892 return( 0 ); 00893 } 00894 00895 #if defined(MBEDTLS_HAVE_TIME_DATE) 00896 /* 00897 * Set the time structure to the current time. 00898 * Return 0 on success, non-zero on failure. 00899 */ 00900 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 00901 static int x509_get_current_time( mbedtls_x509_time *now ) 00902 { 00903 SYSTEMTIME st; 00904 00905 GetSystemTime( &st ); 00906 00907 now->year = st.wYear; 00908 now->mon = st.wMonth; 00909 now->day = st.wDay; 00910 now->hour = st.wHour; 00911 now->min = st.wMinute; 00912 now->sec = st.wSecond; 00913 00914 return( 0 ); 00915 } 00916 #else 00917 static int x509_get_current_time( mbedtls_x509_time *now ) 00918 { 00919 struct tm *lt; 00920 mbedtls_time_t tt; 00921 int ret = 0; 00922 00923 #if defined(MBEDTLS_THREADING_C) 00924 if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 ) 00925 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 00926 #endif 00927 00928 tt = mbedtls_time( NULL ); 00929 lt = gmtime( &tt ); 00930 00931 if( lt == NULL ) 00932 ret = -1; 00933 else 00934 { 00935 now->year = lt->tm_year + 1900; 00936 now->mon = lt->tm_mon + 1; 00937 now->day = lt->tm_mday; 00938 now->hour = lt->tm_hour; 00939 now->min = lt->tm_min; 00940 now->sec = lt->tm_sec; 00941 } 00942 00943 #if defined(MBEDTLS_THREADING_C) 00944 if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 ) 00945 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 00946 #endif 00947 00948 return( ret ); 00949 } 00950 #endif /* _WIN32 && !EFIX64 && !EFI32 */ 00951 00952 /* 00953 * Return 0 if before <= after, 1 otherwise 00954 */ 00955 static int x509_check_time( const mbedtls_x509_time *before, const mbedtls_x509_time *after ) 00956 { 00957 if( before->year > after->year ) 00958 return( 1 ); 00959 00960 if( before->year == after->year && 00961 before->mon > after->mon ) 00962 return( 1 ); 00963 00964 if( before->year == after->year && 00965 before->mon == after->mon && 00966 before->day > after->day ) 00967 return( 1 ); 00968 00969 if( before->year == after->year && 00970 before->mon == after->mon && 00971 before->day == after->day && 00972 before->hour > after->hour ) 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 before->min > after->min ) 00980 return( 1 ); 00981 00982 if( before->year == after->year && 00983 before->mon == after->mon && 00984 before->day == after->day && 00985 before->hour == after->hour && 00986 before->min == after->min && 00987 before->sec > after->sec ) 00988 return( 1 ); 00989 00990 return( 0 ); 00991 } 00992 00993 int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) 00994 { 00995 mbedtls_x509_time now; 00996 00997 if( x509_get_current_time( &now ) != 0 ) 00998 return( 1 ); 00999 01000 return( x509_check_time( &now, to ) ); 01001 } 01002 01003 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) 01004 { 01005 mbedtls_x509_time now; 01006 01007 if( x509_get_current_time( &now ) != 0 ) 01008 return( 1 ); 01009 01010 return( x509_check_time( from, &now ) ); 01011 } 01012 01013 #else /* MBEDTLS_HAVE_TIME_DATE */ 01014 01015 int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) 01016 { 01017 ((void) to); 01018 return( 0 ); 01019 } 01020 01021 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) 01022 { 01023 ((void) from); 01024 return( 0 ); 01025 } 01026 #endif /* MBEDTLS_HAVE_TIME_DATE */ 01027 01028 #if defined(MBEDTLS_SELF_TEST) 01029 01030 #include "mbedtls/x509_crt.h" 01031 #include "mbedtls/certs.h" 01032 01033 /* 01034 * Checkup routine 01035 */ 01036 int mbedtls_x509_self_test( int verbose ) 01037 { 01038 #if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C) 01039 int ret; 01040 uint32_t flags; 01041 mbedtls_x509_crt cacert; 01042 mbedtls_x509_crt clicert; 01043 01044 if( verbose != 0 ) 01045 mbedtls_printf( " X.509 certificate load: " ); 01046 01047 mbedtls_x509_crt_init( &clicert ); 01048 01049 ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt, 01050 mbedtls_test_cli_crt_len ); 01051 if( ret != 0 ) 01052 { 01053 if( verbose != 0 ) 01054 mbedtls_printf( "failed\n" ); 01055 01056 return( ret ); 01057 } 01058 01059 mbedtls_x509_crt_init( &cacert ); 01060 01061 ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt, 01062 mbedtls_test_ca_crt_len ); 01063 if( ret != 0 ) 01064 { 01065 if( verbose != 0 ) 01066 mbedtls_printf( "failed\n" ); 01067 01068 return( ret ); 01069 } 01070 01071 if( verbose != 0 ) 01072 mbedtls_printf( "passed\n X.509 signature verify: "); 01073 01074 ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL ); 01075 if( ret != 0 ) 01076 { 01077 if( verbose != 0 ) 01078 mbedtls_printf( "failed\n" ); 01079 01080 return( ret ); 01081 } 01082 01083 if( verbose != 0 ) 01084 mbedtls_printf( "passed\n\n"); 01085 01086 mbedtls_x509_crt_free( &cacert ); 01087 mbedtls_x509_crt_free( &clicert ); 01088 01089 return( 0 ); 01090 #else 01091 ((void) verbose); 01092 return( 0 ); 01093 #endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */ 01094 } 01095 01096 #endif /* MBEDTLS_SELF_TEST */ 01097 01098 #endif /* MBEDTLS_X509_USE_C */
Generated on Tue Jul 12 2022 17:25:43 by
