1/* 2 * X.509v3 certificate parsing and processing (RFC 3280 profile) 3 * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9#include "includes.h" 10 11#include "common.h" 12#include "crypto/crypto.h" 13#include "asn1.h" 14#include "x509v3.h" 15 16 17static void x509_free_name(struct x509_name *name) 18{ 19 size_t i; 20 21 for (i = 0; i < name->num_attr; i++) { 22 os_free(name->attr[i].value); 23 name->attr[i].value = NULL; 24 name->attr[i].type = X509_NAME_ATTR_NOT_USED; 25 } 26 name->num_attr = 0; 27 os_free(name->email); 28 name->email = NULL; 29 30 os_free(name->alt_email); 31 os_free(name->dns); 32 os_free(name->uri); 33 os_free(name->ip); 34 name->alt_email = name->dns = name->uri = NULL; 35 name->ip = NULL; 36 name->ip_len = 0; 37 os_memset(&name->rid, 0, sizeof(name->rid)); 38} 39 40 41/** 42 * x509_certificate_free - Free an X.509 certificate 43 * @cert: Certificate to be freed 44 */ 45void x509_certificate_free(struct x509_certificate *cert) 46{ 47 if (cert == NULL) 48 return; 49 if (cert->next) { 50 wpa_printf(MSG_DEBUG, "X509: x509_certificate_free: cer=%p " 51 "was still on a list (next=%p)\n", 52 cert, cert->next); 53 } 54 x509_free_name(&cert->issuer); 55 x509_free_name(&cert->subject); 56 os_free(cert->public_key); 57 os_free(cert->sign_value); 58 os_free(cert); 59} 60 61 62/** 63 * x509_certificate_free - Free an X.509 certificate chain 64 * @cert: Pointer to the first certificate in the chain 65 */ 66void x509_certificate_chain_free(struct x509_certificate *cert) 67{ 68 struct x509_certificate *next; 69 70 while (cert) { 71 next = cert->next; 72 cert->next = NULL; 73 x509_certificate_free(cert); 74 cert = next; 75 } 76} 77 78 79static int x509_whitespace(char c) 80{ 81 return c == ' ' || c == '\t'; 82} 83 84 85static void x509_str_strip_whitespace(char *a) 86{ 87 char *ipos, *opos; 88 int remove_whitespace = 1; 89 90 ipos = opos = a; 91 92 while (*ipos) { 93 if (remove_whitespace && x509_whitespace(*ipos)) 94 ipos++; 95 else { 96 remove_whitespace = x509_whitespace(*ipos); 97 *opos++ = *ipos++; 98 } 99 } 100 101 *opos-- = '\0'; 102 if (opos > a && x509_whitespace(*opos)) 103 *opos = '\0'; 104} 105 106 107static int x509_str_compare(const char *a, const char *b) 108{ 109 char *aa, *bb; 110 int ret; 111 112 if (!a && b) 113 return -1; 114 if (a && !b) 115 return 1; 116 if (!a && !b) 117 return 0; 118 119 aa = os_strdup(a); 120 bb = os_strdup(b); 121 122 if (aa == NULL || bb == NULL) { 123 os_free(aa); 124 os_free(bb); 125 return os_strcasecmp(a, b); 126 } 127 128 x509_str_strip_whitespace(aa); 129 x509_str_strip_whitespace(bb); 130 131 ret = os_strcasecmp(aa, bb); 132 133 os_free(aa); 134 os_free(bb); 135 136 return ret; 137} 138 139 140/** 141 * x509_name_compare - Compare X.509 certificate names 142 * @a: Certificate name 143 * @b: Certificate name 144 * Returns: <0, 0, or >0 based on whether a is less than, equal to, or 145 * greater than b 146 */ 147int x509_name_compare(struct x509_name *a, struct x509_name *b) 148{ 149 int res; 150 size_t i; 151 152 if (!a && b) 153 return -1; 154 if (a && !b) 155 return 1; 156 if (!a && !b) 157 return 0; 158 if (a->num_attr < b->num_attr) 159 return -1; 160 if (a->num_attr > b->num_attr) 161 return 1; 162 163 for (i = 0; i < a->num_attr; i++) { 164 if (a->attr[i].type < b->attr[i].type) 165 return -1; 166 if (a->attr[i].type > b->attr[i].type) 167 return -1; 168 res = x509_str_compare(a->attr[i].value, b->attr[i].value); 169 if (res) 170 return res; 171 } 172 res = x509_str_compare(a->email, b->email); 173 if (res) 174 return res; 175 176 return 0; 177} 178 179 180static int x509_parse_algorithm_identifier( 181 const u8 *buf, size_t len, 182 struct x509_algorithm_identifier *id, const u8 **next) 183{ 184 struct asn1_hdr hdr; 185 const u8 *pos, *end; 186 187 /* 188 * AlgorithmIdentifier ::= SEQUENCE { 189 * algorithm OBJECT IDENTIFIER, 190 * parameters ANY DEFINED BY algorithm OPTIONAL 191 * } 192 */ 193 194 if (asn1_get_next(buf, len, &hdr) < 0 || 195 hdr.class != ASN1_CLASS_UNIVERSAL || 196 hdr.tag != ASN1_TAG_SEQUENCE) { 197 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 198 "(AlgorithmIdentifier) - found class %d tag 0x%x", 199 hdr.class, hdr.tag); 200 return -1; 201 } 202 pos = hdr.payload; 203 end = pos + hdr.length; 204 205 if (end > buf + len) 206 return -1; 207 208 *next = end; 209 210 if (asn1_get_oid(pos, end - pos, &id->oid, &pos)) 211 return -1; 212 213 /* TODO: optional parameters */ 214 215 return 0; 216} 217 218 219static int x509_parse_public_key(const u8 *buf, size_t len, 220 struct x509_certificate *cert, 221 const u8 **next) 222{ 223 struct asn1_hdr hdr; 224 const u8 *pos, *end; 225 226 /* 227 * SubjectPublicKeyInfo ::= SEQUENCE { 228 * algorithm AlgorithmIdentifier, 229 * subjectPublicKey BIT STRING 230 * } 231 */ 232 233 pos = buf; 234 end = buf + len; 235 236 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 237 hdr.class != ASN1_CLASS_UNIVERSAL || 238 hdr.tag != ASN1_TAG_SEQUENCE) { 239 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 240 "(SubjectPublicKeyInfo) - found class %d tag 0x%x", 241 hdr.class, hdr.tag); 242 return -1; 243 } 244 pos = hdr.payload; 245 246 if (pos + hdr.length > end) 247 return -1; 248 end = pos + hdr.length; 249 *next = end; 250 251 if (x509_parse_algorithm_identifier(pos, end - pos, 252 &cert->public_key_alg, &pos)) 253 return -1; 254 255 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 256 hdr.class != ASN1_CLASS_UNIVERSAL || 257 hdr.tag != ASN1_TAG_BITSTRING) { 258 wpa_printf(MSG_DEBUG, "X509: Expected BITSTRING " 259 "(subjectPublicKey) - found class %d tag 0x%x", 260 hdr.class, hdr.tag); 261 return -1; 262 } 263 if (hdr.length < 1) 264 return -1; 265 pos = hdr.payload; 266 if (*pos) { 267 wpa_printf(MSG_DEBUG, "X509: BITSTRING - %d unused bits", 268 *pos); 269 /* 270 * TODO: should this be rejected? X.509 certificates are 271 * unlikely to use such a construction. Now we would end up 272 * including the extra bits in the buffer which may also be 273 * ok. 274 */ 275 } 276 os_free(cert->public_key); 277 cert->public_key = os_malloc(hdr.length - 1); 278 if (cert->public_key == NULL) { 279 wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for " 280 "public key"); 281 return -1; 282 } 283 os_memcpy(cert->public_key, pos + 1, hdr.length - 1); 284 cert->public_key_len = hdr.length - 1; 285 wpa_hexdump(MSG_MSGDUMP, "X509: subjectPublicKey", 286 cert->public_key, cert->public_key_len); 287 288 return 0; 289} 290 291 292static int x509_parse_name(const u8 *buf, size_t len, struct x509_name *name, 293 const u8 **next) 294{ 295 struct asn1_hdr hdr; 296 const u8 *pos, *end, *set_pos, *set_end, *seq_pos, *seq_end; 297 struct asn1_oid oid; 298 char *val; 299 300 /* 301 * Name ::= CHOICE { RDNSequence } 302 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName 303 * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue 304 * AttributeTypeAndValue ::= SEQUENCE { 305 * type AttributeType, 306 * value AttributeValue 307 * } 308 * AttributeType ::= OBJECT IDENTIFIER 309 * AttributeValue ::= ANY DEFINED BY AttributeType 310 */ 311 312 if (asn1_get_next(buf, len, &hdr) < 0 || 313 hdr.class != ASN1_CLASS_UNIVERSAL || 314 hdr.tag != ASN1_TAG_SEQUENCE) { 315 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 316 "(Name / RDNSequencer) - found class %d tag 0x%x", 317 hdr.class, hdr.tag); 318 return -1; 319 } 320 pos = hdr.payload; 321 322 if (pos + hdr.length > buf + len) 323 return -1; 324 325 end = *next = pos + hdr.length; 326 327 while (pos < end) { 328 enum x509_name_attr_type type; 329 330 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 331 hdr.class != ASN1_CLASS_UNIVERSAL || 332 hdr.tag != ASN1_TAG_SET) { 333 wpa_printf(MSG_DEBUG, "X509: Expected SET " 334 "(RelativeDistinguishedName) - found class " 335 "%d tag 0x%x", hdr.class, hdr.tag); 336 x509_free_name(name); 337 return -1; 338 } 339 340 set_pos = hdr.payload; 341 pos = set_end = hdr.payload + hdr.length; 342 343 if (asn1_get_next(set_pos, set_end - set_pos, &hdr) < 0 || 344 hdr.class != ASN1_CLASS_UNIVERSAL || 345 hdr.tag != ASN1_TAG_SEQUENCE) { 346 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 347 "(AttributeTypeAndValue) - found class %d " 348 "tag 0x%x", hdr.class, hdr.tag); 349 x509_free_name(name); 350 return -1; 351 } 352 353 seq_pos = hdr.payload; 354 seq_end = hdr.payload + hdr.length; 355 356 if (asn1_get_oid(seq_pos, seq_end - seq_pos, &oid, &seq_pos)) { 357 x509_free_name(name); 358 return -1; 359 } 360 361 if (asn1_get_next(seq_pos, seq_end - seq_pos, &hdr) < 0 || 362 hdr.class != ASN1_CLASS_UNIVERSAL) { 363 wpa_printf(MSG_DEBUG, "X509: Failed to parse " 364 "AttributeValue"); 365 x509_free_name(name); 366 return -1; 367 } 368 369 /* RFC 3280: 370 * MUST: country, organization, organizational-unit, 371 * distinguished name qualifier, state or province name, 372 * common name, serial number. 373 * SHOULD: locality, title, surname, given name, initials, 374 * pseudonym, generation qualifier. 375 * MUST: domainComponent (RFC 2247). 376 */ 377 type = X509_NAME_ATTR_NOT_USED; 378 if (oid.len == 4 && 379 oid.oid[0] == 2 && oid.oid[1] == 5 && oid.oid[2] == 4) { 380 /* id-at ::= 2.5.4 */ 381 switch (oid.oid[3]) { 382 case 3: 383 /* commonName */ 384 type = X509_NAME_ATTR_CN; 385 break; 386 case 6: 387 /* countryName */ 388 type = X509_NAME_ATTR_C; 389 break; 390 case 7: 391 /* localityName */ 392 type = X509_NAME_ATTR_L; 393 break; 394 case 8: 395 /* stateOrProvinceName */ 396 type = X509_NAME_ATTR_ST; 397 break; 398 case 10: 399 /* organizationName */ 400 type = X509_NAME_ATTR_O; 401 break; 402 case 11: 403 /* organizationalUnitName */ 404 type = X509_NAME_ATTR_OU; 405 break; 406 } 407 } else if (oid.len == 7 && 408 oid.oid[0] == 1 && oid.oid[1] == 2 && 409 oid.oid[2] == 840 && oid.oid[3] == 113549 && 410 oid.oid[4] == 1 && oid.oid[5] == 9 && 411 oid.oid[6] == 1) { 412 /* 1.2.840.113549.1.9.1 - e-mailAddress */ 413 os_free(name->email); 414 name->email = os_malloc(hdr.length + 1); 415 if (name->email == NULL) { 416 x509_free_name(name); 417 return -1; 418 } 419 os_memcpy(name->email, hdr.payload, hdr.length); 420 name->email[hdr.length] = '\0'; 421 continue; 422 } else if (oid.len == 7 && 423 oid.oid[0] == 0 && oid.oid[1] == 9 && 424 oid.oid[2] == 2342 && oid.oid[3] == 19200300 && 425 oid.oid[4] == 100 && oid.oid[5] == 1 && 426 oid.oid[6] == 25) { 427 /* 0.9.2342.19200300.100.1.25 - domainComponent */ 428 type = X509_NAME_ATTR_DC; 429 } 430 431 if (type == X509_NAME_ATTR_NOT_USED) { 432 wpa_hexdump(MSG_DEBUG, "X509: Unrecognized OID", 433 (u8 *) oid.oid, 434 oid.len * sizeof(oid.oid[0])); 435 wpa_hexdump_ascii(MSG_MSGDUMP, "X509: Attribute Data", 436 hdr.payload, hdr.length); 437 continue; 438 } 439 440 if (name->num_attr == X509_MAX_NAME_ATTRIBUTES) { 441 wpa_printf(MSG_INFO, "X509: Too many Name attributes"); 442 x509_free_name(name); 443 return -1; 444 } 445 446 val = os_malloc(hdr.length + 1); 447 if (val == NULL) { 448 x509_free_name(name); 449 return -1; 450 } 451 os_memcpy(val, hdr.payload, hdr.length); 452 val[hdr.length] = '\0'; 453 if (os_strlen(val) != hdr.length) { 454 wpa_printf(MSG_INFO, "X509: Reject certificate with " 455 "embedded NUL byte in a string (%s[NUL])", 456 val); 457 x509_free_name(name); 458 return -1; 459 } 460 461 name->attr[name->num_attr].type = type; 462 name->attr[name->num_attr].value = val; 463 name->num_attr++; 464 } 465 466 return 0; 467} 468 469 470static char * x509_name_attr_str(enum x509_name_attr_type type) 471{ 472 switch (type) { 473 case X509_NAME_ATTR_NOT_USED: 474 return "[N/A]"; 475 case X509_NAME_ATTR_DC: 476 return "DC"; 477 case X509_NAME_ATTR_CN: 478 return "CN"; 479 case X509_NAME_ATTR_C: 480 return "C"; 481 case X509_NAME_ATTR_L: 482 return "L"; 483 case X509_NAME_ATTR_ST: 484 return "ST"; 485 case X509_NAME_ATTR_O: 486 return "O"; 487 case X509_NAME_ATTR_OU: 488 return "OU"; 489 } 490 return "?"; 491} 492 493 494/** 495 * x509_name_string - Convert an X.509 certificate name into a string 496 * @name: Name to convert 497 * @buf: Buffer for the string 498 * @len: Maximum buffer length 499 */ 500void x509_name_string(struct x509_name *name, char *buf, size_t len) 501{ 502 char *pos, *end; 503 int ret; 504 size_t i; 505 506 if (len == 0) 507 return; 508 509 pos = buf; 510 end = buf + len; 511 512 for (i = 0; i < name->num_attr; i++) { 513 ret = os_snprintf(pos, end - pos, "%s=%s, ", 514 x509_name_attr_str(name->attr[i].type), 515 name->attr[i].value); 516 if (ret < 0 || ret >= end - pos) 517 goto done; 518 pos += ret; 519 } 520 521 if (pos > buf + 1 && pos[-1] == ' ' && pos[-2] == ',') { 522 pos--; 523 *pos = '\0'; 524 pos--; 525 *pos = '\0'; 526 } 527 528 if (name->email) { 529 ret = os_snprintf(pos, end - pos, "/emailAddress=%s", 530 name->email); 531 if (ret < 0 || ret >= end - pos) 532 goto done; 533 pos += ret; 534 } 535 536done: 537 end[-1] = '\0'; 538} 539 540 541static int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag, 542 os_time_t *val) 543{ 544 const char *pos; 545 int year, month, day, hour, min, sec; 546 547 /* 548 * Time ::= CHOICE { 549 * utcTime UTCTime, 550 * generalTime GeneralizedTime 551 * } 552 * 553 * UTCTime: YYMMDDHHMMSSZ 554 * GeneralizedTime: YYYYMMDDHHMMSSZ 555 */ 556 557 pos = (const char *) buf; 558 559 switch (asn1_tag) { 560 case ASN1_TAG_UTCTIME: 561 if (len != 13 || buf[12] != 'Z') { 562 wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized " 563 "UTCTime format", buf, len); 564 return -1; 565 } 566 if (sscanf(pos, "%02d", &year) != 1) { 567 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse " 568 "UTCTime year", buf, len); 569 return -1; 570 } 571 if (year < 50) 572 year += 2000; 573 else 574 year += 1900; 575 pos += 2; 576 break; 577 case ASN1_TAG_GENERALIZEDTIME: 578 if (len != 15 || buf[14] != 'Z') { 579 wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized " 580 "GeneralizedTime format", buf, len); 581 return -1; 582 } 583 if (sscanf(pos, "%04d", &year) != 1) { 584 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse " 585 "GeneralizedTime year", buf, len); 586 return -1; 587 } 588 pos += 4; 589 break; 590 default: 591 wpa_printf(MSG_DEBUG, "X509: Expected UTCTime or " 592 "GeneralizedTime - found tag 0x%x", asn1_tag); 593 return -1; 594 } 595 596 if (sscanf(pos, "%02d", &month) != 1) { 597 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time " 598 "(month)", buf, len); 599 return -1; 600 } 601 pos += 2; 602 603 if (sscanf(pos, "%02d", &day) != 1) { 604 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time " 605 "(day)", buf, len); 606 return -1; 607 } 608 pos += 2; 609 610 if (sscanf(pos, "%02d", &hour) != 1) { 611 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time " 612 "(hour)", buf, len); 613 return -1; 614 } 615 pos += 2; 616 617 if (sscanf(pos, "%02d", &min) != 1) { 618 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time " 619 "(min)", buf, len); 620 return -1; 621 } 622 pos += 2; 623 624 if (sscanf(pos, "%02d", &sec) != 1) { 625 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time " 626 "(sec)", buf, len); 627 return -1; 628 } 629 630 if (os_mktime(year, month, day, hour, min, sec, val) < 0) { 631 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to convert Time", 632 buf, len); 633 if (year < 1970) { 634 /* 635 * At least some test certificates have been configured 636 * to use dates prior to 1970. Set the date to 637 * beginning of 1970 to handle these case. 638 */ 639 wpa_printf(MSG_DEBUG, "X509: Year=%d before epoch - " 640 "assume epoch as the time", year); 641 *val = 0; 642 return 0; 643 } 644 return -1; 645 } 646 647 return 0; 648} 649 650 651static int x509_parse_validity(const u8 *buf, size_t len, 652 struct x509_certificate *cert, const u8 **next) 653{ 654 struct asn1_hdr hdr; 655 const u8 *pos; 656 size_t plen; 657 658 /* 659 * Validity ::= SEQUENCE { 660 * notBefore Time, 661 * notAfter Time 662 * } 663 * 664 * RFC 3280, 4.1.2.5: 665 * CAs conforming to this profile MUST always encode certificate 666 * validity dates through the year 2049 as UTCTime; certificate 667 * validity dates in 2050 or later MUST be encoded as GeneralizedTime. 668 */ 669 670 if (asn1_get_next(buf, len, &hdr) < 0 || 671 hdr.class != ASN1_CLASS_UNIVERSAL || 672 hdr.tag != ASN1_TAG_SEQUENCE) { 673 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 674 "(Validity) - found class %d tag 0x%x", 675 hdr.class, hdr.tag); 676 return -1; 677 } 678 pos = hdr.payload; 679 plen = hdr.length; 680 681 if (pos + plen > buf + len) 682 return -1; 683 684 *next = pos + plen; 685 686 if (asn1_get_next(pos, plen, &hdr) < 0 || 687 hdr.class != ASN1_CLASS_UNIVERSAL || 688 x509_parse_time(hdr.payload, hdr.length, hdr.tag, 689 &cert->not_before) < 0) { 690 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notBefore " 691 "Time", hdr.payload, hdr.length); 692 return -1; 693 } 694 695 pos = hdr.payload + hdr.length; 696 plen = *next - pos; 697 698 if (asn1_get_next(pos, plen, &hdr) < 0 || 699 hdr.class != ASN1_CLASS_UNIVERSAL || 700 x509_parse_time(hdr.payload, hdr.length, hdr.tag, 701 &cert->not_after) < 0) { 702 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notAfter " 703 "Time", hdr.payload, hdr.length); 704 return -1; 705 } 706 707 wpa_printf(MSG_MSGDUMP, "X509: Validity: notBefore: %lu notAfter: %lu", 708 (unsigned long) cert->not_before, 709 (unsigned long) cert->not_after); 710 711 return 0; 712} 713 714 715static int x509_id_ce_oid(struct asn1_oid *oid) 716{ 717 /* id-ce arc from X.509 for standard X.509v3 extensions */ 718 return oid->len >= 4 && 719 oid->oid[0] == 2 /* joint-iso-ccitt */ && 720 oid->oid[1] == 5 /* ds */ && 721 oid->oid[2] == 29 /* id-ce */; 722} 723 724 725static int x509_parse_ext_key_usage(struct x509_certificate *cert, 726 const u8 *pos, size_t len) 727{ 728 struct asn1_hdr hdr; 729 730 /* 731 * KeyUsage ::= BIT STRING { 732 * digitalSignature (0), 733 * nonRepudiation (1), 734 * keyEncipherment (2), 735 * dataEncipherment (3), 736 * keyAgreement (4), 737 * keyCertSign (5), 738 * cRLSign (6), 739 * encipherOnly (7), 740 * decipherOnly (8) } 741 */ 742 743 if (asn1_get_next(pos, len, &hdr) < 0 || 744 hdr.class != ASN1_CLASS_UNIVERSAL || 745 hdr.tag != ASN1_TAG_BITSTRING || 746 hdr.length < 1) { 747 wpa_printf(MSG_DEBUG, "X509: Expected BIT STRING in " 748 "KeyUsage; found %d tag 0x%x len %d", 749 hdr.class, hdr.tag, hdr.length); 750 return -1; 751 } 752 753 cert->extensions_present |= X509_EXT_KEY_USAGE; 754 cert->key_usage = asn1_bit_string_to_long(hdr.payload, hdr.length); 755 756 wpa_printf(MSG_DEBUG, "X509: KeyUsage 0x%lx", cert->key_usage); 757 758 return 0; 759} 760 761 762static int x509_parse_ext_basic_constraints(struct x509_certificate *cert, 763 const u8 *pos, size_t len) 764{ 765 struct asn1_hdr hdr; 766 unsigned long value; 767 size_t left; 768 769 /* 770 * BasicConstraints ::= SEQUENCE { 771 * cA BOOLEAN DEFAULT FALSE, 772 * pathLenConstraint INTEGER (0..MAX) OPTIONAL } 773 */ 774 775 if (asn1_get_next(pos, len, &hdr) < 0 || 776 hdr.class != ASN1_CLASS_UNIVERSAL || 777 hdr.tag != ASN1_TAG_SEQUENCE) { 778 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE in " 779 "BasicConstraints; found %d tag 0x%x", 780 hdr.class, hdr.tag); 781 return -1; 782 } 783 784 cert->extensions_present |= X509_EXT_BASIC_CONSTRAINTS; 785 786 if (hdr.length == 0) 787 return 0; 788 789 if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 || 790 hdr.class != ASN1_CLASS_UNIVERSAL) { 791 wpa_printf(MSG_DEBUG, "X509: Failed to parse " 792 "BasicConstraints"); 793 return -1; 794 } 795 796 if (hdr.tag == ASN1_TAG_BOOLEAN) { 797 if (hdr.length != 1) { 798 wpa_printf(MSG_DEBUG, "X509: Unexpected " 799 "Boolean length (%u) in BasicConstraints", 800 hdr.length); 801 return -1; 802 } 803 cert->ca = hdr.payload[0]; 804 805 if (hdr.payload + hdr.length == pos + len) { 806 wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d", 807 cert->ca); 808 return 0; 809 } 810 811 if (asn1_get_next(hdr.payload + hdr.length, len - hdr.length, 812 &hdr) < 0 || 813 hdr.class != ASN1_CLASS_UNIVERSAL) { 814 wpa_printf(MSG_DEBUG, "X509: Failed to parse " 815 "BasicConstraints"); 816 return -1; 817 } 818 } 819 820 if (hdr.tag != ASN1_TAG_INTEGER) { 821 wpa_printf(MSG_DEBUG, "X509: Expected INTEGER in " 822 "BasicConstraints; found class %d tag 0x%x", 823 hdr.class, hdr.tag); 824 return -1; 825 } 826 827 pos = hdr.payload; 828 left = hdr.length; 829 value = 0; 830 while (left) { 831 value <<= 8; 832 value |= *pos++; 833 left--; 834 } 835 836 cert->path_len_constraint = value; 837 cert->extensions_present |= X509_EXT_PATH_LEN_CONSTRAINT; 838 839 wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d " 840 "pathLenConstraint=%lu", 841 cert->ca, cert->path_len_constraint); 842 843 return 0; 844} 845 846 847static int x509_parse_alt_name_rfc8222(struct x509_name *name, 848 const u8 *pos, size_t len) 849{ 850 /* rfc822Name IA5String */ 851 wpa_hexdump_ascii(MSG_MSGDUMP, "X509: altName - rfc822Name", pos, len); 852 os_free(name->alt_email); 853 name->alt_email = os_zalloc(len + 1); 854 if (name->alt_email == NULL) 855 return -1; 856 os_memcpy(name->alt_email, pos, len); 857 if (os_strlen(name->alt_email) != len) { 858 wpa_printf(MSG_INFO, "X509: Reject certificate with " 859 "embedded NUL byte in rfc822Name (%s[NUL])", 860 name->alt_email); 861 os_free(name->alt_email); 862 name->alt_email = NULL; 863 return -1; 864 } 865 return 0; 866} 867 868 869static int x509_parse_alt_name_dns(struct x509_name *name, 870 const u8 *pos, size_t len) 871{ 872 /* dNSName IA5String */ 873 wpa_hexdump_ascii(MSG_MSGDUMP, "X509: altName - dNSName", pos, len); 874 os_free(name->dns); 875 name->dns = os_zalloc(len + 1); 876 if (name->dns == NULL) 877 return -1; 878 os_memcpy(name->dns, pos, len); 879 if (os_strlen(name->dns) != len) { 880 wpa_printf(MSG_INFO, "X509: Reject certificate with " 881 "embedded NUL byte in dNSName (%s[NUL])", 882 name->dns); 883 os_free(name->dns); 884 name->dns = NULL; 885 return -1; 886 } 887 return 0; 888} 889 890 891static int x509_parse_alt_name_uri(struct x509_name *name, 892 const u8 *pos, size_t len) 893{ 894 /* uniformResourceIdentifier IA5String */ 895 wpa_hexdump_ascii(MSG_MSGDUMP, 896 "X509: altName - uniformResourceIdentifier", 897 pos, len); 898 os_free(name->uri); 899 name->uri = os_zalloc(len + 1); 900 if (name->uri == NULL) 901 return -1; 902 os_memcpy(name->uri, pos, len); 903 if (os_strlen(name->uri) != len) { 904 wpa_printf(MSG_INFO, "X509: Reject certificate with " 905 "embedded NUL byte in uniformResourceIdentifier " 906 "(%s[NUL])", name->uri); 907 os_free(name->uri); 908 name->uri = NULL; 909 return -1; 910 } 911 return 0; 912} 913 914 915static int x509_parse_alt_name_ip(struct x509_name *name, 916 const u8 *pos, size_t len) 917{ 918 /* iPAddress OCTET STRING */ 919 wpa_hexdump(MSG_MSGDUMP, "X509: altName - iPAddress", pos, len); 920 os_free(name->ip); 921 name->ip = os_malloc(len); 922 if (name->ip == NULL) 923 return -1; 924 os_memcpy(name->ip, pos, len); 925 name->ip_len = len; 926 return 0; 927} 928 929 930static int x509_parse_alt_name_rid(struct x509_name *name, 931 const u8 *pos, size_t len) 932{ 933 char buf[80]; 934 935 /* registeredID OBJECT IDENTIFIER */ 936 if (asn1_parse_oid(pos, len, &name->rid) < 0) 937 return -1; 938 939 asn1_oid_to_str(&name->rid, buf, sizeof(buf)); 940 wpa_printf(MSG_MSGDUMP, "X509: altName - registeredID: %s", buf); 941 942 return 0; 943} 944 945 946static int x509_parse_ext_alt_name(struct x509_name *name, 947 const u8 *pos, size_t len) 948{ 949 struct asn1_hdr hdr; 950 const u8 *p, *end; 951 952 /* 953 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName 954 * 955 * GeneralName ::= CHOICE { 956 * otherName [0] OtherName, 957 * rfc822Name [1] IA5String, 958 * dNSName [2] IA5String, 959 * x400Address [3] ORAddress, 960 * directoryName [4] Name, 961 * ediPartyName [5] EDIPartyName, 962 * uniformResourceIdentifier [6] IA5String, 963 * iPAddress [7] OCTET STRING, 964 * registeredID [8] OBJECT IDENTIFIER } 965 * 966 * OtherName ::= SEQUENCE { 967 * type-id OBJECT IDENTIFIER, 968 * value [0] EXPLICIT ANY DEFINED BY type-id } 969 * 970 * EDIPartyName ::= SEQUENCE { 971 * nameAssigner [0] DirectoryString OPTIONAL, 972 * partyName [1] DirectoryString } 973 */ 974 975 for (p = pos, end = pos + len; p < end; p = hdr.payload + hdr.length) { 976 int res; 977 978 if (asn1_get_next(p, end - p, &hdr) < 0) { 979 wpa_printf(MSG_DEBUG, "X509: Failed to parse " 980 "SubjectAltName item"); 981 return -1; 982 } 983 984 if (hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) 985 continue; 986 987 switch (hdr.tag) { 988 case 1: 989 res = x509_parse_alt_name_rfc8222(name, hdr.payload, 990 hdr.length); 991 break; 992 case 2: 993 res = x509_parse_alt_name_dns(name, hdr.payload, 994 hdr.length); 995 break; 996 case 6: 997 res = x509_parse_alt_name_uri(name, hdr.payload, 998 hdr.length); 999 break; 1000 case 7: 1001 res = x509_parse_alt_name_ip(name, hdr.payload, 1002 hdr.length); 1003 break; 1004 case 8: 1005 res = x509_parse_alt_name_rid(name, hdr.payload, 1006 hdr.length); 1007 break; 1008 case 0: /* TODO: otherName */ 1009 case 3: /* TODO: x500Address */ 1010 case 4: /* TODO: directoryName */ 1011 case 5: /* TODO: ediPartyName */ 1012 default: 1013 res = 0; 1014 break; 1015 } 1016 if (res < 0) 1017 return res; 1018 } 1019 1020 return 0; 1021} 1022 1023 1024static int x509_parse_ext_subject_alt_name(struct x509_certificate *cert, 1025 const u8 *pos, size_t len) 1026{ 1027 struct asn1_hdr hdr; 1028 1029 /* SubjectAltName ::= GeneralNames */ 1030 1031 if (asn1_get_next(pos, len, &hdr) < 0 || 1032 hdr.class != ASN1_CLASS_UNIVERSAL || 1033 hdr.tag != ASN1_TAG_SEQUENCE) { 1034 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE in " 1035 "SubjectAltName; found %d tag 0x%x", 1036 hdr.class, hdr.tag); 1037 return -1; 1038 } 1039 1040 wpa_printf(MSG_DEBUG, "X509: SubjectAltName"); 1041 cert->extensions_present |= X509_EXT_SUBJECT_ALT_NAME; 1042 1043 if (hdr.length == 0) 1044 return 0; 1045 1046 return x509_parse_ext_alt_name(&cert->subject, hdr.payload, 1047 hdr.length); 1048} 1049 1050 1051static int x509_parse_ext_issuer_alt_name(struct x509_certificate *cert, 1052 const u8 *pos, size_t len) 1053{ 1054 struct asn1_hdr hdr; 1055 1056 /* IssuerAltName ::= GeneralNames */ 1057 1058 if (asn1_get_next(pos, len, &hdr) < 0 || 1059 hdr.class != ASN1_CLASS_UNIVERSAL || 1060 hdr.tag != ASN1_TAG_SEQUENCE) { 1061 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE in " 1062 "IssuerAltName; found %d tag 0x%x", 1063 hdr.class, hdr.tag); 1064 return -1; 1065 } 1066 1067 wpa_printf(MSG_DEBUG, "X509: IssuerAltName"); 1068 cert->extensions_present |= X509_EXT_ISSUER_ALT_NAME; 1069 1070 if (hdr.length == 0) 1071 return 0; 1072 1073 return x509_parse_ext_alt_name(&cert->issuer, hdr.payload, 1074 hdr.length); 1075} 1076 1077 1078static int x509_parse_extension_data(struct x509_certificate *cert, 1079 struct asn1_oid *oid, 1080 const u8 *pos, size_t len) 1081{ 1082 if (!x509_id_ce_oid(oid)) 1083 return 1; 1084 1085 /* TODO: add other extensions required by RFC 3280, Ch 4.2: 1086 * certificate policies (section 4.2.1.5) 1087 * name constraints (section 4.2.1.11) 1088 * policy constraints (section 4.2.1.12) 1089 * extended key usage (section 4.2.1.13) 1090 * inhibit any-policy (section 4.2.1.15) 1091 */ 1092 switch (oid->oid[3]) { 1093 case 15: /* id-ce-keyUsage */ 1094 return x509_parse_ext_key_usage(cert, pos, len); 1095 case 17: /* id-ce-subjectAltName */ 1096 return x509_parse_ext_subject_alt_name(cert, pos, len); 1097 case 18: /* id-ce-issuerAltName */ 1098 return x509_parse_ext_issuer_alt_name(cert, pos, len); 1099 case 19: /* id-ce-basicConstraints */ 1100 return x509_parse_ext_basic_constraints(cert, pos, len); 1101 default: 1102 return 1; 1103 } 1104} 1105 1106 1107static int x509_parse_extension(struct x509_certificate *cert, 1108 const u8 *pos, size_t len, const u8 **next) 1109{ 1110 const u8 *end; 1111 struct asn1_hdr hdr; 1112 struct asn1_oid oid; 1113 int critical_ext = 0, res; 1114 char buf[80]; 1115 1116 /* 1117 * Extension ::= SEQUENCE { 1118 * extnID OBJECT IDENTIFIER, 1119 * critical BOOLEAN DEFAULT FALSE, 1120 * extnValue OCTET STRING 1121 * } 1122 */ 1123 1124 if (asn1_get_next(pos, len, &hdr) < 0 || 1125 hdr.class != ASN1_CLASS_UNIVERSAL || 1126 hdr.tag != ASN1_TAG_SEQUENCE) { 1127 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header in " 1128 "Extensions: class %d tag 0x%x; expected SEQUENCE", 1129 hdr.class, hdr.tag); 1130 return -1; 1131 } 1132 pos = hdr.payload; 1133 *next = end = pos + hdr.length; 1134 1135 if (asn1_get_oid(pos, end - pos, &oid, &pos) < 0) { 1136 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 data for " 1137 "Extension (expected OID)"); 1138 return -1; 1139 } 1140 1141 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1142 hdr.class != ASN1_CLASS_UNIVERSAL || 1143 (hdr.tag != ASN1_TAG_BOOLEAN && 1144 hdr.tag != ASN1_TAG_OCTETSTRING)) { 1145 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header in " 1146 "Extensions: class %d tag 0x%x; expected BOOLEAN " 1147 "or OCTET STRING", hdr.class, hdr.tag); 1148 return -1; 1149 } 1150 1151 if (hdr.tag == ASN1_TAG_BOOLEAN) { 1152 if (hdr.length != 1) { 1153 wpa_printf(MSG_DEBUG, "X509: Unexpected " 1154 "Boolean length (%u)", hdr.length); 1155 return -1; 1156 } 1157 critical_ext = hdr.payload[0]; 1158 pos = hdr.payload; 1159 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1160 (hdr.class != ASN1_CLASS_UNIVERSAL && 1161 hdr.class != ASN1_CLASS_PRIVATE) || 1162 hdr.tag != ASN1_TAG_OCTETSTRING) { 1163 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header " 1164 "in Extensions: class %d tag 0x%x; " 1165 "expected OCTET STRING", 1166 hdr.class, hdr.tag); 1167 return -1; 1168 } 1169 } 1170 1171 asn1_oid_to_str(&oid, buf, sizeof(buf)); 1172 wpa_printf(MSG_DEBUG, "X509: Extension: extnID=%s critical=%d", 1173 buf, critical_ext); 1174 wpa_hexdump(MSG_MSGDUMP, "X509: extnValue", hdr.payload, hdr.length); 1175 1176 res = x509_parse_extension_data(cert, &oid, hdr.payload, hdr.length); 1177 if (res < 0) 1178 return res; 1179 if (res == 1 && critical_ext) { 1180 wpa_printf(MSG_INFO, "X509: Unknown critical extension %s", 1181 buf); 1182 return -1; 1183 } 1184 1185 return 0; 1186} 1187 1188 1189static int x509_parse_extensions(struct x509_certificate *cert, 1190 const u8 *pos, size_t len) 1191{ 1192 const u8 *end; 1193 struct asn1_hdr hdr; 1194 1195 /* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension */ 1196 1197 if (asn1_get_next(pos, len, &hdr) < 0 || 1198 hdr.class != ASN1_CLASS_UNIVERSAL || 1199 hdr.tag != ASN1_TAG_SEQUENCE) { 1200 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 data " 1201 "for Extensions: class %d tag 0x%x; " 1202 "expected SEQUENCE", hdr.class, hdr.tag); 1203 return -1; 1204 } 1205 1206 pos = hdr.payload; 1207 end = pos + hdr.length; 1208 1209 while (pos < end) { 1210 if (x509_parse_extension(cert, pos, end - pos, &pos) 1211 < 0) 1212 return -1; 1213 } 1214 1215 return 0; 1216} 1217 1218 1219static int x509_parse_tbs_certificate(const u8 *buf, size_t len, 1220 struct x509_certificate *cert, 1221 const u8 **next) 1222{ 1223 struct asn1_hdr hdr; 1224 const u8 *pos, *end; 1225 size_t left; 1226 char sbuf[128]; 1227 unsigned long value; 1228 1229 /* tbsCertificate TBSCertificate ::= SEQUENCE */ 1230 if (asn1_get_next(buf, len, &hdr) < 0 || 1231 hdr.class != ASN1_CLASS_UNIVERSAL || 1232 hdr.tag != ASN1_TAG_SEQUENCE) { 1233 wpa_printf(MSG_DEBUG, "X509: tbsCertificate did not start " 1234 "with a valid SEQUENCE - found class %d tag 0x%x", 1235 hdr.class, hdr.tag); 1236 return -1; 1237 } 1238 pos = hdr.payload; 1239 end = *next = pos + hdr.length; 1240 1241 /* 1242 * version [0] EXPLICIT Version DEFAULT v1 1243 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 1244 */ 1245 if (asn1_get_next(pos, end - pos, &hdr) < 0) 1246 return -1; 1247 pos = hdr.payload; 1248 1249 if (hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC) { 1250 if (asn1_get_next(pos, end - pos, &hdr) < 0) 1251 return -1; 1252 1253 if (hdr.class != ASN1_CLASS_UNIVERSAL || 1254 hdr.tag != ASN1_TAG_INTEGER) { 1255 wpa_printf(MSG_DEBUG, "X509: No INTEGER tag found for " 1256 "version field - found class %d tag 0x%x", 1257 hdr.class, hdr.tag); 1258 return -1; 1259 } 1260 if (hdr.length != 1) { 1261 wpa_printf(MSG_DEBUG, "X509: Unexpected version field " 1262 "length %u (expected 1)", hdr.length); 1263 return -1; 1264 } 1265 pos = hdr.payload; 1266 left = hdr.length; 1267 value = 0; 1268 while (left) { 1269 value <<= 8; 1270 value |= *pos++; 1271 left--; 1272 } 1273 1274 cert->version = value; 1275 if (cert->version != X509_CERT_V1 && 1276 cert->version != X509_CERT_V2 && 1277 cert->version != X509_CERT_V3) { 1278 wpa_printf(MSG_DEBUG, "X509: Unsupported version %d", 1279 cert->version + 1); 1280 return -1; 1281 } 1282 1283 if (asn1_get_next(pos, end - pos, &hdr) < 0) 1284 return -1; 1285 } else 1286 cert->version = X509_CERT_V1; 1287 wpa_printf(MSG_MSGDUMP, "X509: Version X.509v%d", cert->version + 1); 1288 1289 /* serialNumber CertificateSerialNumber ::= INTEGER */ 1290 if (hdr.class != ASN1_CLASS_UNIVERSAL || 1291 hdr.tag != ASN1_TAG_INTEGER) { 1292 wpa_printf(MSG_DEBUG, "X509: No INTEGER tag found for " 1293 "serialNumber; class=%d tag=0x%x", 1294 hdr.class, hdr.tag); 1295 return -1; 1296 } 1297 1298 pos = hdr.payload; 1299 left = hdr.length; 1300 while (left) { 1301 cert->serial_number <<= 8; 1302 cert->serial_number |= *pos++; 1303 left--; 1304 } 1305 wpa_printf(MSG_MSGDUMP, "X509: serialNumber %lu", cert->serial_number); 1306 1307 /* signature AlgorithmIdentifier */ 1308 if (x509_parse_algorithm_identifier(pos, end - pos, &cert->signature, 1309 &pos)) 1310 return -1; 1311 1312 /* issuer Name */ 1313 if (x509_parse_name(pos, end - pos, &cert->issuer, &pos)) 1314 return -1; 1315 x509_name_string(&cert->issuer, sbuf, sizeof(sbuf)); 1316 wpa_printf(MSG_MSGDUMP, "X509: issuer %s", sbuf); 1317 1318 /* validity Validity */ 1319 if (x509_parse_validity(pos, end - pos, cert, &pos)) 1320 return -1; 1321 1322 /* subject Name */ 1323 if (x509_parse_name(pos, end - pos, &cert->subject, &pos)) 1324 return -1; 1325 x509_name_string(&cert->subject, sbuf, sizeof(sbuf)); 1326 wpa_printf(MSG_MSGDUMP, "X509: subject %s", sbuf); 1327 1328 /* subjectPublicKeyInfo SubjectPublicKeyInfo */ 1329 if (x509_parse_public_key(pos, end - pos, cert, &pos)) 1330 return -1; 1331 1332 if (pos == end) 1333 return 0; 1334 1335 if (cert->version == X509_CERT_V1) 1336 return 0; 1337 1338 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1339 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) { 1340 wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific" 1341 " tag to parse optional tbsCertificate " 1342 "field(s); parsed class %d tag 0x%x", 1343 hdr.class, hdr.tag); 1344 return -1; 1345 } 1346 1347 if (hdr.tag == 1) { 1348 /* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL */ 1349 wpa_printf(MSG_DEBUG, "X509: issuerUniqueID"); 1350 /* TODO: parse UniqueIdentifier ::= BIT STRING */ 1351 1352 if (hdr.payload + hdr.length == end) 1353 return 0; 1354 1355 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1356 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) { 1357 wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific" 1358 " tag to parse optional tbsCertificate " 1359 "field(s); parsed class %d tag 0x%x", 1360 hdr.class, hdr.tag); 1361 return -1; 1362 } 1363 } 1364 1365 if (hdr.tag == 2) { 1366 /* subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL */ 1367 wpa_printf(MSG_DEBUG, "X509: subjectUniqueID"); 1368 /* TODO: parse UniqueIdentifier ::= BIT STRING */ 1369 1370 if (hdr.payload + hdr.length == end) 1371 return 0; 1372 1373 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1374 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) { 1375 wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific" 1376 " tag to parse optional tbsCertificate " 1377 "field(s); parsed class %d tag 0x%x", 1378 hdr.class, hdr.tag); 1379 return -1; 1380 } 1381 } 1382 1383 if (hdr.tag != 3) { 1384 wpa_printf(MSG_DEBUG, "X509: Ignored unexpected " 1385 "Context-Specific tag %d in optional " 1386 "tbsCertificate fields", hdr.tag); 1387 return 0; 1388 } 1389 1390 /* extensions [3] EXPLICIT Extensions OPTIONAL */ 1391 1392 if (cert->version != X509_CERT_V3) { 1393 wpa_printf(MSG_DEBUG, "X509: X.509%d certificate and " 1394 "Extensions data which are only allowed for " 1395 "version 3", cert->version + 1); 1396 return -1; 1397 } 1398 1399 if (x509_parse_extensions(cert, hdr.payload, hdr.length) < 0) 1400 return -1; 1401 1402 pos = hdr.payload + hdr.length; 1403 if (pos < end) { 1404 wpa_hexdump(MSG_DEBUG, 1405 "X509: Ignored extra tbsCertificate data", 1406 pos, end - pos); 1407 } 1408 1409 return 0; 1410} 1411 1412 1413static int x509_rsadsi_oid(struct asn1_oid *oid) 1414{ 1415 return oid->len >= 4 && 1416 oid->oid[0] == 1 /* iso */ && 1417 oid->oid[1] == 2 /* member-body */ && 1418 oid->oid[2] == 840 /* us */ && 1419 oid->oid[3] == 113549 /* rsadsi */; 1420} 1421 1422 1423static int x509_pkcs_oid(struct asn1_oid *oid) 1424{ 1425 return oid->len >= 5 && 1426 x509_rsadsi_oid(oid) && 1427 oid->oid[4] == 1 /* pkcs */; 1428} 1429 1430 1431static int x509_digest_oid(struct asn1_oid *oid) 1432{ 1433 return oid->len >= 5 && 1434 x509_rsadsi_oid(oid) && 1435 oid->oid[4] == 2 /* digestAlgorithm */; 1436} 1437 1438 1439static int x509_sha1_oid(struct asn1_oid *oid) 1440{ 1441 return oid->len == 6 && 1442 oid->oid[0] == 1 /* iso */ && 1443 oid->oid[1] == 3 /* identified-organization */ && 1444 oid->oid[2] == 14 /* oiw */ && 1445 oid->oid[3] == 3 /* secsig */ && 1446 oid->oid[4] == 2 /* algorithms */ && 1447 oid->oid[5] == 26 /* id-sha1 */; 1448} 1449 1450 1451static int x509_sha256_oid(struct asn1_oid *oid) 1452{ 1453 return oid->len == 9 && 1454 oid->oid[0] == 2 /* joint-iso-itu-t */ && 1455 oid->oid[1] == 16 /* country */ && 1456 oid->oid[2] == 840 /* us */ && 1457 oid->oid[3] == 1 /* organization */ && 1458 oid->oid[4] == 101 /* gov */ && 1459 oid->oid[5] == 3 /* csor */ && 1460 oid->oid[6] == 4 /* nistAlgorithm */ && 1461 oid->oid[7] == 2 /* hashAlgs */ && 1462 oid->oid[8] == 1 /* sha256 */; 1463} 1464 1465 1466/** 1467 * x509_certificate_parse - Parse a X.509 certificate in DER format 1468 * @buf: Pointer to the X.509 certificate in DER format 1469 * @len: Buffer length 1470 * Returns: Pointer to the parsed certificate or %NULL on failure 1471 * 1472 * Caller is responsible for freeing the returned certificate by calling 1473 * x509_certificate_free(). 1474 */ 1475struct x509_certificate * x509_certificate_parse(const u8 *buf, size_t len) 1476{ 1477 struct asn1_hdr hdr; 1478 const u8 *pos, *end, *hash_start; 1479 struct x509_certificate *cert; 1480 1481 cert = os_zalloc(sizeof(*cert) + len); 1482 if (cert == NULL) 1483 return NULL; 1484 os_memcpy(cert + 1, buf, len); 1485 cert->cert_start = (u8 *) (cert + 1); 1486 cert->cert_len = len; 1487 1488 pos = buf; 1489 end = buf + len; 1490 1491 /* RFC 3280 - X.509 v3 certificate / ASN.1 DER */ 1492 1493 /* Certificate ::= SEQUENCE */ 1494 if (asn1_get_next(pos, len, &hdr) < 0 || 1495 hdr.class != ASN1_CLASS_UNIVERSAL || 1496 hdr.tag != ASN1_TAG_SEQUENCE) { 1497 wpa_printf(MSG_DEBUG, "X509: Certificate did not start with " 1498 "a valid SEQUENCE - found class %d tag 0x%x", 1499 hdr.class, hdr.tag); 1500 x509_certificate_free(cert); 1501 return NULL; 1502 } 1503 pos = hdr.payload; 1504 1505 if (pos + hdr.length > end) { 1506 x509_certificate_free(cert); 1507 return NULL; 1508 } 1509 1510 if (pos + hdr.length < end) { 1511 wpa_hexdump(MSG_MSGDUMP, "X509: Ignoring extra data after DER " 1512 "encoded certificate", 1513 pos + hdr.length, end - pos + hdr.length); 1514 end = pos + hdr.length; 1515 } 1516 1517 hash_start = pos; 1518 cert->tbs_cert_start = cert->cert_start + (hash_start - buf); 1519 if (x509_parse_tbs_certificate(pos, end - pos, cert, &pos)) { 1520 x509_certificate_free(cert); 1521 return NULL; 1522 } 1523 cert->tbs_cert_len = pos - hash_start; 1524 1525 /* signatureAlgorithm AlgorithmIdentifier */ 1526 if (x509_parse_algorithm_identifier(pos, end - pos, 1527 &cert->signature_alg, &pos)) { 1528 x509_certificate_free(cert); 1529 return NULL; 1530 } 1531 1532 /* signatureValue BIT STRING */ 1533 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1534 hdr.class != ASN1_CLASS_UNIVERSAL || 1535 hdr.tag != ASN1_TAG_BITSTRING) { 1536 wpa_printf(MSG_DEBUG, "X509: Expected BITSTRING " 1537 "(signatureValue) - found class %d tag 0x%x", 1538 hdr.class, hdr.tag); 1539 x509_certificate_free(cert); 1540 return NULL; 1541 } 1542 if (hdr.length < 1) { 1543 x509_certificate_free(cert); 1544 return NULL; 1545 } 1546 pos = hdr.payload; 1547 if (*pos) { 1548 wpa_printf(MSG_DEBUG, "X509: BITSTRING - %d unused bits", 1549 *pos); 1550 /* PKCS #1 v1.5 10.2.1: 1551 * It is an error if the length in bits of the signature S is 1552 * not a multiple of eight. 1553 */ 1554 x509_certificate_free(cert); 1555 return NULL; 1556 } 1557 os_free(cert->sign_value); 1558 cert->sign_value = os_malloc(hdr.length - 1); 1559 if (cert->sign_value == NULL) { 1560 wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for " 1561 "signatureValue"); 1562 x509_certificate_free(cert); 1563 return NULL; 1564 } 1565 os_memcpy(cert->sign_value, pos + 1, hdr.length - 1); 1566 cert->sign_value_len = hdr.length - 1; 1567 wpa_hexdump(MSG_MSGDUMP, "X509: signature", 1568 cert->sign_value, cert->sign_value_len); 1569 1570 return cert; 1571} 1572 1573 1574/** 1575 * x509_certificate_check_signature - Verify certificate signature 1576 * @issuer: Issuer certificate 1577 * @cert: Certificate to be verified 1578 * Returns: 0 if cert has a valid signature that was signed by the issuer, 1579 * -1 if not 1580 */ 1581int x509_certificate_check_signature(struct x509_certificate *issuer, 1582 struct x509_certificate *cert) 1583{ 1584 struct crypto_public_key *pk; 1585 u8 *data; 1586 const u8 *pos, *end, *next, *da_end; 1587 size_t data_len; 1588 struct asn1_hdr hdr; 1589 struct asn1_oid oid; 1590 u8 hash[32]; 1591 size_t hash_len; 1592 1593 if (!x509_pkcs_oid(&cert->signature.oid) || 1594 cert->signature.oid.len != 7 || 1595 cert->signature.oid.oid[5] != 1 /* pkcs-1 */) { 1596 wpa_printf(MSG_DEBUG, "X509: Unrecognized signature " 1597 "algorithm"); 1598 return -1; 1599 } 1600 1601 pk = crypto_public_key_import(issuer->public_key, 1602 issuer->public_key_len); 1603 if (pk == NULL) 1604 return -1; 1605 1606 data_len = cert->sign_value_len; 1607 data = os_malloc(data_len); 1608 if (data == NULL) { 1609 crypto_public_key_free(pk); 1610 return -1; 1611 } 1612 1613 if (crypto_public_key_decrypt_pkcs1(pk, cert->sign_value, 1614 cert->sign_value_len, data, 1615 &data_len) < 0) { 1616 wpa_printf(MSG_DEBUG, "X509: Failed to decrypt signature"); 1617 crypto_public_key_free(pk); 1618 os_free(data); 1619 return -1; 1620 } 1621 crypto_public_key_free(pk); 1622 1623 wpa_hexdump(MSG_MSGDUMP, "X509: Signature data D", data, data_len); 1624 1625 /* 1626 * PKCS #1 v1.5, 10.1.2: 1627 * 1628 * DigestInfo ::= SEQUENCE { 1629 * digestAlgorithm DigestAlgorithmIdentifier, 1630 * digest Digest 1631 * } 1632 * 1633 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier 1634 * 1635 * Digest ::= OCTET STRING 1636 * 1637 */ 1638 if (asn1_get_next(data, data_len, &hdr) < 0 || 1639 hdr.class != ASN1_CLASS_UNIVERSAL || 1640 hdr.tag != ASN1_TAG_SEQUENCE) { 1641 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 1642 "(DigestInfo) - found class %d tag 0x%x", 1643 hdr.class, hdr.tag); 1644 os_free(data); 1645 return -1; 1646 } 1647 1648 pos = hdr.payload; 1649 end = pos + hdr.length; 1650 1651 /* 1652 * X.509: 1653 * AlgorithmIdentifier ::= SEQUENCE { 1654 * algorithm OBJECT IDENTIFIER, 1655 * parameters ANY DEFINED BY algorithm OPTIONAL 1656 * } 1657 */ 1658 1659 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1660 hdr.class != ASN1_CLASS_UNIVERSAL || 1661 hdr.tag != ASN1_TAG_SEQUENCE) { 1662 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 1663 "(AlgorithmIdentifier) - found class %d tag 0x%x", 1664 hdr.class, hdr.tag); 1665 os_free(data); 1666 return -1; 1667 } 1668 da_end = hdr.payload + hdr.length; 1669 1670 if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) { 1671 wpa_printf(MSG_DEBUG, "X509: Failed to parse digestAlgorithm"); 1672 os_free(data); 1673 return -1; 1674 } 1675 1676 if (x509_sha1_oid(&oid)) { 1677 if (cert->signature.oid.oid[6] != 1678 5 /* sha-1WithRSAEncryption */) { 1679 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA1 " 1680 "does not match with certificate " 1681 "signatureAlgorithm (%lu)", 1682 cert->signature.oid.oid[6]); 1683 os_free(data); 1684 return -1; 1685 } 1686 goto skip_digest_oid; 1687 } 1688 1689 if (x509_sha256_oid(&oid)) { 1690 if (cert->signature.oid.oid[6] != 1691 11 /* sha2561WithRSAEncryption */) { 1692 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA256 " 1693 "does not match with certificate " 1694 "signatureAlgorithm (%lu)", 1695 cert->signature.oid.oid[6]); 1696 os_free(data); 1697 return -1; 1698 } 1699 goto skip_digest_oid; 1700 } 1701 1702 if (!x509_digest_oid(&oid)) { 1703 wpa_printf(MSG_DEBUG, "X509: Unrecognized digestAlgorithm"); 1704 os_free(data); 1705 return -1; 1706 } 1707 switch (oid.oid[5]) { 1708 case 5: /* md5 */ 1709 if (cert->signature.oid.oid[6] != 4 /* md5WithRSAEncryption */) 1710 { 1711 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm MD5 does " 1712 "not match with certificate " 1713 "signatureAlgorithm (%lu)", 1714 cert->signature.oid.oid[6]); 1715 os_free(data); 1716 return -1; 1717 } 1718 break; 1719 case 2: /* md2 */ 1720 case 4: /* md4 */ 1721 default: 1722 wpa_printf(MSG_DEBUG, "X509: Unsupported digestAlgorithm " 1723 "(%lu)", oid.oid[5]); 1724 os_free(data); 1725 return -1; 1726 } 1727 1728skip_digest_oid: 1729 /* Digest ::= OCTET STRING */ 1730 pos = da_end; 1731 end = data + data_len; 1732 1733 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1734 hdr.class != ASN1_CLASS_UNIVERSAL || 1735 hdr.tag != ASN1_TAG_OCTETSTRING) { 1736 wpa_printf(MSG_DEBUG, "X509: Expected OCTETSTRING " 1737 "(Digest) - found class %d tag 0x%x", 1738 hdr.class, hdr.tag); 1739 os_free(data); 1740 return -1; 1741 } 1742 wpa_hexdump(MSG_MSGDUMP, "X509: Decrypted Digest", 1743 hdr.payload, hdr.length); 1744 1745 switch (cert->signature.oid.oid[6]) { 1746 case 4: /* md5WithRSAEncryption */ 1747 md5_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len, 1748 hash); 1749 hash_len = 16; 1750 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (MD5)", 1751 hash, hash_len); 1752 break; 1753 case 5: /* sha-1WithRSAEncryption */ 1754 sha1_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len, 1755 hash); 1756 hash_len = 20; 1757 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA1)", 1758 hash, hash_len); 1759 break; 1760 case 11: /* sha256WithRSAEncryption */ 1761 sha256_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len, 1762 hash); 1763 hash_len = 32; 1764 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA256)", 1765 hash, hash_len); 1766 break; 1767 case 2: /* md2WithRSAEncryption */ 1768 case 12: /* sha384WithRSAEncryption */ 1769 case 13: /* sha512WithRSAEncryption */ 1770 default: 1771 wpa_printf(MSG_INFO, "X509: Unsupported certificate signature " 1772 "algorithm (%lu)", cert->signature.oid.oid[6]); 1773 os_free(data); 1774 return -1; 1775 } 1776 1777 if (hdr.length != hash_len || 1778 os_memcmp(hdr.payload, hash, hdr.length) != 0) { 1779 wpa_printf(MSG_INFO, "X509: Certificate Digest does not match " 1780 "with calculated tbsCertificate hash"); 1781 os_free(data); 1782 return -1; 1783 } 1784 1785 os_free(data); 1786 1787 wpa_printf(MSG_DEBUG, "X509: Certificate Digest matches with " 1788 "calculated tbsCertificate hash"); 1789 1790 return 0; 1791} 1792 1793 1794static int x509_valid_issuer(const struct x509_certificate *cert) 1795{ 1796 if ((cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS) && 1797 !cert->ca) { 1798 wpa_printf(MSG_DEBUG, "X509: Non-CA certificate used as an " 1799 "issuer"); 1800 return -1; 1801 } 1802 1803 if (cert->version == X509_CERT_V3 && 1804 !(cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS)) { 1805 wpa_printf(MSG_DEBUG, "X509: v3 CA certificate did not " 1806 "include BasicConstraints extension"); 1807 return -1; 1808 } 1809 1810 if ((cert->extensions_present & X509_EXT_KEY_USAGE) && 1811 !(cert->key_usage & X509_KEY_USAGE_KEY_CERT_SIGN)) { 1812 wpa_printf(MSG_DEBUG, "X509: Issuer certificate did not have " 1813 "keyCertSign bit in Key Usage"); 1814 return -1; 1815 } 1816 1817 return 0; 1818} 1819 1820 1821/** 1822 * x509_certificate_chain_validate - Validate X.509 certificate chain 1823 * @trusted: List of trusted certificates 1824 * @chain: Certificate chain to be validated (first chain must be issued by 1825 * signed by the second certificate in the chain and so on) 1826 * @reason: Buffer for returning failure reason (X509_VALIDATE_*) 1827 * Returns: 0 if chain is valid, -1 if not 1828 */ 1829int x509_certificate_chain_validate(struct x509_certificate *trusted, 1830 struct x509_certificate *chain, 1831 int *reason, int disable_time_checks) 1832{ 1833 long unsigned idx; 1834 int chain_trusted = 0; 1835 struct x509_certificate *cert, *trust; 1836 char buf[128]; 1837 struct os_time now; 1838 1839 *reason = X509_VALIDATE_OK; 1840 1841 wpa_printf(MSG_DEBUG, "X509: Validate certificate chain"); 1842 os_get_time(&now); 1843 1844 for (cert = chain, idx = 0; cert; cert = cert->next, idx++) { 1845 x509_name_string(&cert->subject, buf, sizeof(buf)); 1846 wpa_printf(MSG_DEBUG, "X509: %lu: %s", idx, buf); 1847 1848 if (chain_trusted) 1849 continue; 1850 1851 if (!disable_time_checks && 1852 ((unsigned long) now.sec < 1853 (unsigned long) cert->not_before || 1854 (unsigned long) now.sec > 1855 (unsigned long) cert->not_after)) { 1856 wpa_printf(MSG_INFO, "X509: Certificate not valid " 1857 "(now=%lu not_before=%lu not_after=%lu)", 1858 now.sec, cert->not_before, cert->not_after); 1859 *reason = X509_VALIDATE_CERTIFICATE_EXPIRED; 1860 return -1; 1861 } 1862 1863 if (cert->next) { 1864 if (x509_name_compare(&cert->issuer, 1865 &cert->next->subject) != 0) { 1866 wpa_printf(MSG_DEBUG, "X509: Certificate " 1867 "chain issuer name mismatch"); 1868 x509_name_string(&cert->issuer, buf, 1869 sizeof(buf)); 1870 wpa_printf(MSG_DEBUG, "X509: cert issuer: %s", 1871 buf); 1872 x509_name_string(&cert->next->subject, buf, 1873 sizeof(buf)); 1874 wpa_printf(MSG_DEBUG, "X509: next cert " 1875 "subject: %s", buf); 1876 *reason = X509_VALIDATE_CERTIFICATE_UNKNOWN; 1877 return -1; 1878 } 1879 1880 if (x509_valid_issuer(cert->next) < 0) { 1881 *reason = X509_VALIDATE_BAD_CERTIFICATE; 1882 return -1; 1883 } 1884 1885 if ((cert->next->extensions_present & 1886 X509_EXT_PATH_LEN_CONSTRAINT) && 1887 idx > cert->next->path_len_constraint) { 1888 wpa_printf(MSG_DEBUG, "X509: pathLenConstraint" 1889 " not met (idx=%lu issuer " 1890 "pathLenConstraint=%lu)", idx, 1891 cert->next->path_len_constraint); 1892 *reason = X509_VALIDATE_BAD_CERTIFICATE; 1893 return -1; 1894 } 1895 1896 if (x509_certificate_check_signature(cert->next, cert) 1897 < 0) { 1898 wpa_printf(MSG_DEBUG, "X509: Invalid " 1899 "certificate signature within " 1900 "chain"); 1901 *reason = X509_VALIDATE_BAD_CERTIFICATE; 1902 return -1; 1903 } 1904 } 1905 1906 for (trust = trusted; trust; trust = trust->next) { 1907 if (x509_name_compare(&cert->issuer, &trust->subject) 1908 == 0) 1909 break; 1910 } 1911 1912 if (trust) { 1913 wpa_printf(MSG_DEBUG, "X509: Found issuer from the " 1914 "list of trusted certificates"); 1915 if (x509_valid_issuer(trust) < 0) { 1916 *reason = X509_VALIDATE_BAD_CERTIFICATE; 1917 return -1; 1918 } 1919 1920 if (x509_certificate_check_signature(trust, cert) < 0) 1921 { 1922 wpa_printf(MSG_DEBUG, "X509: Invalid " 1923 "certificate signature"); 1924 *reason = X509_VALIDATE_BAD_CERTIFICATE; 1925 return -1; 1926 } 1927 1928 wpa_printf(MSG_DEBUG, "X509: Trusted certificate " 1929 "found to complete the chain"); 1930 chain_trusted = 1; 1931 } 1932 } 1933 1934 if (!chain_trusted) { 1935 wpa_printf(MSG_DEBUG, "X509: Did not find any of the issuers " 1936 "from the list of trusted certificates"); 1937 if (trusted) { 1938 *reason = X509_VALIDATE_UNKNOWN_CA; 1939 return -1; 1940 } 1941 wpa_printf(MSG_DEBUG, "X509: Certificate chain validation " 1942 "disabled - ignore unknown CA issue"); 1943 } 1944 1945 wpa_printf(MSG_DEBUG, "X509: Certificate chain valid"); 1946 1947 return 0; 1948} 1949 1950 1951/** 1952 * x509_certificate_get_subject - Get a certificate based on Subject name 1953 * @chain: Certificate chain to search through 1954 * @name: Subject name to search for 1955 * Returns: Pointer to the certificate with the given Subject name or 1956 * %NULL on failure 1957 */ 1958struct x509_certificate * 1959x509_certificate_get_subject(struct x509_certificate *chain, 1960 struct x509_name *name) 1961{ 1962 struct x509_certificate *cert; 1963 1964 for (cert = chain; cert; cert = cert->next) { 1965 if (x509_name_compare(&cert->subject, name) == 0) 1966 return cert; 1967 } 1968 return NULL; 1969} 1970 1971 1972/** 1973 * x509_certificate_self_signed - Is the certificate self-signed? 1974 * @cert: Certificate 1975 * Returns: 1 if certificate is self-signed, 0 if not 1976 */ 1977int x509_certificate_self_signed(struct x509_certificate *cert) 1978{ 1979 return x509_name_compare(&cert->issuer, &cert->subject) == 0; 1980} 1981