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