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