$search
00001 /* 00002 * X.509v3 certificate parsing and processing (RFC 3280 profile) 00003 * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 00017 #include "common.h" 00018 #include "crypto/crypto.h" 00019 #include "asn1.h" 00020 #include "x509v3.h" 00021 00022 00023 static void x509_free_name(struct x509_name *name) 00024 { 00025 os_free(name->cn); 00026 os_free(name->c); 00027 os_free(name->l); 00028 os_free(name->st); 00029 os_free(name->o); 00030 os_free(name->ou); 00031 os_free(name->email); 00032 name->cn = name->c = name->l = name->st = name->o = name->ou = NULL; 00033 name->email = NULL; 00034 00035 os_free(name->alt_email); 00036 os_free(name->dns); 00037 os_free(name->uri); 00038 os_free(name->ip); 00039 name->alt_email = name->dns = name->uri = NULL; 00040 name->ip = NULL; 00041 name->ip_len = 0; 00042 os_memset(&name->rid, 0, sizeof(name->rid)); 00043 } 00044 00045 00050 void x509_certificate_free(struct x509_certificate *cert) 00051 { 00052 if (cert == NULL) 00053 return; 00054 if (cert->next) { 00055 wpa_printf(MSG_DEBUG, "X509: x509_certificate_free: cer=%p " 00056 "was still on a list (next=%p)\n", 00057 cert, cert->next); 00058 } 00059 x509_free_name(&cert->issuer); 00060 x509_free_name(&cert->subject); 00061 os_free(cert->public_key); 00062 os_free(cert->sign_value); 00063 os_free(cert); 00064 } 00065 00066 00071 void x509_certificate_chain_free(struct x509_certificate *cert) 00072 { 00073 struct x509_certificate *next; 00074 00075 while (cert) { 00076 next = cert->next; 00077 cert->next = NULL; 00078 x509_certificate_free(cert); 00079 cert = next; 00080 } 00081 } 00082 00083 00084 static int x509_whitespace(char c) 00085 { 00086 return c == ' ' || c == '\t'; 00087 } 00088 00089 00090 static void x509_str_strip_whitespace(char *a) 00091 { 00092 char *ipos, *opos; 00093 int remove_whitespace = 1; 00094 00095 ipos = opos = a; 00096 00097 while (*ipos) { 00098 if (remove_whitespace && x509_whitespace(*ipos)) 00099 ipos++; 00100 else { 00101 remove_whitespace = x509_whitespace(*ipos); 00102 *opos++ = *ipos++; 00103 } 00104 } 00105 00106 *opos-- = '\0'; 00107 if (opos > a && x509_whitespace(*opos)) 00108 *opos = '\0'; 00109 } 00110 00111 00112 static int x509_str_compare(const char *a, const char *b) 00113 { 00114 char *aa, *bb; 00115 int ret; 00116 00117 if (!a && b) 00118 return -1; 00119 if (a && !b) 00120 return 1; 00121 if (!a && !b) 00122 return 0; 00123 00124 aa = os_strdup(a); 00125 bb = os_strdup(b); 00126 00127 if (aa == NULL || bb == NULL) { 00128 os_free(aa); 00129 os_free(bb); 00130 return os_strcasecmp(a, b); 00131 } 00132 00133 x509_str_strip_whitespace(aa); 00134 x509_str_strip_whitespace(bb); 00135 00136 ret = os_strcasecmp(aa, bb); 00137 00138 os_free(aa); 00139 os_free(bb); 00140 00141 return ret; 00142 } 00143 00144 00152 int x509_name_compare(struct x509_name *a, struct x509_name *b) 00153 { 00154 int res; 00155 00156 if (!a && b) 00157 return -1; 00158 if (a && !b) 00159 return 1; 00160 if (!a && !b) 00161 return 0; 00162 00163 res = x509_str_compare(a->cn, b->cn); 00164 if (res) 00165 return res; 00166 res = x509_str_compare(a->c, b->c); 00167 if (res) 00168 return res; 00169 res = x509_str_compare(a->l, b->l); 00170 if (res) 00171 return res; 00172 res = x509_str_compare(a->st, b->st); 00173 if (res) 00174 return res; 00175 res = x509_str_compare(a->o, b->o); 00176 if (res) 00177 return res; 00178 res = x509_str_compare(a->ou, b->ou); 00179 if (res) 00180 return res; 00181 res = x509_str_compare(a->email, b->email); 00182 if (res) 00183 return res; 00184 00185 return 0; 00186 } 00187 00188 00189 static int x509_parse_algorithm_identifier( 00190 const u8 *buf, size_t len, 00191 struct x509_algorithm_identifier *id, const u8 **next) 00192 { 00193 struct asn1_hdr hdr; 00194 const u8 *pos, *end; 00195 00196 /* 00197 * AlgorithmIdentifier ::= SEQUENCE { 00198 * algorithm OBJECT IDENTIFIER, 00199 * parameters ANY DEFINED BY algorithm OPTIONAL 00200 * } 00201 */ 00202 00203 if (asn1_get_next(buf, len, &hdr) < 0 || 00204 hdr.class != ASN1_CLASS_UNIVERSAL || 00205 hdr.tag != ASN1_TAG_SEQUENCE) { 00206 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 00207 "(AlgorithmIdentifier) - found class %d tag 0x%x", 00208 hdr.class, hdr.tag); 00209 return -1; 00210 } 00211 pos = hdr.payload; 00212 end = pos + hdr.length; 00213 00214 if (end > buf + len) 00215 return -1; 00216 00217 *next = end; 00218 00219 if (asn1_get_oid(pos, end - pos, &id->oid, &pos)) 00220 return -1; 00221 00222 /* TODO: optional parameters */ 00223 00224 return 0; 00225 } 00226 00227 00228 static int x509_parse_public_key(const u8 *buf, size_t len, 00229 struct x509_certificate *cert, 00230 const u8 **next) 00231 { 00232 struct asn1_hdr hdr; 00233 const u8 *pos, *end; 00234 00235 /* 00236 * SubjectPublicKeyInfo ::= SEQUENCE { 00237 * algorithm AlgorithmIdentifier, 00238 * subjectPublicKey BIT STRING 00239 * } 00240 */ 00241 00242 pos = buf; 00243 end = buf + len; 00244 00245 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 00246 hdr.class != ASN1_CLASS_UNIVERSAL || 00247 hdr.tag != ASN1_TAG_SEQUENCE) { 00248 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 00249 "(SubjectPublicKeyInfo) - found class %d tag 0x%x", 00250 hdr.class, hdr.tag); 00251 return -1; 00252 } 00253 pos = hdr.payload; 00254 00255 if (pos + hdr.length > end) 00256 return -1; 00257 end = pos + hdr.length; 00258 *next = end; 00259 00260 if (x509_parse_algorithm_identifier(pos, end - pos, 00261 &cert->public_key_alg, &pos)) 00262 return -1; 00263 00264 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 00265 hdr.class != ASN1_CLASS_UNIVERSAL || 00266 hdr.tag != ASN1_TAG_BITSTRING) { 00267 wpa_printf(MSG_DEBUG, "X509: Expected BITSTRING " 00268 "(subjectPublicKey) - found class %d tag 0x%x", 00269 hdr.class, hdr.tag); 00270 return -1; 00271 } 00272 if (hdr.length < 1) 00273 return -1; 00274 pos = hdr.payload; 00275 if (*pos) { 00276 wpa_printf(MSG_DEBUG, "X509: BITSTRING - %d unused bits", 00277 *pos); 00278 /* 00279 * TODO: should this be rejected? X.509 certificates are 00280 * unlikely to use such a construction. Now we would end up 00281 * including the extra bits in the buffer which may also be 00282 * ok. 00283 */ 00284 } 00285 os_free(cert->public_key); 00286 cert->public_key = os_malloc(hdr.length - 1); 00287 if (cert->public_key == NULL) { 00288 wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for " 00289 "public key"); 00290 return -1; 00291 } 00292 os_memcpy(cert->public_key, pos + 1, hdr.length - 1); 00293 cert->public_key_len = hdr.length - 1; 00294 wpa_hexdump(MSG_MSGDUMP, "X509: subjectPublicKey", 00295 cert->public_key, cert->public_key_len); 00296 00297 return 0; 00298 } 00299 00300 00301 static int x509_parse_name(const u8 *buf, size_t len, struct x509_name *name, 00302 const u8 **next) 00303 { 00304 struct asn1_hdr hdr; 00305 const u8 *pos, *end, *set_pos, *set_end, *seq_pos, *seq_end; 00306 struct asn1_oid oid; 00307 char **fieldp; 00308 00309 /* 00310 * Name ::= CHOICE { RDNSequence } 00311 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName 00312 * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue 00313 * AttributeTypeAndValue ::= SEQUENCE { 00314 * type AttributeType, 00315 * value AttributeValue 00316 * } 00317 * AttributeType ::= OBJECT IDENTIFIER 00318 * AttributeValue ::= ANY DEFINED BY AttributeType 00319 */ 00320 00321 if (asn1_get_next(buf, len, &hdr) < 0 || 00322 hdr.class != ASN1_CLASS_UNIVERSAL || 00323 hdr.tag != ASN1_TAG_SEQUENCE) { 00324 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 00325 "(Name / RDNSequencer) - found class %d tag 0x%x", 00326 hdr.class, hdr.tag); 00327 return -1; 00328 } 00329 pos = hdr.payload; 00330 00331 if (pos + hdr.length > buf + len) 00332 return -1; 00333 00334 end = *next = pos + hdr.length; 00335 00336 while (pos < end) { 00337 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 00338 hdr.class != ASN1_CLASS_UNIVERSAL || 00339 hdr.tag != ASN1_TAG_SET) { 00340 wpa_printf(MSG_DEBUG, "X509: Expected SET " 00341 "(RelativeDistinguishedName) - found class " 00342 "%d tag 0x%x", hdr.class, hdr.tag); 00343 x509_free_name(name); 00344 return -1; 00345 } 00346 00347 set_pos = hdr.payload; 00348 pos = set_end = hdr.payload + hdr.length; 00349 00350 if (asn1_get_next(set_pos, set_end - set_pos, &hdr) < 0 || 00351 hdr.class != ASN1_CLASS_UNIVERSAL || 00352 hdr.tag != ASN1_TAG_SEQUENCE) { 00353 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 00354 "(AttributeTypeAndValue) - found class %d " 00355 "tag 0x%x", hdr.class, hdr.tag); 00356 x509_free_name(name); 00357 return -1; 00358 } 00359 00360 seq_pos = hdr.payload; 00361 seq_end = hdr.payload + hdr.length; 00362 00363 if (asn1_get_oid(seq_pos, seq_end - seq_pos, &oid, &seq_pos)) { 00364 x509_free_name(name); 00365 return -1; 00366 } 00367 00368 if (asn1_get_next(seq_pos, seq_end - seq_pos, &hdr) < 0 || 00369 hdr.class != ASN1_CLASS_UNIVERSAL) { 00370 wpa_printf(MSG_DEBUG, "X509: Failed to parse " 00371 "AttributeValue"); 00372 x509_free_name(name); 00373 return -1; 00374 } 00375 00376 /* RFC 3280: 00377 * MUST: country, organization, organizational-unit, 00378 * distinguished name qualifier, state or province name, 00379 * common name, serial number. 00380 * SHOULD: locality, title, surname, given name, initials, 00381 * pseudonym, generation qualifier. 00382 * MUST: domainComponent (RFC 2247). 00383 */ 00384 fieldp = NULL; 00385 if (oid.len == 4 && 00386 oid.oid[0] == 2 && oid.oid[1] == 5 && oid.oid[2] == 4) { 00387 /* id-at ::= 2.5.4 */ 00388 switch (oid.oid[3]) { 00389 case 3: 00390 /* commonName */ 00391 fieldp = &name->cn; 00392 break; 00393 case 6: 00394 /* countryName */ 00395 fieldp = &name->c; 00396 break; 00397 case 7: 00398 /* localityName */ 00399 fieldp = &name->l; 00400 break; 00401 case 8: 00402 /* stateOrProvinceName */ 00403 fieldp = &name->st; 00404 break; 00405 case 10: 00406 /* organizationName */ 00407 fieldp = &name->o; 00408 break; 00409 case 11: 00410 /* organizationalUnitName */ 00411 fieldp = &name->ou; 00412 break; 00413 } 00414 } else if (oid.len == 7 && 00415 oid.oid[0] == 1 && oid.oid[1] == 2 && 00416 oid.oid[2] == 840 && oid.oid[3] == 113549 && 00417 oid.oid[4] == 1 && oid.oid[5] == 9 && 00418 oid.oid[6] == 1) { 00419 /* 1.2.840.113549.1.9.1 - e-mailAddress */ 00420 fieldp = &name->email; 00421 } 00422 00423 if (fieldp == NULL) { 00424 wpa_hexdump(MSG_DEBUG, "X509: Unrecognized OID", 00425 (u8 *) oid.oid, 00426 oid.len * sizeof(oid.oid[0])); 00427 wpa_hexdump_ascii(MSG_MSGDUMP, "X509: Attribute Data", 00428 hdr.payload, hdr.length); 00429 continue; 00430 } 00431 00432 os_free(*fieldp); 00433 *fieldp = os_malloc(hdr.length + 1); 00434 if (*fieldp == NULL) { 00435 x509_free_name(name); 00436 return -1; 00437 } 00438 os_memcpy(*fieldp, hdr.payload, hdr.length); 00439 (*fieldp)[hdr.length] = '\0'; 00440 if (os_strlen(*fieldp) != hdr.length) { 00441 wpa_printf(MSG_INFO, "X509: Reject certificate with " 00442 "embedded NUL byte in a string (%s[NUL])", 00443 *fieldp); 00444 x509_free_name(name); 00445 return -1; 00446 } 00447 } 00448 00449 return 0; 00450 } 00451 00452 00459 void x509_name_string(struct x509_name *name, char *buf, size_t len) 00460 { 00461 char *pos, *end; 00462 int ret; 00463 00464 if (len == 0) 00465 return; 00466 00467 pos = buf; 00468 end = buf + len; 00469 00470 if (name->c) { 00471 ret = os_snprintf(pos, end - pos, "C=%s, ", name->c); 00472 if (ret < 0 || ret >= end - pos) 00473 goto done; 00474 pos += ret; 00475 } 00476 if (name->st) { 00477 ret = os_snprintf(pos, end - pos, "ST=%s, ", name->st); 00478 if (ret < 0 || ret >= end - pos) 00479 goto done; 00480 pos += ret; 00481 } 00482 if (name->l) { 00483 ret = os_snprintf(pos, end - pos, "L=%s, ", name->l); 00484 if (ret < 0 || ret >= end - pos) 00485 goto done; 00486 pos += ret; 00487 } 00488 if (name->o) { 00489 ret = os_snprintf(pos, end - pos, "O=%s, ", name->o); 00490 if (ret < 0 || ret >= end - pos) 00491 goto done; 00492 pos += ret; 00493 } 00494 if (name->ou) { 00495 ret = os_snprintf(pos, end - pos, "OU=%s, ", name->ou); 00496 if (ret < 0 || ret >= end - pos) 00497 goto done; 00498 pos += ret; 00499 } 00500 if (name->cn) { 00501 ret = os_snprintf(pos, end - pos, "CN=%s, ", name->cn); 00502 if (ret < 0 || ret >= end - pos) 00503 goto done; 00504 pos += ret; 00505 } 00506 00507 if (pos > buf + 1 && pos[-1] == ' ' && pos[-2] == ',') { 00508 *pos-- = '\0'; 00509 *pos-- = '\0'; 00510 } 00511 00512 if (name->email) { 00513 ret = os_snprintf(pos, end - pos, "/emailAddress=%s", 00514 name->email); 00515 if (ret < 0 || ret >= end - pos) 00516 goto done; 00517 pos += ret; 00518 } 00519 00520 done: 00521 end[-1] = '\0'; 00522 } 00523 00524 00525 static int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag, 00526 os_time_t *val) 00527 { 00528 const char *pos; 00529 int year, month, day, hour, min, sec; 00530 00531 /* 00532 * Time ::= CHOICE { 00533 * utcTime UTCTime, 00534 * generalTime GeneralizedTime 00535 * } 00536 * 00537 * UTCTime: YYMMDDHHMMSSZ 00538 * GeneralizedTime: YYYYMMDDHHMMSSZ 00539 */ 00540 00541 pos = (const char *) buf; 00542 00543 switch (asn1_tag) { 00544 case ASN1_TAG_UTCTIME: 00545 if (len != 13 || buf[12] != 'Z') { 00546 wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized " 00547 "UTCTime format", buf, len); 00548 return -1; 00549 } 00550 if (sscanf(pos, "%02d", &year) != 1) { 00551 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse " 00552 "UTCTime year", buf, len); 00553 return -1; 00554 } 00555 if (year < 50) 00556 year += 2000; 00557 else 00558 year += 1900; 00559 pos += 2; 00560 break; 00561 case ASN1_TAG_GENERALIZEDTIME: 00562 if (len != 15 || buf[14] != 'Z') { 00563 wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized " 00564 "GeneralizedTime format", buf, len); 00565 return -1; 00566 } 00567 if (sscanf(pos, "%04d", &year) != 1) { 00568 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse " 00569 "GeneralizedTime year", buf, len); 00570 return -1; 00571 } 00572 pos += 4; 00573 break; 00574 default: 00575 wpa_printf(MSG_DEBUG, "X509: Expected UTCTime or " 00576 "GeneralizedTime - found tag 0x%x", asn1_tag); 00577 return -1; 00578 } 00579 00580 if (sscanf(pos, "%02d", &month) != 1) { 00581 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time " 00582 "(month)", buf, len); 00583 return -1; 00584 } 00585 pos += 2; 00586 00587 if (sscanf(pos, "%02d", &day) != 1) { 00588 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time " 00589 "(day)", buf, len); 00590 return -1; 00591 } 00592 pos += 2; 00593 00594 if (sscanf(pos, "%02d", &hour) != 1) { 00595 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time " 00596 "(hour)", buf, len); 00597 return -1; 00598 } 00599 pos += 2; 00600 00601 if (sscanf(pos, "%02d", &min) != 1) { 00602 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time " 00603 "(min)", buf, len); 00604 return -1; 00605 } 00606 pos += 2; 00607 00608 if (sscanf(pos, "%02d", &sec) != 1) { 00609 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time " 00610 "(sec)", buf, len); 00611 return -1; 00612 } 00613 00614 if (os_mktime(year, month, day, hour, min, sec, val) < 0) { 00615 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to convert Time", 00616 buf, len); 00617 if (year < 1970) { 00618 /* 00619 * At least some test certificates have been configured 00620 * to use dates prior to 1970. Set the date to 00621 * beginning of 1970 to handle these case. 00622 */ 00623 wpa_printf(MSG_DEBUG, "X509: Year=%d before epoch - " 00624 "assume epoch as the time", year); 00625 *val = 0; 00626 return 0; 00627 } 00628 return -1; 00629 } 00630 00631 return 0; 00632 } 00633 00634 00635 static int x509_parse_validity(const u8 *buf, size_t len, 00636 struct x509_certificate *cert, const u8 **next) 00637 { 00638 struct asn1_hdr hdr; 00639 const u8 *pos; 00640 size_t plen; 00641 00642 /* 00643 * Validity ::= SEQUENCE { 00644 * notBefore Time, 00645 * notAfter Time 00646 * } 00647 * 00648 * RFC 3280, 4.1.2.5: 00649 * CAs conforming to this profile MUST always encode certificate 00650 * validity dates through the year 2049 as UTCTime; certificate 00651 * validity dates in 2050 or later MUST be encoded as GeneralizedTime. 00652 */ 00653 00654 if (asn1_get_next(buf, len, &hdr) < 0 || 00655 hdr.class != ASN1_CLASS_UNIVERSAL || 00656 hdr.tag != ASN1_TAG_SEQUENCE) { 00657 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 00658 "(Validity) - found class %d tag 0x%x", 00659 hdr.class, hdr.tag); 00660 return -1; 00661 } 00662 pos = hdr.payload; 00663 plen = hdr.length; 00664 00665 if (pos + plen > buf + len) 00666 return -1; 00667 00668 *next = pos + plen; 00669 00670 if (asn1_get_next(pos, plen, &hdr) < 0 || 00671 hdr.class != ASN1_CLASS_UNIVERSAL || 00672 x509_parse_time(hdr.payload, hdr.length, hdr.tag, 00673 &cert->not_before) < 0) { 00674 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notBefore " 00675 "Time", hdr.payload, hdr.length); 00676 return -1; 00677 } 00678 00679 pos = hdr.payload + hdr.length; 00680 plen = *next - pos; 00681 00682 if (asn1_get_next(pos, plen, &hdr) < 0 || 00683 hdr.class != ASN1_CLASS_UNIVERSAL || 00684 x509_parse_time(hdr.payload, hdr.length, hdr.tag, 00685 &cert->not_after) < 0) { 00686 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notAfter " 00687 "Time", hdr.payload, hdr.length); 00688 return -1; 00689 } 00690 00691 wpa_printf(MSG_MSGDUMP, "X509: Validity: notBefore: %lu notAfter: %lu", 00692 (unsigned long) cert->not_before, 00693 (unsigned long) cert->not_after); 00694 00695 return 0; 00696 } 00697 00698 00699 static int x509_id_ce_oid(struct asn1_oid *oid) 00700 { 00701 /* id-ce arc from X.509 for standard X.509v3 extensions */ 00702 return oid->len >= 4 && 00703 oid->oid[0] == 2 /* joint-iso-ccitt */ && 00704 oid->oid[1] == 5 /* ds */ && 00705 oid->oid[2] == 29 /* id-ce */; 00706 } 00707 00708 00709 static int x509_parse_ext_key_usage(struct x509_certificate *cert, 00710 const u8 *pos, size_t len) 00711 { 00712 struct asn1_hdr hdr; 00713 00714 /* 00715 * KeyUsage ::= BIT STRING { 00716 * digitalSignature (0), 00717 * nonRepudiation (1), 00718 * keyEncipherment (2), 00719 * dataEncipherment (3), 00720 * keyAgreement (4), 00721 * keyCertSign (5), 00722 * cRLSign (6), 00723 * encipherOnly (7), 00724 * decipherOnly (8) } 00725 */ 00726 00727 if (asn1_get_next(pos, len, &hdr) < 0 || 00728 hdr.class != ASN1_CLASS_UNIVERSAL || 00729 hdr.tag != ASN1_TAG_BITSTRING || 00730 hdr.length < 1) { 00731 wpa_printf(MSG_DEBUG, "X509: Expected BIT STRING in " 00732 "KeyUsage; found %d tag 0x%x len %d", 00733 hdr.class, hdr.tag, hdr.length); 00734 return -1; 00735 } 00736 00737 cert->extensions_present |= X509_EXT_KEY_USAGE; 00738 cert->key_usage = asn1_bit_string_to_long(hdr.payload, hdr.length); 00739 00740 wpa_printf(MSG_DEBUG, "X509: KeyUsage 0x%lx", cert->key_usage); 00741 00742 return 0; 00743 } 00744 00745 00746 static int x509_parse_ext_basic_constraints(struct x509_certificate *cert, 00747 const u8 *pos, size_t len) 00748 { 00749 struct asn1_hdr hdr; 00750 unsigned long value; 00751 size_t left; 00752 00753 /* 00754 * BasicConstraints ::= SEQUENCE { 00755 * cA BOOLEAN DEFAULT FALSE, 00756 * pathLenConstraint INTEGER (0..MAX) OPTIONAL } 00757 */ 00758 00759 if (asn1_get_next(pos, len, &hdr) < 0 || 00760 hdr.class != ASN1_CLASS_UNIVERSAL || 00761 hdr.tag != ASN1_TAG_SEQUENCE) { 00762 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE in " 00763 "BasicConstraints; found %d tag 0x%x", 00764 hdr.class, hdr.tag); 00765 return -1; 00766 } 00767 00768 cert->extensions_present |= X509_EXT_BASIC_CONSTRAINTS; 00769 00770 if (hdr.length == 0) 00771 return 0; 00772 00773 if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 || 00774 hdr.class != ASN1_CLASS_UNIVERSAL) { 00775 wpa_printf(MSG_DEBUG, "X509: Failed to parse " 00776 "BasicConstraints"); 00777 return -1; 00778 } 00779 00780 if (hdr.tag == ASN1_TAG_BOOLEAN) { 00781 if (hdr.length != 1) { 00782 wpa_printf(MSG_DEBUG, "X509: Unexpected " 00783 "Boolean length (%u) in BasicConstraints", 00784 hdr.length); 00785 return -1; 00786 } 00787 cert->ca = hdr.payload[0]; 00788 00789 if (hdr.payload + hdr.length == pos + len) { 00790 wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d", 00791 cert->ca); 00792 return 0; 00793 } 00794 00795 if (asn1_get_next(hdr.payload + hdr.length, len - hdr.length, 00796 &hdr) < 0 || 00797 hdr.class != ASN1_CLASS_UNIVERSAL) { 00798 wpa_printf(MSG_DEBUG, "X509: Failed to parse " 00799 "BasicConstraints"); 00800 return -1; 00801 } 00802 } 00803 00804 if (hdr.tag != ASN1_TAG_INTEGER) { 00805 wpa_printf(MSG_DEBUG, "X509: Expected INTEGER in " 00806 "BasicConstraints; found class %d tag 0x%x", 00807 hdr.class, hdr.tag); 00808 return -1; 00809 } 00810 00811 pos = hdr.payload; 00812 left = hdr.length; 00813 value = 0; 00814 while (left) { 00815 value <<= 8; 00816 value |= *pos++; 00817 left--; 00818 } 00819 00820 cert->path_len_constraint = value; 00821 cert->extensions_present |= X509_EXT_PATH_LEN_CONSTRAINT; 00822 00823 wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d " 00824 "pathLenConstraint=%lu", 00825 cert->ca, cert->path_len_constraint); 00826 00827 return 0; 00828 } 00829 00830 00831 static int x509_parse_alt_name_rfc8222(struct x509_name *name, 00832 const u8 *pos, size_t len) 00833 { 00834 /* rfc822Name IA5String */ 00835 wpa_hexdump_ascii(MSG_MSGDUMP, "X509: altName - rfc822Name", pos, len); 00836 os_free(name->alt_email); 00837 name->alt_email = os_zalloc(len + 1); 00838 if (name->alt_email == NULL) 00839 return -1; 00840 os_memcpy(name->alt_email, pos, len); 00841 if (os_strlen(name->alt_email) != len) { 00842 wpa_printf(MSG_INFO, "X509: Reject certificate with " 00843 "embedded NUL byte in rfc822Name (%s[NUL])", 00844 name->alt_email); 00845 os_free(name->alt_email); 00846 name->alt_email = NULL; 00847 return -1; 00848 } 00849 return 0; 00850 } 00851 00852 00853 static int x509_parse_alt_name_dns(struct x509_name *name, 00854 const u8 *pos, size_t len) 00855 { 00856 /* dNSName IA5String */ 00857 wpa_hexdump_ascii(MSG_MSGDUMP, "X509: altName - dNSName", pos, len); 00858 os_free(name->dns); 00859 name->dns = os_zalloc(len + 1); 00860 if (name->dns == NULL) 00861 return -1; 00862 os_memcpy(name->dns, pos, len); 00863 if (os_strlen(name->dns) != len) { 00864 wpa_printf(MSG_INFO, "X509: Reject certificate with " 00865 "embedded NUL byte in dNSName (%s[NUL])", 00866 name->dns); 00867 os_free(name->dns); 00868 name->dns = NULL; 00869 return -1; 00870 } 00871 return 0; 00872 } 00873 00874 00875 static int x509_parse_alt_name_uri(struct x509_name *name, 00876 const u8 *pos, size_t len) 00877 { 00878 /* uniformResourceIdentifier IA5String */ 00879 wpa_hexdump_ascii(MSG_MSGDUMP, 00880 "X509: altName - uniformResourceIdentifier", 00881 pos, len); 00882 os_free(name->uri); 00883 name->uri = os_zalloc(len + 1); 00884 if (name->uri == NULL) 00885 return -1; 00886 os_memcpy(name->uri, pos, len); 00887 if (os_strlen(name->uri) != len) { 00888 wpa_printf(MSG_INFO, "X509: Reject certificate with " 00889 "embedded NUL byte in uniformResourceIdentifier " 00890 "(%s[NUL])", name->uri); 00891 os_free(name->uri); 00892 name->uri = NULL; 00893 return -1; 00894 } 00895 return 0; 00896 } 00897 00898 00899 static int x509_parse_alt_name_ip(struct x509_name *name, 00900 const u8 *pos, size_t len) 00901 { 00902 /* iPAddress OCTET STRING */ 00903 wpa_hexdump(MSG_MSGDUMP, "X509: altName - iPAddress", pos, len); 00904 os_free(name->ip); 00905 name->ip = os_malloc(len); 00906 if (name->ip == NULL) 00907 return -1; 00908 os_memcpy(name->ip, pos, len); 00909 name->ip_len = len; 00910 return 0; 00911 } 00912 00913 00914 static int x509_parse_alt_name_rid(struct x509_name *name, 00915 const u8 *pos, size_t len) 00916 { 00917 char buf[80]; 00918 00919 /* registeredID OBJECT IDENTIFIER */ 00920 if (asn1_parse_oid(pos, len, &name->rid) < 0) 00921 return -1; 00922 00923 asn1_oid_to_str(&name->rid, buf, sizeof(buf)); 00924 wpa_printf(MSG_MSGDUMP, "X509: altName - registeredID: %s", buf); 00925 00926 return 0; 00927 } 00928 00929 00930 static int x509_parse_ext_alt_name(struct x509_name *name, 00931 const u8 *pos, size_t len) 00932 { 00933 struct asn1_hdr hdr; 00934 const u8 *p, *end; 00935 00936 /* 00937 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName 00938 * 00939 * GeneralName ::= CHOICE { 00940 * otherName [0] OtherName, 00941 * rfc822Name [1] IA5String, 00942 * dNSName [2] IA5String, 00943 * x400Address [3] ORAddress, 00944 * directoryName [4] Name, 00945 * ediPartyName [5] EDIPartyName, 00946 * uniformResourceIdentifier [6] IA5String, 00947 * iPAddress [7] OCTET STRING, 00948 * registeredID [8] OBJECT IDENTIFIER } 00949 * 00950 * OtherName ::= SEQUENCE { 00951 * type-id OBJECT IDENTIFIER, 00952 * value [0] EXPLICIT ANY DEFINED BY type-id } 00953 * 00954 * EDIPartyName ::= SEQUENCE { 00955 * nameAssigner [0] DirectoryString OPTIONAL, 00956 * partyName [1] DirectoryString } 00957 */ 00958 00959 for (p = pos, end = pos + len; p < end; p = hdr.payload + hdr.length) { 00960 int res; 00961 00962 if (asn1_get_next(p, end - p, &hdr) < 0) { 00963 wpa_printf(MSG_DEBUG, "X509: Failed to parse " 00964 "SubjectAltName item"); 00965 return -1; 00966 } 00967 00968 if (hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) 00969 continue; 00970 00971 switch (hdr.tag) { 00972 case 1: 00973 res = x509_parse_alt_name_rfc8222(name, hdr.payload, 00974 hdr.length); 00975 break; 00976 case 2: 00977 res = x509_parse_alt_name_dns(name, hdr.payload, 00978 hdr.length); 00979 break; 00980 case 6: 00981 res = x509_parse_alt_name_uri(name, hdr.payload, 00982 hdr.length); 00983 break; 00984 case 7: 00985 res = x509_parse_alt_name_ip(name, hdr.payload, 00986 hdr.length); 00987 break; 00988 case 8: 00989 res = x509_parse_alt_name_rid(name, hdr.payload, 00990 hdr.length); 00991 break; 00992 case 0: /* TODO: otherName */ 00993 case 3: /* TODO: x500Address */ 00994 case 4: /* TODO: directoryName */ 00995 case 5: /* TODO: ediPartyName */ 00996 default: 00997 res = 0; 00998 break; 00999 } 01000 if (res < 0) 01001 return res; 01002 } 01003 01004 return 0; 01005 } 01006 01007 01008 static int x509_parse_ext_subject_alt_name(struct x509_certificate *cert, 01009 const u8 *pos, size_t len) 01010 { 01011 struct asn1_hdr hdr; 01012 01013 /* SubjectAltName ::= GeneralNames */ 01014 01015 if (asn1_get_next(pos, len, &hdr) < 0 || 01016 hdr.class != ASN1_CLASS_UNIVERSAL || 01017 hdr.tag != ASN1_TAG_SEQUENCE) { 01018 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE in " 01019 "SubjectAltName; found %d tag 0x%x", 01020 hdr.class, hdr.tag); 01021 return -1; 01022 } 01023 01024 wpa_printf(MSG_DEBUG, "X509: SubjectAltName"); 01025 cert->extensions_present |= X509_EXT_SUBJECT_ALT_NAME; 01026 01027 if (hdr.length == 0) 01028 return 0; 01029 01030 return x509_parse_ext_alt_name(&cert->subject, hdr.payload, 01031 hdr.length); 01032 } 01033 01034 01035 static int x509_parse_ext_issuer_alt_name(struct x509_certificate *cert, 01036 const u8 *pos, size_t len) 01037 { 01038 struct asn1_hdr hdr; 01039 01040 /* IssuerAltName ::= GeneralNames */ 01041 01042 if (asn1_get_next(pos, len, &hdr) < 0 || 01043 hdr.class != ASN1_CLASS_UNIVERSAL || 01044 hdr.tag != ASN1_TAG_SEQUENCE) { 01045 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE in " 01046 "IssuerAltName; found %d tag 0x%x", 01047 hdr.class, hdr.tag); 01048 return -1; 01049 } 01050 01051 wpa_printf(MSG_DEBUG, "X509: IssuerAltName"); 01052 cert->extensions_present |= X509_EXT_ISSUER_ALT_NAME; 01053 01054 if (hdr.length == 0) 01055 return 0; 01056 01057 return x509_parse_ext_alt_name(&cert->issuer, hdr.payload, 01058 hdr.length); 01059 } 01060 01061 01062 static int x509_parse_extension_data(struct x509_certificate *cert, 01063 struct asn1_oid *oid, 01064 const u8 *pos, size_t len) 01065 { 01066 if (!x509_id_ce_oid(oid)) 01067 return 1; 01068 01069 /* TODO: add other extensions required by RFC 3280, Ch 4.2: 01070 * certificate policies (section 4.2.1.5) 01071 * name constraints (section 4.2.1.11) 01072 * policy constraints (section 4.2.1.12) 01073 * extended key usage (section 4.2.1.13) 01074 * inhibit any-policy (section 4.2.1.15) 01075 */ 01076 switch (oid->oid[3]) { 01077 case 15: /* id-ce-keyUsage */ 01078 return x509_parse_ext_key_usage(cert, pos, len); 01079 case 17: /* id-ce-subjectAltName */ 01080 return x509_parse_ext_subject_alt_name(cert, pos, len); 01081 case 18: /* id-ce-issuerAltName */ 01082 return x509_parse_ext_issuer_alt_name(cert, pos, len); 01083 case 19: /* id-ce-basicConstraints */ 01084 return x509_parse_ext_basic_constraints(cert, pos, len); 01085 default: 01086 return 1; 01087 } 01088 } 01089 01090 01091 static int x509_parse_extension(struct x509_certificate *cert, 01092 const u8 *pos, size_t len, const u8 **next) 01093 { 01094 const u8 *end; 01095 struct asn1_hdr hdr; 01096 struct asn1_oid oid; 01097 int critical_ext = 0, res; 01098 char buf[80]; 01099 01100 /* 01101 * Extension ::= SEQUENCE { 01102 * extnID OBJECT IDENTIFIER, 01103 * critical BOOLEAN DEFAULT FALSE, 01104 * extnValue OCTET STRING 01105 * } 01106 */ 01107 01108 if (asn1_get_next(pos, len, &hdr) < 0 || 01109 hdr.class != ASN1_CLASS_UNIVERSAL || 01110 hdr.tag != ASN1_TAG_SEQUENCE) { 01111 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header in " 01112 "Extensions: class %d tag 0x%x; expected SEQUENCE", 01113 hdr.class, hdr.tag); 01114 return -1; 01115 } 01116 pos = hdr.payload; 01117 *next = end = pos + hdr.length; 01118 01119 if (asn1_get_oid(pos, end - pos, &oid, &pos) < 0) { 01120 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 data for " 01121 "Extension (expected OID)"); 01122 return -1; 01123 } 01124 01125 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 01126 hdr.class != ASN1_CLASS_UNIVERSAL || 01127 (hdr.tag != ASN1_TAG_BOOLEAN && 01128 hdr.tag != ASN1_TAG_OCTETSTRING)) { 01129 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header in " 01130 "Extensions: class %d tag 0x%x; expected BOOLEAN " 01131 "or OCTET STRING", hdr.class, hdr.tag); 01132 return -1; 01133 } 01134 01135 if (hdr.tag == ASN1_TAG_BOOLEAN) { 01136 if (hdr.length != 1) { 01137 wpa_printf(MSG_DEBUG, "X509: Unexpected " 01138 "Boolean length (%u)", hdr.length); 01139 return -1; 01140 } 01141 critical_ext = hdr.payload[0]; 01142 pos = hdr.payload; 01143 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 01144 (hdr.class != ASN1_CLASS_UNIVERSAL && 01145 hdr.class != ASN1_CLASS_PRIVATE) || 01146 hdr.tag != ASN1_TAG_OCTETSTRING) { 01147 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header " 01148 "in Extensions: class %d tag 0x%x; " 01149 "expected OCTET STRING", 01150 hdr.class, hdr.tag); 01151 return -1; 01152 } 01153 } 01154 01155 asn1_oid_to_str(&oid, buf, sizeof(buf)); 01156 wpa_printf(MSG_DEBUG, "X509: Extension: extnID=%s critical=%d", 01157 buf, critical_ext); 01158 wpa_hexdump(MSG_MSGDUMP, "X509: extnValue", hdr.payload, hdr.length); 01159 01160 res = x509_parse_extension_data(cert, &oid, hdr.payload, hdr.length); 01161 if (res < 0) 01162 return res; 01163 if (res == 1 && critical_ext) { 01164 wpa_printf(MSG_INFO, "X509: Unknown critical extension %s", 01165 buf); 01166 return -1; 01167 } 01168 01169 return 0; 01170 } 01171 01172 01173 static int x509_parse_extensions(struct x509_certificate *cert, 01174 const u8 *pos, size_t len) 01175 { 01176 const u8 *end; 01177 struct asn1_hdr hdr; 01178 01179 /* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension */ 01180 01181 if (asn1_get_next(pos, len, &hdr) < 0 || 01182 hdr.class != ASN1_CLASS_UNIVERSAL || 01183 hdr.tag != ASN1_TAG_SEQUENCE) { 01184 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 data " 01185 "for Extensions: class %d tag 0x%x; " 01186 "expected SEQUENCE", hdr.class, hdr.tag); 01187 return -1; 01188 } 01189 01190 pos = hdr.payload; 01191 end = pos + hdr.length; 01192 01193 while (pos < end) { 01194 if (x509_parse_extension(cert, pos, end - pos, &pos) 01195 < 0) 01196 return -1; 01197 } 01198 01199 return 0; 01200 } 01201 01202 01203 static int x509_parse_tbs_certificate(const u8 *buf, size_t len, 01204 struct x509_certificate *cert, 01205 const u8 **next) 01206 { 01207 struct asn1_hdr hdr; 01208 const u8 *pos, *end; 01209 size_t left; 01210 char sbuf[128]; 01211 unsigned long value; 01212 01213 /* tbsCertificate TBSCertificate ::= SEQUENCE */ 01214 if (asn1_get_next(buf, len, &hdr) < 0 || 01215 hdr.class != ASN1_CLASS_UNIVERSAL || 01216 hdr.tag != ASN1_TAG_SEQUENCE) { 01217 wpa_printf(MSG_DEBUG, "X509: tbsCertificate did not start " 01218 "with a valid SEQUENCE - found class %d tag 0x%x", 01219 hdr.class, hdr.tag); 01220 return -1; 01221 } 01222 pos = hdr.payload; 01223 end = *next = pos + hdr.length; 01224 01225 /* 01226 * version [0] EXPLICIT Version DEFAULT v1 01227 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 01228 */ 01229 if (asn1_get_next(pos, end - pos, &hdr) < 0) 01230 return -1; 01231 pos = hdr.payload; 01232 01233 if (hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC) { 01234 if (asn1_get_next(pos, end - pos, &hdr) < 0) 01235 return -1; 01236 01237 if (hdr.class != ASN1_CLASS_UNIVERSAL || 01238 hdr.tag != ASN1_TAG_INTEGER) { 01239 wpa_printf(MSG_DEBUG, "X509: No INTEGER tag found for " 01240 "version field - found class %d tag 0x%x", 01241 hdr.class, hdr.tag); 01242 return -1; 01243 } 01244 if (hdr.length != 1) { 01245 wpa_printf(MSG_DEBUG, "X509: Unexpected version field " 01246 "length %u (expected 1)", hdr.length); 01247 return -1; 01248 } 01249 pos = hdr.payload; 01250 left = hdr.length; 01251 value = 0; 01252 while (left) { 01253 value <<= 8; 01254 value |= *pos++; 01255 left--; 01256 } 01257 01258 cert->version = value; 01259 if (cert->version != X509_CERT_V1 && 01260 cert->version != X509_CERT_V2 && 01261 cert->version != X509_CERT_V3) { 01262 wpa_printf(MSG_DEBUG, "X509: Unsupported version %d", 01263 cert->version + 1); 01264 return -1; 01265 } 01266 01267 if (asn1_get_next(pos, end - pos, &hdr) < 0) 01268 return -1; 01269 } else 01270 cert->version = X509_CERT_V1; 01271 wpa_printf(MSG_MSGDUMP, "X509: Version X.509v%d", cert->version + 1); 01272 01273 /* serialNumber CertificateSerialNumber ::= INTEGER */ 01274 if (hdr.class != ASN1_CLASS_UNIVERSAL || 01275 hdr.tag != ASN1_TAG_INTEGER) { 01276 wpa_printf(MSG_DEBUG, "X509: No INTEGER tag found for " 01277 "serialNumber; class=%d tag=0x%x", 01278 hdr.class, hdr.tag); 01279 return -1; 01280 } 01281 01282 pos = hdr.payload; 01283 left = hdr.length; 01284 while (left) { 01285 cert->serial_number <<= 8; 01286 cert->serial_number |= *pos++; 01287 left--; 01288 } 01289 wpa_printf(MSG_MSGDUMP, "X509: serialNumber %lu", cert->serial_number); 01290 01291 /* signature AlgorithmIdentifier */ 01292 if (x509_parse_algorithm_identifier(pos, end - pos, &cert->signature, 01293 &pos)) 01294 return -1; 01295 01296 /* issuer Name */ 01297 if (x509_parse_name(pos, end - pos, &cert->issuer, &pos)) 01298 return -1; 01299 x509_name_string(&cert->issuer, sbuf, sizeof(sbuf)); 01300 wpa_printf(MSG_MSGDUMP, "X509: issuer %s", sbuf); 01301 01302 /* validity Validity */ 01303 if (x509_parse_validity(pos, end - pos, cert, &pos)) 01304 return -1; 01305 01306 /* subject Name */ 01307 if (x509_parse_name(pos, end - pos, &cert->subject, &pos)) 01308 return -1; 01309 x509_name_string(&cert->subject, sbuf, sizeof(sbuf)); 01310 wpa_printf(MSG_MSGDUMP, "X509: subject %s", sbuf); 01311 01312 /* subjectPublicKeyInfo SubjectPublicKeyInfo */ 01313 if (x509_parse_public_key(pos, end - pos, cert, &pos)) 01314 return -1; 01315 01316 if (pos == end) 01317 return 0; 01318 01319 if (cert->version == X509_CERT_V1) 01320 return 0; 01321 01322 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 01323 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) { 01324 wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific" 01325 " tag to parse optional tbsCertificate " 01326 "field(s); parsed class %d tag 0x%x", 01327 hdr.class, hdr.tag); 01328 return -1; 01329 } 01330 01331 if (hdr.tag == 1) { 01332 /* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL */ 01333 wpa_printf(MSG_DEBUG, "X509: issuerUniqueID"); 01334 /* TODO: parse UniqueIdentifier ::= BIT STRING */ 01335 01336 if (hdr.payload + hdr.length == end) 01337 return 0; 01338 01339 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 01340 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) { 01341 wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific" 01342 " tag to parse optional tbsCertificate " 01343 "field(s); parsed class %d tag 0x%x", 01344 hdr.class, hdr.tag); 01345 return -1; 01346 } 01347 } 01348 01349 if (hdr.tag == 2) { 01350 /* subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL */ 01351 wpa_printf(MSG_DEBUG, "X509: subjectUniqueID"); 01352 /* TODO: parse UniqueIdentifier ::= BIT STRING */ 01353 01354 if (hdr.payload + hdr.length == end) 01355 return 0; 01356 01357 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 01358 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) { 01359 wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific" 01360 " tag to parse optional tbsCertificate " 01361 "field(s); parsed class %d tag 0x%x", 01362 hdr.class, hdr.tag); 01363 return -1; 01364 } 01365 } 01366 01367 if (hdr.tag != 3) { 01368 wpa_printf(MSG_DEBUG, "X509: Ignored unexpected " 01369 "Context-Specific tag %d in optional " 01370 "tbsCertificate fields", hdr.tag); 01371 return 0; 01372 } 01373 01374 /* extensions [3] EXPLICIT Extensions OPTIONAL */ 01375 01376 if (cert->version != X509_CERT_V3) { 01377 wpa_printf(MSG_DEBUG, "X509: X.509%d certificate and " 01378 "Extensions data which are only allowed for " 01379 "version 3", cert->version + 1); 01380 return -1; 01381 } 01382 01383 if (x509_parse_extensions(cert, hdr.payload, hdr.length) < 0) 01384 return -1; 01385 01386 pos = hdr.payload + hdr.length; 01387 if (pos < end) { 01388 wpa_hexdump(MSG_DEBUG, 01389 "X509: Ignored extra tbsCertificate data", 01390 pos, end - pos); 01391 } 01392 01393 return 0; 01394 } 01395 01396 01397 static int x509_rsadsi_oid(struct asn1_oid *oid) 01398 { 01399 return oid->len >= 4 && 01400 oid->oid[0] == 1 /* iso */ && 01401 oid->oid[1] == 2 /* member-body */ && 01402 oid->oid[2] == 840 /* us */ && 01403 oid->oid[3] == 113549 /* rsadsi */; 01404 } 01405 01406 01407 static int x509_pkcs_oid(struct asn1_oid *oid) 01408 { 01409 return oid->len >= 5 && 01410 x509_rsadsi_oid(oid) && 01411 oid->oid[4] == 1 /* pkcs */; 01412 } 01413 01414 01415 static int x509_digest_oid(struct asn1_oid *oid) 01416 { 01417 return oid->len >= 5 && 01418 x509_rsadsi_oid(oid) && 01419 oid->oid[4] == 2 /* digestAlgorithm */; 01420 } 01421 01422 01423 static int x509_sha1_oid(struct asn1_oid *oid) 01424 { 01425 return oid->len == 6 && 01426 oid->oid[0] == 1 /* iso */ && 01427 oid->oid[1] == 3 /* identified-organization */ && 01428 oid->oid[2] == 14 /* oiw */ && 01429 oid->oid[3] == 3 /* secsig */ && 01430 oid->oid[4] == 2 /* algorithms */ && 01431 oid->oid[5] == 26 /* id-sha1 */; 01432 } 01433 01434 01435 static int x509_sha256_oid(struct asn1_oid *oid) 01436 { 01437 return oid->len == 9 && 01438 oid->oid[0] == 2 /* joint-iso-itu-t */ && 01439 oid->oid[1] == 16 /* country */ && 01440 oid->oid[2] == 840 /* us */ && 01441 oid->oid[3] == 1 /* organization */ && 01442 oid->oid[4] == 101 /* gov */ && 01443 oid->oid[5] == 3 /* csor */ && 01444 oid->oid[6] == 4 /* nistAlgorithm */ && 01445 oid->oid[7] == 2 /* hashAlgs */ && 01446 oid->oid[8] == 1 /* sha256 */; 01447 } 01448 01449 01459 struct x509_certificate * x509_certificate_parse(const u8 *buf, size_t len) 01460 { 01461 struct asn1_hdr hdr; 01462 const u8 *pos, *end, *hash_start; 01463 struct x509_certificate *cert; 01464 01465 cert = os_zalloc(sizeof(*cert) + len); 01466 if (cert == NULL) 01467 return NULL; 01468 os_memcpy(cert + 1, buf, len); 01469 cert->cert_start = (u8 *) (cert + 1); 01470 cert->cert_len = len; 01471 01472 pos = buf; 01473 end = buf + len; 01474 01475 /* RFC 3280 - X.509 v3 certificate / ASN.1 DER */ 01476 01477 /* Certificate ::= SEQUENCE */ 01478 if (asn1_get_next(pos, len, &hdr) < 0 || 01479 hdr.class != ASN1_CLASS_UNIVERSAL || 01480 hdr.tag != ASN1_TAG_SEQUENCE) { 01481 wpa_printf(MSG_DEBUG, "X509: Certificate did not start with " 01482 "a valid SEQUENCE - found class %d tag 0x%x", 01483 hdr.class, hdr.tag); 01484 x509_certificate_free(cert); 01485 return NULL; 01486 } 01487 pos = hdr.payload; 01488 01489 if (pos + hdr.length > end) { 01490 x509_certificate_free(cert); 01491 return NULL; 01492 } 01493 01494 if (pos + hdr.length < end) { 01495 wpa_hexdump(MSG_MSGDUMP, "X509: Ignoring extra data after DER " 01496 "encoded certificate", 01497 pos + hdr.length, end - pos + hdr.length); 01498 end = pos + hdr.length; 01499 } 01500 01501 hash_start = pos; 01502 cert->tbs_cert_start = cert->cert_start + (hash_start - buf); 01503 if (x509_parse_tbs_certificate(pos, end - pos, cert, &pos)) { 01504 x509_certificate_free(cert); 01505 return NULL; 01506 } 01507 cert->tbs_cert_len = pos - hash_start; 01508 01509 /* signatureAlgorithm AlgorithmIdentifier */ 01510 if (x509_parse_algorithm_identifier(pos, end - pos, 01511 &cert->signature_alg, &pos)) { 01512 x509_certificate_free(cert); 01513 return NULL; 01514 } 01515 01516 /* signatureValue BIT STRING */ 01517 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 01518 hdr.class != ASN1_CLASS_UNIVERSAL || 01519 hdr.tag != ASN1_TAG_BITSTRING) { 01520 wpa_printf(MSG_DEBUG, "X509: Expected BITSTRING " 01521 "(signatureValue) - found class %d tag 0x%x", 01522 hdr.class, hdr.tag); 01523 x509_certificate_free(cert); 01524 return NULL; 01525 } 01526 if (hdr.length < 1) { 01527 x509_certificate_free(cert); 01528 return NULL; 01529 } 01530 pos = hdr.payload; 01531 if (*pos) { 01532 wpa_printf(MSG_DEBUG, "X509: BITSTRING - %d unused bits", 01533 *pos); 01534 /* PKCS #1 v1.5 10.2.1: 01535 * It is an error if the length in bits of the signature S is 01536 * not a multiple of eight. 01537 */ 01538 x509_certificate_free(cert); 01539 return NULL; 01540 } 01541 os_free(cert->sign_value); 01542 cert->sign_value = os_malloc(hdr.length - 1); 01543 if (cert->sign_value == NULL) { 01544 wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for " 01545 "signatureValue"); 01546 x509_certificate_free(cert); 01547 return NULL; 01548 } 01549 os_memcpy(cert->sign_value, pos + 1, hdr.length - 1); 01550 cert->sign_value_len = hdr.length - 1; 01551 wpa_hexdump(MSG_MSGDUMP, "X509: signature", 01552 cert->sign_value, cert->sign_value_len); 01553 01554 return cert; 01555 } 01556 01557 01565 int x509_certificate_check_signature(struct x509_certificate *issuer, 01566 struct x509_certificate *cert) 01567 { 01568 struct crypto_public_key *pk; 01569 u8 *data; 01570 const u8 *pos, *end, *next, *da_end; 01571 size_t data_len; 01572 struct asn1_hdr hdr; 01573 struct asn1_oid oid; 01574 u8 hash[32]; 01575 size_t hash_len; 01576 01577 if (!x509_pkcs_oid(&cert->signature.oid) || 01578 cert->signature.oid.len != 7 || 01579 cert->signature.oid.oid[5] != 1 /* pkcs-1 */) { 01580 wpa_printf(MSG_DEBUG, "X509: Unrecognized signature " 01581 "algorithm"); 01582 return -1; 01583 } 01584 01585 pk = crypto_public_key_import(issuer->public_key, 01586 issuer->public_key_len); 01587 if (pk == NULL) 01588 return -1; 01589 01590 data_len = cert->sign_value_len; 01591 data = os_malloc(data_len); 01592 if (data == NULL) { 01593 crypto_public_key_free(pk); 01594 return -1; 01595 } 01596 01597 if (crypto_public_key_decrypt_pkcs1(pk, cert->sign_value, 01598 cert->sign_value_len, data, 01599 &data_len) < 0) { 01600 wpa_printf(MSG_DEBUG, "X509: Failed to decrypt signature"); 01601 crypto_public_key_free(pk); 01602 os_free(data); 01603 return -1; 01604 } 01605 crypto_public_key_free(pk); 01606 01607 wpa_hexdump(MSG_MSGDUMP, "X509: Signature data D", data, data_len); 01608 01609 /* 01610 * PKCS #1 v1.5, 10.1.2: 01611 * 01612 * DigestInfo ::= SEQUENCE { 01613 * digestAlgorithm DigestAlgorithmIdentifier, 01614 * digest Digest 01615 * } 01616 * 01617 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier 01618 * 01619 * Digest ::= OCTET STRING 01620 * 01621 */ 01622 if (asn1_get_next(data, data_len, &hdr) < 0 || 01623 hdr.class != ASN1_CLASS_UNIVERSAL || 01624 hdr.tag != ASN1_TAG_SEQUENCE) { 01625 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 01626 "(DigestInfo) - found class %d tag 0x%x", 01627 hdr.class, hdr.tag); 01628 os_free(data); 01629 return -1; 01630 } 01631 01632 pos = hdr.payload; 01633 end = pos + hdr.length; 01634 01635 /* 01636 * X.509: 01637 * AlgorithmIdentifier ::= SEQUENCE { 01638 * algorithm OBJECT IDENTIFIER, 01639 * parameters ANY DEFINED BY algorithm OPTIONAL 01640 * } 01641 */ 01642 01643 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 01644 hdr.class != ASN1_CLASS_UNIVERSAL || 01645 hdr.tag != ASN1_TAG_SEQUENCE) { 01646 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE " 01647 "(AlgorithmIdentifier) - found class %d tag 0x%x", 01648 hdr.class, hdr.tag); 01649 os_free(data); 01650 return -1; 01651 } 01652 da_end = hdr.payload + hdr.length; 01653 01654 if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) { 01655 wpa_printf(MSG_DEBUG, "X509: Failed to parse digestAlgorithm"); 01656 os_free(data); 01657 return -1; 01658 } 01659 01660 if (x509_sha1_oid(&oid)) { 01661 if (cert->signature.oid.oid[6] != 01662 5 /* sha-1WithRSAEncryption */) { 01663 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA1 " 01664 "does not match with certificate " 01665 "signatureAlgorithm (%lu)", 01666 cert->signature.oid.oid[6]); 01667 os_free(data); 01668 return -1; 01669 } 01670 goto skip_digest_oid; 01671 } 01672 01673 if (x509_sha256_oid(&oid)) { 01674 if (cert->signature.oid.oid[6] != 01675 11 /* sha2561WithRSAEncryption */) { 01676 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA256 " 01677 "does not match with certificate " 01678 "signatureAlgorithm (%lu)", 01679 cert->signature.oid.oid[6]); 01680 os_free(data); 01681 return -1; 01682 } 01683 goto skip_digest_oid; 01684 } 01685 01686 if (!x509_digest_oid(&oid)) { 01687 wpa_printf(MSG_DEBUG, "X509: Unrecognized digestAlgorithm"); 01688 os_free(data); 01689 return -1; 01690 } 01691 switch (oid.oid[5]) { 01692 case 5: /* md5 */ 01693 if (cert->signature.oid.oid[6] != 4 /* md5WithRSAEncryption */) 01694 { 01695 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm MD5 does " 01696 "not match with certificate " 01697 "signatureAlgorithm (%lu)", 01698 cert->signature.oid.oid[6]); 01699 os_free(data); 01700 return -1; 01701 } 01702 break; 01703 case 2: /* md2 */ 01704 case 4: /* md4 */ 01705 default: 01706 wpa_printf(MSG_DEBUG, "X509: Unsupported digestAlgorithm " 01707 "(%lu)", oid.oid[5]); 01708 os_free(data); 01709 return -1; 01710 } 01711 01712 skip_digest_oid: 01713 /* Digest ::= OCTET STRING */ 01714 pos = da_end; 01715 end = data + data_len; 01716 01717 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 01718 hdr.class != ASN1_CLASS_UNIVERSAL || 01719 hdr.tag != ASN1_TAG_OCTETSTRING) { 01720 wpa_printf(MSG_DEBUG, "X509: Expected OCTETSTRING " 01721 "(Digest) - found class %d tag 0x%x", 01722 hdr.class, hdr.tag); 01723 os_free(data); 01724 return -1; 01725 } 01726 wpa_hexdump(MSG_MSGDUMP, "X509: Decrypted Digest", 01727 hdr.payload, hdr.length); 01728 01729 switch (cert->signature.oid.oid[6]) { 01730 case 4: /* md5WithRSAEncryption */ 01731 md5_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len, 01732 hash); 01733 hash_len = 16; 01734 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (MD5)", 01735 hash, hash_len); 01736 break; 01737 case 5: /* sha-1WithRSAEncryption */ 01738 sha1_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len, 01739 hash); 01740 hash_len = 20; 01741 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA1)", 01742 hash, hash_len); 01743 break; 01744 case 11: /* sha256WithRSAEncryption */ 01745 sha256_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len, 01746 hash); 01747 hash_len = 32; 01748 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA256)", 01749 hash, hash_len); 01750 break; 01751 case 2: /* md2WithRSAEncryption */ 01752 case 12: /* sha384WithRSAEncryption */ 01753 case 13: /* sha512WithRSAEncryption */ 01754 default: 01755 wpa_printf(MSG_INFO, "X509: Unsupported certificate signature " 01756 "algorithm (%lu)", cert->signature.oid.oid[6]); 01757 os_free(data); 01758 return -1; 01759 } 01760 01761 if (hdr.length != hash_len || 01762 os_memcmp(hdr.payload, hash, hdr.length) != 0) { 01763 wpa_printf(MSG_INFO, "X509: Certificate Digest does not match " 01764 "with calculated tbsCertificate hash"); 01765 os_free(data); 01766 return -1; 01767 } 01768 01769 os_free(data); 01770 01771 wpa_printf(MSG_DEBUG, "X509: Certificate Digest matches with " 01772 "calculated tbsCertificate hash"); 01773 01774 return 0; 01775 } 01776 01777 01778 static int x509_valid_issuer(const struct x509_certificate *cert) 01779 { 01780 if ((cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS) && 01781 !cert->ca) { 01782 wpa_printf(MSG_DEBUG, "X509: Non-CA certificate used as an " 01783 "issuer"); 01784 return -1; 01785 } 01786 01787 if (cert->version == X509_CERT_V3 && 01788 !(cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS)) { 01789 wpa_printf(MSG_DEBUG, "X509: v3 CA certificate did not " 01790 "include BasicConstraints extension"); 01791 return -1; 01792 } 01793 01794 if ((cert->extensions_present & X509_EXT_KEY_USAGE) && 01795 !(cert->key_usage & X509_KEY_USAGE_KEY_CERT_SIGN)) { 01796 wpa_printf(MSG_DEBUG, "X509: Issuer certificate did not have " 01797 "keyCertSign bit in Key Usage"); 01798 return -1; 01799 } 01800 01801 return 0; 01802 } 01803 01804 01813 int x509_certificate_chain_validate(struct x509_certificate *trusted, 01814 struct x509_certificate *chain, 01815 int *reason) 01816 { 01817 long unsigned idx; 01818 int chain_trusted = 0; 01819 struct x509_certificate *cert, *trust; 01820 char buf[128]; 01821 struct os_time now; 01822 01823 *reason = X509_VALIDATE_OK; 01824 01825 wpa_printf(MSG_DEBUG, "X509: Validate certificate chain"); 01826 os_get_time(&now); 01827 01828 for (cert = chain, idx = 0; cert; cert = cert->next, idx++) { 01829 x509_name_string(&cert->subject, buf, sizeof(buf)); 01830 wpa_printf(MSG_DEBUG, "X509: %lu: %s", idx, buf); 01831 01832 if (chain_trusted) 01833 continue; 01834 01835 if ((unsigned long) now.sec < 01836 (unsigned long) cert->not_before || 01837 (unsigned long) now.sec > 01838 (unsigned long) cert->not_after) { 01839 wpa_printf(MSG_INFO, "X509: Certificate not valid " 01840 "(now=%lu not_before=%lu not_after=%lu)", 01841 now.sec, cert->not_before, cert->not_after); 01842 *reason = X509_VALIDATE_CERTIFICATE_EXPIRED; 01843 return -1; 01844 } 01845 01846 if (cert->next) { 01847 if (x509_name_compare(&cert->issuer, 01848 &cert->next->subject) != 0) { 01849 wpa_printf(MSG_DEBUG, "X509: Certificate " 01850 "chain issuer name mismatch"); 01851 x509_name_string(&cert->issuer, buf, 01852 sizeof(buf)); 01853 wpa_printf(MSG_DEBUG, "X509: cert issuer: %s", 01854 buf); 01855 x509_name_string(&cert->next->subject, buf, 01856 sizeof(buf)); 01857 wpa_printf(MSG_DEBUG, "X509: next cert " 01858 "subject: %s", buf); 01859 *reason = X509_VALIDATE_CERTIFICATE_UNKNOWN; 01860 return -1; 01861 } 01862 01863 if (x509_valid_issuer(cert->next) < 0) { 01864 *reason = X509_VALIDATE_BAD_CERTIFICATE; 01865 return -1; 01866 } 01867 01868 if ((cert->next->extensions_present & 01869 X509_EXT_PATH_LEN_CONSTRAINT) && 01870 idx > cert->next->path_len_constraint) { 01871 wpa_printf(MSG_DEBUG, "X509: pathLenConstraint" 01872 " not met (idx=%lu issuer " 01873 "pathLenConstraint=%lu)", idx, 01874 cert->next->path_len_constraint); 01875 *reason = X509_VALIDATE_BAD_CERTIFICATE; 01876 return -1; 01877 } 01878 01879 if (x509_certificate_check_signature(cert->next, cert) 01880 < 0) { 01881 wpa_printf(MSG_DEBUG, "X509: Invalid " 01882 "certificate signature within " 01883 "chain"); 01884 *reason = X509_VALIDATE_BAD_CERTIFICATE; 01885 return -1; 01886 } 01887 } 01888 01889 for (trust = trusted; trust; trust = trust->next) { 01890 if (x509_name_compare(&cert->issuer, &trust->subject) 01891 == 0) 01892 break; 01893 } 01894 01895 if (trust) { 01896 wpa_printf(MSG_DEBUG, "X509: Found issuer from the " 01897 "list of trusted certificates"); 01898 if (x509_valid_issuer(trust) < 0) { 01899 *reason = X509_VALIDATE_BAD_CERTIFICATE; 01900 return -1; 01901 } 01902 01903 if (x509_certificate_check_signature(trust, cert) < 0) 01904 { 01905 wpa_printf(MSG_DEBUG, "X509: Invalid " 01906 "certificate signature"); 01907 *reason = X509_VALIDATE_BAD_CERTIFICATE; 01908 return -1; 01909 } 01910 01911 wpa_printf(MSG_DEBUG, "X509: Trusted certificate " 01912 "found to complete the chain"); 01913 chain_trusted = 1; 01914 } 01915 } 01916 01917 if (!chain_trusted) { 01918 wpa_printf(MSG_DEBUG, "X509: Did not find any of the issuers " 01919 "from the list of trusted certificates"); 01920 if (trusted) { 01921 *reason = X509_VALIDATE_UNKNOWN_CA; 01922 return -1; 01923 } 01924 wpa_printf(MSG_DEBUG, "X509: Certificate chain validation " 01925 "disabled - ignore unknown CA issue"); 01926 } 01927 01928 wpa_printf(MSG_DEBUG, "X509: Certificate chain valid"); 01929 01930 return 0; 01931 } 01932 01933 01941 struct x509_certificate * 01942 x509_certificate_get_subject(struct x509_certificate *chain, 01943 struct x509_name *name) 01944 { 01945 struct x509_certificate *cert; 01946 01947 for (cert = chain; cert; cert = cert->next) { 01948 if (x509_name_compare(&cert->subject, name) == 0) 01949 return cert; 01950 } 01951 return NULL; 01952 } 01953 01954 01960 int x509_certificate_self_signed(struct x509_certificate *cert) 01961 { 01962 return x509_name_compare(&cert->issuer, &cert->subject) == 0; 01963 }