]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa/src/tls/x509v3.c
Update hostapd/wpa_supplicant to 2.8 to fix multiple vulnerabilities.
[FreeBSD/FreeBSD.git] / contrib / wpa / 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_memdup(pos + 1, 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         cert->public_key_len = hdr.length - 1;
284         wpa_hexdump(MSG_MSGDUMP, "X509: subjectPublicKey",
285                     cert->public_key, cert->public_key_len);
286
287         return 0;
288 }
289
290
291 int x509_parse_name(const u8 *buf, size_t len, struct x509_name *name,
292                     const u8 **next)
293 {
294         struct asn1_hdr hdr;
295         const u8 *pos, *end, *set_pos, *set_end, *seq_pos, *seq_end;
296         struct asn1_oid oid;
297         char *val;
298
299         /*
300          * Name ::= CHOICE { RDNSequence }
301          * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
302          * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
303          * AttributeTypeAndValue ::= SEQUENCE {
304          *     type     AttributeType,
305          *     value    AttributeValue
306          * }
307          * AttributeType ::= OBJECT IDENTIFIER
308          * AttributeValue ::= ANY DEFINED BY AttributeType
309          */
310
311         if (asn1_get_next(buf, len, &hdr) < 0 ||
312             hdr.class != ASN1_CLASS_UNIVERSAL ||
313             hdr.tag != ASN1_TAG_SEQUENCE) {
314                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
315                            "(Name / RDNSequencer) - found class %d tag 0x%x",
316                            hdr.class, hdr.tag);
317                 return -1;
318         }
319         pos = hdr.payload;
320
321         if (hdr.length > buf + len - pos)
322                 return -1;
323
324         end = *next = pos + hdr.length;
325
326         while (pos < end) {
327                 enum x509_name_attr_type type;
328
329                 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
330                     hdr.class != ASN1_CLASS_UNIVERSAL ||
331                     hdr.tag != ASN1_TAG_SET) {
332                         wpa_printf(MSG_DEBUG, "X509: Expected SET "
333                                    "(RelativeDistinguishedName) - found class "
334                                    "%d tag 0x%x", hdr.class, hdr.tag);
335                         x509_free_name(name);
336                         return -1;
337                 }
338
339                 set_pos = hdr.payload;
340                 pos = set_end = hdr.payload + hdr.length;
341
342                 if (asn1_get_next(set_pos, set_end - set_pos, &hdr) < 0 ||
343                     hdr.class != ASN1_CLASS_UNIVERSAL ||
344                     hdr.tag != ASN1_TAG_SEQUENCE) {
345                         wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
346                                    "(AttributeTypeAndValue) - found class %d "
347                                    "tag 0x%x", hdr.class, hdr.tag);
348                         x509_free_name(name);
349                         return -1;
350                 }
351
352                 seq_pos = hdr.payload;
353                 seq_end = hdr.payload + hdr.length;
354
355                 if (asn1_get_oid(seq_pos, seq_end - seq_pos, &oid, &seq_pos)) {
356                         x509_free_name(name);
357                         return -1;
358                 }
359
360                 if (asn1_get_next(seq_pos, seq_end - seq_pos, &hdr) < 0 ||
361                     hdr.class != ASN1_CLASS_UNIVERSAL) {
362                         wpa_printf(MSG_DEBUG, "X509: Failed to parse "
363                                    "AttributeValue");
364                         x509_free_name(name);
365                         return -1;
366                 }
367
368                 /* RFC 3280:
369                  * MUST: country, organization, organizational-unit,
370                  * distinguished name qualifier, state or province name,
371                  * common name, serial number.
372                  * SHOULD: locality, title, surname, given name, initials,
373                  * pseudonym, generation qualifier.
374                  * MUST: domainComponent (RFC 2247).
375                  */
376                 type = X509_NAME_ATTR_NOT_USED;
377                 if (oid.len == 4 &&
378                     oid.oid[0] == 2 && oid.oid[1] == 5 && oid.oid[2] == 4) {
379                         /* id-at ::= 2.5.4 */
380                         switch (oid.oid[3]) {
381                         case 3:
382                                 /* commonName */
383                                 type = X509_NAME_ATTR_CN;
384                                 break;
385                         case 6:
386                                 /*  countryName */
387                                 type = X509_NAME_ATTR_C;
388                                 break;
389                         case 7:
390                                 /* localityName */
391                                 type = X509_NAME_ATTR_L;
392                                 break;
393                         case 8:
394                                 /* stateOrProvinceName */
395                                 type = X509_NAME_ATTR_ST;
396                                 break;
397                         case 10:
398                                 /* organizationName */
399                                 type = X509_NAME_ATTR_O;
400                                 break;
401                         case 11:
402                                 /* organizationalUnitName */
403                                 type = X509_NAME_ATTR_OU;
404                                 break;
405                         }
406                 } else if (oid.len == 7 &&
407                            oid.oid[0] == 1 && oid.oid[1] == 2 &&
408                            oid.oid[2] == 840 && oid.oid[3] == 113549 &&
409                            oid.oid[4] == 1 && oid.oid[5] == 9 &&
410                            oid.oid[6] == 1) {
411                         /* 1.2.840.113549.1.9.1 - e-mailAddress */
412                         os_free(name->email);
413                         name->email = os_malloc(hdr.length + 1);
414                         if (name->email == NULL) {
415                                 x509_free_name(name);
416                                 return -1;
417                         }
418                         os_memcpy(name->email, hdr.payload, hdr.length);
419                         name->email[hdr.length] = '\0';
420                         continue;
421                 } else if (oid.len == 7 &&
422                            oid.oid[0] == 0 && oid.oid[1] == 9 &&
423                            oid.oid[2] == 2342 && oid.oid[3] == 19200300 &&
424                            oid.oid[4] == 100 && oid.oid[5] == 1 &&
425                            oid.oid[6] == 25) {
426                         /* 0.9.2342.19200300.100.1.25 - domainComponent */
427                         type = X509_NAME_ATTR_DC;
428                 }
429
430                 if (type == X509_NAME_ATTR_NOT_USED) {
431                         wpa_hexdump(MSG_DEBUG, "X509: Unrecognized OID",
432                                     (u8 *) oid.oid,
433                                     oid.len * sizeof(oid.oid[0]));
434                         wpa_hexdump_ascii(MSG_MSGDUMP, "X509: Attribute Data",
435                                           hdr.payload, hdr.length);
436                         continue;
437                 }
438
439                 if (name->num_attr == X509_MAX_NAME_ATTRIBUTES) {
440                         wpa_printf(MSG_INFO, "X509: Too many Name attributes");
441                         x509_free_name(name);
442                         return -1;
443                 }
444
445                 val = dup_binstr(hdr.payload, hdr.length);
446                 if (val == NULL) {
447                         x509_free_name(name);
448                         return -1;
449                 }
450                 if (os_strlen(val) != hdr.length) {
451                         wpa_printf(MSG_INFO, "X509: Reject certificate with "
452                                    "embedded NUL byte in a string (%s[NUL])",
453                                    val);
454                         os_free(val);
455                         x509_free_name(name);
456                         return -1;
457                 }
458
459                 name->attr[name->num_attr].type = type;
460                 name->attr[name->num_attr].value = val;
461                 name->num_attr++;
462         }
463
464         return 0;
465 }
466
467
468 static char * x509_name_attr_str(enum x509_name_attr_type type)
469 {
470         switch (type) {
471         case X509_NAME_ATTR_NOT_USED:
472                 return "[N/A]";
473         case X509_NAME_ATTR_DC:
474                 return "DC";
475         case X509_NAME_ATTR_CN:
476                 return "CN";
477         case X509_NAME_ATTR_C:
478                 return "C";
479         case X509_NAME_ATTR_L:
480                 return "L";
481         case X509_NAME_ATTR_ST:
482                 return "ST";
483         case X509_NAME_ATTR_O:
484                 return "O";
485         case X509_NAME_ATTR_OU:
486                 return "OU";
487         }
488         return "?";
489 }
490
491
492 /**
493  * x509_name_string - Convert an X.509 certificate name into a string
494  * @name: Name to convert
495  * @buf: Buffer for the string
496  * @len: Maximum buffer length
497  */
498 void x509_name_string(struct x509_name *name, char *buf, size_t len)
499 {
500         char *pos, *end;
501         int ret;
502         size_t i;
503
504         if (len == 0)
505                 return;
506
507         pos = buf;
508         end = buf + len;
509
510         for (i = 0; i < name->num_attr; i++) {
511                 ret = os_snprintf(pos, end - pos, "%s=%s, ",
512                                   x509_name_attr_str(name->attr[i].type),
513                                   name->attr[i].value);
514                 if (os_snprintf_error(end - pos, ret))
515                         goto done;
516                 pos += ret;
517         }
518
519         if (pos > buf + 1 && pos[-1] == ' ' && pos[-2] == ',') {
520                 pos--;
521                 *pos = '\0';
522                 pos--;
523                 *pos = '\0';
524         }
525
526         if (name->email) {
527                 ret = os_snprintf(pos, end - pos, "/emailAddress=%s",
528                                   name->email);
529                 if (os_snprintf_error(end - pos, ret))
530                         goto done;
531                 pos += ret;
532         }
533
534 done:
535         if (pos < end)
536                 *pos = '\0';
537         end[-1] = '\0';
538 }
539
540
541 int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag, 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 (plen > (size_t) (buf + len - pos))
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_any_ext_key_usage_oid(struct asn1_oid *oid)
725 {
726         return oid->len == 6 &&
727                 x509_id_ce_oid(oid) &&
728                 oid->oid[3] == 37 /* extKeyUsage */ &&
729                 oid->oid[4] == 0 /* anyExtendedKeyUsage */;
730 }
731
732
733 static int x509_parse_ext_key_usage(struct x509_certificate *cert,
734                                     const u8 *pos, size_t len)
735 {
736         struct asn1_hdr hdr;
737
738         /*
739          * KeyUsage ::= BIT STRING {
740          *     digitalSignature        (0),
741          *     nonRepudiation          (1),
742          *     keyEncipherment         (2),
743          *     dataEncipherment        (3),
744          *     keyAgreement            (4),
745          *     keyCertSign             (5),
746          *     cRLSign                 (6),
747          *     encipherOnly            (7),
748          *     decipherOnly            (8) }
749          */
750
751         if (asn1_get_next(pos, len, &hdr) < 0 ||
752             hdr.class != ASN1_CLASS_UNIVERSAL ||
753             hdr.tag != ASN1_TAG_BITSTRING ||
754             hdr.length < 1) {
755                 wpa_printf(MSG_DEBUG, "X509: Expected BIT STRING in "
756                            "KeyUsage; found %d tag 0x%x len %d",
757                            hdr.class, hdr.tag, hdr.length);
758                 return -1;
759         }
760
761         cert->extensions_present |= X509_EXT_KEY_USAGE;
762         cert->key_usage = asn1_bit_string_to_long(hdr.payload, hdr.length);
763
764         wpa_printf(MSG_DEBUG, "X509: KeyUsage 0x%lx", cert->key_usage);
765
766         return 0;
767 }
768
769
770 static int x509_parse_ext_basic_constraints(struct x509_certificate *cert,
771                                             const u8 *pos, size_t len)
772 {
773         struct asn1_hdr hdr;
774         unsigned long value;
775         size_t left;
776
777         /*
778          * BasicConstraints ::= SEQUENCE {
779          * cA                      BOOLEAN DEFAULT FALSE,
780          * pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
781          */
782
783         if (asn1_get_next(pos, len, &hdr) < 0 ||
784             hdr.class != ASN1_CLASS_UNIVERSAL ||
785             hdr.tag != ASN1_TAG_SEQUENCE) {
786                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE in "
787                            "BasicConstraints; found %d tag 0x%x",
788                            hdr.class, hdr.tag);
789                 return -1;
790         }
791
792         cert->extensions_present |= X509_EXT_BASIC_CONSTRAINTS;
793
794         if (hdr.length == 0)
795                 return 0;
796
797         if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
798             hdr.class != ASN1_CLASS_UNIVERSAL) {
799                 wpa_printf(MSG_DEBUG, "X509: Failed to parse "
800                            "BasicConstraints");
801                 return -1;
802         }
803
804         if (hdr.tag == ASN1_TAG_BOOLEAN) {
805                 if (hdr.length != 1) {
806                         wpa_printf(MSG_DEBUG, "X509: Unexpected "
807                                    "Boolean length (%u) in BasicConstraints",
808                                    hdr.length);
809                         return -1;
810                 }
811                 cert->ca = hdr.payload[0];
812
813                 if (hdr.length == pos + len - hdr.payload) {
814                         wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d",
815                                    cert->ca);
816                         return 0;
817                 }
818
819                 if (asn1_get_next(hdr.payload + hdr.length, len - hdr.length,
820                                   &hdr) < 0 ||
821                     hdr.class != ASN1_CLASS_UNIVERSAL) {
822                         wpa_printf(MSG_DEBUG, "X509: Failed to parse "
823                                    "BasicConstraints");
824                         return -1;
825                 }
826         }
827
828         if (hdr.tag != ASN1_TAG_INTEGER) {
829                 wpa_printf(MSG_DEBUG, "X509: Expected INTEGER in "
830                            "BasicConstraints; found class %d tag 0x%x",
831                            hdr.class, hdr.tag);
832                 return -1;
833         }
834
835         pos = hdr.payload;
836         left = hdr.length;
837         value = 0;
838         while (left) {
839                 value <<= 8;
840                 value |= *pos++;
841                 left--;
842         }
843
844         cert->path_len_constraint = value;
845         cert->extensions_present |= X509_EXT_PATH_LEN_CONSTRAINT;
846
847         wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d "
848                    "pathLenConstraint=%lu",
849                    cert->ca, cert->path_len_constraint);
850
851         return 0;
852 }
853
854
855 static int x509_parse_alt_name_rfc8222(struct x509_name *name,
856                                        const u8 *pos, size_t len)
857 {
858         /* rfc822Name IA5String */
859         wpa_hexdump_ascii(MSG_MSGDUMP, "X509: altName - rfc822Name", pos, len);
860         os_free(name->alt_email);
861         name->alt_email = os_zalloc(len + 1);
862         if (name->alt_email == NULL)
863                 return -1;
864         os_memcpy(name->alt_email, pos, len);
865         if (os_strlen(name->alt_email) != len) {
866                 wpa_printf(MSG_INFO, "X509: Reject certificate with "
867                            "embedded NUL byte in rfc822Name (%s[NUL])",
868                            name->alt_email);
869                 os_free(name->alt_email);
870                 name->alt_email = NULL;
871                 return -1;
872         }
873         return 0;
874 }
875
876
877 static int x509_parse_alt_name_dns(struct x509_name *name,
878                                    const u8 *pos, size_t len)
879 {
880         /* dNSName IA5String */
881         wpa_hexdump_ascii(MSG_MSGDUMP, "X509: altName - dNSName", pos, len);
882         os_free(name->dns);
883         name->dns = os_zalloc(len + 1);
884         if (name->dns == NULL)
885                 return -1;
886         os_memcpy(name->dns, pos, len);
887         if (os_strlen(name->dns) != len) {
888                 wpa_printf(MSG_INFO, "X509: Reject certificate with "
889                            "embedded NUL byte in dNSName (%s[NUL])",
890                            name->dns);
891                 os_free(name->dns);
892                 name->dns = NULL;
893                 return -1;
894         }
895         return 0;
896 }
897
898
899 static int x509_parse_alt_name_uri(struct x509_name *name,
900                                    const u8 *pos, size_t len)
901 {
902         /* uniformResourceIdentifier IA5String */
903         wpa_hexdump_ascii(MSG_MSGDUMP,
904                           "X509: altName - uniformResourceIdentifier",
905                           pos, len);
906         os_free(name->uri);
907         name->uri = os_zalloc(len + 1);
908         if (name->uri == NULL)
909                 return -1;
910         os_memcpy(name->uri, pos, len);
911         if (os_strlen(name->uri) != len) {
912                 wpa_printf(MSG_INFO, "X509: Reject certificate with "
913                            "embedded NUL byte in uniformResourceIdentifier "
914                            "(%s[NUL])", name->uri);
915                 os_free(name->uri);
916                 name->uri = NULL;
917                 return -1;
918         }
919         return 0;
920 }
921
922
923 static int x509_parse_alt_name_ip(struct x509_name *name,
924                                        const u8 *pos, size_t len)
925 {
926         /* iPAddress OCTET STRING */
927         wpa_hexdump(MSG_MSGDUMP, "X509: altName - iPAddress", pos, len);
928         os_free(name->ip);
929         name->ip = os_memdup(pos, len);
930         if (name->ip == NULL)
931                 return -1;
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_memdup(pos + 1, 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         cert->sign_value_len = hdr.length - 1;
1711         wpa_hexdump(MSG_MSGDUMP, "X509: signature",
1712                     cert->sign_value, cert->sign_value_len);
1713
1714         return cert;
1715 }
1716
1717
1718 /**
1719  * x509_certificate_check_signature - Verify certificate signature
1720  * @issuer: Issuer certificate
1721  * @cert: Certificate to be verified
1722  * Returns: 0 if cert has a valid signature that was signed by the issuer,
1723  * -1 if not
1724  */
1725 int x509_certificate_check_signature(struct x509_certificate *issuer,
1726                                      struct x509_certificate *cert)
1727 {
1728         return x509_check_signature(issuer, &cert->signature,
1729                                     cert->sign_value, cert->sign_value_len,
1730                                     cert->tbs_cert_start, cert->tbs_cert_len);
1731 }
1732
1733
1734 int x509_check_signature(struct x509_certificate *issuer,
1735                          struct x509_algorithm_identifier *signature,
1736                          const u8 *sign_value, size_t sign_value_len,
1737                          const u8 *signed_data, size_t signed_data_len)
1738 {
1739         struct crypto_public_key *pk;
1740         u8 *data;
1741         const u8 *pos, *end, *next, *da_end;
1742         size_t data_len;
1743         struct asn1_hdr hdr;
1744         struct asn1_oid oid;
1745         u8 hash[64];
1746         size_t hash_len;
1747         const u8 *addr[1] = { signed_data };
1748         size_t len[1] = { signed_data_len };
1749
1750         if (!x509_pkcs_oid(&signature->oid) ||
1751             signature->oid.len != 7 ||
1752             signature->oid.oid[5] != 1 /* pkcs-1 */) {
1753                 wpa_printf(MSG_DEBUG, "X509: Unrecognized signature "
1754                            "algorithm");
1755                 return -1;
1756         }
1757
1758         pk = crypto_public_key_import(issuer->public_key,
1759                                       issuer->public_key_len);
1760         if (pk == NULL)
1761                 return -1;
1762
1763         data_len = sign_value_len;
1764         data = os_malloc(data_len);
1765         if (data == NULL) {
1766                 crypto_public_key_free(pk);
1767                 return -1;
1768         }
1769
1770         if (crypto_public_key_decrypt_pkcs1(pk, sign_value,
1771                                             sign_value_len, data,
1772                                             &data_len) < 0) {
1773                 wpa_printf(MSG_DEBUG, "X509: Failed to decrypt signature");
1774                 crypto_public_key_free(pk);
1775                 os_free(data);
1776                 return -1;
1777         }
1778         crypto_public_key_free(pk);
1779
1780         wpa_hexdump(MSG_MSGDUMP, "X509: Signature data D", data, data_len);
1781
1782         /*
1783          * PKCS #1 v1.5, 10.1.2:
1784          *
1785          * DigestInfo ::= SEQUENCE {
1786          *     digestAlgorithm DigestAlgorithmIdentifier,
1787          *     digest Digest
1788          * }
1789          *
1790          * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1791          *
1792          * Digest ::= OCTET STRING
1793          *
1794          */
1795         if (asn1_get_next(data, data_len, &hdr) < 0 ||
1796             hdr.class != ASN1_CLASS_UNIVERSAL ||
1797             hdr.tag != ASN1_TAG_SEQUENCE) {
1798                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
1799                            "(DigestInfo) - found class %d tag 0x%x",
1800                            hdr.class, hdr.tag);
1801                 os_free(data);
1802                 return -1;
1803         }
1804
1805         pos = hdr.payload;
1806         end = pos + hdr.length;
1807
1808         /*
1809          * X.509:
1810          * AlgorithmIdentifier ::= SEQUENCE {
1811          *     algorithm            OBJECT IDENTIFIER,
1812          *     parameters           ANY DEFINED BY algorithm OPTIONAL
1813          * }
1814          */
1815
1816         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1817             hdr.class != ASN1_CLASS_UNIVERSAL ||
1818             hdr.tag != ASN1_TAG_SEQUENCE) {
1819                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
1820                            "(AlgorithmIdentifier) - found class %d tag 0x%x",
1821                            hdr.class, hdr.tag);
1822                 os_free(data);
1823                 return -1;
1824         }
1825         da_end = hdr.payload + hdr.length;
1826
1827         if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {
1828                 wpa_printf(MSG_DEBUG, "X509: Failed to parse digestAlgorithm");
1829                 os_free(data);
1830                 return -1;
1831         }
1832
1833         if (x509_sha1_oid(&oid)) {
1834                 if (signature->oid.oid[6] != 5 /* sha-1WithRSAEncryption */) {
1835                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA1 "
1836                                    "does not match with certificate "
1837                                    "signatureAlgorithm (%lu)",
1838                                    signature->oid.oid[6]);
1839                         os_free(data);
1840                         return -1;
1841                 }
1842                 goto skip_digest_oid;
1843         }
1844
1845         if (x509_sha256_oid(&oid)) {
1846                 if (signature->oid.oid[6] !=
1847                     11 /* sha2561WithRSAEncryption */) {
1848                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA256 "
1849                                    "does not match with certificate "
1850                                    "signatureAlgorithm (%lu)",
1851                                    signature->oid.oid[6]);
1852                         os_free(data);
1853                         return -1;
1854                 }
1855                 goto skip_digest_oid;
1856         }
1857
1858         if (x509_sha384_oid(&oid)) {
1859                 if (signature->oid.oid[6] != 12 /* sha384WithRSAEncryption */) {
1860                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA384 "
1861                                    "does not match with certificate "
1862                                    "signatureAlgorithm (%lu)",
1863                                    signature->oid.oid[6]);
1864                         os_free(data);
1865                         return -1;
1866                 }
1867                 goto skip_digest_oid;
1868         }
1869
1870         if (x509_sha512_oid(&oid)) {
1871                 if (signature->oid.oid[6] != 13 /* sha512WithRSAEncryption */) {
1872                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA512 "
1873                                    "does not match with certificate "
1874                                    "signatureAlgorithm (%lu)",
1875                                    signature->oid.oid[6]);
1876                         os_free(data);
1877                         return -1;
1878                 }
1879                 goto skip_digest_oid;
1880         }
1881
1882         if (!x509_digest_oid(&oid)) {
1883                 wpa_printf(MSG_DEBUG, "X509: Unrecognized digestAlgorithm");
1884                 os_free(data);
1885                 return -1;
1886         }
1887         switch (oid.oid[5]) {
1888         case 5: /* md5 */
1889                 if (signature->oid.oid[6] != 4 /* md5WithRSAEncryption */) {
1890                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm MD5 does "
1891                                    "not match with certificate "
1892                                    "signatureAlgorithm (%lu)",
1893                                    signature->oid.oid[6]);
1894                         os_free(data);
1895                         return -1;
1896                 }
1897                 break;
1898         case 2: /* md2 */
1899         case 4: /* md4 */
1900         default:
1901                 wpa_printf(MSG_DEBUG, "X509: Unsupported digestAlgorithm "
1902                            "(%lu)", oid.oid[5]);
1903                 os_free(data);
1904                 return -1;
1905         }
1906
1907 skip_digest_oid:
1908         /* Digest ::= OCTET STRING */
1909         pos = da_end;
1910         end = data + data_len;
1911
1912         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1913             hdr.class != ASN1_CLASS_UNIVERSAL ||
1914             hdr.tag != ASN1_TAG_OCTETSTRING) {
1915                 wpa_printf(MSG_DEBUG, "X509: Expected OCTETSTRING "
1916                            "(Digest) - found class %d tag 0x%x",
1917                            hdr.class, hdr.tag);
1918                 os_free(data);
1919                 return -1;
1920         }
1921         wpa_hexdump(MSG_MSGDUMP, "X509: Decrypted Digest",
1922                     hdr.payload, hdr.length);
1923
1924         switch (signature->oid.oid[6]) {
1925         case 4: /* md5WithRSAEncryption */
1926                 md5_vector(1, addr, len, hash);
1927                 hash_len = 16;
1928                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (MD5)",
1929                             hash, hash_len);
1930                 break;
1931         case 5: /* sha-1WithRSAEncryption */
1932                 sha1_vector(1, addr, len, hash);
1933                 hash_len = 20;
1934                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA1)",
1935                             hash, hash_len);
1936                 break;
1937         case 11: /* sha256WithRSAEncryption */
1938                 sha256_vector(1, addr, len, hash);
1939                 hash_len = 32;
1940                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA256)",
1941                             hash, hash_len);
1942                 break;
1943         case 12: /* sha384WithRSAEncryption */
1944                 sha384_vector(1, addr, len, hash);
1945                 hash_len = 48;
1946                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA384)",
1947                             hash, hash_len);
1948                 break;
1949         case 13: /* sha512WithRSAEncryption */
1950                 sha512_vector(1, addr, len, hash);
1951                 hash_len = 64;
1952                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA512)",
1953                             hash, hash_len);
1954                 break;
1955         case 2: /* md2WithRSAEncryption */
1956         default:
1957                 wpa_printf(MSG_INFO, "X509: Unsupported certificate signature "
1958                            "algorithm (%lu)", signature->oid.oid[6]);
1959                 os_free(data);
1960                 return -1;
1961         }
1962
1963         if (hdr.length != hash_len ||
1964             os_memcmp_const(hdr.payload, hash, hdr.length) != 0) {
1965                 wpa_printf(MSG_INFO, "X509: Certificate Digest does not match "
1966                            "with calculated tbsCertificate hash");
1967                 os_free(data);
1968                 return -1;
1969         }
1970
1971         if (hdr.payload + hdr.length < data + data_len) {
1972                 wpa_hexdump(MSG_INFO,
1973                             "X509: Extra data after certificate signature hash",
1974                             hdr.payload + hdr.length,
1975                             data + data_len - hdr.payload - hdr.length);
1976                 os_free(data);
1977                 return -1;
1978         }
1979
1980         os_free(data);
1981
1982         wpa_printf(MSG_DEBUG, "X509: Certificate Digest matches with "
1983                    "calculated tbsCertificate hash");
1984
1985         return 0;
1986 }
1987
1988
1989 static int x509_valid_issuer(const struct x509_certificate *cert)
1990 {
1991         if ((cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS) &&
1992             !cert->ca) {
1993                 wpa_printf(MSG_DEBUG, "X509: Non-CA certificate used as an "
1994                            "issuer");
1995                 return -1;
1996         }
1997
1998         if (cert->version == X509_CERT_V3 &&
1999             !(cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS)) {
2000                 wpa_printf(MSG_DEBUG, "X509: v3 CA certificate did not "
2001                            "include BasicConstraints extension");
2002                 return -1;
2003         }
2004
2005         if ((cert->extensions_present & X509_EXT_KEY_USAGE) &&
2006             !(cert->key_usage & X509_KEY_USAGE_KEY_CERT_SIGN)) {
2007                 wpa_printf(MSG_DEBUG, "X509: Issuer certificate did not have "
2008                            "keyCertSign bit in Key Usage");
2009                 return -1;
2010         }
2011
2012         return 0;
2013 }
2014
2015
2016 /**
2017  * x509_certificate_chain_validate - Validate X.509 certificate chain
2018  * @trusted: List of trusted certificates
2019  * @chain: Certificate chain to be validated (first chain must be issued by
2020  * signed by the second certificate in the chain and so on)
2021  * @reason: Buffer for returning failure reason (X509_VALIDATE_*)
2022  * Returns: 0 if chain is valid, -1 if not
2023  */
2024 int x509_certificate_chain_validate(struct x509_certificate *trusted,
2025                                     struct x509_certificate *chain,
2026                                     int *reason, int disable_time_checks)
2027 {
2028         long unsigned idx;
2029         int chain_trusted = 0;
2030         struct x509_certificate *cert, *trust;
2031         char buf[128];
2032         struct os_time now;
2033
2034         *reason = X509_VALIDATE_OK;
2035
2036         wpa_printf(MSG_DEBUG, "X509: Validate certificate chain");
2037         os_get_time(&now);
2038
2039         for (cert = chain, idx = 0; cert; cert = cert->next, idx++) {
2040                 cert->issuer_trusted = 0;
2041                 x509_name_string(&cert->subject, buf, sizeof(buf));
2042                 wpa_printf(MSG_DEBUG, "X509: %lu: %s", idx, buf);
2043
2044                 if (chain_trusted)
2045                         continue;
2046
2047                 if (!disable_time_checks &&
2048                     ((unsigned long) now.sec <
2049                      (unsigned long) cert->not_before ||
2050                      (unsigned long) now.sec >
2051                      (unsigned long) cert->not_after)) {
2052                         wpa_printf(MSG_INFO, "X509: Certificate not valid "
2053                                    "(now=%lu not_before=%lu not_after=%lu)",
2054                                    now.sec, cert->not_before, cert->not_after);
2055                         *reason = X509_VALIDATE_CERTIFICATE_EXPIRED;
2056                         return -1;
2057                 }
2058
2059                 if (cert->next) {
2060                         if (x509_name_compare(&cert->issuer,
2061                                               &cert->next->subject) != 0) {
2062                                 wpa_printf(MSG_DEBUG, "X509: Certificate "
2063                                            "chain issuer name mismatch");
2064                                 x509_name_string(&cert->issuer, buf,
2065                                                  sizeof(buf));
2066                                 wpa_printf(MSG_DEBUG, "X509: cert issuer: %s",
2067                                            buf);
2068                                 x509_name_string(&cert->next->subject, buf,
2069                                                  sizeof(buf));
2070                                 wpa_printf(MSG_DEBUG, "X509: next cert "
2071                                            "subject: %s", buf);
2072                                 *reason = X509_VALIDATE_CERTIFICATE_UNKNOWN;
2073                                 return -1;
2074                         }
2075
2076                         if (x509_valid_issuer(cert->next) < 0) {
2077                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2078                                 return -1;
2079                         }
2080
2081                         if ((cert->next->extensions_present &
2082                              X509_EXT_PATH_LEN_CONSTRAINT) &&
2083                             idx > cert->next->path_len_constraint) {
2084                                 wpa_printf(MSG_DEBUG, "X509: pathLenConstraint"
2085                                            " not met (idx=%lu issuer "
2086                                            "pathLenConstraint=%lu)", idx,
2087                                            cert->next->path_len_constraint);
2088                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2089                                 return -1;
2090                         }
2091
2092                         if (x509_certificate_check_signature(cert->next, cert)
2093                             < 0) {
2094                                 wpa_printf(MSG_DEBUG, "X509: Invalid "
2095                                            "certificate signature within "
2096                                            "chain");
2097                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2098                                 return -1;
2099                         }
2100                 }
2101
2102                 for (trust = trusted; trust; trust = trust->next) {
2103                         if (x509_name_compare(&cert->issuer, &trust->subject)
2104                             == 0)
2105                                 break;
2106                 }
2107
2108                 if (trust) {
2109                         wpa_printf(MSG_DEBUG, "X509: Found issuer from the "
2110                                    "list of trusted certificates");
2111                         if (x509_valid_issuer(trust) < 0) {
2112                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2113                                 return -1;
2114                         }
2115
2116                         if (x509_certificate_check_signature(trust, cert) < 0)
2117                         {
2118                                 wpa_printf(MSG_DEBUG, "X509: Invalid "
2119                                            "certificate signature");
2120                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
2121                                 return -1;
2122                         }
2123
2124                         wpa_printf(MSG_DEBUG, "X509: Trusted certificate "
2125                                    "found to complete the chain");
2126                         cert->issuer_trusted = 1;
2127                         chain_trusted = 1;
2128                 }
2129         }
2130
2131         if (!chain_trusted) {
2132                 wpa_printf(MSG_DEBUG, "X509: Did not find any of the issuers "
2133                            "from the list of trusted certificates");
2134                 if (trusted) {
2135                         *reason = X509_VALIDATE_UNKNOWN_CA;
2136                         return -1;
2137                 }
2138                 wpa_printf(MSG_DEBUG, "X509: Certificate chain validation "
2139                            "disabled - ignore unknown CA issue");
2140         }
2141
2142         wpa_printf(MSG_DEBUG, "X509: Certificate chain valid");
2143
2144         return 0;
2145 }
2146
2147
2148 /**
2149  * x509_certificate_get_subject - Get a certificate based on Subject name
2150  * @chain: Certificate chain to search through
2151  * @name: Subject name to search for
2152  * Returns: Pointer to the certificate with the given Subject name or
2153  * %NULL on failure
2154  */
2155 struct x509_certificate *
2156 x509_certificate_get_subject(struct x509_certificate *chain,
2157                              struct x509_name *name)
2158 {
2159         struct x509_certificate *cert;
2160
2161         for (cert = chain; cert; cert = cert->next) {
2162                 if (x509_name_compare(&cert->subject, name) == 0)
2163                         return cert;
2164         }
2165         return NULL;
2166 }
2167
2168
2169 /**
2170  * x509_certificate_self_signed - Is the certificate self-signed?
2171  * @cert: Certificate
2172  * Returns: 1 if certificate is self-signed, 0 if not
2173  */
2174 int x509_certificate_self_signed(struct x509_certificate *cert)
2175 {
2176         return x509_name_compare(&cert->issuer, &cert->subject) == 0;
2177 }