1 /*
2 * X.509v3 certificate parsing and processing (RFC 3280 profile)
3 * Copyright (c) 2006-2015, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "includes.h"
10
11 #include "common.h"
12 #include "crypto/crypto.h"
13 #include "asn1.h"
14 #include "x509v3.h"
15
16
x509_free_name(struct x509_name * name)17 void x509_free_name(struct x509_name *name)
18 {
19 size_t i;
20
21 for (i = 0; i < name->num_attr; i++) {
22 os_free(name->attr[i].value);
23 name->attr[i].value = NULL;
24 name->attr[i].type = X509_NAME_ATTR_NOT_USED;
25 }
26 name->num_attr = 0;
27 os_free(name->email);
28 name->email = NULL;
29
30 os_free(name->alt_email);
31 os_free(name->dns);
32 os_free(name->uri);
33 os_free(name->ip);
34 name->alt_email = name->dns = name->uri = NULL;
35 name->ip = NULL;
36 name->ip_len = 0;
37 os_memset(&name->rid, 0, sizeof(name->rid));
38 }
39
40
41 /**
42 * x509_certificate_free - Free an X.509 certificate
43 * @cert: Certificate to be freed
44 */
x509_certificate_free(struct x509_certificate * cert)45 void x509_certificate_free(struct x509_certificate *cert)
46 {
47 if (cert == NULL)
48 return;
49 if (cert->next) {
50 wpa_printf(MSG_DEBUG, "X509: x509_certificate_free: cer=%p "
51 "was still on a list (next=%p)\n",
52 cert, cert->next);
53 }
54 x509_free_name(&cert->issuer);
55 x509_free_name(&cert->subject);
56 os_free(cert->public_key);
57 os_free(cert->sign_value);
58 os_free(cert->subject_dn);
59 os_free(cert);
60 }
61
62
63 /**
64 * x509_certificate_free - Free an X.509 certificate chain
65 * @cert: Pointer to the first certificate in the chain
66 */
x509_certificate_chain_free(struct x509_certificate * cert)67 void x509_certificate_chain_free(struct x509_certificate *cert)
68 {
69 struct x509_certificate *next;
70
71 while (cert) {
72 next = cert->next;
73 cert->next = NULL;
74 x509_certificate_free(cert);
75 cert = next;
76 }
77 }
78
79
x509_whitespace(char c)80 static int x509_whitespace(char c)
81 {
82 return c == ' ' || c == '\t';
83 }
84
85
x509_str_strip_whitespace(char * a)86 static void x509_str_strip_whitespace(char *a)
87 {
88 char *ipos, *opos;
89 int remove_whitespace = 1;
90
91 ipos = opos = a;
92
93 while (*ipos) {
94 if (remove_whitespace && x509_whitespace(*ipos))
95 ipos++;
96 else {
97 remove_whitespace = x509_whitespace(*ipos);
98 *opos++ = *ipos++;
99 }
100 }
101
102 *opos-- = '\0';
103 if (opos > a && x509_whitespace(*opos))
104 *opos = '\0';
105 }
106
107
x509_str_compare(const char * a,const char * b)108 static int x509_str_compare(const char *a, const char *b)
109 {
110 char *aa, *bb;
111 int ret;
112
113 if (!a && b)
114 return -1;
115 if (a && !b)
116 return 1;
117 if (!a && !b)
118 return 0;
119
120 aa = os_strdup(a);
121 bb = os_strdup(b);
122
123 if (aa == NULL || bb == NULL) {
124 os_free(aa);
125 os_free(bb);
126 return os_strcasecmp(a, b);
127 }
128
129 x509_str_strip_whitespace(aa);
130 x509_str_strip_whitespace(bb);
131
132 ret = os_strcasecmp(aa, bb);
133
134 os_free(aa);
135 os_free(bb);
136
137 return ret;
138 }
139
140
141 /**
142 * x509_name_compare - Compare X.509 certificate names
143 * @a: Certificate name
144 * @b: Certificate name
145 * Returns: <0, 0, or >0 based on whether a is less than, equal to, or
146 * greater than b
147 */
x509_name_compare(struct x509_name * a,struct x509_name * b)148 int x509_name_compare(struct x509_name *a, struct x509_name *b)
149 {
150 int res;
151 size_t i;
152
153 if (!a && b)
154 return -1;
155 if (a && !b)
156 return 1;
157 if (!a && !b)
158 return 0;
159 if (a->num_attr < b->num_attr)
160 return -1;
161 if (a->num_attr > b->num_attr)
162 return 1;
163
164 for (i = 0; i < a->num_attr; i++) {
165 if (a->attr[i].type < b->attr[i].type)
166 return -1;
167 if (a->attr[i].type > b->attr[i].type)
168 return -1;
169 res = x509_str_compare(a->attr[i].value, b->attr[i].value);
170 if (res)
171 return res;
172 }
173 res = x509_str_compare(a->email, b->email);
174 if (res)
175 return res;
176
177 return 0;
178 }
179
180
x509_parse_algorithm_identifier(const u8 * buf,size_t len,struct x509_algorithm_identifier * id,const u8 ** next)181 int x509_parse_algorithm_identifier(const u8 *buf, size_t len,
182 struct x509_algorithm_identifier *id,
183 const u8 **next)
184 {
185 struct asn1_hdr hdr;
186 const u8 *pos, *end;
187
188 /*
189 * AlgorithmIdentifier ::= SEQUENCE {
190 * algorithm OBJECT IDENTIFIER,
191 * parameters ANY DEFINED BY algorithm OPTIONAL
192 * }
193 */
194
195 if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
196 asn1_unexpected(&hdr,
197 "X509: Expected SEQUENCE (AlgorithmIdentifier)");
198 return -1;
199 }
200 if (hdr.length > buf + len - hdr.payload)
201 return -1;
202 pos = hdr.payload;
203 end = pos + hdr.length;
204
205 *next = end;
206
207 if (asn1_get_oid(pos, end - pos, &id->oid, &pos))
208 return -1;
209
210 /* TODO: optional parameters */
211
212 return 0;
213 }
214
215
x509_parse_public_key(const u8 * buf,size_t len,struct x509_certificate * cert,const u8 ** next)216 static int x509_parse_public_key(const u8 *buf, size_t len,
217 struct x509_certificate *cert,
218 const u8 **next)
219 {
220 struct asn1_hdr hdr;
221 const u8 *pos, *end;
222
223 /*
224 * SubjectPublicKeyInfo ::= SEQUENCE {
225 * algorithm AlgorithmIdentifier,
226 * subjectPublicKey BIT STRING
227 * }
228 */
229
230 pos = buf;
231 end = buf + len;
232
233 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
234 !asn1_is_sequence(&hdr)) {
235 asn1_unexpected(&hdr,
236 "X509: Expected SEQUENCE (SubjectPublicKeyInfo)");
237 return -1;
238 }
239 pos = hdr.payload;
240
241 if (hdr.length > end - pos)
242 return -1;
243 end = pos + hdr.length;
244 *next = end;
245
246 if (x509_parse_algorithm_identifier(pos, end - pos,
247 &cert->public_key_alg, &pos))
248 return -1;
249
250 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
251 !asn1_is_bitstring(&hdr)) {
252 asn1_unexpected(&hdr,
253 "X509: Expected BITSTRING (subjectPublicKey)");
254 return -1;
255 }
256 if (hdr.length < 1)
257 return -1;
258 pos = hdr.payload;
259 if (*pos) {
260 wpa_printf(MSG_DEBUG,
261 "X509: BITSTRING (subjectPublicKey) - %d unused bits",
262 *pos);
263 /*
264 * TODO: should this be rejected? X.509 certificates are
265 * unlikely to use such a construction. Now we would end up
266 * including the extra bits in the buffer which may also be
267 * ok.
268 */
269 }
270 os_free(cert->public_key);
271 cert->public_key = os_memdup(pos + 1, hdr.length - 1);
272 if (cert->public_key == NULL) {
273 wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for "
274 "public key");
275 return -1;
276 }
277 cert->public_key_len = hdr.length - 1;
278 wpa_hexdump(MSG_MSGDUMP, "X509: subjectPublicKey",
279 cert->public_key, cert->public_key_len);
280
281 return 0;
282 }
283
284
x509_parse_name(const u8 * buf,size_t len,struct x509_name * name,const u8 ** next)285 int x509_parse_name(const u8 *buf, size_t len, struct x509_name *name,
286 const u8 **next)
287 {
288 struct asn1_hdr hdr;
289 const u8 *pos, *end, *set_pos, *set_end, *seq_pos, *seq_end;
290 struct asn1_oid oid;
291 char *val;
292
293 /*
294 * Name ::= CHOICE { RDNSequence }
295 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
296 * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
297 * AttributeTypeAndValue ::= SEQUENCE {
298 * type AttributeType,
299 * value AttributeValue
300 * }
301 * AttributeType ::= OBJECT IDENTIFIER
302 * AttributeValue ::= ANY DEFINED BY AttributeType
303 */
304
305 if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
306 asn1_unexpected(&hdr,
307 "X509: Expected SEQUENCE (Name / RDNSequencer)");
308 return -1;
309 }
310 pos = hdr.payload;
311
312 if (hdr.length > buf + len - pos)
313 return -1;
314
315 end = *next = pos + hdr.length;
316
317 while (pos < end) {
318 enum x509_name_attr_type type;
319
320 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
321 !asn1_is_set(&hdr)) {
322 asn1_unexpected(&hdr,
323 "X509: Expected SET (RelativeDistinguishedName)");
324 x509_free_name(name);
325 return -1;
326 }
327
328 set_pos = hdr.payload;
329 pos = set_end = hdr.payload + hdr.length;
330
331 if (asn1_get_next(set_pos, set_end - set_pos, &hdr) < 0 ||
332 !asn1_is_sequence(&hdr)) {
333 asn1_unexpected(&hdr,
334 "X509: Expected SEQUENCE (AttributeTypeAndValue)");
335 x509_free_name(name);
336 return -1;
337 }
338
339 seq_pos = hdr.payload;
340 seq_end = hdr.payload + hdr.length;
341
342 if (asn1_get_oid(seq_pos, seq_end - seq_pos, &oid, &seq_pos)) {
343 x509_free_name(name);
344 return -1;
345 }
346
347 if (asn1_get_next(seq_pos, seq_end - seq_pos, &hdr) < 0 ||
348 hdr.class != ASN1_CLASS_UNIVERSAL) {
349 wpa_printf(MSG_DEBUG, "X509: Failed to parse "
350 "AttributeValue");
351 x509_free_name(name);
352 return -1;
353 }
354
355 if (!asn1_is_string_type(&hdr)) {
356 wpa_printf(MSG_DEBUG,
357 "X509: Ignore non-string type attribute (tag 0x%x)",
358 hdr.tag);
359 continue;
360 }
361
362 /* RFC 3280:
363 * MUST: country, organization, organizational-unit,
364 * distinguished name qualifier, state or province name,
365 * common name, serial number.
366 * SHOULD: locality, title, surname, given name, initials,
367 * pseudonym, generation qualifier.
368 * MUST: domainComponent (RFC 2247).
369 */
370 type = X509_NAME_ATTR_NOT_USED;
371 if (oid.len == 4 &&
372 oid.oid[0] == 2 && oid.oid[1] == 5 && oid.oid[2] == 4) {
373 /* id-at ::= 2.5.4 */
374 switch (oid.oid[3]) {
375 case 3:
376 /* commonName */
377 type = X509_NAME_ATTR_CN;
378 break;
379 case 6:
380 /* countryName */
381 type = X509_NAME_ATTR_C;
382 break;
383 case 7:
384 /* localityName */
385 type = X509_NAME_ATTR_L;
386 break;
387 case 8:
388 /* stateOrProvinceName */
389 type = X509_NAME_ATTR_ST;
390 break;
391 case 10:
392 /* organizationName */
393 type = X509_NAME_ATTR_O;
394 break;
395 case 11:
396 /* organizationalUnitName */
397 type = X509_NAME_ATTR_OU;
398 break;
399 }
400 } else if (oid.len == 7 &&
401 oid.oid[0] == 1 && oid.oid[1] == 2 &&
402 oid.oid[2] == 840 && oid.oid[3] == 113549 &&
403 oid.oid[4] == 1 && oid.oid[5] == 9 &&
404 oid.oid[6] == 1) {
405 /* 1.2.840.113549.1.9.1 - e-mailAddress */
406 os_free(name->email);
407 name->email = os_malloc(hdr.length + 1);
408 if (name->email == NULL) {
409 x509_free_name(name);
410 return -1;
411 }
412 os_memcpy(name->email, hdr.payload, hdr.length);
413 name->email[hdr.length] = '\0';
414 continue;
415 } else if (oid.len == 7 &&
416 oid.oid[0] == 0 && oid.oid[1] == 9 &&
417 oid.oid[2] == 2342 && oid.oid[3] == 19200300 &&
418 oid.oid[4] == 100 && oid.oid[5] == 1 &&
419 oid.oid[6] == 25) {
420 /* 0.9.2342.19200300.100.1.25 - domainComponent */
421 type = X509_NAME_ATTR_DC;
422 }
423
424 if (type == X509_NAME_ATTR_NOT_USED) {
425 wpa_hexdump(MSG_DEBUG, "X509: Unrecognized OID",
426 (u8 *) oid.oid,
427 oid.len * sizeof(oid.oid[0]));
428 wpa_hexdump_ascii(MSG_MSGDUMP, "X509: Attribute Data",
429 hdr.payload, hdr.length);
430 continue;
431 }
432
433 if (name->num_attr == X509_MAX_NAME_ATTRIBUTES) {
434 wpa_printf(MSG_INFO, "X509: Too many Name attributes");
435 x509_free_name(name);
436 return -1;
437 }
438
439 val = dup_binstr(hdr.payload, hdr.length);
440 if (val == NULL) {
441 x509_free_name(name);
442 return -1;
443 }
444 if (os_strlen(val) != hdr.length) {
445 wpa_printf(MSG_INFO, "X509: Reject certificate with "
446 "embedded NUL byte in a string (%s[NUL])",
447 val);
448 os_free(val);
449 x509_free_name(name);
450 return -1;
451 }
452
453 name->attr[name->num_attr].type = type;
454 name->attr[name->num_attr].value = val;
455 name->num_attr++;
456 }
457
458 return 0;
459 }
460
461
x509_name_attr_str(enum x509_name_attr_type type)462 static char * x509_name_attr_str(enum x509_name_attr_type type)
463 {
464 switch (type) {
465 case X509_NAME_ATTR_NOT_USED:
466 return "[N/A]";
467 case X509_NAME_ATTR_DC:
468 return "DC";
469 case X509_NAME_ATTR_CN:
470 return "CN";
471 case X509_NAME_ATTR_C:
472 return "C";
473 case X509_NAME_ATTR_L:
474 return "L";
475 case X509_NAME_ATTR_ST:
476 return "ST";
477 case X509_NAME_ATTR_O:
478 return "O";
479 case X509_NAME_ATTR_OU:
480 return "OU";
481 }
482 return "?";
483 }
484
485
486 /**
487 * x509_name_string - Convert an X.509 certificate name into a string
488 * @name: Name to convert
489 * @buf: Buffer for the string
490 * @len: Maximum buffer length
491 */
x509_name_string(struct x509_name * name,char * buf,size_t len)492 void x509_name_string(struct x509_name *name, char *buf, size_t len)
493 {
494 char *pos, *end;
495 int ret;
496 size_t i;
497
498 if (len == 0)
499 return;
500
501 pos = buf;
502 end = buf + len;
503
504 for (i = 0; i < name->num_attr; i++) {
505 ret = os_snprintf(pos, end - pos, "%s=%s, ",
506 x509_name_attr_str(name->attr[i].type),
507 name->attr[i].value);
508 if (os_snprintf_error(end - pos, ret))
509 goto done;
510 pos += ret;
511 }
512
513 if (pos > buf + 1 && pos[-1] == ' ' && pos[-2] == ',') {
514 pos--;
515 *pos = '\0';
516 pos--;
517 *pos = '\0';
518 }
519
520 if (name->email) {
521 ret = os_snprintf(pos, end - pos, "/emailAddress=%s",
522 name->email);
523 if (os_snprintf_error(end - pos, ret))
524 goto done;
525 pos += ret;
526 }
527
528 done:
529 if (pos < end)
530 *pos = '\0';
531 end[-1] = '\0';
532 }
533
534
parse_uint2(const char * pos,size_t len)535 static int parse_uint2(const char *pos, size_t len)
536 {
537 char buf[3];
538 int ret;
539
540 if (len < 2)
541 return -1;
542 buf[0] = pos[0];
543 buf[1] = pos[1];
544 buf[2] = 0x00;
545 if (sscanf(buf, "%2d", &ret) != 1)
546 return -1;
547 return ret;
548 }
549
550
parse_uint4(const char * pos,size_t len)551 static int parse_uint4(const char *pos, size_t len)
552 {
553 char buf[5];
554 int ret;
555
556 if (len < 4)
557 return -1;
558 buf[0] = pos[0];
559 buf[1] = pos[1];
560 buf[2] = pos[2];
561 buf[3] = pos[3];
562 buf[4] = 0x00;
563 if (sscanf(buf, "%4d", &ret) != 1)
564 return -1;
565 return ret;
566 }
567
568
x509_parse_time(const u8 * buf,size_t len,u8 asn1_tag,os_time_t * val)569 int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag, os_time_t *val)
570 {
571 const char *pos, *end;
572 int year, month, day, hour, min, sec;
573
574 /*
575 * Time ::= CHOICE {
576 * utcTime UTCTime,
577 * generalTime GeneralizedTime
578 * }
579 *
580 * UTCTime: YYMMDDHHMMSSZ
581 * GeneralizedTime: YYYYMMDDHHMMSSZ
582 */
583
584 pos = (const char *) buf;
585 end = pos + len;
586
587 switch (asn1_tag) {
588 case ASN1_TAG_UTCTIME:
589 if (len != 13 || buf[12] != 'Z') {
590 wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized "
591 "UTCTime format", buf, len);
592 return -1;
593 }
594 year = parse_uint2(pos, end - pos);
595 if (year < 0) {
596 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse "
597 "UTCTime year", buf, len);
598 return -1;
599 }
600 if (year < 50)
601 year += 2000;
602 else
603 year += 1900;
604 pos += 2;
605 break;
606 case ASN1_TAG_GENERALIZEDTIME:
607 if (len != 15 || buf[14] != 'Z') {
608 wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized "
609 "GeneralizedTime format", buf, len);
610 return -1;
611 }
612 year = parse_uint4(pos, end - pos);
613 if (year < 0) {
614 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse "
615 "GeneralizedTime year", buf, len);
616 return -1;
617 }
618 pos += 4;
619 break;
620 default:
621 wpa_printf(MSG_DEBUG, "X509: Expected UTCTime or "
622 "GeneralizedTime - found tag 0x%x", asn1_tag);
623 return -1;
624 }
625
626 month = parse_uint2(pos, end - pos);
627 if (month < 0) {
628 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
629 "(month)", buf, len);
630 return -1;
631 }
632 pos += 2;
633
634 day = parse_uint2(pos, end - pos);
635 if (day < 0) {
636 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
637 "(day)", buf, len);
638 return -1;
639 }
640 pos += 2;
641
642 hour = parse_uint2(pos, end - pos);
643 if (hour < 0) {
644 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
645 "(hour)", buf, len);
646 return -1;
647 }
648 pos += 2;
649
650 min = parse_uint2(pos, end - pos);
651 if (min < 0) {
652 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
653 "(min)", buf, len);
654 return -1;
655 }
656 pos += 2;
657
658 sec = parse_uint2(pos, end - pos);
659 if (sec < 0) {
660 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
661 "(sec)", buf, len);
662 return -1;
663 }
664
665 if (os_mktime(year, month, day, hour, min, sec, val) < 0) {
666 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to convert Time",
667 buf, len);
668 if (year < 1970) {
669 /*
670 * At least some test certificates have been configured
671 * to use dates prior to 1970. Set the date to
672 * beginning of 1970 to handle these case.
673 */
674 wpa_printf(MSG_DEBUG, "X509: Year=%d before epoch - "
675 "assume epoch as the time", year);
676 *val = 0;
677 return 0;
678 }
679 return -1;
680 }
681
682 return 0;
683 }
684
685
x509_parse_validity(const u8 * buf,size_t len,struct x509_certificate * cert,const u8 ** next)686 static int x509_parse_validity(const u8 *buf, size_t len,
687 struct x509_certificate *cert, const u8 **next)
688 {
689 struct asn1_hdr hdr;
690 const u8 *pos;
691 size_t plen;
692
693 /*
694 * Validity ::= SEQUENCE {
695 * notBefore Time,
696 * notAfter Time
697 * }
698 *
699 * RFC 3280, 4.1.2.5:
700 * CAs conforming to this profile MUST always encode certificate
701 * validity dates through the year 2049 as UTCTime; certificate
702 * validity dates in 2050 or later MUST be encoded as GeneralizedTime.
703 */
704
705 if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
706 asn1_unexpected(&hdr, "X509: Expected SEQUENCE (Validity)");
707 return -1;
708 }
709 pos = hdr.payload;
710 plen = hdr.length;
711
712 if (plen > (size_t) (buf + len - pos))
713 return -1;
714
715 *next = pos + plen;
716
717 if (asn1_get_next(pos, plen, &hdr) < 0 ||
718 (!asn1_is_utctime(&hdr) && !asn1_is_generalizedtime(&hdr)) ||
719 x509_parse_time(hdr.payload, hdr.length, hdr.tag,
720 &cert->not_before) < 0) {
721 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notBefore "
722 "Time", hdr.payload, hdr.length);
723 return -1;
724 }
725
726 pos = hdr.payload + hdr.length;
727 plen = *next - pos;
728
729 if (asn1_get_next(pos, plen, &hdr) < 0 ||
730 (!asn1_is_utctime(&hdr) && !asn1_is_generalizedtime(&hdr)) ||
731 x509_parse_time(hdr.payload, hdr.length, hdr.tag,
732 &cert->not_after) < 0) {
733 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notAfter "
734 "Time", hdr.payload, hdr.length);
735 return -1;
736 }
737
738 wpa_printf(MSG_MSGDUMP, "X509: Validity: notBefore: %lu notAfter: %lu",
739 (unsigned long) cert->not_before,
740 (unsigned long) cert->not_after);
741
742 return 0;
743 }
744
745
x509_id_ce_oid(struct asn1_oid * oid)746 static int x509_id_ce_oid(struct asn1_oid *oid)
747 {
748 /* id-ce arc from X.509 for standard X.509v3 extensions */
749 return oid->len >= 4 &&
750 oid->oid[0] == 2 /* joint-iso-ccitt */ &&
751 oid->oid[1] == 5 /* ds */ &&
752 oid->oid[2] == 29 /* id-ce */;
753 }
754
755
x509_any_ext_key_usage_oid(struct asn1_oid * oid)756 static int x509_any_ext_key_usage_oid(struct asn1_oid *oid)
757 {
758 return oid->len == 6 &&
759 x509_id_ce_oid(oid) &&
760 oid->oid[3] == 37 /* extKeyUsage */ &&
761 oid->oid[4] == 0 /* anyExtendedKeyUsage */;
762 }
763
764
x509_parse_ext_key_usage(struct x509_certificate * cert,const u8 * pos,size_t len)765 static int x509_parse_ext_key_usage(struct x509_certificate *cert,
766 const u8 *pos, size_t len)
767 {
768 struct asn1_hdr hdr;
769
770 /*
771 * KeyUsage ::= BIT STRING {
772 * digitalSignature (0),
773 * nonRepudiation (1),
774 * keyEncipherment (2),
775 * dataEncipherment (3),
776 * keyAgreement (4),
777 * keyCertSign (5),
778 * cRLSign (6),
779 * encipherOnly (7),
780 * decipherOnly (8) }
781 */
782
783 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_bitstring(&hdr) ||
784 hdr.length < 1) {
785 asn1_unexpected(&hdr, "X509: Expected BIT STRING in KeyUsage");
786 return -1;
787 }
788
789 cert->extensions_present |= X509_EXT_KEY_USAGE;
790 cert->key_usage = asn1_bit_string_to_long(hdr.payload, hdr.length);
791
792 wpa_printf(MSG_DEBUG, "X509: KeyUsage 0x%lx", cert->key_usage);
793
794 return 0;
795 }
796
797
x509_parse_ext_basic_constraints(struct x509_certificate * cert,const u8 * pos,size_t len)798 static int x509_parse_ext_basic_constraints(struct x509_certificate *cert,
799 const u8 *pos, size_t len)
800 {
801 struct asn1_hdr hdr;
802 unsigned long value;
803 size_t left;
804 const u8 *end_seq;
805
806 /*
807 * BasicConstraints ::= SEQUENCE {
808 * cA BOOLEAN DEFAULT FALSE,
809 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
810 */
811
812 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
813 asn1_unexpected(&hdr,
814 "X509: Expected SEQUENCE in BasicConstraints");
815 return -1;
816 }
817
818 cert->extensions_present |= X509_EXT_BASIC_CONSTRAINTS;
819
820 if (hdr.length == 0)
821 return 0;
822
823 end_seq = hdr.payload + hdr.length;
824 if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0) {
825 wpa_printf(MSG_DEBUG, "X509: Failed to parse "
826 "BasicConstraints");
827 return -1;
828 }
829
830 if (asn1_is_boolean(&hdr)) {
831 cert->ca = hdr.payload[0];
832
833 pos = hdr.payload + hdr.length;
834 if (pos >= end_seq) {
835 /* No optional pathLenConstraint */
836 wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d",
837 cert->ca);
838 return 0;
839 }
840 if (asn1_get_next(pos, end_seq - pos, &hdr) < 0) {
841 wpa_printf(MSG_DEBUG, "X509: Failed to parse "
842 "BasicConstraints");
843 return -1;
844 }
845 }
846
847 if (!asn1_is_integer(&hdr)) {
848 asn1_unexpected(&hdr,
849 "X509: Expected INTEGER in BasicConstraints");
850 return -1;
851 }
852
853 pos = hdr.payload;
854 left = hdr.length;
855 value = 0;
856 while (left) {
857 value <<= 8;
858 value |= *pos++;
859 left--;
860 }
861
862 cert->path_len_constraint = value;
863 cert->extensions_present |= X509_EXT_PATH_LEN_CONSTRAINT;
864
865 wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d "
866 "pathLenConstraint=%lu",
867 cert->ca, cert->path_len_constraint);
868
869 return 0;
870 }
871
872
x509_parse_alt_name_rfc8222(struct x509_name * name,const u8 * pos,size_t len)873 static int x509_parse_alt_name_rfc8222(struct x509_name *name,
874 const u8 *pos, size_t len)
875 {
876 /* rfc822Name IA5String */
877 wpa_hexdump_ascii(MSG_MSGDUMP, "X509: altName - rfc822Name", pos, len);
878 os_free(name->alt_email);
879 name->alt_email = os_zalloc(len + 1);
880 if (name->alt_email == NULL)
881 return -1;
882 os_memcpy(name->alt_email, pos, len);
883 if (os_strlen(name->alt_email) != len) {
884 wpa_printf(MSG_INFO, "X509: Reject certificate with "
885 "embedded NUL byte in rfc822Name (%s[NUL])",
886 name->alt_email);
887 os_free(name->alt_email);
888 name->alt_email = NULL;
889 return -1;
890 }
891 return 0;
892 }
893
894
x509_parse_alt_name_dns(struct x509_name * name,const u8 * pos,size_t len)895 static int x509_parse_alt_name_dns(struct x509_name *name,
896 const u8 *pos, size_t len)
897 {
898 /* dNSName IA5String */
899 wpa_hexdump_ascii(MSG_MSGDUMP, "X509: altName - dNSName", pos, len);
900 os_free(name->dns);
901 name->dns = os_zalloc(len + 1);
902 if (name->dns == NULL)
903 return -1;
904 os_memcpy(name->dns, pos, len);
905 if (os_strlen(name->dns) != len) {
906 wpa_printf(MSG_INFO, "X509: Reject certificate with "
907 "embedded NUL byte in dNSName (%s[NUL])",
908 name->dns);
909 os_free(name->dns);
910 name->dns = NULL;
911 return -1;
912 }
913 return 0;
914 }
915
916
x509_parse_alt_name_uri(struct x509_name * name,const u8 * pos,size_t len)917 static int x509_parse_alt_name_uri(struct x509_name *name,
918 const u8 *pos, size_t len)
919 {
920 /* uniformResourceIdentifier IA5String */
921 wpa_hexdump_ascii(MSG_MSGDUMP,
922 "X509: altName - uniformResourceIdentifier",
923 pos, len);
924 os_free(name->uri);
925 name->uri = os_zalloc(len + 1);
926 if (name->uri == NULL)
927 return -1;
928 os_memcpy(name->uri, pos, len);
929 if (os_strlen(name->uri) != len) {
930 wpa_printf(MSG_INFO, "X509: Reject certificate with "
931 "embedded NUL byte in uniformResourceIdentifier "
932 "(%s[NUL])", name->uri);
933 os_free(name->uri);
934 name->uri = NULL;
935 return -1;
936 }
937 return 0;
938 }
939
940
x509_parse_alt_name_ip(struct x509_name * name,const u8 * pos,size_t len)941 static int x509_parse_alt_name_ip(struct x509_name *name,
942 const u8 *pos, size_t len)
943 {
944 /* iPAddress OCTET STRING */
945 wpa_hexdump(MSG_MSGDUMP, "X509: altName - iPAddress", pos, len);
946 os_free(name->ip);
947 name->ip = os_memdup(pos, len);
948 if (name->ip == NULL)
949 return -1;
950 name->ip_len = len;
951 return 0;
952 }
953
954
x509_parse_alt_name_rid(struct x509_name * name,const u8 * pos,size_t len)955 static int x509_parse_alt_name_rid(struct x509_name *name,
956 const u8 *pos, size_t len)
957 {
958 char buf[80];
959
960 /* registeredID OBJECT IDENTIFIER */
961 if (asn1_parse_oid(pos, len, &name->rid) < 0)
962 return -1;
963
964 asn1_oid_to_str(&name->rid, buf, sizeof(buf));
965 wpa_printf(MSG_MSGDUMP, "X509: altName - registeredID: %s", buf);
966
967 return 0;
968 }
969
970
x509_parse_ext_alt_name(struct x509_name * name,const u8 * pos,size_t len)971 static int x509_parse_ext_alt_name(struct x509_name *name,
972 const u8 *pos, size_t len)
973 {
974 struct asn1_hdr hdr;
975 const u8 *p, *end;
976
977 /*
978 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
979 *
980 * GeneralName ::= CHOICE {
981 * otherName [0] OtherName,
982 * rfc822Name [1] IA5String,
983 * dNSName [2] IA5String,
984 * x400Address [3] ORAddress,
985 * directoryName [4] Name,
986 * ediPartyName [5] EDIPartyName,
987 * uniformResourceIdentifier [6] IA5String,
988 * iPAddress [7] OCTET STRING,
989 * registeredID [8] OBJECT IDENTIFIER }
990 *
991 * OtherName ::= SEQUENCE {
992 * type-id OBJECT IDENTIFIER,
993 * value [0] EXPLICIT ANY DEFINED BY type-id }
994 *
995 * EDIPartyName ::= SEQUENCE {
996 * nameAssigner [0] DirectoryString OPTIONAL,
997 * partyName [1] DirectoryString }
998 */
999
1000 for (p = pos, end = pos + len; p < end; p = hdr.payload + hdr.length) {
1001 int res;
1002
1003 if (asn1_get_next(p, end - p, &hdr) < 0) {
1004 wpa_printf(MSG_DEBUG, "X509: Failed to parse "
1005 "SubjectAltName item");
1006 return -1;
1007 }
1008
1009 if (hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC)
1010 continue;
1011
1012 switch (hdr.tag) {
1013 case 1:
1014 res = x509_parse_alt_name_rfc8222(name, hdr.payload,
1015 hdr.length);
1016 break;
1017 case 2:
1018 res = x509_parse_alt_name_dns(name, hdr.payload,
1019 hdr.length);
1020 break;
1021 case 6:
1022 res = x509_parse_alt_name_uri(name, hdr.payload,
1023 hdr.length);
1024 break;
1025 case 7:
1026 res = x509_parse_alt_name_ip(name, hdr.payload,
1027 hdr.length);
1028 break;
1029 case 8:
1030 res = x509_parse_alt_name_rid(name, hdr.payload,
1031 hdr.length);
1032 break;
1033 case 0: /* TODO: otherName */
1034 case 3: /* TODO: x500Address */
1035 case 4: /* TODO: directoryName */
1036 case 5: /* TODO: ediPartyName */
1037 default:
1038 res = 0;
1039 break;
1040 }
1041 if (res < 0)
1042 return res;
1043 }
1044
1045 return 0;
1046 }
1047
1048
x509_parse_ext_subject_alt_name(struct x509_certificate * cert,const u8 * pos,size_t len)1049 static int x509_parse_ext_subject_alt_name(struct x509_certificate *cert,
1050 const u8 *pos, size_t len)
1051 {
1052 struct asn1_hdr hdr;
1053
1054 /* SubjectAltName ::= GeneralNames */
1055
1056 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1057 asn1_unexpected(&hdr,
1058 "X509: Expected SEQUENCE in SubjectAltName");
1059 return -1;
1060 }
1061
1062 wpa_printf(MSG_DEBUG, "X509: SubjectAltName");
1063 cert->extensions_present |= X509_EXT_SUBJECT_ALT_NAME;
1064
1065 if (hdr.length == 0)
1066 return 0;
1067
1068 return x509_parse_ext_alt_name(&cert->subject, hdr.payload,
1069 hdr.length);
1070 }
1071
1072
x509_parse_ext_issuer_alt_name(struct x509_certificate * cert,const u8 * pos,size_t len)1073 static int x509_parse_ext_issuer_alt_name(struct x509_certificate *cert,
1074 const u8 *pos, size_t len)
1075 {
1076 struct asn1_hdr hdr;
1077
1078 /* IssuerAltName ::= GeneralNames */
1079
1080 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1081 asn1_unexpected(&hdr,
1082 "X509: Expected SEQUENCE in IssuerAltName");
1083 return -1;
1084 }
1085
1086 wpa_printf(MSG_DEBUG, "X509: IssuerAltName");
1087 cert->extensions_present |= X509_EXT_ISSUER_ALT_NAME;
1088
1089 if (hdr.length == 0)
1090 return 0;
1091
1092 return x509_parse_ext_alt_name(&cert->issuer, hdr.payload,
1093 hdr.length);
1094 }
1095
1096
x509_id_cert_policy_any_oid(struct asn1_oid * oid)1097 static int x509_id_cert_policy_any_oid(struct asn1_oid *oid)
1098 {
1099 return oid->len == 5 &&
1100 oid->oid[0] == 2 /* iso/itu-t */ &&
1101 oid->oid[1] == 5 /* X.500 Directory Services */ &&
1102 oid->oid[2] == 29 /* id-ce */ &&
1103 oid->oid[3] == 32 /* id-ce-certificate-policies */ &&
1104 oid->oid[4] == 0 /* anyPolicy */;
1105 }
1106
1107
x509_id_wfa_oid(struct asn1_oid * oid)1108 static int x509_id_wfa_oid(struct asn1_oid *oid)
1109 {
1110 return oid->len >= 7 &&
1111 oid->oid[0] == 1 /* iso */ &&
1112 oid->oid[1] == 3 /* identified-organization */ &&
1113 oid->oid[2] == 6 /* dod */ &&
1114 oid->oid[3] == 1 /* internet */ &&
1115 oid->oid[4] == 4 /* private */ &&
1116 oid->oid[5] == 1 /* enterprise */ &&
1117 oid->oid[6] == 40808 /* WFA */;
1118 }
1119
1120
x509_id_wfa_tod_oid(struct asn1_oid * oid)1121 static int x509_id_wfa_tod_oid(struct asn1_oid *oid)
1122 {
1123 return oid->len >= 9 &&
1124 x509_id_wfa_oid(oid) &&
1125 oid->oid[7] == 1 &&
1126 oid->oid[8] == 3;
1127 }
1128
1129
x509_id_wfa_tod_strict_oid(struct asn1_oid * oid)1130 static int x509_id_wfa_tod_strict_oid(struct asn1_oid *oid)
1131 {
1132 return oid->len == 10 &&
1133 x509_id_wfa_tod_oid(oid) &&
1134 oid->oid[9] == 1;
1135 }
1136
1137
x509_id_wfa_tod_tofu_oid(struct asn1_oid * oid)1138 static int x509_id_wfa_tod_tofu_oid(struct asn1_oid *oid)
1139 {
1140 return oid->len == 10 &&
1141 x509_id_wfa_tod_oid(oid) &&
1142 oid->oid[9] == 2;
1143 }
1144
1145
x509_parse_ext_certificate_policies(struct x509_certificate * cert,const u8 * pos,size_t len)1146 static int x509_parse_ext_certificate_policies(struct x509_certificate *cert,
1147 const u8 *pos, size_t len)
1148 {
1149 struct asn1_hdr hdr;
1150 const u8 *end;
1151
1152 /*
1153 * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
1154 *
1155 * PolicyInformation ::= SEQUENCE {
1156 * policyIdentifier CertPolicyId,
1157 * policyQualifiers SEQUENCE SIZE (1..MAX) OF
1158 * PolicyQualifierInfo OPTIONAL }
1159 *
1160 * CertPolicyId ::= OBJECT IDENTIFIER
1161 */
1162
1163 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1164 asn1_unexpected(&hdr,
1165 "X509: Expected SEQUENCE (certificatePolicies)");
1166 return -1;
1167 }
1168 if (hdr.length > pos + len - hdr.payload)
1169 return -1;
1170 pos = hdr.payload;
1171 end = pos + hdr.length;
1172
1173 wpa_hexdump(MSG_MSGDUMP, "X509: certificatePolicies", pos, end - pos);
1174
1175 while (pos < end) {
1176 const u8 *pol_end;
1177 struct asn1_oid oid;
1178 char buf[80];
1179
1180 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1181 !asn1_is_sequence(&hdr)) {
1182 asn1_unexpected(&hdr,
1183 "X509: Expected SEQUENCE (PolicyInformation)");
1184 return -1;
1185 }
1186 if (hdr.length > end - hdr.payload)
1187 return -1;
1188 pos = hdr.payload;
1189 pol_end = pos + hdr.length;
1190 wpa_hexdump(MSG_MSGDUMP, "X509: PolicyInformation",
1191 pos, pol_end - pos);
1192
1193 if (asn1_get_oid(pos, pol_end - pos, &oid, &pos))
1194 return -1;
1195 if (x509_id_cert_policy_any_oid(&oid)) {
1196 os_strlcpy(buf, "anyPolicy-STRICT", sizeof(buf));
1197 cert->certificate_policy |=
1198 X509_EXT_CERT_POLICY_ANY;
1199 } else if (x509_id_wfa_tod_strict_oid(&oid)) {
1200 os_strlcpy(buf, "TOD-STRICT", sizeof(buf));
1201 cert->certificate_policy |=
1202 X509_EXT_CERT_POLICY_TOD_STRICT;
1203 } else if (x509_id_wfa_tod_tofu_oid(&oid)) {
1204 os_strlcpy(buf, "TOD-TOFU", sizeof(buf));
1205 cert->certificate_policy |=
1206 X509_EXT_CERT_POLICY_TOD_TOFU;
1207 } else {
1208 asn1_oid_to_str(&oid, buf, sizeof(buf));
1209 }
1210 wpa_printf(MSG_DEBUG, "policyIdentifier: %s", buf);
1211
1212 pos = pol_end;
1213 }
1214
1215 cert->extensions_present |= X509_EXT_CERTIFICATE_POLICY;
1216
1217 return 0;
1218 }
1219
1220
x509_id_pkix_oid(struct asn1_oid * oid)1221 static int x509_id_pkix_oid(struct asn1_oid *oid)
1222 {
1223 return oid->len >= 7 &&
1224 oid->oid[0] == 1 /* iso */ &&
1225 oid->oid[1] == 3 /* identified-organization */ &&
1226 oid->oid[2] == 6 /* dod */ &&
1227 oid->oid[3] == 1 /* internet */ &&
1228 oid->oid[4] == 5 /* security */ &&
1229 oid->oid[5] == 5 /* mechanisms */ &&
1230 oid->oid[6] == 7 /* id-pkix */;
1231 }
1232
1233
x509_id_kp_oid(struct asn1_oid * oid)1234 static int x509_id_kp_oid(struct asn1_oid *oid)
1235 {
1236 /* id-kp */
1237 return oid->len >= 8 &&
1238 x509_id_pkix_oid(oid) &&
1239 oid->oid[7] == 3 /* id-kp */;
1240 }
1241
1242
x509_id_kp_server_auth_oid(struct asn1_oid * oid)1243 static int x509_id_kp_server_auth_oid(struct asn1_oid *oid)
1244 {
1245 /* id-kp */
1246 return oid->len == 9 &&
1247 x509_id_kp_oid(oid) &&
1248 oid->oid[8] == 1 /* id-kp-serverAuth */;
1249 }
1250
1251
x509_id_kp_client_auth_oid(struct asn1_oid * oid)1252 static int x509_id_kp_client_auth_oid(struct asn1_oid *oid)
1253 {
1254 /* id-kp */
1255 return oid->len == 9 &&
1256 x509_id_kp_oid(oid) &&
1257 oid->oid[8] == 2 /* id-kp-clientAuth */;
1258 }
1259
1260
x509_id_kp_ocsp_oid(struct asn1_oid * oid)1261 static int x509_id_kp_ocsp_oid(struct asn1_oid *oid)
1262 {
1263 /* id-kp */
1264 return oid->len == 9 &&
1265 x509_id_kp_oid(oid) &&
1266 oid->oid[8] == 9 /* id-kp-OCSPSigning */;
1267 }
1268
1269
x509_parse_ext_ext_key_usage(struct x509_certificate * cert,const u8 * pos,size_t len)1270 static int x509_parse_ext_ext_key_usage(struct x509_certificate *cert,
1271 const u8 *pos, size_t len)
1272 {
1273 struct asn1_hdr hdr;
1274 const u8 *end;
1275 struct asn1_oid oid;
1276
1277 /*
1278 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
1279 *
1280 * KeyPurposeId ::= OBJECT IDENTIFIER
1281 */
1282
1283 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1284 asn1_unexpected(&hdr,
1285 "X509: Expected SEQUENCE (ExtKeyUsageSyntax)");
1286 return -1;
1287 }
1288 if (hdr.length > pos + len - hdr.payload)
1289 return -1;
1290 pos = hdr.payload;
1291 end = pos + hdr.length;
1292
1293 wpa_hexdump(MSG_MSGDUMP, "X509: ExtKeyUsageSyntax", pos, end - pos);
1294
1295 while (pos < end) {
1296 char buf[80];
1297
1298 if (asn1_get_oid(pos, end - pos, &oid, &pos))
1299 return -1;
1300 if (x509_any_ext_key_usage_oid(&oid)) {
1301 os_strlcpy(buf, "anyExtendedKeyUsage", sizeof(buf));
1302 cert->ext_key_usage |= X509_EXT_KEY_USAGE_ANY;
1303 } else if (x509_id_kp_server_auth_oid(&oid)) {
1304 os_strlcpy(buf, "id-kp-serverAuth", sizeof(buf));
1305 cert->ext_key_usage |= X509_EXT_KEY_USAGE_SERVER_AUTH;
1306 } else if (x509_id_kp_client_auth_oid(&oid)) {
1307 os_strlcpy(buf, "id-kp-clientAuth", sizeof(buf));
1308 cert->ext_key_usage |= X509_EXT_KEY_USAGE_CLIENT_AUTH;
1309 } else if (x509_id_kp_ocsp_oid(&oid)) {
1310 os_strlcpy(buf, "id-kp-OCSPSigning", sizeof(buf));
1311 cert->ext_key_usage |= X509_EXT_KEY_USAGE_OCSP;
1312 } else {
1313 asn1_oid_to_str(&oid, buf, sizeof(buf));
1314 }
1315 wpa_printf(MSG_DEBUG, "ExtKeyUsage KeyPurposeId: %s", buf);
1316 }
1317
1318 cert->extensions_present |= X509_EXT_EXT_KEY_USAGE;
1319
1320 return 0;
1321 }
1322
1323
x509_parse_extension_data(struct x509_certificate * cert,struct asn1_oid * oid,const u8 * pos,size_t len)1324 static int x509_parse_extension_data(struct x509_certificate *cert,
1325 struct asn1_oid *oid,
1326 const u8 *pos, size_t len)
1327 {
1328 if (!x509_id_ce_oid(oid))
1329 return 1;
1330
1331 /* TODO: add other extensions required by RFC 3280, Ch 4.2:
1332 * name constraints (section 4.2.1.11)
1333 * policy constraints (section 4.2.1.12)
1334 * inhibit any-policy (section 4.2.1.15)
1335 */
1336 switch (oid->oid[3]) {
1337 case 15: /* id-ce-keyUsage */
1338 return x509_parse_ext_key_usage(cert, pos, len);
1339 case 17: /* id-ce-subjectAltName */
1340 return x509_parse_ext_subject_alt_name(cert, pos, len);
1341 case 18: /* id-ce-issuerAltName */
1342 return x509_parse_ext_issuer_alt_name(cert, pos, len);
1343 case 19: /* id-ce-basicConstraints */
1344 return x509_parse_ext_basic_constraints(cert, pos, len);
1345 case 32: /* id-ce-certificatePolicies */
1346 return x509_parse_ext_certificate_policies(cert, pos, len);
1347 case 37: /* id-ce-extKeyUsage */
1348 return x509_parse_ext_ext_key_usage(cert, pos, len);
1349 default:
1350 return 1;
1351 }
1352 }
1353
1354
x509_parse_extension(struct x509_certificate * cert,const u8 * pos,size_t len,const u8 ** next)1355 static int x509_parse_extension(struct x509_certificate *cert,
1356 const u8 *pos, size_t len, const u8 **next)
1357 {
1358 const u8 *end;
1359 struct asn1_hdr hdr;
1360 struct asn1_oid oid;
1361 int critical_ext = 0, res;
1362 char buf[80];
1363
1364 /*
1365 * Extension ::= SEQUENCE {
1366 * extnID OBJECT IDENTIFIER,
1367 * critical BOOLEAN DEFAULT FALSE,
1368 * extnValue OCTET STRING
1369 * }
1370 */
1371
1372 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1373 asn1_unexpected(&hdr, "X509: Expected SEQUENCE in Extensions");
1374 return -1;
1375 }
1376 pos = hdr.payload;
1377 *next = end = pos + hdr.length;
1378
1379 if (asn1_get_oid(pos, end - pos, &oid, &pos) < 0) {
1380 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 data for "
1381 "Extension (expected OID)");
1382 return -1;
1383 }
1384
1385 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1386 (!asn1_is_boolean(&hdr) && !asn1_is_octetstring(&hdr))) {
1387 asn1_unexpected(&hdr,
1388 "X509: Expected BOOLEAN or OCTETSTRING in Extensions");
1389 return -1;
1390 }
1391
1392 if (hdr.tag == ASN1_TAG_BOOLEAN) {
1393 critical_ext = hdr.payload[0];
1394 pos = hdr.payload;
1395 /*
1396 * Number of CA certificates seem to be using Private class in
1397 * one of the X.509v3 extensions, so let's accept that instead
1398 * of rejecting the certificate. asn1_is_octetstring() covers
1399 * the more common case.
1400 */
1401 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1402 (!asn1_is_octetstring(&hdr) &&
1403 !(hdr.class == ASN1_CLASS_PRIVATE &&
1404 hdr.tag == ASN1_TAG_OCTETSTRING))) {
1405 asn1_unexpected(&hdr,
1406 "X509: Expected OCTETSTRING in Extensions");
1407 return -1;
1408 }
1409 }
1410
1411 asn1_oid_to_str(&oid, buf, sizeof(buf));
1412 wpa_printf(MSG_DEBUG, "X509: Extension: extnID=%s critical=%d",
1413 buf, critical_ext);
1414 wpa_hexdump(MSG_MSGDUMP, "X509: extnValue", hdr.payload, hdr.length);
1415
1416 res = x509_parse_extension_data(cert, &oid, hdr.payload, hdr.length);
1417 if (res < 0)
1418 return res;
1419 if (res == 1 && critical_ext) {
1420 wpa_printf(MSG_INFO, "X509: Unknown critical extension %s",
1421 buf);
1422 return -1;
1423 }
1424
1425 return 0;
1426 }
1427
1428
x509_parse_extensions(struct x509_certificate * cert,const u8 * pos,size_t len)1429 static int x509_parse_extensions(struct x509_certificate *cert,
1430 const u8 *pos, size_t len)
1431 {
1432 const u8 *end;
1433 struct asn1_hdr hdr;
1434
1435 /* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension */
1436
1437 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1438 asn1_unexpected(&hdr, "X509: Expected SEQUENCE for Extensions");
1439 return -1;
1440 }
1441
1442 pos = hdr.payload;
1443 end = pos + hdr.length;
1444
1445 while (pos < end) {
1446 if (x509_parse_extension(cert, pos, end - pos, &pos)
1447 < 0)
1448 return -1;
1449 }
1450
1451 return 0;
1452 }
1453
1454
x509_parse_tbs_certificate(const u8 * buf,size_t len,struct x509_certificate * cert,const u8 ** next)1455 static int x509_parse_tbs_certificate(const u8 *buf, size_t len,
1456 struct x509_certificate *cert,
1457 const u8 **next)
1458 {
1459 struct asn1_hdr hdr;
1460 const u8 *pos, *end;
1461 size_t left;
1462 char sbuf[128];
1463 unsigned long value;
1464 const u8 *subject_dn;
1465
1466 /* tbsCertificate TBSCertificate ::= SEQUENCE */
1467 if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1468 asn1_unexpected(&hdr,
1469 "X509: tbsCertificate did not start with a valid SEQUENCE");
1470 return -1;
1471 }
1472 pos = hdr.payload;
1473 end = *next = pos + hdr.length;
1474
1475 /*
1476 * version [0] EXPLICIT Version DEFAULT v1
1477 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1478 */
1479 if (asn1_get_next(pos, end - pos, &hdr) < 0)
1480 return -1;
1481 pos = hdr.payload;
1482
1483 if (asn1_is_cs_tag(&hdr, 0) && hdr.constructed) {
1484 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1485 !asn1_is_integer(&hdr)) {
1486 asn1_unexpected(&hdr,
1487 "X509: No INTEGER tag found for version field");
1488 return -1;
1489 }
1490 if (hdr.length != 1) {
1491 wpa_printf(MSG_DEBUG, "X509: Unexpected version field "
1492 "length %u (expected 1)", hdr.length);
1493 return -1;
1494 }
1495 pos = hdr.payload;
1496 left = hdr.length;
1497 value = 0;
1498 while (left) {
1499 value <<= 8;
1500 value |= *pos++;
1501 left--;
1502 }
1503
1504 cert->version = value;
1505 if (cert->version != X509_CERT_V1 &&
1506 cert->version != X509_CERT_V2 &&
1507 cert->version != X509_CERT_V3) {
1508 wpa_printf(MSG_DEBUG, "X509: Unsupported version %d",
1509 cert->version + 1);
1510 return -1;
1511 }
1512
1513 if (asn1_get_next(pos, end - pos, &hdr) < 0)
1514 return -1;
1515 } else
1516 cert->version = X509_CERT_V1;
1517 wpa_printf(MSG_MSGDUMP, "X509: Version X.509v%d", cert->version + 1);
1518
1519 /* serialNumber CertificateSerialNumber ::= INTEGER */
1520 if (!asn1_is_integer(&hdr) ||
1521 hdr.length < 1 || hdr.length > X509_MAX_SERIAL_NUM_LEN) {
1522 asn1_unexpected(&hdr,
1523 "X509: No INTEGER tag found for serialNumber");
1524 return -1;
1525 }
1526
1527 pos = hdr.payload + hdr.length;
1528 while (hdr.length > 0 && hdr.payload[0] == 0) {
1529 hdr.payload++;
1530 hdr.length--;
1531 }
1532 os_memcpy(cert->serial_number, hdr.payload, hdr.length);
1533 cert->serial_number_len = hdr.length;
1534 wpa_hexdump(MSG_MSGDUMP, "X509: serialNumber", cert->serial_number,
1535 cert->serial_number_len);
1536
1537 /* signature AlgorithmIdentifier */
1538 if (x509_parse_algorithm_identifier(pos, end - pos, &cert->signature,
1539 &pos))
1540 return -1;
1541
1542 /* issuer Name */
1543 if (x509_parse_name(pos, end - pos, &cert->issuer, &pos))
1544 return -1;
1545 x509_name_string(&cert->issuer, sbuf, sizeof(sbuf));
1546 wpa_printf(MSG_MSGDUMP, "X509: issuer %s", sbuf);
1547
1548 /* validity Validity */
1549 if (x509_parse_validity(pos, end - pos, cert, &pos))
1550 return -1;
1551
1552 /* subject Name */
1553 subject_dn = pos;
1554 if (x509_parse_name(pos, end - pos, &cert->subject, &pos))
1555 return -1;
1556 cert->subject_dn = os_malloc(pos - subject_dn);
1557 if (!cert->subject_dn)
1558 return -1;
1559 cert->subject_dn_len = pos - subject_dn;
1560 os_memcpy(cert->subject_dn, subject_dn, cert->subject_dn_len);
1561 x509_name_string(&cert->subject, sbuf, sizeof(sbuf));
1562 wpa_printf(MSG_MSGDUMP, "X509: subject %s", sbuf);
1563
1564 /* subjectPublicKeyInfo SubjectPublicKeyInfo */
1565 if (x509_parse_public_key(pos, end - pos, cert, &pos))
1566 return -1;
1567
1568 if (pos == end)
1569 return 0;
1570
1571 if (cert->version == X509_CERT_V1)
1572 return 0;
1573
1574 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1575 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1576 asn1_unexpected(&hdr,
1577 "X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
1578 return -1;
1579 }
1580
1581 if (hdr.tag == 1) {
1582 /* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL */
1583 wpa_printf(MSG_DEBUG, "X509: issuerUniqueID");
1584 /* TODO: parse UniqueIdentifier ::= BIT STRING */
1585
1586 pos = hdr.payload + hdr.length;
1587 if (pos == end)
1588 return 0;
1589
1590 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1591 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1592 asn1_unexpected(&hdr,
1593 "X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
1594 return -1;
1595 }
1596 }
1597
1598 if (hdr.tag == 2) {
1599 /* subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL */
1600 wpa_printf(MSG_DEBUG, "X509: subjectUniqueID");
1601 /* TODO: parse UniqueIdentifier ::= BIT STRING */
1602
1603 pos = hdr.payload + hdr.length;
1604 if (pos == end)
1605 return 0;
1606
1607 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1608 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1609 asn1_unexpected(&hdr,
1610 "X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
1611 return -1;
1612 }
1613 }
1614
1615 if (hdr.tag != 3) {
1616 wpa_printf(MSG_DEBUG,
1617 "X509: Ignored unexpected Context-Specific constructed %d tag %d in optional tbsCertificate fields",
1618 hdr.constructed, hdr.tag);
1619 return 0;
1620 }
1621
1622 /* extensions [3] EXPLICIT Extensions OPTIONAL */
1623
1624 if (cert->version != X509_CERT_V3) {
1625 wpa_printf(MSG_DEBUG, "X509: X.509%d certificate and "
1626 "Extensions data which are only allowed for "
1627 "version 3", cert->version + 1);
1628 return -1;
1629 }
1630
1631 if (x509_parse_extensions(cert, hdr.payload, hdr.length) < 0)
1632 return -1;
1633
1634 pos = hdr.payload + hdr.length;
1635 if (pos < end) {
1636 wpa_hexdump(MSG_DEBUG,
1637 "X509: Ignored extra tbsCertificate data",
1638 pos, end - pos);
1639 }
1640
1641 return 0;
1642 }
1643
1644
x509_rsadsi_oid(struct asn1_oid * oid)1645 static int x509_rsadsi_oid(struct asn1_oid *oid)
1646 {
1647 return oid->len >= 4 &&
1648 oid->oid[0] == 1 /* iso */ &&
1649 oid->oid[1] == 2 /* member-body */ &&
1650 oid->oid[2] == 840 /* us */ &&
1651 oid->oid[3] == 113549 /* rsadsi */;
1652 }
1653
1654
x509_pkcs_oid(struct asn1_oid * oid)1655 static int x509_pkcs_oid(struct asn1_oid *oid)
1656 {
1657 return oid->len >= 5 &&
1658 x509_rsadsi_oid(oid) &&
1659 oid->oid[4] == 1 /* pkcs */;
1660 }
1661
1662
x509_digest_oid(struct asn1_oid * oid)1663 static int x509_digest_oid(struct asn1_oid *oid)
1664 {
1665 return oid->len >= 5 &&
1666 x509_rsadsi_oid(oid) &&
1667 oid->oid[4] == 2 /* digestAlgorithm */;
1668 }
1669
1670
x509_sha1_oid(struct asn1_oid * oid)1671 int x509_sha1_oid(struct asn1_oid *oid)
1672 {
1673 return oid->len == 6 &&
1674 oid->oid[0] == 1 /* iso */ &&
1675 oid->oid[1] == 3 /* identified-organization */ &&
1676 oid->oid[2] == 14 /* oiw */ &&
1677 oid->oid[3] == 3 /* secsig */ &&
1678 oid->oid[4] == 2 /* algorithms */ &&
1679 oid->oid[5] == 26 /* id-sha1 */;
1680 }
1681
1682
x509_sha2_oid(struct asn1_oid * oid)1683 static int x509_sha2_oid(struct asn1_oid *oid)
1684 {
1685 return oid->len == 9 &&
1686 oid->oid[0] == 2 /* joint-iso-itu-t */ &&
1687 oid->oid[1] == 16 /* country */ &&
1688 oid->oid[2] == 840 /* us */ &&
1689 oid->oid[3] == 1 /* organization */ &&
1690 oid->oid[4] == 101 /* gov */ &&
1691 oid->oid[5] == 3 /* csor */ &&
1692 oid->oid[6] == 4 /* nistAlgorithm */ &&
1693 oid->oid[7] == 2 /* hashAlgs */;
1694 }
1695
1696
x509_sha256_oid(struct asn1_oid * oid)1697 int x509_sha256_oid(struct asn1_oid *oid)
1698 {
1699 return x509_sha2_oid(oid) &&
1700 oid->oid[8] == 1 /* sha256 */;
1701 }
1702
1703
x509_sha384_oid(struct asn1_oid * oid)1704 int x509_sha384_oid(struct asn1_oid *oid)
1705 {
1706 return x509_sha2_oid(oid) &&
1707 oid->oid[8] == 2 /* sha384 */;
1708 }
1709
1710
x509_sha512_oid(struct asn1_oid * oid)1711 int x509_sha512_oid(struct asn1_oid *oid)
1712 {
1713 return x509_sha2_oid(oid) &&
1714 oid->oid[8] == 3 /* sha512 */;
1715 }
1716
1717
1718 /**
1719 * x509_certificate_parse - Parse a X.509 certificate in DER format
1720 * @buf: Pointer to the X.509 certificate in DER format
1721 * @len: Buffer length
1722 * Returns: Pointer to the parsed certificate or %NULL on failure
1723 *
1724 * Caller is responsible for freeing the returned certificate by calling
1725 * x509_certificate_free().
1726 */
x509_certificate_parse(const u8 * buf,size_t len)1727 struct x509_certificate * x509_certificate_parse(const u8 *buf, size_t len)
1728 {
1729 struct asn1_hdr hdr;
1730 const u8 *pos, *end, *hash_start;
1731 struct x509_certificate *cert;
1732
1733 cert = os_zalloc(sizeof(*cert) + len);
1734 if (cert == NULL)
1735 return NULL;
1736 os_memcpy(cert + 1, buf, len);
1737 cert->cert_start = (u8 *) (cert + 1);
1738 cert->cert_len = len;
1739
1740 pos = buf;
1741 end = buf + len;
1742
1743 /* RFC 3280 - X.509 v3 certificate / ASN.1 DER */
1744
1745 /* Certificate ::= SEQUENCE */
1746 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1747 asn1_unexpected(&hdr,
1748 "X509: Certificate did not start with a valid SEQUENCE");
1749 x509_certificate_free(cert);
1750 return NULL;
1751 }
1752 pos = hdr.payload;
1753
1754 if (hdr.length > end - pos) {
1755 x509_certificate_free(cert);
1756 return NULL;
1757 }
1758
1759 if (hdr.length < end - pos) {
1760 wpa_hexdump(MSG_MSGDUMP, "X509: Ignoring extra data after DER "
1761 "encoded certificate",
1762 pos + hdr.length, end - (pos + hdr.length));
1763 end = pos + hdr.length;
1764 }
1765
1766 hash_start = pos;
1767 cert->tbs_cert_start = cert->cert_start + (hash_start - buf);
1768 if (x509_parse_tbs_certificate(pos, end - pos, cert, &pos)) {
1769 x509_certificate_free(cert);
1770 return NULL;
1771 }
1772 cert->tbs_cert_len = pos - hash_start;
1773
1774 /* signatureAlgorithm AlgorithmIdentifier */
1775 if (x509_parse_algorithm_identifier(pos, end - pos,
1776 &cert->signature_alg, &pos)) {
1777 x509_certificate_free(cert);
1778 return NULL;
1779 }
1780
1781 /* signatureValue BIT STRING */
1782 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1783 !asn1_is_bitstring(&hdr)) {
1784 asn1_unexpected(&hdr,
1785 "X509: Expected BITSTRING (signatureValue)");
1786 x509_certificate_free(cert);
1787 return NULL;
1788 }
1789 if (hdr.length < 1) {
1790 x509_certificate_free(cert);
1791 return NULL;
1792 }
1793 pos = hdr.payload;
1794 if (*pos) {
1795 wpa_printf(MSG_DEBUG,
1796 "X509: BITSTRING (signatureValue) - %d unused bits",
1797 *pos);
1798 /* PKCS #1 v1.5 10.2.1:
1799 * It is an error if the length in bits of the signature S is
1800 * not a multiple of eight.
1801 */
1802 x509_certificate_free(cert);
1803 return NULL;
1804 }
1805 os_free(cert->sign_value);
1806 cert->sign_value = os_memdup(pos + 1, hdr.length - 1);
1807 if (cert->sign_value == NULL) {
1808 wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for "
1809 "signatureValue");
1810 x509_certificate_free(cert);
1811 return NULL;
1812 }
1813 cert->sign_value_len = hdr.length - 1;
1814 wpa_hexdump(MSG_MSGDUMP, "X509: signature",
1815 cert->sign_value, cert->sign_value_len);
1816
1817 return cert;
1818 }
1819
1820
1821 /**
1822 * x509_certificate_check_signature - Verify certificate signature
1823 * @issuer: Issuer certificate
1824 * @cert: Certificate to be verified
1825 * Returns: 0 if cert has a valid signature that was signed by the issuer,
1826 * -1 if not
1827 */
x509_certificate_check_signature(struct x509_certificate * issuer,struct x509_certificate * cert)1828 int x509_certificate_check_signature(struct x509_certificate *issuer,
1829 struct x509_certificate *cert)
1830 {
1831 return x509_check_signature(issuer, &cert->signature,
1832 cert->sign_value, cert->sign_value_len,
1833 cert->tbs_cert_start, cert->tbs_cert_len);
1834 }
1835
1836
x509_check_signature(struct x509_certificate * issuer,struct x509_algorithm_identifier * signature,const u8 * sign_value,size_t sign_value_len,const u8 * signed_data,size_t signed_data_len)1837 int x509_check_signature(struct x509_certificate *issuer,
1838 struct x509_algorithm_identifier *signature,
1839 const u8 *sign_value, size_t sign_value_len,
1840 const u8 *signed_data, size_t signed_data_len)
1841 {
1842 struct crypto_public_key *pk;
1843 u8 *data;
1844 const u8 *pos, *end, *next, *da_end;
1845 size_t data_len;
1846 struct asn1_hdr hdr;
1847 struct asn1_oid oid;
1848 u8 hash[64];
1849 size_t hash_len;
1850 const u8 *addr[1] = { signed_data };
1851 size_t len[1] = { signed_data_len };
1852
1853 if (!x509_pkcs_oid(&signature->oid) ||
1854 signature->oid.len != 7 ||
1855 signature->oid.oid[5] != 1 /* pkcs-1 */) {
1856 wpa_printf(MSG_DEBUG, "X509: Unrecognized signature "
1857 "algorithm");
1858 return -1;
1859 }
1860
1861 pk = crypto_public_key_import(issuer->public_key,
1862 issuer->public_key_len);
1863 if (pk == NULL)
1864 return -1;
1865
1866 data_len = sign_value_len;
1867 data = os_malloc(data_len);
1868 if (data == NULL) {
1869 crypto_public_key_free(pk);
1870 return -1;
1871 }
1872
1873 if (crypto_public_key_decrypt_pkcs1(pk, sign_value,
1874 sign_value_len, data,
1875 &data_len) < 0) {
1876 wpa_printf(MSG_DEBUG, "X509: Failed to decrypt signature");
1877 crypto_public_key_free(pk);
1878 os_free(data);
1879 return -1;
1880 }
1881 crypto_public_key_free(pk);
1882
1883 wpa_hexdump(MSG_MSGDUMP, "X509: Signature data D", data, data_len);
1884
1885 /*
1886 * PKCS #1 v1.5, 10.1.2:
1887 *
1888 * DigestInfo ::= SEQUENCE {
1889 * digestAlgorithm DigestAlgorithmIdentifier,
1890 * digest Digest
1891 * }
1892 *
1893 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1894 *
1895 * Digest ::= OCTET STRING
1896 *
1897 */
1898 if (asn1_get_next(data, data_len, &hdr) < 0 ||
1899 !asn1_is_sequence(&hdr)) {
1900 asn1_unexpected(&hdr, "X509: Expected SEQUENCE (DigestInfo)");
1901 os_free(data);
1902 return -1;
1903 }
1904 wpa_hexdump(MSG_MSGDUMP, "X509: DigestInfo", hdr.payload, hdr.length);
1905
1906 pos = hdr.payload;
1907 end = pos + hdr.length;
1908
1909 /*
1910 * X.509:
1911 * AlgorithmIdentifier ::= SEQUENCE {
1912 * algorithm OBJECT IDENTIFIER,
1913 * parameters ANY DEFINED BY algorithm OPTIONAL
1914 * }
1915 */
1916
1917 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1918 !asn1_is_sequence(&hdr)) {
1919 asn1_unexpected(&hdr,
1920 "X509: Expected SEQUENCE (AlgorithmIdentifier)");
1921 os_free(data);
1922 return -1;
1923 }
1924 wpa_hexdump(MSG_MSGDUMP, "X509: DigestAlgorithmIdentifier",
1925 hdr.payload, hdr.length);
1926 da_end = hdr.payload + hdr.length;
1927
1928 if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {
1929 wpa_printf(MSG_DEBUG, "X509: Failed to parse digestAlgorithm");
1930 os_free(data);
1931 return -1;
1932 }
1933 wpa_hexdump(MSG_MSGDUMP, "X509: Digest algorithm parameters",
1934 next, da_end - next);
1935
1936 /*
1937 * RFC 5754: The correct encoding for the SHA2 algorithms would be to
1938 * omit the parameters, but there are implementation that encode these
1939 * as a NULL element. Allow these two cases and reject anything else.
1940 */
1941 if (da_end > next &&
1942 (asn1_get_next(next, da_end - next, &hdr) < 0 ||
1943 !asn1_is_null(&hdr) ||
1944 hdr.payload + hdr.length != da_end)) {
1945 wpa_printf(MSG_DEBUG,
1946 "X509: Unexpected digest algorithm parameters");
1947 os_free(data);
1948 return -1;
1949 }
1950
1951 if (x509_sha1_oid(&oid)) {
1952 if (signature->oid.oid[6] != 5 /* sha-1WithRSAEncryption */) {
1953 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA1 "
1954 "does not match with certificate "
1955 "signatureAlgorithm (%lu)",
1956 signature->oid.oid[6]);
1957 os_free(data);
1958 return -1;
1959 }
1960 goto skip_digest_oid;
1961 }
1962
1963 if (x509_sha256_oid(&oid)) {
1964 if (signature->oid.oid[6] !=
1965 11 /* sha2561WithRSAEncryption */) {
1966 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA256 "
1967 "does not match with certificate "
1968 "signatureAlgorithm (%lu)",
1969 signature->oid.oid[6]);
1970 os_free(data);
1971 return -1;
1972 }
1973 goto skip_digest_oid;
1974 }
1975
1976 if (x509_sha384_oid(&oid)) {
1977 if (signature->oid.oid[6] != 12 /* sha384WithRSAEncryption */) {
1978 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA384 "
1979 "does not match with certificate "
1980 "signatureAlgorithm (%lu)",
1981 signature->oid.oid[6]);
1982 os_free(data);
1983 return -1;
1984 }
1985 goto skip_digest_oid;
1986 }
1987
1988 if (x509_sha512_oid(&oid)) {
1989 if (signature->oid.oid[6] != 13 /* sha512WithRSAEncryption */) {
1990 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA512 "
1991 "does not match with certificate "
1992 "signatureAlgorithm (%lu)",
1993 signature->oid.oid[6]);
1994 os_free(data);
1995 return -1;
1996 }
1997 goto skip_digest_oid;
1998 }
1999
2000 if (!x509_digest_oid(&oid)) {
2001 wpa_printf(MSG_DEBUG, "X509: Unrecognized digestAlgorithm");
2002 os_free(data);
2003 return -1;
2004 }
2005 switch (oid.oid[5]) {
2006 case 5: /* md5 */
2007 if (signature->oid.oid[6] != 4 /* md5WithRSAEncryption */) {
2008 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm MD5 does "
2009 "not match with certificate "
2010 "signatureAlgorithm (%lu)",
2011 signature->oid.oid[6]);
2012 os_free(data);
2013 return -1;
2014 }
2015 break;
2016 case 2: /* md2 */
2017 case 4: /* md4 */
2018 default:
2019 wpa_printf(MSG_DEBUG, "X509: Unsupported digestAlgorithm "
2020 "(%lu)", oid.oid[5]);
2021 os_free(data);
2022 return -1;
2023 }
2024
2025 skip_digest_oid:
2026 /* Digest ::= OCTET STRING */
2027 pos = da_end;
2028
2029 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
2030 !asn1_is_octetstring(&hdr)) {
2031 asn1_unexpected(&hdr, "X509: Expected OCTETSTRING (Digest)");
2032 os_free(data);
2033 return -1;
2034 }
2035 wpa_hexdump(MSG_MSGDUMP, "X509: Decrypted Digest",
2036 hdr.payload, hdr.length);
2037
2038 switch (signature->oid.oid[6]) {
2039 case 4: /* md5WithRSAEncryption */
2040 md5_vector(1, addr, len, hash);
2041 hash_len = 16;
2042 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (MD5)",
2043 hash, hash_len);
2044 break;
2045 case 5: /* sha-1WithRSAEncryption */
2046 sha1_vector(1, addr, len, hash);
2047 hash_len = 20;
2048 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA1)",
2049 hash, hash_len);
2050 break;
2051 case 11: /* sha256WithRSAEncryption */
2052 sha256_vector(1, addr, len, hash);
2053 hash_len = 32;
2054 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA256)",
2055 hash, hash_len);
2056 break;
2057 case 12: /* sha384WithRSAEncryption */
2058 sha384_vector(1, addr, len, hash);
2059 hash_len = 48;
2060 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA384)",
2061 hash, hash_len);
2062 break;
2063 case 13: /* sha512WithRSAEncryption */
2064 sha512_vector(1, addr, len, hash);
2065 hash_len = 64;
2066 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA512)",
2067 hash, hash_len);
2068 break;
2069 case 2: /* md2WithRSAEncryption */
2070 default:
2071 wpa_printf(MSG_INFO, "X509: Unsupported certificate signature "
2072 "algorithm (%lu)", signature->oid.oid[6]);
2073 os_free(data);
2074 return -1;
2075 }
2076
2077 if (hdr.length != hash_len ||
2078 os_memcmp_const(hdr.payload, hash, hdr.length) != 0) {
2079 wpa_printf(MSG_INFO, "X509: Certificate Digest does not match "
2080 "with calculated tbsCertificate hash");
2081 os_free(data);
2082 return -1;
2083 }
2084
2085 if (hdr.payload + hdr.length < data + data_len) {
2086 wpa_hexdump(MSG_INFO,
2087 "X509: Extra data after certificate signature hash",
2088 hdr.payload + hdr.length,
2089 data + data_len - hdr.payload - hdr.length);
2090 os_free(data);
2091 return -1;
2092 }
2093
2094 os_free(data);
2095
2096 wpa_printf(MSG_DEBUG, "X509: Certificate Digest matches with "
2097 "calculated tbsCertificate hash");
2098
2099 return 0;
2100 }
2101
2102
x509_valid_issuer(const struct x509_certificate * cert)2103 static int x509_valid_issuer(const struct x509_certificate *cert)
2104 {
2105 if ((cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS) &&
2106 !cert->ca) {
2107 wpa_printf(MSG_DEBUG, "X509: Non-CA certificate used as an "
2108 "issuer");
2109 return -1;
2110 }
2111
2112 if (cert->version == X509_CERT_V3 &&
2113 !(cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS)) {
2114 wpa_printf(MSG_DEBUG, "X509: v3 CA certificate did not "
2115 "include BasicConstraints extension");
2116 return -1;
2117 }
2118
2119 if ((cert->extensions_present & X509_EXT_KEY_USAGE) &&
2120 !(cert->key_usage & X509_KEY_USAGE_KEY_CERT_SIGN)) {
2121 wpa_printf(MSG_DEBUG, "X509: Issuer certificate did not have "
2122 "keyCertSign bit in Key Usage");
2123 return -1;
2124 }
2125
2126 return 0;
2127 }
2128
2129
2130 /**
2131 * x509_certificate_chain_validate - Validate X.509 certificate chain
2132 * @trusted: List of trusted certificates
2133 * @chain: Certificate chain to be validated (first chain must be issued by
2134 * signed by the second certificate in the chain and so on)
2135 * @reason: Buffer for returning failure reason (X509_VALIDATE_*)
2136 * Returns: 0 if chain is valid, -1 if not
2137 */
x509_certificate_chain_validate(struct x509_certificate * trusted,struct x509_certificate * chain,int * reason,int disable_time_checks)2138 int x509_certificate_chain_validate(struct x509_certificate *trusted,
2139 struct x509_certificate *chain,
2140 int *reason, int disable_time_checks)
2141 {
2142 long unsigned idx;
2143 int chain_trusted = 0;
2144 struct x509_certificate *cert, *trust;
2145 char buf[128];
2146 struct os_time now;
2147
2148 *reason = X509_VALIDATE_OK;
2149
2150 wpa_printf(MSG_DEBUG, "X509: Validate certificate chain");
2151 os_get_time(&now);
2152
2153 for (cert = chain, idx = 0; cert; cert = cert->next, idx++) {
2154 cert->issuer_trusted = 0;
2155 x509_name_string(&cert->subject, buf, sizeof(buf));
2156 wpa_printf(MSG_DEBUG, "X509: %lu: %s", idx, buf);
2157
2158 if (chain_trusted)
2159 continue;
2160
2161 if (!disable_time_checks &&
2162 ((unsigned long) now.sec <
2163 (unsigned long) cert->not_before ||
2164 (unsigned long) now.sec >
2165 (unsigned long) cert->not_after)) {
2166 wpa_printf(MSG_INFO, "X509: Certificate not valid "
2167 "(now=%lu not_before=%lu not_after=%lu)",
2168 now.sec, cert->not_before, cert->not_after);
2169 *reason = X509_VALIDATE_CERTIFICATE_EXPIRED;
2170 return -1;
2171 }
2172
2173 if (cert->next) {
2174 if (x509_name_compare(&cert->issuer,
2175 &cert->next->subject) != 0) {
2176 wpa_printf(MSG_DEBUG, "X509: Certificate "
2177 "chain issuer name mismatch");
2178 x509_name_string(&cert->issuer, buf,
2179 sizeof(buf));
2180 wpa_printf(MSG_DEBUG, "X509: cert issuer: %s",
2181 buf);
2182 x509_name_string(&cert->next->subject, buf,
2183 sizeof(buf));
2184 wpa_printf(MSG_DEBUG, "X509: next cert "
2185 "subject: %s", buf);
2186 *reason = X509_VALIDATE_CERTIFICATE_UNKNOWN;
2187 return -1;
2188 }
2189
2190 if (x509_valid_issuer(cert->next) < 0) {
2191 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2192 return -1;
2193 }
2194
2195 if ((cert->next->extensions_present &
2196 X509_EXT_PATH_LEN_CONSTRAINT) &&
2197 idx > cert->next->path_len_constraint) {
2198 wpa_printf(MSG_DEBUG, "X509: pathLenConstraint"
2199 " not met (idx=%lu issuer "
2200 "pathLenConstraint=%lu)", idx,
2201 cert->next->path_len_constraint);
2202 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2203 return -1;
2204 }
2205
2206 if (x509_certificate_check_signature(cert->next, cert)
2207 < 0) {
2208 wpa_printf(MSG_DEBUG, "X509: Invalid "
2209 "certificate signature within "
2210 "chain");
2211 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2212 return -1;
2213 }
2214 }
2215
2216 for (trust = trusted; trust; trust = trust->next) {
2217 if (x509_name_compare(&cert->issuer, &trust->subject)
2218 == 0)
2219 break;
2220 }
2221
2222 if (trust) {
2223 wpa_printf(MSG_DEBUG, "X509: Found issuer from the "
2224 "list of trusted certificates");
2225 if (x509_valid_issuer(trust) < 0) {
2226 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2227 return -1;
2228 }
2229
2230 if (x509_certificate_check_signature(trust, cert) < 0)
2231 {
2232 wpa_printf(MSG_DEBUG, "X509: Invalid "
2233 "certificate signature");
2234 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2235 return -1;
2236 }
2237
2238 wpa_printf(MSG_DEBUG, "X509: Trusted certificate "
2239 "found to complete the chain");
2240 cert->issuer_trusted = 1;
2241 chain_trusted = 1;
2242 }
2243 }
2244
2245 if (!chain_trusted) {
2246 wpa_printf(MSG_DEBUG, "X509: Did not find any of the issuers "
2247 "from the list of trusted certificates");
2248 if (trusted) {
2249 *reason = X509_VALIDATE_UNKNOWN_CA;
2250 return -1;
2251 }
2252 wpa_printf(MSG_DEBUG, "X509: Certificate chain validation "
2253 "disabled - ignore unknown CA issue");
2254 }
2255
2256 wpa_printf(MSG_DEBUG, "X509: Certificate chain valid");
2257
2258 return 0;
2259 }
2260
2261
2262 /**
2263 * x509_certificate_get_subject - Get a certificate based on Subject name
2264 * @chain: Certificate chain to search through
2265 * @name: Subject name to search for
2266 * Returns: Pointer to the certificate with the given Subject name or
2267 * %NULL on failure
2268 */
2269 struct x509_certificate *
x509_certificate_get_subject(struct x509_certificate * chain,struct x509_name * name)2270 x509_certificate_get_subject(struct x509_certificate *chain,
2271 struct x509_name *name)
2272 {
2273 struct x509_certificate *cert;
2274
2275 for (cert = chain; cert; cert = cert->next) {
2276 if (x509_name_compare(&cert->subject, name) == 0)
2277 return cert;
2278 }
2279 return NULL;
2280 }
2281
2282
2283 /**
2284 * x509_certificate_self_signed - Is the certificate self-signed?
2285 * @cert: Certificate
2286 * Returns: 1 if certificate is self-signed, 0 if not
2287 */
x509_certificate_self_signed(struct x509_certificate * cert)2288 int x509_certificate_self_signed(struct x509_certificate *cert)
2289 {
2290 return x509_name_compare(&cert->issuer, &cert->subject) == 0;
2291 }
2292