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