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