Updated to hostap_2_6
[mech_eap.git] / libeap / src / tls / x509v3.c
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
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  */
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  */
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
80 static int x509_whitespace(char c)
81 {
82         return c == ' ' || c == '\t';
83 }
84
85
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
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  */
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
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
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, "X509: BITSTRING - %d unused bits",
268                            *pos);
269                 /*
270                  * TODO: should this be rejected? X.509 certificates are
271                  * unlikely to use such a construction. Now we would end up
272                  * including the extra bits in the buffer which may also be
273                  * ok.
274                  */
275         }
276         os_free(cert->public_key);
277         cert->public_key = os_malloc(hdr.length - 1);
278         if (cert->public_key == NULL) {
279                 wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for "
280                            "public key");
281                 return -1;
282         }
283         os_memcpy(cert->public_key, pos + 1, hdr.length - 1);
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
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
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  */
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         end[-1] = '\0';
537 }
538
539
540 int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag, 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_id_kp_ocsp_oid(struct asn1_oid *oid)
1126 {
1127         /* id-kp */
1128         return oid->len == 9 &&
1129                 x509_id_kp_oid(oid) &&
1130                 oid->oid[8] == 9 /* id-kp-OCSPSigning */;
1131 }
1132
1133
1134 static int x509_parse_ext_ext_key_usage(struct x509_certificate *cert,
1135                                         const u8 *pos, size_t len)
1136 {
1137         struct asn1_hdr hdr;
1138         const u8 *end;
1139         struct asn1_oid oid;
1140
1141         /*
1142          * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
1143          *
1144          * KeyPurposeId ::= OBJECT IDENTIFIER
1145          */
1146
1147         if (asn1_get_next(pos, len, &hdr) < 0 ||
1148             hdr.class != ASN1_CLASS_UNIVERSAL ||
1149             hdr.tag != ASN1_TAG_SEQUENCE) {
1150                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
1151                            "(ExtKeyUsageSyntax) - found class %d tag 0x%x",
1152                            hdr.class, hdr.tag);
1153                 return -1;
1154         }
1155         if (hdr.length > pos + len - hdr.payload)
1156                 return -1;
1157         pos = hdr.payload;
1158         end = pos + hdr.length;
1159
1160         wpa_hexdump(MSG_MSGDUMP, "X509: ExtKeyUsageSyntax", pos, end - pos);
1161
1162         while (pos < end) {
1163                 char buf[80];
1164
1165                 if (asn1_get_oid(pos, end - pos, &oid, &pos))
1166                         return -1;
1167                 if (x509_any_ext_key_usage_oid(&oid)) {
1168                         os_strlcpy(buf, "anyExtendedKeyUsage", sizeof(buf));
1169                         cert->ext_key_usage |= X509_EXT_KEY_USAGE_ANY;
1170                 } else if (x509_id_kp_server_auth_oid(&oid)) {
1171                         os_strlcpy(buf, "id-kp-serverAuth", sizeof(buf));
1172                         cert->ext_key_usage |= X509_EXT_KEY_USAGE_SERVER_AUTH;
1173                 } else if (x509_id_kp_client_auth_oid(&oid)) {
1174                         os_strlcpy(buf, "id-kp-clientAuth", sizeof(buf));
1175                         cert->ext_key_usage |= X509_EXT_KEY_USAGE_CLIENT_AUTH;
1176                 } else if (x509_id_kp_ocsp_oid(&oid)) {
1177                         os_strlcpy(buf, "id-kp-OCSPSigning", sizeof(buf));
1178                         cert->ext_key_usage |= X509_EXT_KEY_USAGE_OCSP;
1179                 } else {
1180                         asn1_oid_to_str(&oid, buf, sizeof(buf));
1181                 }
1182                 wpa_printf(MSG_DEBUG, "ExtKeyUsage KeyPurposeId: %s", buf);
1183         }
1184
1185         cert->extensions_present |= X509_EXT_EXT_KEY_USAGE;
1186
1187         return 0;
1188 }
1189
1190
1191 static int x509_parse_extension_data(struct x509_certificate *cert,
1192                                      struct asn1_oid *oid,
1193                                      const u8 *pos, size_t len)
1194 {
1195         if (!x509_id_ce_oid(oid))
1196                 return 1;
1197
1198         /* TODO: add other extensions required by RFC 3280, Ch 4.2:
1199          * certificate policies (section 4.2.1.5)
1200          * name constraints (section 4.2.1.11)
1201          * policy constraints (section 4.2.1.12)
1202          * inhibit any-policy (section 4.2.1.15)
1203          */
1204         switch (oid->oid[3]) {
1205         case 15: /* id-ce-keyUsage */
1206                 return x509_parse_ext_key_usage(cert, pos, len);
1207         case 17: /* id-ce-subjectAltName */
1208                 return x509_parse_ext_subject_alt_name(cert, pos, len);
1209         case 18: /* id-ce-issuerAltName */
1210                 return x509_parse_ext_issuer_alt_name(cert, pos, len);
1211         case 19: /* id-ce-basicConstraints */
1212                 return x509_parse_ext_basic_constraints(cert, pos, len);
1213         case 37: /* id-ce-extKeyUsage */
1214                 return x509_parse_ext_ext_key_usage(cert, pos, len);
1215         default:
1216                 return 1;
1217         }
1218 }
1219
1220
1221 static int x509_parse_extension(struct x509_certificate *cert,
1222                                 const u8 *pos, size_t len, const u8 **next)
1223 {
1224         const u8 *end;
1225         struct asn1_hdr hdr;
1226         struct asn1_oid oid;
1227         int critical_ext = 0, res;
1228         char buf[80];
1229
1230         /*
1231          * Extension  ::=  SEQUENCE  {
1232          *     extnID      OBJECT IDENTIFIER,
1233          *     critical    BOOLEAN DEFAULT FALSE,
1234          *     extnValue   OCTET STRING
1235          * }
1236          */
1237
1238         if (asn1_get_next(pos, len, &hdr) < 0 ||
1239             hdr.class != ASN1_CLASS_UNIVERSAL ||
1240             hdr.tag != ASN1_TAG_SEQUENCE) {
1241                 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header in "
1242                            "Extensions: class %d tag 0x%x; expected SEQUENCE",
1243                            hdr.class, hdr.tag);
1244                 return -1;
1245         }
1246         pos = hdr.payload;
1247         *next = end = pos + hdr.length;
1248
1249         if (asn1_get_oid(pos, end - pos, &oid, &pos) < 0) {
1250                 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 data for "
1251                            "Extension (expected OID)");
1252                 return -1;
1253         }
1254
1255         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1256             hdr.class != ASN1_CLASS_UNIVERSAL ||
1257             (hdr.tag != ASN1_TAG_BOOLEAN &&
1258              hdr.tag != ASN1_TAG_OCTETSTRING)) {
1259                 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header in "
1260                            "Extensions: class %d tag 0x%x; expected BOOLEAN "
1261                            "or OCTET STRING", hdr.class, hdr.tag);
1262                 return -1;
1263         }
1264
1265         if (hdr.tag == ASN1_TAG_BOOLEAN) {
1266                 if (hdr.length != 1) {
1267                         wpa_printf(MSG_DEBUG, "X509: Unexpected "
1268                                    "Boolean length (%u)", hdr.length);
1269                         return -1;
1270                 }
1271                 critical_ext = hdr.payload[0];
1272                 pos = hdr.payload;
1273                 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1274                     (hdr.class != ASN1_CLASS_UNIVERSAL &&
1275                      hdr.class != ASN1_CLASS_PRIVATE) ||
1276                     hdr.tag != ASN1_TAG_OCTETSTRING) {
1277                         wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header "
1278                                    "in Extensions: class %d tag 0x%x; "
1279                                    "expected OCTET STRING",
1280                                    hdr.class, hdr.tag);
1281                         return -1;
1282                 }
1283         }
1284
1285         asn1_oid_to_str(&oid, buf, sizeof(buf));
1286         wpa_printf(MSG_DEBUG, "X509: Extension: extnID=%s critical=%d",
1287                    buf, critical_ext);
1288         wpa_hexdump(MSG_MSGDUMP, "X509: extnValue", hdr.payload, hdr.length);
1289
1290         res = x509_parse_extension_data(cert, &oid, hdr.payload, hdr.length);
1291         if (res < 0)
1292                 return res;
1293         if (res == 1 && critical_ext) {
1294                 wpa_printf(MSG_INFO, "X509: Unknown critical extension %s",
1295                            buf);
1296                 return -1;
1297         }
1298
1299         return 0;
1300 }
1301
1302
1303 static int x509_parse_extensions(struct x509_certificate *cert,
1304                                  const u8 *pos, size_t len)
1305 {
1306         const u8 *end;
1307         struct asn1_hdr hdr;
1308
1309         /* Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension */
1310
1311         if (asn1_get_next(pos, len, &hdr) < 0 ||
1312             hdr.class != ASN1_CLASS_UNIVERSAL ||
1313             hdr.tag != ASN1_TAG_SEQUENCE) {
1314                 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 data "
1315                            "for Extensions: class %d tag 0x%x; "
1316                            "expected SEQUENCE", hdr.class, hdr.tag);
1317                 return -1;
1318         }
1319
1320         pos = hdr.payload;
1321         end = pos + hdr.length;
1322
1323         while (pos < end) {
1324                 if (x509_parse_extension(cert, pos, end - pos, &pos)
1325                     < 0)
1326                         return -1;
1327         }
1328
1329         return 0;
1330 }
1331
1332
1333 static int x509_parse_tbs_certificate(const u8 *buf, size_t len,
1334                                       struct x509_certificate *cert,
1335                                       const u8 **next)
1336 {
1337         struct asn1_hdr hdr;
1338         const u8 *pos, *end;
1339         size_t left;
1340         char sbuf[128];
1341         unsigned long value;
1342         const u8 *subject_dn;
1343
1344         /* tbsCertificate TBSCertificate ::= SEQUENCE */
1345         if (asn1_get_next(buf, len, &hdr) < 0 ||
1346             hdr.class != ASN1_CLASS_UNIVERSAL ||
1347             hdr.tag != ASN1_TAG_SEQUENCE) {
1348                 wpa_printf(MSG_DEBUG, "X509: tbsCertificate did not start "
1349                            "with a valid SEQUENCE - found class %d tag 0x%x",
1350                            hdr.class, hdr.tag);
1351                 return -1;
1352         }
1353         pos = hdr.payload;
1354         end = *next = pos + hdr.length;
1355
1356         /*
1357          * version [0]  EXPLICIT Version DEFAULT v1
1358          * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
1359          */
1360         if (asn1_get_next(pos, end - pos, &hdr) < 0)
1361                 return -1;
1362         pos = hdr.payload;
1363
1364         if (hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC) {
1365                 if (asn1_get_next(pos, end - pos, &hdr) < 0)
1366                         return -1;
1367
1368                 if (hdr.class != ASN1_CLASS_UNIVERSAL ||
1369                     hdr.tag != ASN1_TAG_INTEGER) {
1370                         wpa_printf(MSG_DEBUG, "X509: No INTEGER tag found for "
1371                                    "version field - found class %d tag 0x%x",
1372                                    hdr.class, hdr.tag);
1373                         return -1;
1374                 }
1375                 if (hdr.length != 1) {
1376                         wpa_printf(MSG_DEBUG, "X509: Unexpected version field "
1377                                    "length %u (expected 1)", hdr.length);
1378                         return -1;
1379                 }
1380                 pos = hdr.payload;
1381                 left = hdr.length;
1382                 value = 0;
1383                 while (left) {
1384                         value <<= 8;
1385                         value |= *pos++;
1386                         left--;
1387                 }
1388
1389                 cert->version = value;
1390                 if (cert->version != X509_CERT_V1 &&
1391                     cert->version != X509_CERT_V2 &&
1392                     cert->version != X509_CERT_V3) {
1393                         wpa_printf(MSG_DEBUG, "X509: Unsupported version %d",
1394                                    cert->version + 1);
1395                         return -1;
1396                 }
1397
1398                 if (asn1_get_next(pos, end - pos, &hdr) < 0)
1399                         return -1;
1400         } else
1401                 cert->version = X509_CERT_V1;
1402         wpa_printf(MSG_MSGDUMP, "X509: Version X.509v%d", cert->version + 1);
1403
1404         /* serialNumber CertificateSerialNumber ::= INTEGER */
1405         if (hdr.class != ASN1_CLASS_UNIVERSAL ||
1406             hdr.tag != ASN1_TAG_INTEGER ||
1407             hdr.length < 1 || hdr.length > X509_MAX_SERIAL_NUM_LEN) {
1408                 wpa_printf(MSG_DEBUG, "X509: No INTEGER tag found for "
1409                            "serialNumber; class=%d tag=0x%x length=%u",
1410                            hdr.class, hdr.tag, hdr.length);
1411                 return -1;
1412         }
1413
1414         pos = hdr.payload + hdr.length;
1415         while (hdr.length > 0 && hdr.payload[0] == 0) {
1416                 hdr.payload++;
1417                 hdr.length--;
1418         }
1419         os_memcpy(cert->serial_number, hdr.payload, hdr.length);
1420         cert->serial_number_len = hdr.length;
1421         wpa_hexdump(MSG_MSGDUMP, "X509: serialNumber", cert->serial_number,
1422                     cert->serial_number_len);
1423
1424         /* signature AlgorithmIdentifier */
1425         if (x509_parse_algorithm_identifier(pos, end - pos, &cert->signature,
1426                                             &pos))
1427                 return -1;
1428
1429         /* issuer Name */
1430         if (x509_parse_name(pos, end - pos, &cert->issuer, &pos))
1431                 return -1;
1432         x509_name_string(&cert->issuer, sbuf, sizeof(sbuf));
1433         wpa_printf(MSG_MSGDUMP, "X509: issuer %s", sbuf);
1434
1435         /* validity Validity */
1436         if (x509_parse_validity(pos, end - pos, cert, &pos))
1437                 return -1;
1438
1439         /* subject Name */
1440         subject_dn = pos;
1441         if (x509_parse_name(pos, end - pos, &cert->subject, &pos))
1442                 return -1;
1443         cert->subject_dn = os_malloc(pos - subject_dn);
1444         if (!cert->subject_dn)
1445                 return -1;
1446         cert->subject_dn_len = pos - subject_dn;
1447         os_memcpy(cert->subject_dn, subject_dn, cert->subject_dn_len);
1448         x509_name_string(&cert->subject, sbuf, sizeof(sbuf));
1449         wpa_printf(MSG_MSGDUMP, "X509: subject %s", sbuf);
1450
1451         /* subjectPublicKeyInfo SubjectPublicKeyInfo */
1452         if (x509_parse_public_key(pos, end - pos, cert, &pos))
1453                 return -1;
1454
1455         if (pos == end)
1456                 return 0;
1457
1458         if (cert->version == X509_CERT_V1)
1459                 return 0;
1460
1461         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1462             hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1463                 wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific"
1464                            " tag to parse optional tbsCertificate "
1465                            "field(s); parsed class %d tag 0x%x",
1466                            hdr.class, hdr.tag);
1467                 return -1;
1468         }
1469
1470         if (hdr.tag == 1) {
1471                 /* issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL */
1472                 wpa_printf(MSG_DEBUG, "X509: issuerUniqueID");
1473                 /* TODO: parse UniqueIdentifier ::= BIT STRING */
1474
1475                 pos = hdr.payload + hdr.length;
1476                 if (pos == end)
1477                         return 0;
1478
1479                 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1480                     hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1481                         wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific"
1482                                    " tag to parse optional tbsCertificate "
1483                                    "field(s); parsed class %d tag 0x%x",
1484                                    hdr.class, hdr.tag);
1485                         return -1;
1486                 }
1487         }
1488
1489         if (hdr.tag == 2) {
1490                 /* subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL */
1491                 wpa_printf(MSG_DEBUG, "X509: subjectUniqueID");
1492                 /* TODO: parse UniqueIdentifier ::= BIT STRING */
1493
1494                 pos = hdr.payload + hdr.length;
1495                 if (pos == end)
1496                         return 0;
1497
1498                 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1499                     hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1500                         wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific"
1501                                    " tag to parse optional tbsCertificate "
1502                                    "field(s); parsed class %d tag 0x%x",
1503                                    hdr.class, hdr.tag);
1504                         return -1;
1505                 }
1506         }
1507
1508         if (hdr.tag != 3) {
1509                 wpa_printf(MSG_DEBUG, "X509: Ignored unexpected "
1510                            "Context-Specific tag %d in optional "
1511                            "tbsCertificate fields", hdr.tag);
1512                 return 0;
1513         }
1514
1515         /* extensions      [3]  EXPLICIT Extensions OPTIONAL */
1516
1517         if (cert->version != X509_CERT_V3) {
1518                 wpa_printf(MSG_DEBUG, "X509: X.509%d certificate and "
1519                            "Extensions data which are only allowed for "
1520                            "version 3", cert->version + 1);
1521                 return -1;
1522         }
1523
1524         if (x509_parse_extensions(cert, hdr.payload, hdr.length) < 0)
1525                 return -1;
1526
1527         pos = hdr.payload + hdr.length;
1528         if (pos < end) {
1529                 wpa_hexdump(MSG_DEBUG,
1530                             "X509: Ignored extra tbsCertificate data",
1531                             pos, end - pos);
1532         }
1533
1534         return 0;
1535 }
1536
1537
1538 static int x509_rsadsi_oid(struct asn1_oid *oid)
1539 {
1540         return oid->len >= 4 &&
1541                 oid->oid[0] == 1 /* iso */ &&
1542                 oid->oid[1] == 2 /* member-body */ &&
1543                 oid->oid[2] == 840 /* us */ &&
1544                 oid->oid[3] == 113549 /* rsadsi */;
1545 }
1546
1547
1548 static int x509_pkcs_oid(struct asn1_oid *oid)
1549 {
1550         return oid->len >= 5 &&
1551                 x509_rsadsi_oid(oid) &&
1552                 oid->oid[4] == 1 /* pkcs */;
1553 }
1554
1555
1556 static int x509_digest_oid(struct asn1_oid *oid)
1557 {
1558         return oid->len >= 5 &&
1559                 x509_rsadsi_oid(oid) &&
1560                 oid->oid[4] == 2 /* digestAlgorithm */;
1561 }
1562
1563
1564 int x509_sha1_oid(struct asn1_oid *oid)
1565 {
1566         return oid->len == 6 &&
1567                 oid->oid[0] == 1 /* iso */ &&
1568                 oid->oid[1] == 3 /* identified-organization */ &&
1569                 oid->oid[2] == 14 /* oiw */ &&
1570                 oid->oid[3] == 3 /* secsig */ &&
1571                 oid->oid[4] == 2 /* algorithms */ &&
1572                 oid->oid[5] == 26 /* id-sha1 */;
1573 }
1574
1575
1576 static int x509_sha2_oid(struct asn1_oid *oid)
1577 {
1578         return oid->len == 9 &&
1579                 oid->oid[0] == 2 /* joint-iso-itu-t */ &&
1580                 oid->oid[1] == 16 /* country */ &&
1581                 oid->oid[2] == 840 /* us */ &&
1582                 oid->oid[3] == 1 /* organization */ &&
1583                 oid->oid[4] == 101 /* gov */ &&
1584                 oid->oid[5] == 3 /* csor */ &&
1585                 oid->oid[6] == 4 /* nistAlgorithm */ &&
1586                 oid->oid[7] == 2 /* hashAlgs */;
1587 }
1588
1589
1590 int x509_sha256_oid(struct asn1_oid *oid)
1591 {
1592         return x509_sha2_oid(oid) &&
1593                 oid->oid[8] == 1 /* sha256 */;
1594 }
1595
1596
1597 int x509_sha384_oid(struct asn1_oid *oid)
1598 {
1599         return x509_sha2_oid(oid) &&
1600                 oid->oid[8] == 2 /* sha384 */;
1601 }
1602
1603
1604 int x509_sha512_oid(struct asn1_oid *oid)
1605 {
1606         return x509_sha2_oid(oid) &&
1607                 oid->oid[8] == 3 /* sha512 */;
1608 }
1609
1610
1611 /**
1612  * x509_certificate_parse - Parse a X.509 certificate in DER format
1613  * @buf: Pointer to the X.509 certificate in DER format
1614  * @len: Buffer length
1615  * Returns: Pointer to the parsed certificate or %NULL on failure
1616  *
1617  * Caller is responsible for freeing the returned certificate by calling
1618  * x509_certificate_free().
1619  */
1620 struct x509_certificate * x509_certificate_parse(const u8 *buf, size_t len)
1621 {
1622         struct asn1_hdr hdr;
1623         const u8 *pos, *end, *hash_start;
1624         struct x509_certificate *cert;
1625
1626         cert = os_zalloc(sizeof(*cert) + len);
1627         if (cert == NULL)
1628                 return NULL;
1629         os_memcpy(cert + 1, buf, len);
1630         cert->cert_start = (u8 *) (cert + 1);
1631         cert->cert_len = len;
1632
1633         pos = buf;
1634         end = buf + len;
1635
1636         /* RFC 3280 - X.509 v3 certificate / ASN.1 DER */
1637
1638         /* Certificate ::= SEQUENCE */
1639         if (asn1_get_next(pos, len, &hdr) < 0 ||
1640             hdr.class != ASN1_CLASS_UNIVERSAL ||
1641             hdr.tag != ASN1_TAG_SEQUENCE) {
1642                 wpa_printf(MSG_DEBUG, "X509: Certificate did not start with "
1643                            "a valid SEQUENCE - found class %d tag 0x%x",
1644                            hdr.class, hdr.tag);
1645                 x509_certificate_free(cert);
1646                 return NULL;
1647         }
1648         pos = hdr.payload;
1649
1650         if (hdr.length > end - pos) {
1651                 x509_certificate_free(cert);
1652                 return NULL;
1653         }
1654
1655         if (hdr.length < end - pos) {
1656                 wpa_hexdump(MSG_MSGDUMP, "X509: Ignoring extra data after DER "
1657                             "encoded certificate",
1658                             pos + hdr.length, end - (pos + hdr.length));
1659                 end = pos + hdr.length;
1660         }
1661
1662         hash_start = pos;
1663         cert->tbs_cert_start = cert->cert_start + (hash_start - buf);
1664         if (x509_parse_tbs_certificate(pos, end - pos, cert, &pos)) {
1665                 x509_certificate_free(cert);
1666                 return NULL;
1667         }
1668         cert->tbs_cert_len = pos - hash_start;
1669
1670         /* signatureAlgorithm AlgorithmIdentifier */
1671         if (x509_parse_algorithm_identifier(pos, end - pos,
1672                                             &cert->signature_alg, &pos)) {
1673                 x509_certificate_free(cert);
1674                 return NULL;
1675         }
1676
1677         /* signatureValue BIT STRING */
1678         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1679             hdr.class != ASN1_CLASS_UNIVERSAL ||
1680             hdr.tag != ASN1_TAG_BITSTRING) {
1681                 wpa_printf(MSG_DEBUG, "X509: Expected BITSTRING "
1682                            "(signatureValue) - found class %d tag 0x%x",
1683                            hdr.class, hdr.tag);
1684                 x509_certificate_free(cert);
1685                 return NULL;
1686         }
1687         if (hdr.length < 1) {
1688                 x509_certificate_free(cert);
1689                 return NULL;
1690         }
1691         pos = hdr.payload;
1692         if (*pos) {
1693                 wpa_printf(MSG_DEBUG, "X509: BITSTRING - %d unused bits",
1694                            *pos);
1695                 /* PKCS #1 v1.5 10.2.1:
1696                  * It is an error if the length in bits of the signature S is
1697                  * not a multiple of eight.
1698                  */
1699                 x509_certificate_free(cert);
1700                 return NULL;
1701         }
1702         os_free(cert->sign_value);
1703         cert->sign_value = os_malloc(hdr.length - 1);
1704         if (cert->sign_value == NULL) {
1705                 wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for "
1706                            "signatureValue");
1707                 x509_certificate_free(cert);
1708                 return NULL;
1709         }
1710         os_memcpy(cert->sign_value, pos + 1, hdr.length - 1);
1711         cert->sign_value_len = hdr.length - 1;
1712         wpa_hexdump(MSG_MSGDUMP, "X509: signature",
1713                     cert->sign_value, cert->sign_value_len);
1714
1715         return cert;
1716 }
1717
1718
1719 /**
1720  * x509_certificate_check_signature - Verify certificate signature
1721  * @issuer: Issuer certificate
1722  * @cert: Certificate to be verified
1723  * Returns: 0 if cert has a valid signature that was signed by the issuer,
1724  * -1 if not
1725  */
1726 int x509_certificate_check_signature(struct x509_certificate *issuer,
1727                                      struct x509_certificate *cert)
1728 {
1729         return x509_check_signature(issuer, &cert->signature,
1730                                     cert->sign_value, cert->sign_value_len,
1731                                     cert->tbs_cert_start, cert->tbs_cert_len);
1732 }
1733
1734
1735 int x509_check_signature(struct x509_certificate *issuer,
1736                          struct x509_algorithm_identifier *signature,
1737                          const u8 *sign_value, size_t sign_value_len,
1738                          const u8 *signed_data, size_t signed_data_len)
1739 {
1740         struct crypto_public_key *pk;
1741         u8 *data;
1742         const u8 *pos, *end, *next, *da_end;
1743         size_t data_len;
1744         struct asn1_hdr hdr;
1745         struct asn1_oid oid;
1746         u8 hash[64];
1747         size_t hash_len;
1748         const u8 *addr[1] = { signed_data };
1749         size_t len[1] = { signed_data_len };
1750
1751         if (!x509_pkcs_oid(&signature->oid) ||
1752             signature->oid.len != 7 ||
1753             signature->oid.oid[5] != 1 /* pkcs-1 */) {
1754                 wpa_printf(MSG_DEBUG, "X509: Unrecognized signature "
1755                            "algorithm");
1756                 return -1;
1757         }
1758
1759         pk = crypto_public_key_import(issuer->public_key,
1760                                       issuer->public_key_len);
1761         if (pk == NULL)
1762                 return -1;
1763
1764         data_len = sign_value_len;
1765         data = os_malloc(data_len);
1766         if (data == NULL) {
1767                 crypto_public_key_free(pk);
1768                 return -1;
1769         }
1770
1771         if (crypto_public_key_decrypt_pkcs1(pk, sign_value,
1772                                             sign_value_len, data,
1773                                             &data_len) < 0) {
1774                 wpa_printf(MSG_DEBUG, "X509: Failed to decrypt signature");
1775                 crypto_public_key_free(pk);
1776                 os_free(data);
1777                 return -1;
1778         }
1779         crypto_public_key_free(pk);
1780
1781         wpa_hexdump(MSG_MSGDUMP, "X509: Signature data D", data, data_len);
1782
1783         /*
1784          * PKCS #1 v1.5, 10.1.2:
1785          *
1786          * DigestInfo ::= SEQUENCE {
1787          *     digestAlgorithm DigestAlgorithmIdentifier,
1788          *     digest Digest
1789          * }
1790          *
1791          * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1792          *
1793          * Digest ::= OCTET STRING
1794          *
1795          */
1796         if (asn1_get_next(data, data_len, &hdr) < 0 ||
1797             hdr.class != ASN1_CLASS_UNIVERSAL ||
1798             hdr.tag != ASN1_TAG_SEQUENCE) {
1799                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
1800                            "(DigestInfo) - found class %d tag 0x%x",
1801                            hdr.class, hdr.tag);
1802                 os_free(data);
1803                 return -1;
1804         }
1805
1806         pos = hdr.payload;
1807         end = pos + hdr.length;
1808
1809         /*
1810          * X.509:
1811          * AlgorithmIdentifier ::= SEQUENCE {
1812          *     algorithm            OBJECT IDENTIFIER,
1813          *     parameters           ANY DEFINED BY algorithm OPTIONAL
1814          * }
1815          */
1816
1817         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1818             hdr.class != ASN1_CLASS_UNIVERSAL ||
1819             hdr.tag != ASN1_TAG_SEQUENCE) {
1820                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
1821                            "(AlgorithmIdentifier) - found class %d tag 0x%x",
1822                            hdr.class, hdr.tag);
1823                 os_free(data);
1824                 return -1;
1825         }
1826         da_end = hdr.payload + hdr.length;
1827
1828         if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {
1829                 wpa_printf(MSG_DEBUG, "X509: Failed to parse digestAlgorithm");
1830                 os_free(data);
1831                 return -1;
1832         }
1833
1834         if (x509_sha1_oid(&oid)) {
1835                 if (signature->oid.oid[6] != 5 /* sha-1WithRSAEncryption */) {
1836                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA1 "
1837                                    "does not match with certificate "
1838                                    "signatureAlgorithm (%lu)",
1839                                    signature->oid.oid[6]);
1840                         os_free(data);
1841                         return -1;
1842                 }
1843                 goto skip_digest_oid;
1844         }
1845
1846         if (x509_sha256_oid(&oid)) {
1847                 if (signature->oid.oid[6] !=
1848                     11 /* sha2561WithRSAEncryption */) {
1849                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA256 "
1850                                    "does not match with certificate "
1851                                    "signatureAlgorithm (%lu)",
1852                                    signature->oid.oid[6]);
1853                         os_free(data);
1854                         return -1;
1855                 }
1856                 goto skip_digest_oid;
1857         }
1858
1859         if (x509_sha384_oid(&oid)) {
1860                 if (signature->oid.oid[6] != 12 /* sha384WithRSAEncryption */) {
1861                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA384 "
1862                                    "does not match with certificate "
1863                                    "signatureAlgorithm (%lu)",
1864                                    signature->oid.oid[6]);
1865                         os_free(data);
1866                         return -1;
1867                 }
1868                 goto skip_digest_oid;
1869         }
1870
1871         if (x509_sha512_oid(&oid)) {
1872                 if (signature->oid.oid[6] != 13 /* sha512WithRSAEncryption */) {
1873                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA512 "
1874                                    "does not match with certificate "
1875                                    "signatureAlgorithm (%lu)",
1876                                    signature->oid.oid[6]);
1877                         os_free(data);
1878                         return -1;
1879                 }
1880                 goto skip_digest_oid;
1881         }
1882
1883         if (!x509_digest_oid(&oid)) {
1884                 wpa_printf(MSG_DEBUG, "X509: Unrecognized digestAlgorithm");
1885                 os_free(data);
1886                 return -1;
1887         }
1888         switch (oid.oid[5]) {
1889         case 5: /* md5 */
1890                 if (signature->oid.oid[6] != 4 /* md5WithRSAEncryption */) {
1891                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm MD5 does "
1892                                    "not match with certificate "
1893                                    "signatureAlgorithm (%lu)",
1894                                    signature->oid.oid[6]);
1895                         os_free(data);
1896                         return -1;
1897                 }
1898                 break;
1899         case 2: /* md2 */
1900         case 4: /* md4 */
1901         default:
1902                 wpa_printf(MSG_DEBUG, "X509: Unsupported digestAlgorithm "
1903                            "(%lu)", oid.oid[5]);
1904                 os_free(data);
1905                 return -1;
1906         }
1907
1908 skip_digest_oid:
1909         /* Digest ::= OCTET STRING */
1910         pos = da_end;
1911         end = data + data_len;
1912
1913         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1914             hdr.class != ASN1_CLASS_UNIVERSAL ||
1915             hdr.tag != ASN1_TAG_OCTETSTRING) {
1916                 wpa_printf(MSG_DEBUG, "X509: Expected OCTETSTRING "
1917                            "(Digest) - found class %d tag 0x%x",
1918                            hdr.class, hdr.tag);
1919                 os_free(data);
1920                 return -1;
1921         }
1922         wpa_hexdump(MSG_MSGDUMP, "X509: Decrypted Digest",
1923                     hdr.payload, hdr.length);
1924
1925         switch (signature->oid.oid[6]) {
1926         case 4: /* md5WithRSAEncryption */
1927                 md5_vector(1, addr, len, hash);
1928                 hash_len = 16;
1929                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (MD5)",
1930                             hash, hash_len);
1931                 break;
1932         case 5: /* sha-1WithRSAEncryption */
1933                 sha1_vector(1, addr, len, hash);
1934                 hash_len = 20;
1935                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA1)",
1936                             hash, hash_len);
1937                 break;
1938         case 11: /* sha256WithRSAEncryption */
1939                 sha256_vector(1, addr, len, hash);
1940                 hash_len = 32;
1941                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA256)",
1942                             hash, hash_len);
1943                 break;
1944         case 12: /* sha384WithRSAEncryption */
1945                 sha384_vector(1, addr, len, hash);
1946                 hash_len = 48;
1947                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA384)",
1948                             hash, hash_len);
1949                 break;
1950         case 13: /* sha512WithRSAEncryption */
1951                 sha512_vector(1, addr, len, hash);
1952                 hash_len = 64;
1953                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA512)",
1954                             hash, hash_len);
1955                 break;
1956         case 2: /* md2WithRSAEncryption */
1957         default:
1958                 wpa_printf(MSG_INFO, "X509: Unsupported certificate signature "
1959                            "algorithm (%lu)", signature->oid.oid[6]);
1960                 os_free(data);
1961                 return -1;
1962         }
1963
1964         if (hdr.length != hash_len ||
1965             os_memcmp_const(hdr.payload, hash, hdr.length) != 0) {
1966                 wpa_printf(MSG_INFO, "X509: Certificate Digest does not match "
1967                            "with calculated tbsCertificate hash");
1968                 os_free(data);
1969                 return -1;
1970         }
1971
1972         if (hdr.payload + hdr.length < data + data_len) {
1973                 wpa_hexdump(MSG_INFO,
1974                             "X509: Extra data after certificate signature hash",
1975                             hdr.payload + hdr.length,
1976                             data + data_len - hdr.payload - hdr.length);
1977                 os_free(data);
1978                 return -1;
1979         }
1980
1981         os_free(data);
1982
1983         wpa_printf(MSG_DEBUG, "X509: Certificate Digest matches with "
1984                    "calculated tbsCertificate hash");
1985
1986         return 0;
1987 }
1988
1989
1990 static int x509_valid_issuer(const struct x509_certificate *cert)
1991 {
1992         if ((cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS) &&
1993             !cert->ca) {
1994                 wpa_printf(MSG_DEBUG, "X509: Non-CA certificate used as an "
1995                            "issuer");
1996                 return -1;
1997         }
1998
1999         if (cert->version == X509_CERT_V3 &&
2000             !(cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS)) {
2001                 wpa_printf(MSG_DEBUG, "X509: v3 CA certificate did not "
2002                            "include BasicConstraints extension");
2003                 return -1;
2004         }
2005
2006         if ((cert->extensions_present & X509_EXT_KEY_USAGE) &&
2007             !(cert->key_usage & X509_KEY_USAGE_KEY_CERT_SIGN)) {
2008                 wpa_printf(MSG_DEBUG, "X509: Issuer certificate did not have "
2009                            "keyCertSign bit in Key Usage");
2010                 return -1;
2011         }
2012
2013         return 0;
2014 }
2015
2016
2017 /**
2018  * x509_certificate_chain_validate - Validate X.509 certificate chain
2019  * @trusted: List of trusted certificates
2020  * @chain: Certificate chain to be validated (first chain must be issued by
2021  * signed by the second certificate in the chain and so on)
2022  * @reason: Buffer for returning failure reason (X509_VALIDATE_*)
2023  * Returns: 0 if chain is valid, -1 if not
2024  */
2025 int x509_certificate_chain_validate(struct x509_certificate *trusted,
2026                                     struct x509_certificate *chain,
2027                                     int *reason, int disable_time_checks)
2028 {
2029         long unsigned idx;
2030         int chain_trusted = 0;
2031         struct x509_certificate *cert, *trust;
2032         char buf[128];
2033         struct os_time now;
2034
2035         *reason = X509_VALIDATE_OK;
2036
2037         wpa_printf(MSG_DEBUG, "X509: Validate certificate chain");
2038         os_get_time(&now);
2039
2040         for (cert = chain, idx = 0; cert; cert = cert->next, idx++) {
2041                 cert->issuer_trusted = 0;
2042                 x509_name_string(&cert->subject, buf, sizeof(buf)); 
2043                 wpa_printf(MSG_DEBUG, "X509: %lu: %s", idx, buf);
2044
2045                 if (chain_trusted)
2046                         continue;
2047
2048                 if (!disable_time_checks &&
2049                     ((unsigned long) now.sec <
2050                      (unsigned long) cert->not_before ||
2051                      (unsigned long) now.sec >
2052                      (unsigned long) cert->not_after)) {
2053                         wpa_printf(MSG_INFO, "X509: Certificate not valid "
2054                                    "(now=%lu not_before=%lu not_after=%lu)",
2055                                    now.sec, cert->not_before, cert->not_after);
2056                         *reason = X509_VALIDATE_CERTIFICATE_EXPIRED;
2057                         return -1;
2058                 }
2059
2060                 if (cert->next) {
2061                         if (x509_name_compare(&cert->issuer,
2062                                               &cert->next->subject) != 0) {
2063                                 wpa_printf(MSG_DEBUG, "X509: Certificate "
2064                                            "chain issuer name mismatch");
2065                                 x509_name_string(&cert->issuer, buf,
2066                                                  sizeof(buf)); 
2067                                 wpa_printf(MSG_DEBUG, "X509: cert issuer: %s",
2068                                            buf);
2069                                 x509_name_string(&cert->next->subject, buf,
2070                                                  sizeof(buf)); 
2071                                 wpa_printf(MSG_DEBUG, "X509: next cert "
2072                                            "subject: %s", buf);
2073                                 *reason = X509_VALIDATE_CERTIFICATE_UNKNOWN;
2074                                 return -1;
2075                         }
2076
2077                         if (x509_valid_issuer(cert->next) < 0) {
2078                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2079                                 return -1;
2080                         }
2081
2082                         if ((cert->next->extensions_present &
2083                              X509_EXT_PATH_LEN_CONSTRAINT) &&
2084                             idx > cert->next->path_len_constraint) {
2085                                 wpa_printf(MSG_DEBUG, "X509: pathLenConstraint"
2086                                            " not met (idx=%lu issuer "
2087                                            "pathLenConstraint=%lu)", idx,
2088                                            cert->next->path_len_constraint);
2089                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2090                                 return -1;
2091                         }
2092
2093                         if (x509_certificate_check_signature(cert->next, cert)
2094                             < 0) {
2095                                 wpa_printf(MSG_DEBUG, "X509: Invalid "
2096                                            "certificate signature within "
2097                                            "chain");
2098                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2099                                 return -1;
2100                         }
2101                 }
2102
2103                 for (trust = trusted; trust; trust = trust->next) {
2104                         if (x509_name_compare(&cert->issuer, &trust->subject)
2105                             == 0)
2106                                 break;
2107                 }
2108
2109                 if (trust) {
2110                         wpa_printf(MSG_DEBUG, "X509: Found issuer from the "
2111                                    "list of trusted certificates");
2112                         if (x509_valid_issuer(trust) < 0) {
2113                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2114                                 return -1;
2115                         }
2116
2117                         if (x509_certificate_check_signature(trust, cert) < 0)
2118                         {
2119                                 wpa_printf(MSG_DEBUG, "X509: Invalid "
2120                                            "certificate signature");
2121                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2122                                 return -1;
2123                         }
2124
2125                         wpa_printf(MSG_DEBUG, "X509: Trusted certificate "
2126                                    "found to complete the chain");
2127                         cert->issuer_trusted = 1;
2128                         chain_trusted = 1;
2129                 }
2130         }
2131
2132         if (!chain_trusted) {
2133                 wpa_printf(MSG_DEBUG, "X509: Did not find any of the issuers "
2134                            "from the list of trusted certificates");
2135                 if (trusted) {
2136                         *reason = X509_VALIDATE_UNKNOWN_CA;
2137                         return -1;
2138                 }
2139                 wpa_printf(MSG_DEBUG, "X509: Certificate chain validation "
2140                            "disabled - ignore unknown CA issue");
2141         }
2142
2143         wpa_printf(MSG_DEBUG, "X509: Certificate chain valid");
2144
2145         return 0;
2146 }
2147
2148
2149 /**
2150  * x509_certificate_get_subject - Get a certificate based on Subject name
2151  * @chain: Certificate chain to search through
2152  * @name: Subject name to search for
2153  * Returns: Pointer to the certificate with the given Subject name or
2154  * %NULL on failure
2155  */
2156 struct x509_certificate *
2157 x509_certificate_get_subject(struct x509_certificate *chain,
2158                              struct x509_name *name)
2159 {
2160         struct x509_certificate *cert;
2161
2162         for (cert = chain; cert; cert = cert->next) {
2163                 if (x509_name_compare(&cert->subject, name) == 0)
2164                         return cert;
2165         }
2166         return NULL;
2167 }
2168
2169
2170 /**
2171  * x509_certificate_self_signed - Is the certificate self-signed?
2172  * @cert: Certificate
2173  * Returns: 1 if certificate is self-signed, 0 if not
2174  */
2175 int x509_certificate_self_signed(struct x509_certificate *cert)
2176 {
2177         return x509_name_compare(&cert->issuer, &cert->subject) == 0;
2178 }