1 /* 2 * X.509 common functions for parsing and verification 3 * 4 * Copyright The Mbed TLS Contributors 5 * SPDX-License-Identifier: Apache-2.0 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may 8 * not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 /* 20 * The ITU-T X.509 standard defines a certificate format for PKI. 21 * 22 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) 23 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) 24 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) 25 * 26 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf 27 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf 28 */ 29 30 #include "common.h" 31 32 #if defined(MBEDTLS_X509_USE_C) 33 34 #include "mbedtls/x509.h" 35 #include "mbedtls/asn1.h" 36 #include "mbedtls/error.h" 37 #include "mbedtls/oid.h" 38 39 #include <stdio.h> 40 #include <string.h> 41 42 #if defined(MBEDTLS_PEM_PARSE_C) 43 #include "mbedtls/pem.h" 44 #endif 45 46 #if defined(MBEDTLS_PLATFORM_C) 47 #include "mbedtls/platform.h" 48 #else 49 #include <stdio.h> 50 #include <stdlib.h> 51 #define mbedtls_free free 52 #define mbedtls_calloc calloc 53 #define mbedtls_printf printf 54 #define mbedtls_snprintf snprintf 55 #endif 56 57 #if defined(MBEDTLS_HAVE_TIME) 58 #include "mbedtls/platform_time.h" 59 #endif 60 #if defined(MBEDTLS_HAVE_TIME_DATE) 61 #include "mbedtls/platform_util.h" 62 #include <time.h> 63 #endif 64 65 #define CHECK(code) if( ( ret = ( code ) ) != 0 ){ return( ret ); } 66 #define CHECK_RANGE(min, max, val) \ 67 do \ 68 { \ 69 if( ( val ) < ( min ) || ( val ) > ( max ) ) \ 70 { \ 71 return( ret ); \ 72 } \ 73 } while( 0 ) 74 75 /* 76 * CertificateSerialNumber ::= INTEGER 77 */ 78 int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, 79 mbedtls_x509_buf *serial ) 80 { 81 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 82 83 if( ( end - *p ) < 1 ) 84 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SERIAL, 85 MBEDTLS_ERR_ASN1_OUT_OF_DATA ) ); 86 87 if( **p != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2 ) && 88 **p != MBEDTLS_ASN1_INTEGER ) 89 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SERIAL, 90 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ); 91 92 serial->tag = *(*p)++; 93 94 if( ( ret = mbedtls_asn1_get_len( p, end, &serial->len ) ) != 0 ) 95 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SERIAL, ret ) ); 96 97 serial->p = *p; 98 *p += serial->len; 99 100 return( 0 ); 101 } 102 103 /* Get an algorithm identifier without parameters (eg for signatures) 104 * 105 * AlgorithmIdentifier ::= SEQUENCE { 106 * algorithm OBJECT IDENTIFIER, 107 * parameters ANY DEFINED BY algorithm OPTIONAL } 108 */ 109 int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, 110 mbedtls_x509_buf *alg ) 111 { 112 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 113 114 if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 ) 115 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) ); 116 117 return( 0 ); 118 } 119 120 /* 121 * Parse an algorithm identifier with (optional) parameters 122 */ 123 int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, 124 mbedtls_x509_buf *alg, mbedtls_x509_buf *params ) 125 { 126 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 127 128 if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 ) 129 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) ); 130 131 return( 0 ); 132 } 133 134 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 135 /* 136 * HashAlgorithm ::= AlgorithmIdentifier 137 * 138 * AlgorithmIdentifier ::= SEQUENCE { 139 * algorithm OBJECT IDENTIFIER, 140 * parameters ANY DEFINED BY algorithm OPTIONAL } 141 * 142 * For HashAlgorithm, parameters MUST be NULL or absent. 143 */ 144 static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg ) 145 { 146 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 147 unsigned char *p; 148 const unsigned char *end; 149 mbedtls_x509_buf md_oid; 150 size_t len; 151 152 /* Make sure we got a SEQUENCE and setup bounds */ 153 if( alg->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) 154 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, 155 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ); 156 157 p = alg->p; 158 end = p + alg->len; 159 160 if( p >= end ) 161 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, 162 MBEDTLS_ERR_ASN1_OUT_OF_DATA ) ); 163 164 /* Parse md_oid */ 165 md_oid.tag = *p; 166 167 if( ( ret = mbedtls_asn1_get_tag( &p, end, &md_oid.len, MBEDTLS_ASN1_OID ) ) != 0 ) 168 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) ); 169 170 md_oid.p = p; 171 p += md_oid.len; 172 173 /* Get md_alg from md_oid */ 174 if( ( ret = mbedtls_oid_get_md_alg( &md_oid, md_alg ) ) != 0 ) 175 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) ); 176 177 /* Make sure params is absent of NULL */ 178 if( p == end ) 179 return( 0 ); 180 181 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_NULL ) ) != 0 || len != 0 ) 182 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) ); 183 184 if( p != end ) 185 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, 186 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); 187 188 return( 0 ); 189 } 190 191 /* 192 * RSASSA-PSS-params ::= SEQUENCE { 193 * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier, 194 * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier, 195 * saltLength [2] INTEGER DEFAULT 20, 196 * trailerField [3] INTEGER DEFAULT 1 } 197 * -- Note that the tags in this Sequence are explicit. 198 * 199 * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value 200 * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other 201 * option. Enfore this at parsing time. 202 */ 203 int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, 204 mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, 205 int *salt_len ) 206 { 207 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 208 unsigned char *p; 209 const unsigned char *end, *end2; 210 size_t len; 211 mbedtls_x509_buf alg_id, alg_params; 212 213 /* First set everything to defaults */ 214 *md_alg = MBEDTLS_MD_SHA1; 215 *mgf_md = MBEDTLS_MD_SHA1; 216 *salt_len = 20; 217 218 /* Make sure params is a SEQUENCE and setup bounds */ 219 if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) 220 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, 221 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ); 222 223 p = (unsigned char *) params->p; 224 end = p + params->len; 225 226 if( p == end ) 227 return( 0 ); 228 229 /* 230 * HashAlgorithm 231 */ 232 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 233 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 ) 234 { 235 end2 = p + len; 236 237 /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */ 238 if( ( ret = mbedtls_x509_get_alg_null( &p, end2, &alg_id ) ) != 0 ) 239 return( ret ); 240 241 if( ( ret = mbedtls_oid_get_md_alg( &alg_id, md_alg ) ) != 0 ) 242 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) ); 243 244 if( p != end2 ) 245 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, 246 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); 247 } 248 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 249 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) ); 250 251 if( p == end ) 252 return( 0 ); 253 254 /* 255 * MaskGenAlgorithm 256 */ 257 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 258 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 ) 259 { 260 end2 = p + len; 261 262 /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */ 263 if( ( ret = mbedtls_x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 ) 264 return( ret ); 265 266 /* Only MFG1 is recognised for now */ 267 if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1, &alg_id ) != 0 ) 268 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE, 269 MBEDTLS_ERR_OID_NOT_FOUND ) ); 270 271 /* Parse HashAlgorithm */ 272 if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 ) 273 return( ret ); 274 275 if( p != end2 ) 276 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, 277 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); 278 } 279 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 280 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) ); 281 282 if( p == end ) 283 return( 0 ); 284 285 /* 286 * salt_len 287 */ 288 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 289 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 2 ) ) == 0 ) 290 { 291 end2 = p + len; 292 293 if( ( ret = mbedtls_asn1_get_int( &p, end2, salt_len ) ) != 0 ) 294 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) ); 295 296 if( p != end2 ) 297 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, 298 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); 299 } 300 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 301 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) ); 302 303 if( p == end ) 304 return( 0 ); 305 306 /* 307 * trailer_field (if present, must be 1) 308 */ 309 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 310 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 3 ) ) == 0 ) 311 { 312 int trailer_field; 313 314 end2 = p + len; 315 316 if( ( ret = mbedtls_asn1_get_int( &p, end2, &trailer_field ) ) != 0 ) 317 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) ); 318 319 if( p != end2 ) 320 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, 321 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); 322 323 if( trailer_field != 1 ) 324 return( MBEDTLS_ERR_X509_INVALID_ALG ); 325 } 326 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 327 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) ); 328 329 if( p != end ) 330 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, 331 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); 332 333 return( 0 ); 334 } 335 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 336 337 /* 338 * AttributeTypeAndValue ::= SEQUENCE { 339 * type AttributeType, 340 * value AttributeValue } 341 * 342 * AttributeType ::= OBJECT IDENTIFIER 343 * 344 * AttributeValue ::= ANY DEFINED BY AttributeType 345 */ 346 static int x509_get_attr_type_value( unsigned char **p, 347 const unsigned char *end, 348 mbedtls_x509_name *cur ) 349 { 350 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 351 size_t len; 352 mbedtls_x509_buf *oid; 353 mbedtls_x509_buf *val; 354 355 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 356 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 357 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) ); 358 359 end = *p + len; 360 361 if( ( end - *p ) < 1 ) 362 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, 363 MBEDTLS_ERR_ASN1_OUT_OF_DATA ) ); 364 365 oid = &cur->oid; 366 oid->tag = **p; 367 368 if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 ) 369 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) ); 370 371 oid->p = *p; 372 *p += oid->len; 373 374 if( ( end - *p ) < 1 ) 375 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, 376 MBEDTLS_ERR_ASN1_OUT_OF_DATA ) ); 377 378 if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING && 379 **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING && 380 **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING && 381 **p != MBEDTLS_ASN1_BIT_STRING ) 382 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, 383 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ); 384 385 val = &cur->val; 386 val->tag = *(*p)++; 387 388 if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 ) 389 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) ); 390 391 val->p = *p; 392 *p += val->len; 393 394 if( *p != end ) 395 { 396 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, 397 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); 398 } 399 400 cur->next = NULL; 401 402 return( 0 ); 403 } 404 405 /* 406 * Name ::= CHOICE { -- only one possibility for now -- 407 * rdnSequence RDNSequence } 408 * 409 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName 410 * 411 * RelativeDistinguishedName ::= 412 * SET OF AttributeTypeAndValue 413 * 414 * AttributeTypeAndValue ::= SEQUENCE { 415 * type AttributeType, 416 * value AttributeValue } 417 * 418 * AttributeType ::= OBJECT IDENTIFIER 419 * 420 * AttributeValue ::= ANY DEFINED BY AttributeType 421 * 422 * The data structure is optimized for the common case where each RDN has only 423 * one element, which is represented as a list of AttributeTypeAndValue. 424 * For the general case we still use a flat list, but we mark elements of the 425 * same set so that they are "merged" together in the functions that consume 426 * this list, eg mbedtls_x509_dn_gets(). 427 */ 428 int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, 429 mbedtls_x509_name *cur ) 430 { 431 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 432 size_t set_len; 433 const unsigned char *end_set; 434 435 /* don't use recursion, we'd risk stack overflow if not optimized */ 436 while( 1 ) 437 { 438 /* 439 * parse SET 440 */ 441 if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len, 442 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 ) 443 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) ); 444 445 end_set = *p + set_len; 446 447 while( 1 ) 448 { 449 if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 ) 450 return( ret ); 451 452 if( *p == end_set ) 453 break; 454 455 /* Mark this item as being no the only one in a set */ 456 cur->next_merged = 1; 457 458 cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); 459 460 if( cur->next == NULL ) 461 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 462 463 cur = cur->next; 464 } 465 466 /* 467 * continue until end of SEQUENCE is reached 468 */ 469 if( *p == end ) 470 return( 0 ); 471 472 cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); 473 474 if( cur->next == NULL ) 475 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 476 477 cur = cur->next; 478 } 479 } 480 481 static int x509_parse_int( unsigned char **p, size_t n, int *res ) 482 { 483 *res = 0; 484 485 for( ; n > 0; --n ) 486 { 487 if( ( **p < '0') || ( **p > '9' ) ) 488 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 489 490 *res *= 10; 491 *res += ( *(*p)++ - '0' ); 492 } 493 494 return( 0 ); 495 } 496 497 static int x509_date_is_valid(const mbedtls_x509_time *t ) 498 { 499 int ret = MBEDTLS_ERR_X509_INVALID_DATE; 500 int month_len; 501 502 CHECK_RANGE( 0, 9999, t->year ); 503 CHECK_RANGE( 0, 23, t->hour ); 504 CHECK_RANGE( 0, 59, t->min ); 505 CHECK_RANGE( 0, 59, t->sec ); 506 507 switch( t->mon ) 508 { 509 case 1: case 3: case 5: case 7: case 8: case 10: case 12: 510 month_len = 31; 511 break; 512 case 4: case 6: case 9: case 11: 513 month_len = 30; 514 break; 515 case 2: 516 if( ( !( t->year % 4 ) && t->year % 100 ) || 517 !( t->year % 400 ) ) 518 month_len = 29; 519 else 520 month_len = 28; 521 break; 522 default: 523 return( ret ); 524 } 525 CHECK_RANGE( 1, month_len, t->day ); 526 527 return( 0 ); 528 } 529 530 /* 531 * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4) 532 * field. 533 */ 534 static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen, 535 mbedtls_x509_time *tm ) 536 { 537 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 538 539 /* 540 * Minimum length is 10 or 12 depending on yearlen 541 */ 542 if ( len < yearlen + 8 ) 543 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 544 len -= yearlen + 8; 545 546 /* 547 * Parse year, month, day, hour, minute 548 */ 549 CHECK( x509_parse_int( p, yearlen, &tm->year ) ); 550 if ( 2 == yearlen ) 551 { 552 if ( tm->year < 50 ) 553 tm->year += 100; 554 555 tm->year += 1900; 556 } 557 558 CHECK( x509_parse_int( p, 2, &tm->mon ) ); 559 CHECK( x509_parse_int( p, 2, &tm->day ) ); 560 CHECK( x509_parse_int( p, 2, &tm->hour ) ); 561 CHECK( x509_parse_int( p, 2, &tm->min ) ); 562 563 /* 564 * Parse seconds if present 565 */ 566 if ( len >= 2 ) 567 { 568 CHECK( x509_parse_int( p, 2, &tm->sec ) ); 569 len -= 2; 570 } 571 else 572 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 573 574 /* 575 * Parse trailing 'Z' if present 576 */ 577 if ( 1 == len && 'Z' == **p ) 578 { 579 (*p)++; 580 len--; 581 } 582 583 /* 584 * We should have parsed all characters at this point 585 */ 586 if ( 0 != len ) 587 return ( MBEDTLS_ERR_X509_INVALID_DATE ); 588 589 CHECK( x509_date_is_valid( tm ) ); 590 591 return ( 0 ); 592 } 593 594 /* 595 * Time ::= CHOICE { 596 * utcTime UTCTime, 597 * generalTime GeneralizedTime } 598 */ 599 int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, 600 mbedtls_x509_time *tm ) 601 { 602 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 603 size_t len, year_len; 604 unsigned char tag; 605 606 if( ( end - *p ) < 1 ) 607 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE, 608 MBEDTLS_ERR_ASN1_OUT_OF_DATA ) ); 609 610 tag = **p; 611 612 if( tag == MBEDTLS_ASN1_UTC_TIME ) 613 year_len = 2; 614 else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME ) 615 year_len = 4; 616 else 617 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE, 618 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ); 619 620 (*p)++; 621 ret = mbedtls_asn1_get_len( p, end, &len ); 622 623 if( ret != 0 ) 624 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE, ret ) ); 625 626 return x509_parse_time( p, len, year_len, tm ); 627 } 628 629 int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ) 630 { 631 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 632 size_t len; 633 int tag_type; 634 635 if( ( end - *p ) < 1 ) 636 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SIGNATURE, 637 MBEDTLS_ERR_ASN1_OUT_OF_DATA ) ); 638 639 tag_type = **p; 640 641 if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) 642 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SIGNATURE, ret ) ); 643 644 sig->tag = tag_type; 645 sig->len = len; 646 sig->p = *p; 647 648 *p += len; 649 650 return( 0 ); 651 } 652 653 /* 654 * Get signature algorithm from alg OID and optional parameters 655 */ 656 int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, 657 mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, 658 void **sig_opts ) 659 { 660 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 661 662 if( *sig_opts != NULL ) 663 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 664 665 if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 ) 666 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG, ret ) ); 667 668 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 669 if( *pk_alg == MBEDTLS_PK_RSASSA_PSS ) 670 { 671 mbedtls_pk_rsassa_pss_options *pss_opts; 672 673 pss_opts = mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options ) ); 674 if( pss_opts == NULL ) 675 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 676 677 ret = mbedtls_x509_get_rsassa_pss_params( sig_params, 678 md_alg, 679 &pss_opts->mgf1_hash_id, 680 &pss_opts->expected_salt_len ); 681 if( ret != 0 ) 682 { 683 mbedtls_free( pss_opts ); 684 return( ret ); 685 } 686 687 *sig_opts = (void *) pss_opts; 688 } 689 else 690 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 691 { 692 /* Make sure parameters are absent or NULL */ 693 if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) || 694 sig_params->len != 0 ) 695 return( MBEDTLS_ERR_X509_INVALID_ALG ); 696 } 697 698 return( 0 ); 699 } 700 701 /* 702 * X.509 Extensions (No parsing of extensions, pointer should 703 * be either manually updated or extensions should be parsed!) 704 */ 705 int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, 706 mbedtls_x509_buf *ext, int tag ) 707 { 708 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 709 size_t len; 710 711 /* Extension structure use EXPLICIT tagging. That is, the actual 712 * `Extensions` structure is wrapped by a tag-length pair using 713 * the respective context-specific tag. */ 714 ret = mbedtls_asn1_get_tag( p, end, &ext->len, 715 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ); 716 if( ret != 0 ) 717 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) ); 718 719 ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag; 720 ext->p = *p; 721 end = *p + ext->len; 722 723 /* 724 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 725 */ 726 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 727 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 728 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) ); 729 730 if( end != *p + len ) 731 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, 732 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); 733 734 return( 0 ); 735 } 736 737 /* 738 * Store the name in printable form into buf; no more 739 * than size characters will be written 740 */ 741 int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn ) 742 { 743 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 744 size_t i, j, n; 745 unsigned char c, merge = 0; 746 const mbedtls_x509_name *name; 747 const char *short_name = NULL; 748 char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p; 749 750 memset( s, 0, sizeof( s ) ); 751 752 name = dn; 753 p = buf; 754 n = size; 755 756 while( name != NULL ) 757 { 758 if( !name->oid.p ) 759 { 760 name = name->next; 761 continue; 762 } 763 764 if( name != dn ) 765 { 766 ret = mbedtls_snprintf( p, n, merge ? " + " : ", " ); 767 MBEDTLS_X509_SAFE_SNPRINTF; 768 } 769 770 ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name ); 771 772 if( ret == 0 ) 773 ret = mbedtls_snprintf( p, n, "%s=", short_name ); 774 else 775 ret = mbedtls_snprintf( p, n, "\?\?=" ); 776 MBEDTLS_X509_SAFE_SNPRINTF; 777 778 for( i = 0, j = 0; i < name->val.len; i++, j++ ) 779 { 780 if( j >= sizeof( s ) - 1 ) 781 return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL ); 782 783 c = name->val.p[i]; 784 // Special characters requiring escaping, RFC 1779 785 if( c && strchr( ",=+<>#;\"\\", c ) ) 786 { 787 if( j + 1 >= sizeof( s ) - 1 ) 788 return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL ); 789 s[j++] = '\\'; 790 } 791 if( c < 32 || c >= 127 ) 792 s[j] = '?'; 793 else s[j] = c; 794 } 795 s[j] = '\0'; 796 ret = mbedtls_snprintf( p, n, "%s", s ); 797 MBEDTLS_X509_SAFE_SNPRINTF; 798 799 merge = name->next_merged; 800 name = name->next; 801 } 802 803 return( (int) ( size - n ) ); 804 } 805 806 /* 807 * Store the serial in printable form into buf; no more 808 * than size characters will be written 809 */ 810 int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial ) 811 { 812 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 813 size_t i, n, nr; 814 char *p; 815 816 p = buf; 817 n = size; 818 819 nr = ( serial->len <= 32 ) 820 ? serial->len : 28; 821 822 for( i = 0; i < nr; i++ ) 823 { 824 if( i == 0 && nr > 1 && serial->p[i] == 0x0 ) 825 continue; 826 827 ret = mbedtls_snprintf( p, n, "%02X%s", 828 serial->p[i], ( i < nr - 1 ) ? ":" : "" ); 829 MBEDTLS_X509_SAFE_SNPRINTF; 830 } 831 832 if( nr != serial->len ) 833 { 834 ret = mbedtls_snprintf( p, n, "...." ); 835 MBEDTLS_X509_SAFE_SNPRINTF; 836 } 837 838 return( (int) ( size - n ) ); 839 } 840 841 /* 842 * Helper for writing signature algorithms 843 */ 844 int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, 845 mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, 846 const void *sig_opts ) 847 { 848 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 849 char *p = buf; 850 size_t n = size; 851 const char *desc = NULL; 852 853 ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc ); 854 if( ret != 0 ) 855 ret = mbedtls_snprintf( p, n, "???" ); 856 else 857 ret = mbedtls_snprintf( p, n, "%s", desc ); 858 MBEDTLS_X509_SAFE_SNPRINTF; 859 860 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 861 if( pk_alg == MBEDTLS_PK_RSASSA_PSS ) 862 { 863 const mbedtls_pk_rsassa_pss_options *pss_opts; 864 const mbedtls_md_info_t *md_info, *mgf_md_info; 865 866 pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts; 867 868 md_info = mbedtls_md_info_from_type( md_alg ); 869 mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id ); 870 871 ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)", 872 md_info ? mbedtls_md_get_name( md_info ) : "???", 873 mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???", 874 (unsigned int) pss_opts->expected_salt_len ); 875 MBEDTLS_X509_SAFE_SNPRINTF; 876 } 877 #else 878 ((void) pk_alg); 879 ((void) md_alg); 880 ((void) sig_opts); 881 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 882 883 return( (int)( size - n ) ); 884 } 885 886 /* 887 * Helper for writing "RSA key size", "EC key size", etc 888 */ 889 int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ) 890 { 891 char *p = buf; 892 size_t n = buf_size; 893 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 894 895 ret = mbedtls_snprintf( p, n, "%s key size", name ); 896 MBEDTLS_X509_SAFE_SNPRINTF; 897 898 return( 0 ); 899 } 900 901 #if defined(MBEDTLS_HAVE_TIME_DATE) 902 /* 903 * Set the time structure to the current time. 904 * Return 0 on success, non-zero on failure. 905 */ 906 static int x509_get_current_time( mbedtls_x509_time *now ) 907 { 908 struct tm *lt, tm_buf; 909 mbedtls_time_t tt; 910 int ret = 0; 911 912 tt = mbedtls_time( NULL ); 913 lt = mbedtls_platform_gmtime_r( &tt, &tm_buf ); 914 915 if( lt == NULL ) 916 ret = -1; 917 else 918 { 919 now->year = lt->tm_year + 1900; 920 now->mon = lt->tm_mon + 1; 921 now->day = lt->tm_mday; 922 now->hour = lt->tm_hour; 923 now->min = lt->tm_min; 924 now->sec = lt->tm_sec; 925 } 926 927 return( ret ); 928 } 929 930 /* 931 * Return 0 if before <= after, 1 otherwise 932 */ 933 static int x509_check_time( const mbedtls_x509_time *before, const mbedtls_x509_time *after ) 934 { 935 if( before->year > after->year ) 936 return( 1 ); 937 938 if( before->year == after->year && 939 before->mon > after->mon ) 940 return( 1 ); 941 942 if( before->year == after->year && 943 before->mon == after->mon && 944 before->day > after->day ) 945 return( 1 ); 946 947 if( before->year == after->year && 948 before->mon == after->mon && 949 before->day == after->day && 950 before->hour > after->hour ) 951 return( 1 ); 952 953 if( before->year == after->year && 954 before->mon == after->mon && 955 before->day == after->day && 956 before->hour == after->hour && 957 before->min > after->min ) 958 return( 1 ); 959 960 if( before->year == after->year && 961 before->mon == after->mon && 962 before->day == after->day && 963 before->hour == after->hour && 964 before->min == after->min && 965 before->sec > after->sec ) 966 return( 1 ); 967 968 return( 0 ); 969 } 970 971 int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) 972 { 973 mbedtls_x509_time now; 974 975 if( x509_get_current_time( &now ) != 0 ) 976 return( 1 ); 977 978 return( x509_check_time( &now, to ) ); 979 } 980 981 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) 982 { 983 mbedtls_x509_time now; 984 985 if( x509_get_current_time( &now ) != 0 ) 986 return( 1 ); 987 988 return( x509_check_time( from, &now ) ); 989 } 990 991 #else /* MBEDTLS_HAVE_TIME_DATE */ 992 993 int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) 994 { 995 ((void) to); 996 return( 0 ); 997 } 998 999 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) 1000 { 1001 ((void) from); 1002 return( 0 ); 1003 } 1004 #endif /* MBEDTLS_HAVE_TIME_DATE */ 1005 1006 #if defined(MBEDTLS_SELF_TEST) 1007 1008 #include "mbedtls/x509_crt.h" 1009 #include "mbedtls/certs.h" 1010 1011 /* 1012 * Checkup routine 1013 */ 1014 int mbedtls_x509_self_test( int verbose ) 1015 { 1016 int ret = 0; 1017 #if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C) 1018 uint32_t flags; 1019 mbedtls_x509_crt cacert; 1020 mbedtls_x509_crt clicert; 1021 1022 if( verbose != 0 ) 1023 mbedtls_printf( " X.509 certificate load: " ); 1024 1025 mbedtls_x509_crt_init( &cacert ); 1026 mbedtls_x509_crt_init( &clicert ); 1027 1028 ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt, 1029 mbedtls_test_cli_crt_len ); 1030 if( ret != 0 ) 1031 { 1032 if( verbose != 0 ) 1033 mbedtls_printf( "failed\n" ); 1034 1035 goto cleanup; 1036 } 1037 1038 ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt, 1039 mbedtls_test_ca_crt_len ); 1040 if( ret != 0 ) 1041 { 1042 if( verbose != 0 ) 1043 mbedtls_printf( "failed\n" ); 1044 1045 goto cleanup; 1046 } 1047 1048 if( verbose != 0 ) 1049 mbedtls_printf( "passed\n X.509 signature verify: "); 1050 1051 ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL ); 1052 if( ret != 0 ) 1053 { 1054 if( verbose != 0 ) 1055 mbedtls_printf( "failed\n" ); 1056 1057 goto cleanup; 1058 } 1059 1060 if( verbose != 0 ) 1061 mbedtls_printf( "passed\n\n"); 1062 1063 cleanup: 1064 mbedtls_x509_crt_free( &cacert ); 1065 mbedtls_x509_crt_free( &clicert ); 1066 #else 1067 ((void) verbose); 1068 #endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA256_C */ 1069 return( ret ); 1070 } 1071 1072 #endif /* MBEDTLS_SELF_TEST */ 1073 1074 #endif /* MBEDTLS_X509_USE_C */ 1075