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