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