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