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[2] = {0};
538 int ret = 0;
539 int i;
540
541 if (len < 2)
542 return -1;
543
544 for (i = 0; i < 2; i++) {
545 buf[0] = pos[i];
546 ret *= 10;
547 ret += atoi(buf);
548 }
549
550 return ret;
551 }
552
553
parse_uint4(const char * pos,size_t len)554 static int parse_uint4(const char *pos, size_t len)
555 {
556 char buf[2] = {0};
557 int ret = 0;
558 int i;
559
560 if (len < 4)
561 return -1;
562
563 for (i = 0; i < 4; i++) {
564 buf[0] = pos[i];
565 ret *= 10;
566 ret += atoi(buf);
567 }
568
569 return ret;
570 }
571
572
x509_parse_time(const u8 * buf,size_t len,u8 asn1_tag,os_time_t * val)573 int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag, os_time_t *val)
574 {
575 const char *pos, *end;
576 int year, month, day, hour, min, sec;
577
578 /*
579 * Time ::= CHOICE {
580 * utcTime UTCTime,
581 * generalTime GeneralizedTime
582 * }
583 *
584 * UTCTime: YYMMDDHHMMSSZ
585 * GeneralizedTime: YYYYMMDDHHMMSSZ
586 */
587
588 pos = (const char *) buf;
589 end = pos + len;
590
591 switch (asn1_tag) {
592 case ASN1_TAG_UTCTIME:
593 if (len != 13 || buf[12] != 'Z') {
594 wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized "
595 "UTCTime format", buf, len);
596 return -1;
597 }
598 year = parse_uint2(pos, end - pos);
599 if (year < 0) {
600 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse "
601 "UTCTime year", buf, len);
602 return -1;
603 }
604 if (year < 50)
605 year += 2000;
606 else
607 year += 1900;
608 pos += 2;
609 break;
610 case ASN1_TAG_GENERALIZEDTIME:
611 if (len != 15 || buf[14] != 'Z') {
612 wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized "
613 "GeneralizedTime format", buf, len);
614 return -1;
615 }
616 year = parse_uint4(pos, end - pos);
617 if (year < 0) {
618 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse "
619 "GeneralizedTime year", buf, len);
620 return -1;
621 }
622 pos += 4;
623 break;
624 default:
625 wpa_printf(MSG_DEBUG, "X509: Expected UTCTime or "
626 "GeneralizedTime - found tag 0x%x", asn1_tag);
627 return -1;
628 }
629
630 month = parse_uint2(pos, end - pos);
631 if (month < 0) {
632 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
633 "(month)", buf, len);
634 return -1;
635 }
636 pos += 2;
637
638 day = parse_uint2(pos, end - pos);
639 if (day < 0) {
640 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
641 "(day)", buf, len);
642 return -1;
643 }
644 pos += 2;
645
646 hour = parse_uint2(pos, end - pos);
647 if (hour < 0) {
648 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
649 "(hour)", buf, len);
650 return -1;
651 }
652 pos += 2;
653
654 min = parse_uint2(pos, end - pos);
655 if (min < 0) {
656 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
657 "(min)", buf, len);
658 return -1;
659 }
660 pos += 2;
661
662 sec = parse_uint2(pos, end - pos);
663 if (sec < 0) {
664 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
665 "(sec)", buf, len);
666 return -1;
667 }
668
669 if (os_mktime(year, month, day, hour, min, sec, val) < 0) {
670 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to convert Time",
671 buf, len);
672 if (year < 1970) {
673 /*
674 * At least some test certificates have been configured
675 * to use dates prior to 1970. Set the date to
676 * beginning of 1970 to handle these case.
677 */
678 wpa_printf(MSG_DEBUG, "X509: Year=%d before epoch - "
679 "assume epoch as the time", year);
680 *val = 0;
681 return 0;
682 }
683 return -1;
684 }
685
686 return 0;
687 }
688
689
x509_parse_validity(const u8 * buf,size_t len,struct x509_certificate * cert,const u8 ** next)690 static int x509_parse_validity(const u8 *buf, size_t len,
691 struct x509_certificate *cert, const u8 **next)
692 {
693 struct asn1_hdr hdr;
694 const u8 *pos;
695 size_t plen;
696
697 /*
698 * Validity ::= SEQUENCE {
699 * notBefore Time,
700 * notAfter Time
701 * }
702 *
703 * RFC 3280, 4.1.2.5:
704 * CAs conforming to this profile MUST always encode certificate
705 * validity dates through the year 2049 as UTCTime; certificate
706 * validity dates in 2050 or later MUST be encoded as GeneralizedTime.
707 */
708
709 if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
710 asn1_unexpected(&hdr, "X509: Expected SEQUENCE (Validity)");
711 return -1;
712 }
713 pos = hdr.payload;
714 plen = hdr.length;
715
716 if (plen > (size_t) (buf + len - pos))
717 return -1;
718
719 *next = pos + plen;
720
721 if (asn1_get_next(pos, plen, &hdr) < 0 ||
722 (!asn1_is_utctime(&hdr) && !asn1_is_generalizedtime(&hdr)) ||
723 x509_parse_time(hdr.payload, hdr.length, hdr.tag,
724 &cert->not_before) < 0) {
725 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notBefore "
726 "Time", hdr.payload, hdr.length);
727 return -1;
728 }
729
730 pos = hdr.payload + hdr.length;
731 plen = *next - pos;
732
733 if (asn1_get_next(pos, plen, &hdr) < 0 ||
734 (!asn1_is_utctime(&hdr) && !asn1_is_generalizedtime(&hdr)) ||
735 x509_parse_time(hdr.payload, hdr.length, hdr.tag,
736 &cert->not_after) < 0) {
737 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notAfter "
738 "Time", hdr.payload, hdr.length);
739 return -1;
740 }
741
742 wpa_printf(MSG_MSGDUMP, "X509: Validity: notBefore: %lu notAfter: %lu",
743 (unsigned long) cert->not_before,
744 (unsigned long) cert->not_after);
745
746 return 0;
747 }
748
749
x509_id_ce_oid(struct asn1_oid * oid)750 static int x509_id_ce_oid(struct asn1_oid *oid)
751 {
752 /* id-ce arc from X.509 for standard X.509v3 extensions */
753 return oid->len >= 4 &&
754 oid->oid[0] == 2 /* joint-iso-ccitt */ &&
755 oid->oid[1] == 5 /* ds */ &&
756 oid->oid[2] == 29 /* id-ce */;
757 }
758
759
x509_any_ext_key_usage_oid(struct asn1_oid * oid)760 static int x509_any_ext_key_usage_oid(struct asn1_oid *oid)
761 {
762 return oid->len == 6 &&
763 x509_id_ce_oid(oid) &&
764 oid->oid[3] == 37 /* extKeyUsage */ &&
765 oid->oid[4] == 0 /* anyExtendedKeyUsage */;
766 }
767
768
x509_parse_ext_key_usage(struct x509_certificate * cert,const u8 * pos,size_t len)769 static int x509_parse_ext_key_usage(struct x509_certificate *cert,
770 const u8 *pos, size_t len)
771 {
772 struct asn1_hdr hdr;
773
774 /*
775 * KeyUsage ::= BIT STRING {
776 * digitalSignature (0),
777 * nonRepudiation (1),
778 * keyEncipherment (2),
779 * dataEncipherment (3),
780 * keyAgreement (4),
781 * keyCertSign (5),
782 * cRLSign (6),
783 * encipherOnly (7),
784 * decipherOnly (8) }
785 */
786
787 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_bitstring(&hdr) ||
788 hdr.length < 1) {
789 asn1_unexpected(&hdr, "X509: Expected BIT STRING in KeyUsage");
790 return -1;
791 }
792
793 cert->extensions_present |= X509_EXT_KEY_USAGE;
794 cert->key_usage = asn1_bit_string_to_long(hdr.payload, hdr.length);
795
796 wpa_printf(MSG_DEBUG, "X509: KeyUsage 0x%lx", cert->key_usage);
797
798 return 0;
799 }
800
801
x509_parse_ext_basic_constraints(struct x509_certificate * cert,const u8 * pos,size_t len)802 static int x509_parse_ext_basic_constraints(struct x509_certificate *cert,
803 const u8 *pos, size_t len)
804 {
805 struct asn1_hdr hdr;
806 unsigned long value;
807 size_t left;
808 const u8 *end_seq;
809
810 /*
811 * BasicConstraints ::= SEQUENCE {
812 * cA BOOLEAN DEFAULT FALSE,
813 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
814 */
815
816 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
817 asn1_unexpected(&hdr,
818 "X509: Expected SEQUENCE in BasicConstraints");
819 return -1;
820 }
821
822 cert->extensions_present |= X509_EXT_BASIC_CONSTRAINTS;
823
824 if (hdr.length == 0)
825 return 0;
826
827 end_seq = hdr.payload + hdr.length;
828 if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0) {
829 wpa_printf(MSG_DEBUG, "X509: Failed to parse "
830 "BasicConstraints");
831 return -1;
832 }
833
834 if (asn1_is_boolean(&hdr)) {
835 cert->ca = hdr.payload[0];
836
837 pos = hdr.payload + hdr.length;
838 if (pos >= end_seq) {
839 /* No optional pathLenConstraint */
840 wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d",
841 cert->ca);
842 return 0;
843 }
844 if (asn1_get_next(pos, end_seq - pos, &hdr) < 0) {
845 wpa_printf(MSG_DEBUG, "X509: Failed to parse "
846 "BasicConstraints");
847 return -1;
848 }
849 }
850
851 if (!asn1_is_integer(&hdr)) {
852 asn1_unexpected(&hdr,
853 "X509: Expected INTEGER in BasicConstraints");
854 return -1;
855 }
856
857 pos = hdr.payload;
858 left = hdr.length;
859 value = 0;
860 while (left) {
861 value <<= 8;
862 value |= *pos++;
863 left--;
864 }
865
866 cert->path_len_constraint = value;
867 cert->extensions_present |= X509_EXT_PATH_LEN_CONSTRAINT;
868
869 wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d "
870 "pathLenConstraint=%lu",
871 cert->ca, cert->path_len_constraint);
872
873 return 0;
874 }
875
876
x509_parse_alt_name_rfc8222(struct x509_name * name,const u8 * pos,size_t len)877 static int x509_parse_alt_name_rfc8222(struct x509_name *name,
878 const u8 *pos, size_t len)
879 {
880 /* rfc822Name IA5String */
881 wpa_hexdump_ascii(MSG_MSGDUMP, "X509: altName - rfc822Name", pos, len);
882 os_free(name->alt_email);
883 name->alt_email = os_zalloc(len + 1);
884 if (name->alt_email == NULL)
885 return -1;
886 os_memcpy(name->alt_email, pos, len);
887 if (os_strlen(name->alt_email) != len) {
888 wpa_printf(MSG_INFO, "X509: Reject certificate with "
889 "embedded NUL byte in rfc822Name (%s[NUL])",
890 name->alt_email);
891 os_free(name->alt_email);
892 name->alt_email = NULL;
893 return -1;
894 }
895 return 0;
896 }
897
898
x509_parse_alt_name_dns(struct x509_name * name,const u8 * pos,size_t len)899 static int x509_parse_alt_name_dns(struct x509_name *name,
900 const u8 *pos, size_t len)
901 {
902 /* dNSName IA5String */
903 wpa_hexdump_ascii(MSG_MSGDUMP, "X509: altName - dNSName", pos, len);
904 os_free(name->dns);
905 name->dns = os_zalloc(len + 1);
906 if (name->dns == NULL)
907 return -1;
908 os_memcpy(name->dns, pos, len);
909 if (os_strlen(name->dns) != len) {
910 wpa_printf(MSG_INFO, "X509: Reject certificate with "
911 "embedded NUL byte in dNSName (%s[NUL])",
912 name->dns);
913 os_free(name->dns);
914 name->dns = NULL;
915 return -1;
916 }
917 return 0;
918 }
919
920
x509_parse_alt_name_uri(struct x509_name * name,const u8 * pos,size_t len)921 static int x509_parse_alt_name_uri(struct x509_name *name,
922 const u8 *pos, size_t len)
923 {
924 /* uniformResourceIdentifier IA5String */
925 wpa_hexdump_ascii(MSG_MSGDUMP,
926 "X509: altName - uniformResourceIdentifier",
927 pos, len);
928 os_free(name->uri);
929 name->uri = os_zalloc(len + 1);
930 if (name->uri == NULL)
931 return -1;
932 os_memcpy(name->uri, pos, len);
933 if (os_strlen(name->uri) != len) {
934 wpa_printf(MSG_INFO, "X509: Reject certificate with "
935 "embedded NUL byte in uniformResourceIdentifier "
936 "(%s[NUL])", name->uri);
937 os_free(name->uri);
938 name->uri = NULL;
939 return -1;
940 }
941 return 0;
942 }
943
944
x509_parse_alt_name_ip(struct x509_name * name,const u8 * pos,size_t len)945 static int x509_parse_alt_name_ip(struct x509_name *name,
946 const u8 *pos, size_t len)
947 {
948 /* iPAddress OCTET STRING */
949 wpa_hexdump(MSG_MSGDUMP, "X509: altName - iPAddress", pos, len);
950 os_free(name->ip);
951 name->ip = os_memdup(pos, len);
952 if (name->ip == NULL)
953 return -1;
954 name->ip_len = len;
955 return 0;
956 }
957
958
x509_parse_alt_name_rid(struct x509_name * name,const u8 * pos,size_t len)959 static int x509_parse_alt_name_rid(struct x509_name *name,
960 const u8 *pos, size_t len)
961 {
962 char buf[80];
963
964 /* registeredID OBJECT IDENTIFIER */
965 if (asn1_parse_oid(pos, len, &name->rid) < 0)
966 return -1;
967
968 asn1_oid_to_str(&name->rid, buf, sizeof(buf));
969 wpa_printf(MSG_MSGDUMP, "X509: altName - registeredID: %s", buf);
970
971 return 0;
972 }
973
974
x509_parse_ext_alt_name(struct x509_name * name,const u8 * pos,size_t len)975 static int x509_parse_ext_alt_name(struct x509_name *name,
976 const u8 *pos, size_t len)
977 {
978 struct asn1_hdr hdr;
979 const u8 *p, *end;
980
981 /*
982 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
983 *
984 * GeneralName ::= CHOICE {
985 * otherName [0] OtherName,
986 * rfc822Name [1] IA5String,
987 * dNSName [2] IA5String,
988 * x400Address [3] ORAddress,
989 * directoryName [4] Name,
990 * ediPartyName [5] EDIPartyName,
991 * uniformResourceIdentifier [6] IA5String,
992 * iPAddress [7] OCTET STRING,
993 * registeredID [8] OBJECT IDENTIFIER }
994 *
995 * OtherName ::= SEQUENCE {
996 * type-id OBJECT IDENTIFIER,
997 * value [0] EXPLICIT ANY DEFINED BY type-id }
998 *
999 * EDIPartyName ::= SEQUENCE {
1000 * nameAssigner [0] DirectoryString OPTIONAL,
1001 * partyName [1] DirectoryString }
1002 */
1003
1004 for (p = pos, end = pos + len; p < end; p = hdr.payload + hdr.length) {
1005 int res;
1006
1007 if (asn1_get_next(p, end - p, &hdr) < 0) {
1008 wpa_printf(MSG_DEBUG, "X509: Failed to parse "
1009 "SubjectAltName item");
1010 return -1;
1011 }
1012
1013 if (hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC)
1014 continue;
1015
1016 switch (hdr.tag) {
1017 case 1:
1018 res = x509_parse_alt_name_rfc8222(name, hdr.payload,
1019 hdr.length);
1020 break;
1021 case 2:
1022 res = x509_parse_alt_name_dns(name, hdr.payload,
1023 hdr.length);
1024 break;
1025 case 6:
1026 res = x509_parse_alt_name_uri(name, hdr.payload,
1027 hdr.length);
1028 break;
1029 case 7:
1030 res = x509_parse_alt_name_ip(name, hdr.payload,
1031 hdr.length);
1032 break;
1033 case 8:
1034 res = x509_parse_alt_name_rid(name, hdr.payload,
1035 hdr.length);
1036 break;
1037 case 0: /* TODO: otherName */
1038 case 3: /* TODO: x500Address */
1039 case 4: /* TODO: directoryName */
1040 case 5: /* TODO: ediPartyName */
1041 default:
1042 res = 0;
1043 break;
1044 }
1045 if (res < 0)
1046 return res;
1047 }
1048
1049 return 0;
1050 }
1051
1052
x509_parse_ext_subject_alt_name(struct x509_certificate * cert,const u8 * pos,size_t len)1053 static int x509_parse_ext_subject_alt_name(struct x509_certificate *cert,
1054 const u8 *pos, size_t len)
1055 {
1056 struct asn1_hdr hdr;
1057
1058 /* SubjectAltName ::= GeneralNames */
1059
1060 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1061 asn1_unexpected(&hdr,
1062 "X509: Expected SEQUENCE in SubjectAltName");
1063 return -1;
1064 }
1065
1066 wpa_printf(MSG_DEBUG, "X509: SubjectAltName");
1067 cert->extensions_present |= X509_EXT_SUBJECT_ALT_NAME;
1068
1069 if (hdr.length == 0)
1070 return 0;
1071
1072 return x509_parse_ext_alt_name(&cert->subject, hdr.payload,
1073 hdr.length);
1074 }
1075
1076
x509_parse_ext_issuer_alt_name(struct x509_certificate * cert,const u8 * pos,size_t len)1077 static int x509_parse_ext_issuer_alt_name(struct x509_certificate *cert,
1078 const u8 *pos, size_t len)
1079 {
1080 struct asn1_hdr hdr;
1081
1082 /* IssuerAltName ::= GeneralNames */
1083
1084 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1085 asn1_unexpected(&hdr,
1086 "X509: Expected SEQUENCE in IssuerAltName");
1087 return -1;
1088 }
1089
1090 wpa_printf(MSG_DEBUG, "X509: IssuerAltName");
1091 cert->extensions_present |= X509_EXT_ISSUER_ALT_NAME;
1092
1093 if (hdr.length == 0)
1094 return 0;
1095
1096 return x509_parse_ext_alt_name(&cert->issuer, hdr.payload,
1097 hdr.length);
1098 }
1099
1100
x509_id_cert_policy_any_oid(struct asn1_oid * oid)1101 static int x509_id_cert_policy_any_oid(struct asn1_oid *oid)
1102 {
1103 return oid->len == 5 &&
1104 oid->oid[0] == 2 /* iso/itu-t */ &&
1105 oid->oid[1] == 5 /* X.500 Directory Services */ &&
1106 oid->oid[2] == 29 /* id-ce */ &&
1107 oid->oid[3] == 32 /* id-ce-certificate-policies */ &&
1108 oid->oid[4] == 0 /* anyPolicy */;
1109 }
1110
1111
x509_id_wfa_oid(struct asn1_oid * oid)1112 static int x509_id_wfa_oid(struct asn1_oid *oid)
1113 {
1114 return oid->len >= 7 &&
1115 oid->oid[0] == 1 /* iso */ &&
1116 oid->oid[1] == 3 /* identified-organization */ &&
1117 oid->oid[2] == 6 /* dod */ &&
1118 oid->oid[3] == 1 /* internet */ &&
1119 oid->oid[4] == 4 /* private */ &&
1120 oid->oid[5] == 1 /* enterprise */ &&
1121 oid->oid[6] == 40808 /* WFA */;
1122 }
1123
1124
x509_id_wfa_tod_oid(struct asn1_oid * oid)1125 static int x509_id_wfa_tod_oid(struct asn1_oid *oid)
1126 {
1127 return oid->len >= 9 &&
1128 x509_id_wfa_oid(oid) &&
1129 oid->oid[7] == 1 &&
1130 oid->oid[8] == 3;
1131 }
1132
1133
x509_id_wfa_tod_strict_oid(struct asn1_oid * oid)1134 static int x509_id_wfa_tod_strict_oid(struct asn1_oid *oid)
1135 {
1136 return oid->len == 10 &&
1137 x509_id_wfa_tod_oid(oid) &&
1138 oid->oid[9] == 1;
1139 }
1140
1141
x509_id_wfa_tod_tofu_oid(struct asn1_oid * oid)1142 static int x509_id_wfa_tod_tofu_oid(struct asn1_oid *oid)
1143 {
1144 return oid->len == 10 &&
1145 x509_id_wfa_tod_oid(oid) &&
1146 oid->oid[9] == 2;
1147 }
1148
1149
x509_parse_ext_certificate_policies(struct x509_certificate * cert,const u8 * pos,size_t len)1150 static int x509_parse_ext_certificate_policies(struct x509_certificate *cert,
1151 const u8 *pos, size_t len)
1152 {
1153 struct asn1_hdr hdr;
1154 const u8 *end;
1155
1156 /*
1157 * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
1158 *
1159 * PolicyInformation ::= SEQUENCE {
1160 * policyIdentifier CertPolicyId,
1161 * policyQualifiers SEQUENCE SIZE (1..MAX) OF
1162 * PolicyQualifierInfo OPTIONAL }
1163 *
1164 * CertPolicyId ::= OBJECT IDENTIFIER
1165 */
1166
1167 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1168 asn1_unexpected(&hdr,
1169 "X509: Expected SEQUENCE (certificatePolicies)");
1170 return -1;
1171 }
1172 if (hdr.length > pos + len - hdr.payload)
1173 return -1;
1174 pos = hdr.payload;
1175 end = pos + hdr.length;
1176
1177 wpa_hexdump(MSG_MSGDUMP, "X509: certificatePolicies", pos, end - pos);
1178
1179 while (pos < end) {
1180 const u8 *pol_end;
1181 struct asn1_oid oid;
1182 char buf[80];
1183
1184 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1185 !asn1_is_sequence(&hdr)) {
1186 asn1_unexpected(&hdr,
1187 "X509: Expected SEQUENCE (PolicyInformation)");
1188 return -1;
1189 }
1190 if (hdr.length > end - hdr.payload)
1191 return -1;
1192 pos = hdr.payload;
1193 pol_end = pos + hdr.length;
1194 wpa_hexdump(MSG_MSGDUMP, "X509: PolicyInformation",
1195 pos, pol_end - pos);
1196
1197 if (asn1_get_oid(pos, pol_end - pos, &oid, &pos))
1198 return -1;
1199 if (x509_id_cert_policy_any_oid(&oid)) {
1200 os_strlcpy(buf, "anyPolicy-STRICT", sizeof(buf));
1201 cert->certificate_policy |=
1202 X509_EXT_CERT_POLICY_ANY;
1203 } else if (x509_id_wfa_tod_strict_oid(&oid)) {
1204 os_strlcpy(buf, "TOD-STRICT", sizeof(buf));
1205 cert->certificate_policy |=
1206 X509_EXT_CERT_POLICY_TOD_STRICT;
1207 } else if (x509_id_wfa_tod_tofu_oid(&oid)) {
1208 os_strlcpy(buf, "TOD-TOFU", sizeof(buf));
1209 cert->certificate_policy |=
1210 X509_EXT_CERT_POLICY_TOD_TOFU;
1211 } else {
1212 asn1_oid_to_str(&oid, buf, sizeof(buf));
1213 }
1214 wpa_printf(MSG_DEBUG, "policyIdentifier: %s", buf);
1215
1216 pos = pol_end;
1217 }
1218
1219 cert->extensions_present |= X509_EXT_CERTIFICATE_POLICY;
1220
1221 return 0;
1222 }
1223
1224
x509_id_pkix_oid(struct asn1_oid * oid)1225 static int x509_id_pkix_oid(struct asn1_oid *oid)
1226 {
1227 return oid->len >= 7 &&
1228 oid->oid[0] == 1 /* iso */ &&
1229 oid->oid[1] == 3 /* identified-organization */ &&
1230 oid->oid[2] == 6 /* dod */ &&
1231 oid->oid[3] == 1 /* internet */ &&
1232 oid->oid[4] == 5 /* security */ &&
1233 oid->oid[5] == 5 /* mechanisms */ &&
1234 oid->oid[6] == 7 /* id-pkix */;
1235 }
1236
1237
x509_id_kp_oid(struct asn1_oid * oid)1238 static int x509_id_kp_oid(struct asn1_oid *oid)
1239 {
1240 /* id-kp */
1241 return oid->len >= 8 &&
1242 x509_id_pkix_oid(oid) &&
1243 oid->oid[7] == 3 /* id-kp */;
1244 }
1245
1246
x509_id_kp_server_auth_oid(struct asn1_oid * oid)1247 static int x509_id_kp_server_auth_oid(struct asn1_oid *oid)
1248 {
1249 /* id-kp */
1250 return oid->len == 9 &&
1251 x509_id_kp_oid(oid) &&
1252 oid->oid[8] == 1 /* id-kp-serverAuth */;
1253 }
1254
1255
x509_id_kp_client_auth_oid(struct asn1_oid * oid)1256 static int x509_id_kp_client_auth_oid(struct asn1_oid *oid)
1257 {
1258 /* id-kp */
1259 return oid->len == 9 &&
1260 x509_id_kp_oid(oid) &&
1261 oid->oid[8] == 2 /* id-kp-clientAuth */;
1262 }
1263
1264
x509_id_kp_ocsp_oid(struct asn1_oid * oid)1265 static int x509_id_kp_ocsp_oid(struct asn1_oid *oid)
1266 {
1267 /* id-kp */
1268 return oid->len == 9 &&
1269 x509_id_kp_oid(oid) &&
1270 oid->oid[8] == 9 /* id-kp-OCSPSigning */;
1271 }
1272
1273
x509_parse_ext_ext_key_usage(struct x509_certificate * cert,const u8 * pos,size_t len)1274 static int x509_parse_ext_ext_key_usage(struct x509_certificate *cert,
1275 const u8 *pos, size_t len)
1276 {
1277 struct asn1_hdr hdr;
1278 const u8 *end;
1279 struct asn1_oid oid;
1280
1281 /*
1282 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
1283 *
1284 * KeyPurposeId ::= OBJECT IDENTIFIER
1285 */
1286
1287 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1288 asn1_unexpected(&hdr,
1289 "X509: Expected SEQUENCE (ExtKeyUsageSyntax)");
1290 return -1;
1291 }
1292 if (hdr.length > pos + len - hdr.payload)
1293 return -1;
1294 pos = hdr.payload;
1295 end = pos + hdr.length;
1296
1297 wpa_hexdump(MSG_MSGDUMP, "X509: ExtKeyUsageSyntax", pos, end - pos);
1298
1299 while (pos < end) {
1300 char buf[80];
1301
1302 if (asn1_get_oid(pos, end - pos, &oid, &pos))
1303 return -1;
1304 if (x509_any_ext_key_usage_oid(&oid)) {
1305 os_strlcpy(buf, "anyExtendedKeyUsage", sizeof(buf));
1306 cert->ext_key_usage |= X509_EXT_KEY_USAGE_ANY;
1307 } else if (x509_id_kp_server_auth_oid(&oid)) {
1308 os_strlcpy(buf, "id-kp-serverAuth", sizeof(buf));
1309 cert->ext_key_usage |= X509_EXT_KEY_USAGE_SERVER_AUTH;
1310 } else if (x509_id_kp_client_auth_oid(&oid)) {
1311 os_strlcpy(buf, "id-kp-clientAuth", sizeof(buf));
1312 cert->ext_key_usage |= X509_EXT_KEY_USAGE_CLIENT_AUTH;
1313 } else if (x509_id_kp_ocsp_oid(&oid)) {
1314 os_strlcpy(buf, "id-kp-OCSPSigning", sizeof(buf));
1315 cert->ext_key_usage |= X509_EXT_KEY_USAGE_OCSP;
1316 } else {
1317 asn1_oid_to_str(&oid, buf, sizeof(buf));
1318 }
1319 wpa_printf(MSG_DEBUG, "ExtKeyUsage KeyPurposeId: %s", buf);
1320 }
1321
1322 cert->extensions_present |= X509_EXT_EXT_KEY_USAGE;
1323
1324 return 0;
1325 }
1326
1327
x509_parse_extension_data(struct x509_certificate * cert,struct asn1_oid * oid,const u8 * pos,size_t len)1328 static int x509_parse_extension_data(struct x509_certificate *cert,
1329 struct asn1_oid *oid,
1330 const u8 *pos, size_t len)
1331 {
1332 if (!x509_id_ce_oid(oid))
1333 return 1;
1334
1335 /* TODO: add other extensions required by RFC 3280, Ch 4.2:
1336 * name constraints (section 4.2.1.11)
1337 * policy constraints (section 4.2.1.12)
1338 * inhibit any-policy (section 4.2.1.15)
1339 */
1340 switch (oid->oid[3]) {
1341 case 15: /* id-ce-keyUsage */
1342 return x509_parse_ext_key_usage(cert, pos, len);
1343 case 17: /* id-ce-subjectAltName */
1344 return x509_parse_ext_subject_alt_name(cert, pos, len);
1345 case 18: /* id-ce-issuerAltName */
1346 return x509_parse_ext_issuer_alt_name(cert, pos, len);
1347 case 19: /* id-ce-basicConstraints */
1348 return x509_parse_ext_basic_constraints(cert, pos, len);
1349 case 32: /* id-ce-certificatePolicies */
1350 return x509_parse_ext_certificate_policies(cert, pos, len);
1351 case 37: /* id-ce-extKeyUsage */
1352 return x509_parse_ext_ext_key_usage(cert, pos, len);
1353 default:
1354 return 1;
1355 }
1356 }
1357
1358
x509_parse_extension(struct x509_certificate * cert,const u8 * pos,size_t len,const u8 ** next)1359 static int x509_parse_extension(struct x509_certificate *cert,
1360 const u8 *pos, size_t len, const u8 **next)
1361 {
1362 const u8 *end;
1363 struct asn1_hdr hdr;
1364 struct asn1_oid oid;
1365 int critical_ext = 0, res;
1366 char buf[80];
1367
1368 /*
1369 * Extension ::= SEQUENCE {
1370 * extnID OBJECT IDENTIFIER,
1371 * critical BOOLEAN DEFAULT FALSE,
1372 * extnValue OCTET STRING
1373 * }
1374 */
1375
1376 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1377 asn1_unexpected(&hdr, "X509: Expected SEQUENCE in Extensions");
1378 return -1;
1379 }
1380 pos = hdr.payload;
1381 *next = end = pos + hdr.length;
1382
1383 if (asn1_get_oid(pos, end - pos, &oid, &pos) < 0) {
1384 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 data for "
1385 "Extension (expected OID)");
1386 return -1;
1387 }
1388
1389 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1390 (!asn1_is_boolean(&hdr) && !asn1_is_octetstring(&hdr))) {
1391 asn1_unexpected(&hdr,
1392 "X509: Expected BOOLEAN or OCTETSTRING in Extensions");
1393 return -1;
1394 }
1395
1396 if (hdr.tag == ASN1_TAG_BOOLEAN) {
1397 critical_ext = hdr.payload[0];
1398 pos = hdr.payload;
1399 /*
1400 * Number of CA certificates seem to be using Private class in
1401 * one of the X.509v3 extensions, so let's accept that instead
1402 * of rejecting the certificate. asn1_is_octetstring() covers
1403 * the more common case.
1404 */
1405 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1406 (!asn1_is_octetstring(&hdr) &&
1407 !(hdr.class == ASN1_CLASS_PRIVATE &&
1408 hdr.tag == ASN1_TAG_OCTETSTRING))) {
1409 asn1_unexpected(&hdr,
1410 "X509: Expected OCTETSTRING in Extensions");
1411 return -1;
1412 }
1413 }
1414
1415 asn1_oid_to_str(&oid, buf, sizeof(buf));
1416 wpa_printf(MSG_DEBUG, "X509: Extension: extnID=%s critical=%d",
1417 buf, critical_ext);
1418 wpa_hexdump(MSG_MSGDUMP, "X509: extnValue", hdr.payload, hdr.length);
1419
1420 res = x509_parse_extension_data(cert, &oid, hdr.payload, hdr.length);
1421 if (res < 0)
1422 return res;
1423 if (res == 1 && critical_ext) {
1424 wpa_printf(MSG_INFO, "X509: Unknown critical extension %s",
1425 buf);
1426 return -1;
1427 }
1428
1429 return 0;
1430 }
1431
1432
x509_parse_extensions(struct x509_certificate * cert,const u8 * pos,size_t len)1433 static int x509_parse_extensions(struct x509_certificate *cert,
1434 const u8 *pos, size_t len)
1435 {
1436 const u8 *end;
1437 struct asn1_hdr hdr;
1438
1439 /* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension */
1440
1441 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1442 asn1_unexpected(&hdr, "X509: Expected SEQUENCE for Extensions");
1443 return -1;
1444 }
1445
1446 pos = hdr.payload;
1447 end = pos + hdr.length;
1448
1449 while (pos < end) {
1450 if (x509_parse_extension(cert, pos, end - pos, &pos)
1451 < 0)
1452 return -1;
1453 }
1454
1455 return 0;
1456 }
1457
1458
x509_parse_tbs_certificate(const u8 * buf,size_t len,struct x509_certificate * cert,const u8 ** next)1459 static int x509_parse_tbs_certificate(const u8 *buf, size_t len,
1460 struct x509_certificate *cert,
1461 const u8 **next)
1462 {
1463 struct asn1_hdr hdr;
1464 const u8 *pos, *end;
1465 size_t left;
1466 char sbuf[128];
1467 unsigned long value;
1468 const u8 *subject_dn;
1469
1470 /* tbsCertificate TBSCertificate ::= SEQUENCE */
1471 if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1472 asn1_unexpected(&hdr,
1473 "X509: tbsCertificate did not start with a valid SEQUENCE");
1474 return -1;
1475 }
1476 pos = hdr.payload;
1477 end = *next = pos + hdr.length;
1478
1479 /*
1480 * version [0] EXPLICIT Version DEFAULT v1
1481 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
1482 */
1483 if (asn1_get_next(pos, end - pos, &hdr) < 0)
1484 return -1;
1485 pos = hdr.payload;
1486
1487 if (asn1_is_cs_tag(&hdr, 0) && hdr.constructed) {
1488 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1489 !asn1_is_integer(&hdr)) {
1490 asn1_unexpected(&hdr,
1491 "X509: No INTEGER tag found for version field");
1492 return -1;
1493 }
1494 if (hdr.length != 1) {
1495 wpa_printf(MSG_DEBUG, "X509: Unexpected version field "
1496 "length %u (expected 1)", hdr.length);
1497 return -1;
1498 }
1499 pos = hdr.payload;
1500 left = hdr.length;
1501 value = 0;
1502 while (left) {
1503 value <<= 8;
1504 value |= *pos++;
1505 left--;
1506 }
1507
1508 cert->version = value;
1509 if (cert->version != X509_CERT_V1 &&
1510 cert->version != X509_CERT_V2 &&
1511 cert->version != X509_CERT_V3) {
1512 wpa_printf(MSG_DEBUG, "X509: Unsupported version %d",
1513 cert->version + 1);
1514 return -1;
1515 }
1516
1517 if (asn1_get_next(pos, end - pos, &hdr) < 0)
1518 return -1;
1519 } else
1520 cert->version = X509_CERT_V1;
1521 wpa_printf(MSG_MSGDUMP, "X509: Version X.509v%d", cert->version + 1);
1522
1523 /* serialNumber CertificateSerialNumber ::= INTEGER */
1524 if (!asn1_is_integer(&hdr) ||
1525 hdr.length < 1 || hdr.length > X509_MAX_SERIAL_NUM_LEN) {
1526 asn1_unexpected(&hdr,
1527 "X509: No INTEGER tag found for serialNumber");
1528 return -1;
1529 }
1530
1531 pos = hdr.payload + hdr.length;
1532 while (hdr.length > 0 && hdr.payload[0] == 0) {
1533 hdr.payload++;
1534 hdr.length--;
1535 }
1536 os_memcpy(cert->serial_number, hdr.payload, hdr.length);
1537 cert->serial_number_len = hdr.length;
1538 wpa_hexdump(MSG_MSGDUMP, "X509: serialNumber", cert->serial_number,
1539 cert->serial_number_len);
1540
1541 /* signature AlgorithmIdentifier */
1542 if (x509_parse_algorithm_identifier(pos, end - pos, &cert->signature,
1543 &pos))
1544 return -1;
1545
1546 /* issuer Name */
1547 if (x509_parse_name(pos, end - pos, &cert->issuer, &pos))
1548 return -1;
1549 x509_name_string(&cert->issuer, sbuf, sizeof(sbuf));
1550 wpa_printf(MSG_MSGDUMP, "X509: issuer %s", sbuf);
1551
1552 /* validity Validity */
1553 if (x509_parse_validity(pos, end - pos, cert, &pos))
1554 return -1;
1555
1556 /* subject Name */
1557 subject_dn = pos;
1558 if (x509_parse_name(pos, end - pos, &cert->subject, &pos))
1559 return -1;
1560 cert->subject_dn = os_malloc(pos - subject_dn);
1561 if (!cert->subject_dn)
1562 return -1;
1563 cert->subject_dn_len = pos - subject_dn;
1564 os_memcpy(cert->subject_dn, subject_dn, cert->subject_dn_len);
1565 x509_name_string(&cert->subject, sbuf, sizeof(sbuf));
1566 wpa_printf(MSG_MSGDUMP, "X509: subject %s", sbuf);
1567
1568 /* subjectPublicKeyInfo SubjectPublicKeyInfo */
1569 if (x509_parse_public_key(pos, end - pos, cert, &pos))
1570 return -1;
1571
1572 if (pos == end)
1573 return 0;
1574
1575 if (cert->version == X509_CERT_V1)
1576 return 0;
1577
1578 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1579 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1580 asn1_unexpected(&hdr,
1581 "X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
1582 return -1;
1583 }
1584
1585 if (hdr.tag == 1) {
1586 /* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL */
1587 wpa_printf(MSG_DEBUG, "X509: issuerUniqueID");
1588 /* TODO: parse UniqueIdentifier ::= BIT STRING */
1589
1590 pos = hdr.payload + hdr.length;
1591 if (pos == end)
1592 return 0;
1593
1594 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1595 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1596 asn1_unexpected(&hdr,
1597 "X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
1598 return -1;
1599 }
1600 }
1601
1602 if (hdr.tag == 2) {
1603 /* subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL */
1604 wpa_printf(MSG_DEBUG, "X509: subjectUniqueID");
1605 /* TODO: parse UniqueIdentifier ::= BIT STRING */
1606
1607 pos = hdr.payload + hdr.length;
1608 if (pos == end)
1609 return 0;
1610
1611 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1612 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1613 asn1_unexpected(&hdr,
1614 "X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
1615 return -1;
1616 }
1617 }
1618
1619 if (hdr.tag != 3) {
1620 wpa_printf(MSG_DEBUG,
1621 "X509: Ignored unexpected Context-Specific constructed %d tag %d in optional tbsCertificate fields",
1622 hdr.constructed, hdr.tag);
1623 return 0;
1624 }
1625
1626 /* extensions [3] EXPLICIT Extensions OPTIONAL */
1627
1628 if (cert->version != X509_CERT_V3) {
1629 wpa_printf(MSG_DEBUG, "X509: X.509%d certificate and "
1630 "Extensions data which are only allowed for "
1631 "version 3", cert->version + 1);
1632 return -1;
1633 }
1634
1635 if (x509_parse_extensions(cert, hdr.payload, hdr.length) < 0)
1636 return -1;
1637
1638 pos = hdr.payload + hdr.length;
1639 if (pos < end) {
1640 wpa_hexdump(MSG_DEBUG,
1641 "X509: Ignored extra tbsCertificate data",
1642 pos, end - pos);
1643 }
1644
1645 return 0;
1646 }
1647
1648
x509_rsadsi_oid(struct asn1_oid * oid)1649 static int x509_rsadsi_oid(struct asn1_oid *oid)
1650 {
1651 return oid->len >= 4 &&
1652 oid->oid[0] == 1 /* iso */ &&
1653 oid->oid[1] == 2 /* member-body */ &&
1654 oid->oid[2] == 840 /* us */ &&
1655 oid->oid[3] == 113549 /* rsadsi */;
1656 }
1657
1658
x509_pkcs_oid(struct asn1_oid * oid)1659 static int x509_pkcs_oid(struct asn1_oid *oid)
1660 {
1661 return oid->len >= 5 &&
1662 x509_rsadsi_oid(oid) &&
1663 oid->oid[4] == 1 /* pkcs */;
1664 }
1665
1666
x509_digest_oid(struct asn1_oid * oid)1667 static int x509_digest_oid(struct asn1_oid *oid)
1668 {
1669 return oid->len >= 5 &&
1670 x509_rsadsi_oid(oid) &&
1671 oid->oid[4] == 2 /* digestAlgorithm */;
1672 }
1673
1674
x509_sha1_oid(struct asn1_oid * oid)1675 int x509_sha1_oid(struct asn1_oid *oid)
1676 {
1677 return oid->len == 6 &&
1678 oid->oid[0] == 1 /* iso */ &&
1679 oid->oid[1] == 3 /* identified-organization */ &&
1680 oid->oid[2] == 14 /* oiw */ &&
1681 oid->oid[3] == 3 /* secsig */ &&
1682 oid->oid[4] == 2 /* algorithms */ &&
1683 oid->oid[5] == 26 /* id-sha1 */;
1684 }
1685
1686
x509_sha2_oid(struct asn1_oid * oid)1687 static int x509_sha2_oid(struct asn1_oid *oid)
1688 {
1689 return oid->len == 9 &&
1690 oid->oid[0] == 2 /* joint-iso-itu-t */ &&
1691 oid->oid[1] == 16 /* country */ &&
1692 oid->oid[2] == 840 /* us */ &&
1693 oid->oid[3] == 1 /* organization */ &&
1694 oid->oid[4] == 101 /* gov */ &&
1695 oid->oid[5] == 3 /* csor */ &&
1696 oid->oid[6] == 4 /* nistAlgorithm */ &&
1697 oid->oid[7] == 2 /* hashAlgs */;
1698 }
1699
1700
x509_sha256_oid(struct asn1_oid * oid)1701 int x509_sha256_oid(struct asn1_oid *oid)
1702 {
1703 return x509_sha2_oid(oid) &&
1704 oid->oid[8] == 1 /* sha256 */;
1705 }
1706
1707
x509_sha384_oid(struct asn1_oid * oid)1708 int x509_sha384_oid(struct asn1_oid *oid)
1709 {
1710 return x509_sha2_oid(oid) &&
1711 oid->oid[8] == 2 /* sha384 */;
1712 }
1713
1714
x509_sha512_oid(struct asn1_oid * oid)1715 int x509_sha512_oid(struct asn1_oid *oid)
1716 {
1717 return x509_sha2_oid(oid) &&
1718 oid->oid[8] == 3 /* sha512 */;
1719 }
1720
1721
1722 /**
1723 * x509_certificate_parse - Parse a X.509 certificate in DER format
1724 * @buf: Pointer to the X.509 certificate in DER format
1725 * @len: Buffer length
1726 * Returns: Pointer to the parsed certificate or %NULL on failure
1727 *
1728 * Caller is responsible for freeing the returned certificate by calling
1729 * x509_certificate_free().
1730 */
x509_certificate_parse(const u8 * buf,size_t len)1731 struct x509_certificate * x509_certificate_parse(const u8 *buf, size_t len)
1732 {
1733 struct asn1_hdr hdr;
1734 const u8 *pos, *end, *hash_start;
1735 struct x509_certificate *cert;
1736
1737 cert = os_zalloc(sizeof(*cert) + len);
1738 if (cert == NULL)
1739 return NULL;
1740 os_memcpy(cert + 1, buf, len);
1741 cert->cert_start = (u8 *) (cert + 1);
1742 cert->cert_len = len;
1743
1744 pos = buf;
1745 end = buf + len;
1746
1747 /* RFC 3280 - X.509 v3 certificate / ASN.1 DER */
1748
1749 /* Certificate ::= SEQUENCE */
1750 if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
1751 asn1_unexpected(&hdr,
1752 "X509: Certificate did not start with a valid SEQUENCE");
1753 x509_certificate_free(cert);
1754 return NULL;
1755 }
1756 pos = hdr.payload;
1757
1758 if (hdr.length > end - pos) {
1759 x509_certificate_free(cert);
1760 return NULL;
1761 }
1762
1763 if (hdr.length < end - pos) {
1764 wpa_hexdump(MSG_MSGDUMP, "X509: Ignoring extra data after DER "
1765 "encoded certificate",
1766 pos + hdr.length, end - (pos + hdr.length));
1767 end = pos + hdr.length;
1768 }
1769
1770 hash_start = pos;
1771 cert->tbs_cert_start = cert->cert_start + (hash_start - buf);
1772 if (x509_parse_tbs_certificate(pos, end - pos, cert, &pos)) {
1773 x509_certificate_free(cert);
1774 return NULL;
1775 }
1776 cert->tbs_cert_len = pos - hash_start;
1777
1778 /* signatureAlgorithm AlgorithmIdentifier */
1779 if (x509_parse_algorithm_identifier(pos, end - pos,
1780 &cert->signature_alg, &pos)) {
1781 x509_certificate_free(cert);
1782 return NULL;
1783 }
1784
1785 /* signatureValue BIT STRING */
1786 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1787 !asn1_is_bitstring(&hdr)) {
1788 asn1_unexpected(&hdr,
1789 "X509: Expected BITSTRING (signatureValue)");
1790 x509_certificate_free(cert);
1791 return NULL;
1792 }
1793 if (hdr.length < 1) {
1794 x509_certificate_free(cert);
1795 return NULL;
1796 }
1797 pos = hdr.payload;
1798 if (*pos) {
1799 wpa_printf(MSG_DEBUG,
1800 "X509: BITSTRING (signatureValue) - %d unused bits",
1801 *pos);
1802 /* PKCS #1 v1.5 10.2.1:
1803 * It is an error if the length in bits of the signature S is
1804 * not a multiple of eight.
1805 */
1806 x509_certificate_free(cert);
1807 return NULL;
1808 }
1809 os_free(cert->sign_value);
1810 cert->sign_value = os_memdup(pos + 1, hdr.length - 1);
1811 if (cert->sign_value == NULL) {
1812 wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for "
1813 "signatureValue");
1814 x509_certificate_free(cert);
1815 return NULL;
1816 }
1817 cert->sign_value_len = hdr.length - 1;
1818 wpa_hexdump(MSG_MSGDUMP, "X509: signature",
1819 cert->sign_value, cert->sign_value_len);
1820
1821 return cert;
1822 }
1823
1824
1825 /**
1826 * x509_certificate_check_signature - Verify certificate signature
1827 * @issuer: Issuer certificate
1828 * @cert: Certificate to be verified
1829 * Returns: 0 if cert has a valid signature that was signed by the issuer,
1830 * -1 if not
1831 */
x509_certificate_check_signature(struct x509_certificate * issuer,struct x509_certificate * cert)1832 int x509_certificate_check_signature(struct x509_certificate *issuer,
1833 struct x509_certificate *cert)
1834 {
1835 return x509_check_signature(issuer, &cert->signature,
1836 cert->sign_value, cert->sign_value_len,
1837 cert->tbs_cert_start, cert->tbs_cert_len);
1838 }
1839
1840
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)1841 int x509_check_signature(struct x509_certificate *issuer,
1842 struct x509_algorithm_identifier *signature,
1843 const u8 *sign_value, size_t sign_value_len,
1844 const u8 *signed_data, size_t signed_data_len)
1845 {
1846 struct crypto_public_key *pk;
1847 u8 *data;
1848 const u8 *pos, *end, *next, *da_end;
1849 size_t data_len;
1850 struct asn1_hdr hdr;
1851 struct asn1_oid oid;
1852 u8 hash[64];
1853 size_t hash_len;
1854 const u8 *addr[1] = { signed_data };
1855 size_t len[1] = { signed_data_len };
1856
1857 if (!x509_pkcs_oid(&signature->oid) ||
1858 signature->oid.len != 7 ||
1859 signature->oid.oid[5] != 1 /* pkcs-1 */) {
1860 wpa_printf(MSG_DEBUG, "X509: Unrecognized signature "
1861 "algorithm");
1862 return -1;
1863 }
1864
1865 pk = crypto_public_key_import(issuer->public_key,
1866 issuer->public_key_len);
1867 if (pk == NULL)
1868 return -1;
1869
1870 data_len = sign_value_len;
1871 data = os_malloc(data_len);
1872 if (data == NULL) {
1873 crypto_public_key_free(pk);
1874 return -1;
1875 }
1876
1877 if (crypto_public_key_decrypt_pkcs1(pk, sign_value,
1878 sign_value_len, data,
1879 &data_len) < 0) {
1880 wpa_printf(MSG_DEBUG, "X509: Failed to decrypt signature");
1881 crypto_public_key_free(pk);
1882 os_free(data);
1883 return -1;
1884 }
1885 crypto_public_key_free(pk);
1886
1887 wpa_hexdump(MSG_MSGDUMP, "X509: Signature data D", data, data_len);
1888
1889 /*
1890 * PKCS #1 v1.5, 10.1.2:
1891 *
1892 * DigestInfo ::= SEQUENCE {
1893 * digestAlgorithm DigestAlgorithmIdentifier,
1894 * digest Digest
1895 * }
1896 *
1897 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1898 *
1899 * Digest ::= OCTET STRING
1900 *
1901 */
1902 if (asn1_get_next(data, data_len, &hdr) < 0 ||
1903 !asn1_is_sequence(&hdr)) {
1904 asn1_unexpected(&hdr, "X509: Expected SEQUENCE (DigestInfo)");
1905 os_free(data);
1906 return -1;
1907 }
1908 wpa_hexdump(MSG_MSGDUMP, "X509: DigestInfo", hdr.payload, hdr.length);
1909
1910 pos = hdr.payload;
1911 end = pos + hdr.length;
1912
1913 /*
1914 * X.509:
1915 * AlgorithmIdentifier ::= SEQUENCE {
1916 * algorithm OBJECT IDENTIFIER,
1917 * parameters ANY DEFINED BY algorithm OPTIONAL
1918 * }
1919 */
1920
1921 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1922 !asn1_is_sequence(&hdr)) {
1923 asn1_unexpected(&hdr,
1924 "X509: Expected SEQUENCE (AlgorithmIdentifier)");
1925 os_free(data);
1926 return -1;
1927 }
1928 wpa_hexdump(MSG_MSGDUMP, "X509: DigestAlgorithmIdentifier",
1929 hdr.payload, hdr.length);
1930 da_end = hdr.payload + hdr.length;
1931
1932 if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {
1933 wpa_printf(MSG_DEBUG, "X509: Failed to parse digestAlgorithm");
1934 os_free(data);
1935 return -1;
1936 }
1937 wpa_hexdump(MSG_MSGDUMP, "X509: Digest algorithm parameters",
1938 next, da_end - next);
1939
1940 /*
1941 * RFC 5754: The correct encoding for the SHA2 algorithms would be to
1942 * omit the parameters, but there are implementation that encode these
1943 * as a NULL element. Allow these two cases and reject anything else.
1944 */
1945 if (da_end > next &&
1946 (asn1_get_next(next, da_end - next, &hdr) < 0 ||
1947 !asn1_is_null(&hdr) ||
1948 hdr.payload + hdr.length != da_end)) {
1949 wpa_printf(MSG_DEBUG,
1950 "X509: Unexpected digest algorithm parameters");
1951 os_free(data);
1952 return -1;
1953 }
1954
1955 if (x509_sha1_oid(&oid)) {
1956 if (signature->oid.oid[6] != 5 /* sha-1WithRSAEncryption */) {
1957 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA1 "
1958 "does not match with certificate "
1959 "signatureAlgorithm (%lu)",
1960 signature->oid.oid[6]);
1961 os_free(data);
1962 return -1;
1963 }
1964 goto skip_digest_oid;
1965 }
1966
1967 if (x509_sha256_oid(&oid)) {
1968 if (signature->oid.oid[6] !=
1969 11 /* sha2561WithRSAEncryption */) {
1970 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA256 "
1971 "does not match with certificate "
1972 "signatureAlgorithm (%lu)",
1973 signature->oid.oid[6]);
1974 os_free(data);
1975 return -1;
1976 }
1977 goto skip_digest_oid;
1978 }
1979
1980 if (x509_sha384_oid(&oid)) {
1981 if (signature->oid.oid[6] != 12 /* sha384WithRSAEncryption */) {
1982 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA384 "
1983 "does not match with certificate "
1984 "signatureAlgorithm (%lu)",
1985 signature->oid.oid[6]);
1986 os_free(data);
1987 return -1;
1988 }
1989 goto skip_digest_oid;
1990 }
1991
1992 if (x509_sha512_oid(&oid)) {
1993 if (signature->oid.oid[6] != 13 /* sha512WithRSAEncryption */) {
1994 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA512 "
1995 "does not match with certificate "
1996 "signatureAlgorithm (%lu)",
1997 signature->oid.oid[6]);
1998 os_free(data);
1999 return -1;
2000 }
2001 goto skip_digest_oid;
2002 }
2003
2004 if (!x509_digest_oid(&oid)) {
2005 wpa_printf(MSG_DEBUG, "X509: Unrecognized digestAlgorithm");
2006 os_free(data);
2007 return -1;
2008 }
2009 switch (oid.oid[5]) {
2010 case 5: /* md5 */
2011 if (signature->oid.oid[6] != 4 /* md5WithRSAEncryption */) {
2012 wpa_printf(MSG_DEBUG, "X509: digestAlgorithm MD5 does "
2013 "not match with certificate "
2014 "signatureAlgorithm (%lu)",
2015 signature->oid.oid[6]);
2016 os_free(data);
2017 return -1;
2018 }
2019 break;
2020 case 2: /* md2 */
2021 case 4: /* md4 */
2022 default:
2023 wpa_printf(MSG_DEBUG, "X509: Unsupported digestAlgorithm "
2024 "(%lu)", oid.oid[5]);
2025 os_free(data);
2026 return -1;
2027 }
2028
2029 skip_digest_oid:
2030 /* Digest ::= OCTET STRING */
2031 pos = da_end;
2032
2033 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
2034 !asn1_is_octetstring(&hdr)) {
2035 asn1_unexpected(&hdr, "X509: Expected OCTETSTRING (Digest)");
2036 os_free(data);
2037 return -1;
2038 }
2039 wpa_hexdump(MSG_MSGDUMP, "X509: Decrypted Digest",
2040 hdr.payload, hdr.length);
2041
2042 switch (signature->oid.oid[6]) {
2043 case 4: /* md5WithRSAEncryption */
2044 md5_vector(1, addr, len, hash);
2045 hash_len = 16;
2046 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (MD5)",
2047 hash, hash_len);
2048 break;
2049 case 5: /* sha-1WithRSAEncryption */
2050 sha1_vector(1, addr, len, hash);
2051 hash_len = 20;
2052 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA1)",
2053 hash, hash_len);
2054 break;
2055 case 11: /* sha256WithRSAEncryption */
2056 sha256_vector(1, addr, len, hash);
2057 hash_len = 32;
2058 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA256)",
2059 hash, hash_len);
2060 break;
2061 case 12: /* sha384WithRSAEncryption */
2062 sha384_vector(1, addr, len, hash);
2063 hash_len = 48;
2064 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA384)",
2065 hash, hash_len);
2066 break;
2067 case 13: /* sha512WithRSAEncryption */
2068 sha512_vector(1, addr, len, hash);
2069 hash_len = 64;
2070 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA512)",
2071 hash, hash_len);
2072 break;
2073 case 2: /* md2WithRSAEncryption */
2074 default:
2075 wpa_printf(MSG_INFO, "X509: Unsupported certificate signature "
2076 "algorithm (%lu)", signature->oid.oid[6]);
2077 os_free(data);
2078 return -1;
2079 }
2080
2081 if (hdr.length != hash_len ||
2082 os_memcmp_const(hdr.payload, hash, hdr.length) != 0) {
2083 wpa_printf(MSG_INFO, "X509: Certificate Digest does not match "
2084 "with calculated tbsCertificate hash");
2085 os_free(data);
2086 return -1;
2087 }
2088
2089 if (hdr.payload + hdr.length < data + data_len) {
2090 wpa_hexdump(MSG_INFO,
2091 "X509: Extra data after certificate signature hash",
2092 hdr.payload + hdr.length,
2093 data + data_len - hdr.payload - hdr.length);
2094 os_free(data);
2095 return -1;
2096 }
2097
2098 os_free(data);
2099
2100 wpa_printf(MSG_DEBUG, "X509: Certificate Digest matches with "
2101 "calculated tbsCertificate hash");
2102
2103 return 0;
2104 }
2105
2106
x509_valid_issuer(const struct x509_certificate * cert)2107 static int x509_valid_issuer(const struct x509_certificate *cert)
2108 {
2109 if ((cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS) &&
2110 !cert->ca) {
2111 wpa_printf(MSG_DEBUG, "X509: Non-CA certificate used as an "
2112 "issuer");
2113 return -1;
2114 }
2115
2116 if (cert->version == X509_CERT_V3 &&
2117 !(cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS)) {
2118 wpa_printf(MSG_DEBUG, "X509: v3 CA certificate did not "
2119 "include BasicConstraints extension");
2120 return -1;
2121 }
2122
2123 if ((cert->extensions_present & X509_EXT_KEY_USAGE) &&
2124 !(cert->key_usage & X509_KEY_USAGE_KEY_CERT_SIGN)) {
2125 wpa_printf(MSG_DEBUG, "X509: Issuer certificate did not have "
2126 "keyCertSign bit in Key Usage");
2127 return -1;
2128 }
2129
2130 return 0;
2131 }
2132
2133
2134 /**
2135 * x509_certificate_chain_validate - Validate X.509 certificate chain
2136 * @trusted: List of trusted certificates
2137 * @chain: Certificate chain to be validated (first chain must be issued by
2138 * signed by the second certificate in the chain and so on)
2139 * @reason: Buffer for returning failure reason (X509_VALIDATE_*)
2140 * Returns: 0 if chain is valid, -1 if not
2141 */
x509_certificate_chain_validate(struct x509_certificate * trusted,struct x509_certificate * chain,int * reason,int disable_time_checks)2142 int x509_certificate_chain_validate(struct x509_certificate *trusted,
2143 struct x509_certificate *chain,
2144 int *reason, int disable_time_checks)
2145 {
2146 long unsigned idx;
2147 int chain_trusted = 0;
2148 struct x509_certificate *cert, *trust;
2149 char buf[128];
2150 struct os_time now;
2151
2152 *reason = X509_VALIDATE_OK;
2153
2154 wpa_printf(MSG_DEBUG, "X509: Validate certificate chain");
2155 os_get_time(&now);
2156
2157 for (cert = chain, idx = 0; cert; cert = cert->next, idx++) {
2158 cert->issuer_trusted = 0;
2159 x509_name_string(&cert->subject, buf, sizeof(buf));
2160 wpa_printf(MSG_DEBUG, "X509: %lu: %s", idx, buf);
2161
2162 if (chain_trusted)
2163 continue;
2164
2165 if (!disable_time_checks &&
2166 ((unsigned long) now.sec <
2167 (unsigned long) cert->not_before ||
2168 (unsigned long) now.sec >
2169 (unsigned long) cert->not_after)) {
2170 wpa_printf(MSG_INFO, "X509: Certificate not valid "
2171 "(now=%lu not_before=%lu not_after=%lu)",
2172 now.sec, cert->not_before, cert->not_after);
2173 *reason = X509_VALIDATE_CERTIFICATE_EXPIRED;
2174 return -1;
2175 }
2176
2177 if (cert->next) {
2178 if (x509_name_compare(&cert->issuer,
2179 &cert->next->subject) != 0) {
2180 wpa_printf(MSG_DEBUG, "X509: Certificate "
2181 "chain issuer name mismatch");
2182 x509_name_string(&cert->issuer, buf,
2183 sizeof(buf));
2184 wpa_printf(MSG_DEBUG, "X509: cert issuer: %s",
2185 buf);
2186 x509_name_string(&cert->next->subject, buf,
2187 sizeof(buf));
2188 wpa_printf(MSG_DEBUG, "X509: next cert "
2189 "subject: %s", buf);
2190 *reason = X509_VALIDATE_CERTIFICATE_UNKNOWN;
2191 return -1;
2192 }
2193
2194 if (x509_valid_issuer(cert->next) < 0) {
2195 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2196 return -1;
2197 }
2198
2199 if ((cert->next->extensions_present &
2200 X509_EXT_PATH_LEN_CONSTRAINT) &&
2201 idx > cert->next->path_len_constraint) {
2202 wpa_printf(MSG_DEBUG, "X509: pathLenConstraint"
2203 " not met (idx=%lu issuer "
2204 "pathLenConstraint=%lu)", idx,
2205 cert->next->path_len_constraint);
2206 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2207 return -1;
2208 }
2209
2210 if (x509_certificate_check_signature(cert->next, cert)
2211 < 0) {
2212 wpa_printf(MSG_DEBUG, "X509: Invalid "
2213 "certificate signature within "
2214 "chain");
2215 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2216 return -1;
2217 }
2218 }
2219
2220 for (trust = trusted; trust; trust = trust->next) {
2221 if (x509_name_compare(&cert->issuer, &trust->subject)
2222 == 0)
2223 break;
2224 }
2225
2226 if (trust) {
2227 wpa_printf(MSG_DEBUG, "X509: Found issuer from the "
2228 "list of trusted certificates");
2229 if (x509_valid_issuer(trust) < 0) {
2230 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2231 return -1;
2232 }
2233
2234 if (x509_certificate_check_signature(trust, cert) < 0)
2235 {
2236 wpa_printf(MSG_DEBUG, "X509: Invalid "
2237 "certificate signature");
2238 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2239 return -1;
2240 }
2241
2242 wpa_printf(MSG_DEBUG, "X509: Trusted certificate "
2243 "found to complete the chain");
2244 cert->issuer_trusted = 1;
2245 chain_trusted = 1;
2246 }
2247 }
2248
2249 if (!chain_trusted) {
2250 wpa_printf(MSG_DEBUG, "X509: Did not find any of the issuers "
2251 "from the list of trusted certificates");
2252 if (trusted) {
2253 *reason = X509_VALIDATE_UNKNOWN_CA;
2254 return -1;
2255 }
2256 wpa_printf(MSG_DEBUG, "X509: Certificate chain validation "
2257 "disabled - ignore unknown CA issue");
2258 }
2259
2260 wpa_printf(MSG_DEBUG, "X509: Certificate chain valid");
2261
2262 return 0;
2263 }
2264
2265
2266 /**
2267 * x509_certificate_get_subject - Get a certificate based on Subject name
2268 * @chain: Certificate chain to search through
2269 * @name: Subject name to search for
2270 * Returns: Pointer to the certificate with the given Subject name or
2271 * %NULL on failure
2272 */
2273 struct x509_certificate *
x509_certificate_get_subject(struct x509_certificate * chain,struct x509_name * name)2274 x509_certificate_get_subject(struct x509_certificate *chain,
2275 struct x509_name *name)
2276 {
2277 struct x509_certificate *cert;
2278
2279 for (cert = chain; cert; cert = cert->next) {
2280 if (x509_name_compare(&cert->subject, name) == 0)
2281 return cert;
2282 }
2283 return NULL;
2284 }
2285
2286
2287 /**
2288 * x509_certificate_self_signed - Is the certificate self-signed?
2289 * @cert: Certificate
2290 * Returns: 1 if certificate is self-signed, 0 if not
2291 */
x509_certificate_self_signed(struct x509_certificate * cert)2292 int x509_certificate_self_signed(struct x509_certificate *cert)
2293 {
2294 return x509_name_compare(&cert->issuer, &cert->subject) == 0;
2295 }
2296