Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
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, size_t n, int *res ) 00484 { 00485 *res = 0; 00486 00487 for( ; n > 0; --n ) 00488 { 00489 if( ( **p < '0') || ( **p > '9' ) ) 00490 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 00491 00492 *res *= 10; 00493 *res += ( *(*p)++ - '0' ); 00494 } 00495 00496 return( 0 ); 00497 } 00498 00499 static int x509_date_is_valid(const mbedtls_x509_time *t) 00500 { 00501 int ret = MBEDTLS_ERR_X509_INVALID_DATE; 00502 00503 CHECK_RANGE( 0, 9999, t->year ); 00504 CHECK_RANGE( 0, 23, t->hour ); 00505 CHECK_RANGE( 0, 59, t->min ); 00506 CHECK_RANGE( 0, 59, t->sec ); 00507 00508 switch( t->mon ) 00509 { 00510 case 1: case 3: case 5: case 7: case 8: case 10: case 12: 00511 CHECK_RANGE( 1, 31, t->day ); 00512 break; 00513 case 4: case 6: case 9: case 11: 00514 CHECK_RANGE( 1, 30, t->day ); 00515 break; 00516 case 2: 00517 CHECK_RANGE( 1, 28 + (t->year % 4 == 0), t->day ); 00518 break; 00519 default: 00520 return( ret ); 00521 } 00522 00523 return( 0 ); 00524 } 00525 00526 /* 00527 * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4) 00528 * field. 00529 */ 00530 static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen, 00531 mbedtls_x509_time *tm ) 00532 { 00533 int ret; 00534 00535 /* 00536 * Minimum length is 10 or 12 depending on yearlen 00537 */ 00538 if ( len < yearlen + 8 ) 00539 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 00540 len -= yearlen + 8; 00541 00542 /* 00543 * Parse year, month, day, hour, minute 00544 */ 00545 CHECK( x509_parse_int( p, yearlen, &tm->year ) ); 00546 if ( 2 == yearlen ) 00547 { 00548 if ( tm->year < 50 ) 00549 tm->year += 100; 00550 00551 tm->year += 1900; 00552 } 00553 00554 CHECK( x509_parse_int( p, 2, &tm->mon ) ); 00555 CHECK( x509_parse_int( p, 2, &tm->day ) ); 00556 CHECK( x509_parse_int( p, 2, &tm->hour ) ); 00557 CHECK( x509_parse_int( p, 2, &tm->min ) ); 00558 00559 /* 00560 * Parse seconds if present 00561 */ 00562 if ( len >= 2 ) 00563 { 00564 CHECK( x509_parse_int( p, 2, &tm->sec ) ); 00565 len -= 2; 00566 } 00567 else 00568 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 00569 00570 /* 00571 * Parse trailing 'Z' if present 00572 */ 00573 if ( 1 == len && 'Z' == **p ) 00574 { 00575 (*p)++; 00576 len--; 00577 } 00578 00579 /* 00580 * We should have parsed all characters at this point 00581 */ 00582 if ( 0 != len ) 00583 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 00584 00585 CHECK( x509_date_is_valid( tm ) ); 00586 00587 return ( 0 ); 00588 } 00589 00590 /* 00591 * Time ::= CHOICE { 00592 * utcTime UTCTime, 00593 * generalTime GeneralizedTime } 00594 */ 00595 int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, 00596 mbedtls_x509_time *tm ) 00597 { 00598 int ret; 00599 size_t len, year_len; 00600 unsigned char tag; 00601 00602 if( ( end - *p ) < 1 ) 00603 return( MBEDTLS_ERR_X509_INVALID_DATE + 00604 MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00605 00606 tag = **p; 00607 00608 if( tag == MBEDTLS_ASN1_UTC_TIME ) 00609 year_len = 2; 00610 else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME ) 00611 year_len = 4; 00612 else 00613 return( MBEDTLS_ERR_X509_INVALID_DATE + 00614 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 00615 00616 (*p)++; 00617 ret = mbedtls_asn1_get_len( p, end, &len ); 00618 00619 if( ret != 0 ) 00620 return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); 00621 00622 return x509_parse_time( p, len, year_len, tm ); 00623 } 00624 00625 int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ) 00626 { 00627 int ret; 00628 size_t len; 00629 int tag_type; 00630 00631 if( ( end - *p ) < 1 ) 00632 return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + 00633 MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00634 00635 tag_type = **p; 00636 00637 if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) 00638 return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret ); 00639 00640 sig->tag = tag_type; 00641 sig->len = len; 00642 sig->p = *p; 00643 00644 *p += len; 00645 00646 return( 0 ); 00647 } 00648 00649 /* 00650 * Get signature algorithm from alg OID and optional parameters 00651 */ 00652 int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, 00653 mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, 00654 void **sig_opts ) 00655 { 00656 int ret; 00657 00658 if( *sig_opts != NULL ) 00659 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 00660 00661 if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 ) 00662 return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret ); 00663 00664 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 00665 if( *pk_alg == MBEDTLS_PK_RSASSA_PSS ) 00666 { 00667 mbedtls_pk_rsassa_pss_options *pss_opts; 00668 00669 pss_opts = mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options ) ); 00670 if( pss_opts == NULL ) 00671 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 00672 00673 ret = mbedtls_x509_get_rsassa_pss_params( sig_params, 00674 md_alg, 00675 &pss_opts->mgf1_hash_id, 00676 &pss_opts->expected_salt_len ); 00677 if( ret != 0 ) 00678 { 00679 mbedtls_free( pss_opts ); 00680 return( ret ); 00681 } 00682 00683 *sig_opts = (void *) pss_opts; 00684 } 00685 else 00686 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 00687 { 00688 /* Make sure parameters are absent or NULL */ 00689 if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) || 00690 sig_params->len != 0 ) 00691 return( MBEDTLS_ERR_X509_INVALID_ALG ); 00692 } 00693 00694 return( 0 ); 00695 } 00696 00697 /* 00698 * X.509 Extensions (No parsing of extensions, pointer should 00699 * be either manually updated or extensions should be parsed!) 00700 */ 00701 int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, 00702 mbedtls_x509_buf *ext, int tag ) 00703 { 00704 int ret; 00705 size_t len; 00706 00707 if( *p == end ) 00708 return( 0 ); 00709 00710 ext->tag = **p; 00711 00712 if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len, 00713 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ) ) != 0 ) 00714 return( ret ); 00715 00716 ext->p = *p; 00717 end = *p + ext->len; 00718 00719 /* 00720 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 00721 * 00722 * Extension ::= SEQUENCE { 00723 * extnID OBJECT IDENTIFIER, 00724 * critical BOOLEAN DEFAULT FALSE, 00725 * extnValue OCTET STRING } 00726 */ 00727 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00728 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00729 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00730 00731 if( end != *p + len ) 00732 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00733 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00734 00735 return( 0 ); 00736 } 00737 00738 /* 00739 * Store the name in printable form into buf; no more 00740 * than size characters will be written 00741 */ 00742 int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn ) 00743 { 00744 int ret; 00745 size_t i, n; 00746 unsigned char c, merge = 0; 00747 const mbedtls_x509_name *name; 00748 const char *short_name = NULL; 00749 char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p; 00750 00751 memset( s, 0, sizeof( s ) ); 00752 00753 name = dn; 00754 p = buf; 00755 n = size; 00756 00757 while( name != NULL ) 00758 { 00759 if( !name->oid.p ) 00760 { 00761 name = name->next; 00762 continue; 00763 } 00764 00765 if( name != dn ) 00766 { 00767 ret = mbedtls_snprintf( p, n, merge ? " + " : ", " ); 00768 MBEDTLS_X509_SAFE_SNPRINTF; 00769 } 00770 00771 ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name ); 00772 00773 if( ret == 0 ) 00774 ret = mbedtls_snprintf( p, n, "%s=", short_name ); 00775 else 00776 ret = mbedtls_snprintf( p, n, "\?\?=" ); 00777 MBEDTLS_X509_SAFE_SNPRINTF; 00778 00779 for( i = 0; i < name->val.len; i++ ) 00780 { 00781 if( i >= sizeof( s ) - 1 ) 00782 break; 00783 00784 c = name->val.p[i]; 00785 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) 00786 s[i] = '?'; 00787 else s[i] = c; 00788 } 00789 s[i] = '\0'; 00790 ret = mbedtls_snprintf( p, n, "%s", s ); 00791 MBEDTLS_X509_SAFE_SNPRINTF; 00792 00793 merge = name->next_merged; 00794 name = name->next; 00795 } 00796 00797 return( (int) ( size - n ) ); 00798 } 00799 00800 /* 00801 * Store the serial in printable form into buf; no more 00802 * than size characters will be written 00803 */ 00804 int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial ) 00805 { 00806 int ret; 00807 size_t i, n, nr; 00808 char *p; 00809 00810 p = buf; 00811 n = size; 00812 00813 nr = ( serial->len <= 32 ) 00814 ? serial->len : 28; 00815 00816 for( i = 0; i < nr; i++ ) 00817 { 00818 if( i == 0 && nr > 1 && serial->p[i] == 0x0 ) 00819 continue; 00820 00821 ret = mbedtls_snprintf( p, n, "%02X%s", 00822 serial->p[i], ( i < nr - 1 ) ? ":" : "" ); 00823 MBEDTLS_X509_SAFE_SNPRINTF; 00824 } 00825 00826 if( nr != serial->len ) 00827 { 00828 ret = mbedtls_snprintf( p, n, "...." ); 00829 MBEDTLS_X509_SAFE_SNPRINTF; 00830 } 00831 00832 return( (int) ( size - n ) ); 00833 } 00834 00835 /* 00836 * Helper for writing signature algorithms 00837 */ 00838 int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, 00839 mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, 00840 const void *sig_opts ) 00841 { 00842 int ret; 00843 char *p = buf; 00844 size_t n = size; 00845 const char *desc = NULL; 00846 00847 ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc ); 00848 if( ret != 0 ) 00849 ret = mbedtls_snprintf( p, n, "???" ); 00850 else 00851 ret = mbedtls_snprintf( p, n, "%s", desc ); 00852 MBEDTLS_X509_SAFE_SNPRINTF; 00853 00854 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 00855 if( pk_alg == MBEDTLS_PK_RSASSA_PSS ) 00856 { 00857 const mbedtls_pk_rsassa_pss_options *pss_opts; 00858 const mbedtls_md_info_t *md_info, *mgf_md_info; 00859 00860 pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts; 00861 00862 md_info = mbedtls_md_info_from_type( md_alg ); 00863 mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id ); 00864 00865 ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)", 00866 md_info ? mbedtls_md_get_name( md_info ) : "???", 00867 mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???", 00868 pss_opts->expected_salt_len ); 00869 MBEDTLS_X509_SAFE_SNPRINTF; 00870 } 00871 #else 00872 ((void) pk_alg); 00873 ((void) md_alg); 00874 ((void) sig_opts); 00875 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 00876 00877 return( (int)( size - n ) ); 00878 } 00879 00880 /* 00881 * Helper for writing "RSA key size", "EC key size", etc 00882 */ 00883 int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ) 00884 { 00885 char *p = buf; 00886 size_t n = buf_size; 00887 int ret; 00888 00889 ret = mbedtls_snprintf( p, n, "%s key size", name ); 00890 MBEDTLS_X509_SAFE_SNPRINTF; 00891 00892 return( 0 ); 00893 } 00894 00895 #if defined(MBEDTLS_HAVE_TIME_DATE) 00896 /* 00897 * Set the time structure to the current time. 00898 * Return 0 on success, non-zero on failure. 00899 */ 00900 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 00901 static int x509_get_current_time( mbedtls_x509_time *now ) 00902 { 00903 SYSTEMTIME st; 00904 00905 GetSystemTime( &st ); 00906 00907 now->year = st.wYear; 00908 now->mon = st.wMonth; 00909 now->day = st.wDay; 00910 now->hour = st.wHour; 00911 now->min = st.wMinute; 00912 now->sec = st.wSecond; 00913 00914 return( 0 ); 00915 } 00916 #else 00917 static int x509_get_current_time( mbedtls_x509_time *now ) 00918 { 00919 struct tm *lt; 00920 mbedtls_time_t tt; 00921 int ret = 0; 00922 00923 #if defined(MBEDTLS_THREADING_C) 00924 if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 ) 00925 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 00926 #endif 00927 00928 tt = mbedtls_time( NULL ); 00929 lt = gmtime( &tt ); 00930 00931 if( lt == NULL ) 00932 ret = -1; 00933 else 00934 { 00935 now->year = lt->tm_year + 1900; 00936 now->mon = lt->tm_mon + 1; 00937 now->day = lt->tm_mday; 00938 now->hour = lt->tm_hour; 00939 now->min = lt->tm_min; 00940 now->sec = lt->tm_sec; 00941 } 00942 00943 #if defined(MBEDTLS_THREADING_C) 00944 if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 ) 00945 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 00946 #endif 00947 00948 return( ret ); 00949 } 00950 #endif /* _WIN32 && !EFIX64 && !EFI32 */ 00951 00952 /* 00953 * Return 0 if before <= after, 1 otherwise 00954 */ 00955 static int x509_check_time( const mbedtls_x509_time *before, const mbedtls_x509_time *after ) 00956 { 00957 if( before->year > after->year ) 00958 return( 1 ); 00959 00960 if( before->year == after->year && 00961 before->mon > after->mon ) 00962 return( 1 ); 00963 00964 if( before->year == after->year && 00965 before->mon == after->mon && 00966 before->day > after->day ) 00967 return( 1 ); 00968 00969 if( before->year == after->year && 00970 before->mon == after->mon && 00971 before->day == after->day && 00972 before->hour > after->hour ) 00973 return( 1 ); 00974 00975 if( before->year == after->year && 00976 before->mon == after->mon && 00977 before->day == after->day && 00978 before->hour == after->hour && 00979 before->min > after->min ) 00980 return( 1 ); 00981 00982 if( before->year == after->year && 00983 before->mon == after->mon && 00984 before->day == after->day && 00985 before->hour == after->hour && 00986 before->min == after->min && 00987 before->sec > after->sec ) 00988 return( 1 ); 00989 00990 return( 0 ); 00991 } 00992 00993 int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) 00994 { 00995 mbedtls_x509_time now; 00996 00997 if( x509_get_current_time( &now ) != 0 ) 00998 return( 1 ); 00999 01000 return( x509_check_time( &now, to ) ); 01001 } 01002 01003 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) 01004 { 01005 mbedtls_x509_time now; 01006 01007 if( x509_get_current_time( &now ) != 0 ) 01008 return( 1 ); 01009 01010 return( x509_check_time( from, &now ) ); 01011 } 01012 01013 #else /* MBEDTLS_HAVE_TIME_DATE */ 01014 01015 int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) 01016 { 01017 ((void) to); 01018 return( 0 ); 01019 } 01020 01021 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) 01022 { 01023 ((void) from); 01024 return( 0 ); 01025 } 01026 #endif /* MBEDTLS_HAVE_TIME_DATE */ 01027 01028 #if defined(MBEDTLS_SELF_TEST) 01029 01030 #include "mbedtls/x509_crt.h" 01031 #include "mbedtls/certs.h" 01032 01033 /* 01034 * Checkup routine 01035 */ 01036 int mbedtls_x509_self_test( int verbose ) 01037 { 01038 #if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C) 01039 int ret; 01040 uint32_t flags; 01041 mbedtls_x509_crt cacert; 01042 mbedtls_x509_crt clicert; 01043 01044 if( verbose != 0 ) 01045 mbedtls_printf( " X.509 certificate load: " ); 01046 01047 mbedtls_x509_crt_init( &clicert ); 01048 01049 ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt, 01050 mbedtls_test_cli_crt_len ); 01051 if( ret != 0 ) 01052 { 01053 if( verbose != 0 ) 01054 mbedtls_printf( "failed\n" ); 01055 01056 return( ret ); 01057 } 01058 01059 mbedtls_x509_crt_init( &cacert ); 01060 01061 ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt, 01062 mbedtls_test_ca_crt_len ); 01063 if( ret != 0 ) 01064 { 01065 if( verbose != 0 ) 01066 mbedtls_printf( "failed\n" ); 01067 01068 return( ret ); 01069 } 01070 01071 if( verbose != 0 ) 01072 mbedtls_printf( "passed\n X.509 signature verify: "); 01073 01074 ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL ); 01075 if( ret != 0 ) 01076 { 01077 if( verbose != 0 ) 01078 mbedtls_printf( "failed\n" ); 01079 01080 return( ret ); 01081 } 01082 01083 if( verbose != 0 ) 01084 mbedtls_printf( "passed\n\n"); 01085 01086 mbedtls_x509_crt_free( &cacert ); 01087 mbedtls_x509_crt_free( &clicert ); 01088 01089 return( 0 ); 01090 #else 01091 ((void) verbose); 01092 return( 0 ); 01093 #endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */ 01094 } 01095 01096 #endif /* MBEDTLS_SELF_TEST */ 01097 01098 #endif /* MBEDTLS_X509_USE_C */
Generated on Sun Jul 17 2022 08:25:33 by 1.7.2