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