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