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