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