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 /** 1189 * x509_certificate_parse - Parse a X.509 certificate in DER format 1190 * @buf: Pointer to the X.509 certificate in DER format 1191 * @len: Buffer length 1192 * Returns: Pointer to the parsed certificate or %NULL on failure 1193 * 1194 * Caller is responsible for freeing the returned certificate by calling 1195 * x509_certificate_free(). 1196 */ 1197 struct x509_certificate * x509_certificate_parse(const u8 *buf, size_t len) 1198 { 1199 struct asn1_hdr hdr; 1200 const u8 *pos, *end, *hash_start; 1201 struct x509_certificate *cert; 1202 1203 cert = os_zalloc(sizeof(*cert) + len); 1204 if (cert == NULL) 1205 return NULL; 1206 os_memcpy(cert + 1, buf, len); 1207 cert->cert_start = (u8 *) (cert + 1); 1208 cert->cert_len = len; 1209 1210 pos = buf; 1211 end = buf + len; 1212 1213 /* RFC 3280 - X.509 v3 certificate / ASN.1 DER */ 1214 1215 /* Certificate ::= SEQUENCE */ 1216 if (asn1_get_next(pos, len, &hdr) < 0 || 1217 hdr.class != ASN1_CLASS_UNIVERSAL || 1218 hdr.tag != ASN1_TAG_SEQUENCE) { 1219 wpa_printf(MSG_DEBUG, "X509: Certificate did not start with " 1220 "a valid SEQUENCE - found class %d tag 0x%x", 1221 hdr.class, hdr.tag); 1222 x509_certificate_free(cert); 1223 return NULL; 1224 } 1225 pos = hdr.payload; 1226 1227 if (pos + hdr.length > end) { 1228 x509_certificate_free(cert); 1229 return NULL; 1230 } 1231 1232 if (pos + hdr.length < end) { 1233 wpa_hexdump(MSG_MSGDUMP, "X509: Ignoring extra data after DER " 1234 "encoded certificate", 1235 pos + hdr.length, end - pos + hdr.length); 1236 end = pos + hdr.length; 1237 } 1238 1239 hash_start = pos; 1240 cert->tbs_cert_start = cert->cert_start + (hash_start - buf); 1241 if (x509_parse_tbs_certificate(pos, end - pos, cert, &pos)) { 1242 x509_certificate_free(cert); 1243 return NULL; 1244 } 1245 cert->tbs_cert_len = pos - hash_start; 1246 1247 /* signatureAlgorithm AlgorithmIdentifier */ 1248 if (x509_parse_algorithm_identifier(pos, end - pos, 1249 &cert->signature_alg, &pos)) { 1250 x509_certificate_free(cert); 1251 return NULL; 1252 } 1253 1254 /* signatureValue BIT STRING */ 1255 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1256 hdr.class != ASN1_CLASS_UNIVERSAL || 1257 hdr.tag != ASN1_TAG_BITSTRING) { 1258 wpa_printf(MSG_DEBUG, "X509: Expected BITSTRING " 1259 "(signatureValue) - found class %d tag 0x%x", 1260 hdr.class, hdr.tag); 1261 x509_certificate_free(cert); 1262 return NULL; 1263 } 1264 if (hdr.length < 1) { 1265 x509_certificate_free(cert); 1266 return NULL; 1267 } 1268 pos = hdr.payload; 1269 if (*pos) { 1270 wpa_printf(MSG_DEBUG, "X509: BITSTRING - %d unused bits", 1271 *pos); 1272 /* PKCS #1 v1.5 10.2.1: 1273 * It is an error if the length in bits of the signature S is 1274 * not a multiple of eight. 1275 */ 1276 x509_certificate_free(cert); 1277 return NULL; 1278 } 1279 os_free(cert->sign_value); 1280 cert->sign_value = os_malloc(hdr.length - 1); 1281 if (cert->sign_value == NULL) { 1282 wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for " 1283 "signatureValue"); 1284 x509_certificate_free(cert); 1285 return NULL; 1286 } 1287 os_memcpy(cert->sign_value, pos + 1, hdr.length - 1); 1288 cert->sign_value_len = hdr.length - 1; 1289 wpa_hexdump(MSG_MSGDUMP, "X509: signature", 1290 cert->sign_value, cert->sign_value_len); 1291 1292 return cert; 1293 } 1294 1295 1296 /** 1297 * x509_certificate_check_signature - Verify certificate signature 1298 * @issuer: Issuer certificate 1299 * @cert: Certificate to be verified 1300 * Returns: 0 if cert has a valid signature that was signed by the issuer, 1301 * -1 if not 1302 */ 1303 int x509_certificate_check_signature(struct x509_certificate *issuer, 1304 struct x509_certificate *cert) 1305 { 1306 struct crypto_public_key *pk; 1307 u8 *data; 1308 const u8 *pos, *end, *next, *da_end; 1309 size_t data_len; 1310 struct asn1_hdr hdr; 1311 struct asn1_oid oid; 1312 u8 hash[20]; 1313 size_t hash_len; 1314 1315 if (!x509_pkcs_oid(&cert->signature.oid) || 1316 cert->signature.oid.len != 7 || 1317 cert->signature.oid.oid[5] != 1 /* pkcs-1 */) { 1318 wpa_printf(MSG_DEBUG, "X509: Unrecognized signature " 1319 "algorithm"); 1320 return -1; 1321 } 1322 1323 pk = crypto_public_key_import(issuer->public_key, 1324 issuer->public_key_len); 1325 if (pk == NULL) 1326 return -1; 1327 1328 data_len = cert->sign_value_len; 1329 data = os_malloc(data_len); 1330 if (data == NULL) { 1331 crypto_public_key_free(pk); 1332 return -1; 1333 } 1334 1335 if (crypto_public_key_decrypt_pkcs1(pk, cert->sign_value, 1336 cert->sign_value_len, data, 1337 &data_len) < 0) { 1338 wpa_printf(MSG_DEBUG, "X509: Failed to decrypt signature"); 1339 crypto_public_key_free(pk); 1340 os_free(data); 1341 return -1; 1342 } 1343 crypto_public_key_free(pk); 1344 1345 wpa_hexdump(MSG_MSGDUMP, "X509: Signature data D", data, data_len); 1346 1347 /* 1348 * PKCS #1 v1.5, 10.1.2: 1349 * 1350 * DigestInfo ::= SEQUENCE { 1351 * digestAlgorithm DigestAlgorithmIdentifier, 1352 * digest Digest 1353 * } 1354 * 1355 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier 1356 * 1357 * Digest ::= OCTET STRING 1358 * 1359 */ 1360 if (asn1_get_next(data, data_len, &hdr) < 0 || 1361 hdr.class != ASN1_CLASS_UNIVERSAL || 1362 hdr.tag != ASN1_TAG_SEQUENCE) { 1363 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 1364 "(DigestInfo) - found class %d tag 0x%x", 1365 hdr.class, hdr.tag); 1366 os_free(data); 1367 return -1; 1368 } 1369 1370 pos = hdr.payload; 1371 end = pos + hdr.length; 1372 1373 /* 1374 * X.509: 1375 * AlgorithmIdentifier ::= SEQUENCE { 1376 * algorithm OBJECT IDENTIFIER, 1377 * parameters ANY DEFINED BY algorithm OPTIONAL 1378 * } 1379 */ 1380 1381 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1382 hdr.class != ASN1_CLASS_UNIVERSAL || 1383 hdr.tag != ASN1_TAG_SEQUENCE) { 1384 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 1385 "(AlgorithmIdentifier) - found class %d tag 0x%x", 1386 hdr.class, hdr.tag); 1387 os_free(data); 1388 return -1; 1389 } 1390 da_end = hdr.payload + hdr.length; 1391 1392 if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) { 1393 wpa_printf(MSG_DEBUG, "X509: Failed to parse digestAlgorithm"); 1394 os_free(data); 1395 return -1; 1396 } 1397 1398 if (x509_sha1_oid(&oid)) { 1399 if (cert->signature.oid.oid[6] != 1400 5 /* sha-1WithRSAEncryption */) { 1401 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA1 " 1402 "does not match with certificate " 1403 "signatureAlgorithm (%lu)", 1404 cert->signature.oid.oid[6]); 1405 os_free(data); 1406 return -1; 1407 } 1408 goto skip_digest_oid; 1409 } 1410 1411 if (!x509_digest_oid(&oid)) { 1412 wpa_printf(MSG_DEBUG, "X509: Unrecognized digestAlgorithm"); 1413 os_free(data); 1414 return -1; 1415 } 1416 switch (oid.oid[5]) { 1417 case 5: /* md5 */ 1418 if (cert->signature.oid.oid[6] != 4 /* md5WithRSAEncryption */) 1419 { 1420 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm MD5 does " 1421 "not match with certificate " 1422 "signatureAlgorithm (%lu)", 1423 cert->signature.oid.oid[6]); 1424 os_free(data); 1425 return -1; 1426 } 1427 break; 1428 case 2: /* md2 */ 1429 case 4: /* md4 */ 1430 default: 1431 wpa_printf(MSG_DEBUG, "X509: Unsupported digestAlgorithm " 1432 "(%lu)", oid.oid[5]); 1433 os_free(data); 1434 return -1; 1435 } 1436 1437 skip_digest_oid: 1438 /* Digest ::= OCTET STRING */ 1439 pos = da_end; 1440 end = data + data_len; 1441 1442 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 1443 hdr.class != ASN1_CLASS_UNIVERSAL || 1444 hdr.tag != ASN1_TAG_OCTETSTRING) { 1445 wpa_printf(MSG_DEBUG, "X509: Expected OCTETSTRING " 1446 "(Digest) - found class %d tag 0x%x", 1447 hdr.class, hdr.tag); 1448 os_free(data); 1449 return -1; 1450 } 1451 wpa_hexdump(MSG_MSGDUMP, "X509: Decrypted Digest", 1452 hdr.payload, hdr.length); 1453 1454 switch (cert->signature.oid.oid[6]) { 1455 case 4: /* md5WithRSAEncryption */ 1456 md5_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len, 1457 hash); 1458 hash_len = 16; 1459 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (MD5)", 1460 hash, hash_len); 1461 break; 1462 case 5: /* sha-1WithRSAEncryption */ 1463 sha1_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len, 1464 hash); 1465 hash_len = 20; 1466 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA1)", 1467 hash, hash_len); 1468 break; 1469 case 2: /* md2WithRSAEncryption */ 1470 case 11: /* sha256WithRSAEncryption */ 1471 case 12: /* sha384WithRSAEncryption */ 1472 case 13: /* sha512WithRSAEncryption */ 1473 default: 1474 wpa_printf(MSG_INFO, "X509: Unsupported certificate signature " 1475 "algorithm (%lu)", cert->signature.oid.oid[6]); 1476 os_free(data); 1477 return -1; 1478 } 1479 1480 if (hdr.length != hash_len || 1481 os_memcmp(hdr.payload, hash, hdr.length) != 0) { 1482 wpa_printf(MSG_INFO, "X509: Certificate Digest does not match " 1483 "with calculated tbsCertificate hash"); 1484 os_free(data); 1485 return -1; 1486 } 1487 1488 os_free(data); 1489 1490 wpa_printf(MSG_DEBUG, "X509: Certificate Digest matches with " 1491 "calculated tbsCertificate hash"); 1492 1493 return 0; 1494 } 1495 1496 1497 static int x509_valid_issuer(const struct x509_certificate *cert) 1498 { 1499 if ((cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS) && 1500 !cert->ca) { 1501 wpa_printf(MSG_DEBUG, "X509: Non-CA certificate used as an " 1502 "issuer"); 1503 return -1; 1504 } 1505 1506 if (cert->version == X509_CERT_V3 && 1507 !(cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS)) { 1508 wpa_printf(MSG_DEBUG, "X509: v3 CA certificate did not " 1509 "include BasicConstraints extension"); 1510 return -1; 1511 } 1512 1513 if ((cert->extensions_present & X509_EXT_KEY_USAGE) && 1514 !(cert->key_usage & X509_KEY_USAGE_KEY_CERT_SIGN)) { 1515 wpa_printf(MSG_DEBUG, "X509: Issuer certificate did not have " 1516 "keyCertSign bit in Key Usage"); 1517 return -1; 1518 } 1519 1520 return 0; 1521 } 1522 1523 1524 /** 1525 * x509_certificate_chain_validate - Validate X.509 certificate chain 1526 * @trusted: List of trusted certificates 1527 * @chain: Certificate chain to be validated (first chain must be issued by 1528 * signed by the second certificate in the chain and so on) 1529 * @reason: Buffer for returning failure reason (X509_VALIDATE_*) 1530 * Returns: 0 if chain is valid, -1 if not 1531 */ 1532 int x509_certificate_chain_validate(struct x509_certificate *trusted, 1533 struct x509_certificate *chain, 1534 int *reason) 1535 { 1536 long unsigned idx; 1537 int chain_trusted = 0; 1538 struct x509_certificate *cert, *trust; 1539 char buf[128]; 1540 struct os_time now; 1541 1542 *reason = X509_VALIDATE_OK; 1543 1544 wpa_printf(MSG_DEBUG, "X509: Validate certificate chain"); 1545 os_get_time(&now); 1546 1547 for (cert = chain, idx = 0; cert; cert = cert->next, idx++) { 1548 x509_name_string(&cert->subject, buf, sizeof(buf)); 1549 wpa_printf(MSG_DEBUG, "X509: %lu: %s", idx, buf); 1550 1551 if (chain_trusted) 1552 continue; 1553 1554 if ((unsigned long) now.sec < 1555 (unsigned long) cert->not_before || 1556 (unsigned long) now.sec > 1557 (unsigned long) cert->not_after) { 1558 wpa_printf(MSG_INFO, "X509: Certificate not valid " 1559 "(now=%lu not_before=%lu not_after=%lu)", 1560 now.sec, cert->not_before, cert->not_after); 1561 *reason = X509_VALIDATE_CERTIFICATE_EXPIRED; 1562 return -1; 1563 } 1564 1565 if (cert->next) { 1566 if (x509_name_compare(&cert->issuer, 1567 &cert->next->subject) != 0) { 1568 wpa_printf(MSG_DEBUG, "X509: Certificate " 1569 "chain issuer name mismatch"); 1570 *reason = X509_VALIDATE_CERTIFICATE_UNKNOWN; 1571 return -1; 1572 } 1573 1574 if (x509_valid_issuer(cert->next) < 0) { 1575 *reason = X509_VALIDATE_BAD_CERTIFICATE; 1576 return -1; 1577 } 1578 1579 if ((cert->next->extensions_present & 1580 X509_EXT_PATH_LEN_CONSTRAINT) && 1581 idx > cert->next->path_len_constraint) { 1582 wpa_printf(MSG_DEBUG, "X509: pathLenConstraint" 1583 " not met (idx=%lu issuer " 1584 "pathLenConstraint=%lu)", idx, 1585 cert->next->path_len_constraint); 1586 *reason = X509_VALIDATE_BAD_CERTIFICATE; 1587 return -1; 1588 } 1589 1590 if (x509_certificate_check_signature(cert->next, cert) 1591 < 0) { 1592 wpa_printf(MSG_DEBUG, "X509: Invalid " 1593 "certificate signature within " 1594 "chain"); 1595 *reason = X509_VALIDATE_BAD_CERTIFICATE; 1596 return -1; 1597 } 1598 } 1599 1600 for (trust = trusted; trust; trust = trust->next) { 1601 if (x509_name_compare(&cert->issuer, &trust->subject) 1602 == 0) 1603 break; 1604 } 1605 1606 if (trust) { 1607 wpa_printf(MSG_DEBUG, "X509: Found issuer from the " 1608 "list of trusted certificates"); 1609 if (x509_valid_issuer(trust) < 0) { 1610 *reason = X509_VALIDATE_BAD_CERTIFICATE; 1611 return -1; 1612 } 1613 1614 if (x509_certificate_check_signature(trust, cert) < 0) 1615 { 1616 wpa_printf(MSG_DEBUG, "X509: Invalid " 1617 "certificate signature"); 1618 *reason = X509_VALIDATE_BAD_CERTIFICATE; 1619 return -1; 1620 } 1621 1622 wpa_printf(MSG_DEBUG, "X509: Trusted certificate " 1623 "found to complete the chain"); 1624 chain_trusted = 1; 1625 } 1626 } 1627 1628 if (!chain_trusted) { 1629 wpa_printf(MSG_DEBUG, "X509: Did not find any of the issuers " 1630 "from the list of trusted certificates"); 1631 if (trusted) { 1632 *reason = X509_VALIDATE_UNKNOWN_CA; 1633 return -1; 1634 } 1635 wpa_printf(MSG_DEBUG, "X509: Certificate chain validation " 1636 "disabled - ignore unknown CA issue"); 1637 } 1638 1639 wpa_printf(MSG_DEBUG, "X509: Certificate chain valid"); 1640 1641 return 0; 1642 } 1643 1644 1645 /** 1646 * x509_certificate_get_subject - Get a certificate based on Subject name 1647 * @chain: Certificate chain to search through 1648 * @name: Subject name to search for 1649 * Returns: Pointer to the certificate with the given Subject name or 1650 * %NULL on failure 1651 */ 1652 struct x509_certificate * 1653 x509_certificate_get_subject(struct x509_certificate *chain, 1654 struct x509_name *name) 1655 { 1656 struct x509_certificate *cert; 1657 1658 for (cert = chain; cert; cert = cert->next) { 1659 if (x509_name_compare(&cert->subject, name) == 0) 1660 return cert; 1661 } 1662 return NULL; 1663 } 1664 1665 1666 /** 1667 * x509_certificate_self_signed - Is the certificate self-signed? 1668 * @cert: Certificate 1669 * Returns: 1 if certificate is self-signed, 0 if not 1670 */ 1671 int x509_certificate_self_signed(struct x509_certificate *cert) 1672 { 1673 return x509_name_compare(&cert->issuer, &cert->subject) == 0; 1674 } 1675 1676 #endif /* CONFIG_INTERNAL_X509 */ 1677