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.
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo 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_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 12:28:59 by
