00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00198
00199
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
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
00237
00238
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
00280
00281
00282
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
00311
00312
00313
00314
00315
00316
00317
00318
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
00377
00378
00379
00380
00381
00382
00383
00384 fieldp = NULL;
00385 if (oid.len == 4 &&
00386 oid.oid[0] == 2 && oid.oid[1] == 5 && oid.oid[2] == 4) {
00387
00388 switch (oid.oid[3]) {
00389 case 3:
00390
00391 fieldp = &name->cn;
00392 break;
00393 case 6:
00394
00395 fieldp = &name->c;
00396 break;
00397 case 7:
00398
00399 fieldp = &name->l;
00400 break;
00401 case 8:
00402
00403 fieldp = &name->st;
00404 break;
00405 case 10:
00406
00407 fieldp = &name->o;
00408 break;
00409 case 11:
00410
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
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
00533
00534
00535
00536
00537
00538
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
00620
00621
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
00644
00645
00646
00647
00648
00649
00650
00651
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
00702 return oid->len >= 4 &&
00703 oid->oid[0] == 2 &&
00704 oid->oid[1] == 5 &&
00705 oid->oid[2] == 29 ;
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
00716
00717
00718
00719
00720
00721
00722
00723
00724
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
00755
00756
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
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
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
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
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
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
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
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:
00993 case 3:
00994 case 4:
00995 case 5:
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
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
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
01070
01071
01072
01073
01074
01075
01076 switch (oid->oid[3]) {
01077 case 15:
01078 return x509_parse_ext_key_usage(cert, pos, len);
01079 case 17:
01080 return x509_parse_ext_subject_alt_name(cert, pos, len);
01081 case 18:
01082 return x509_parse_ext_issuer_alt_name(cert, pos, len);
01083 case 19:
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
01102
01103
01104
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
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
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
01227
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
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
01292 if (x509_parse_algorithm_identifier(pos, end - pos, &cert->signature,
01293 &pos))
01294 return -1;
01295
01296
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
01303 if (x509_parse_validity(pos, end - pos, cert, &pos))
01304 return -1;
01305
01306
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
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
01333 wpa_printf(MSG_DEBUG, "X509: issuerUniqueID");
01334
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
01351 wpa_printf(MSG_DEBUG, "X509: subjectUniqueID");
01352
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
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 &&
01401 oid->oid[1] == 2 &&
01402 oid->oid[2] == 840 &&
01403 oid->oid[3] == 113549 ;
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 ;
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 ;
01420 }
01421
01422
01423 static int x509_sha1_oid(struct asn1_oid *oid)
01424 {
01425 return oid->len == 6 &&
01426 oid->oid[0] == 1 &&
01427 oid->oid[1] == 3 &&
01428 oid->oid[2] == 14 &&
01429 oid->oid[3] == 3 &&
01430 oid->oid[4] == 2 &&
01431 oid->oid[5] == 26 ;
01432 }
01433
01434
01435 static int x509_sha256_oid(struct asn1_oid *oid)
01436 {
01437 return oid->len == 9 &&
01438 oid->oid[0] == 2 &&
01439 oid->oid[1] == 16 &&
01440 oid->oid[2] == 840 &&
01441 oid->oid[3] == 1 &&
01442 oid->oid[4] == 101 &&
01443 oid->oid[5] == 3 &&
01444 oid->oid[6] == 4 &&
01445 oid->oid[7] == 2 &&
01446 oid->oid[8] == 1 ;
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
01476
01477
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
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
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
01535
01536
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 ) {
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
01611
01612
01613
01614
01615
01616
01617
01618
01619
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
01637
01638
01639
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 ) {
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 ) {
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:
01693 if (cert->signature.oid.oid[6] != 4 )
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:
01704 case 4:
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
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:
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:
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:
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:
01752 case 12:
01753 case 13:
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 }