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