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