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