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.
Dependents: mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510
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 11:03:00 by
