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