]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - contrib/wpa_supplicant/x509v3.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / contrib / wpa_supplicant / x509v3.c
1 /*
2  * X.509v3 certificate parsing and processing (RFC 3280 profile)
3  * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "includes.h"
16
17 #include "common.h"
18
19 #ifdef CONFIG_INTERNAL_X509
20
21 #include "asn1.h"
22 #include "crypto.h"
23 #include "x509v3.h"
24
25
26 static void x509_free_name(struct x509_name *name)
27 {
28         os_free(name->cn);
29         os_free(name->c);
30         os_free(name->l);
31         os_free(name->st);
32         os_free(name->o);
33         os_free(name->ou);
34         os_free(name->email);
35         name->cn = name->c = name->l = name->st = name->o = name->ou = NULL;
36         name->email = NULL;
37 }
38
39
40 /**
41  * x509_certificate_free - Free an X.509 certificate
42  * @cert: Certificate to be freed
43  */
44 void x509_certificate_free(struct x509_certificate *cert)
45 {
46         if (cert == NULL)
47                 return;
48         if (cert->next) {
49                 wpa_printf(MSG_DEBUG, "X509: x509_certificate_free: cer=%p "
50                            "was still on a list (next=%p)\n",
51                            cert, cert->next);
52         }
53         x509_free_name(&cert->issuer);
54         x509_free_name(&cert->subject);
55         os_free(cert->public_key);
56         os_free(cert->sign_value);
57         os_free(cert);
58 }
59
60
61 /**
62  * x509_certificate_free - Free an X.509 certificate chain
63  * @cert: Pointer to the first certificate in the chain
64  */
65 void x509_certificate_chain_free(struct x509_certificate *cert)
66 {
67         struct x509_certificate *next;
68
69         while (cert) {
70                 next = cert->next;
71                 cert->next = NULL;
72                 x509_certificate_free(cert);
73                 cert = next;
74         }
75 }
76
77
78 static int x509_whitespace(char c)
79 {
80         return c == ' ' || c == '\t';
81 }
82
83
84 static void x509_str_strip_whitespace(char *a)
85 {
86         char *ipos, *opos;
87         int remove_whitespace = 1;
88
89         ipos = opos = a;
90
91         while (*ipos) {
92                 if (remove_whitespace && x509_whitespace(*ipos))
93                         ipos++;
94                 else {
95                         remove_whitespace = x509_whitespace(*ipos);
96                         *opos++ = *ipos++;
97                 }
98         }
99
100         *opos-- = '\0';
101         if (opos > a && x509_whitespace(*opos))
102                 *opos = '\0';
103 }
104
105
106 static int x509_str_compare(const char *a, const char *b)
107 {
108         char *aa, *bb;
109         int ret;
110
111         if (!a && b)
112                 return -1;
113         if (a && !b)
114                 return 1;
115         if (!a && !b)
116                 return 0;
117
118         aa = os_strdup(a);
119         bb = os_strdup(b);
120
121         if (aa == NULL || bb == NULL) {
122                 os_free(aa);
123                 os_free(bb);
124                 return os_strcasecmp(a, b);
125         }
126
127         x509_str_strip_whitespace(aa);
128         x509_str_strip_whitespace(bb);
129
130         ret = os_strcasecmp(aa, bb);
131
132         os_free(aa);
133         os_free(bb);
134
135         return ret;
136 }
137
138
139 /**
140  * x509_name_compare - Compare X.509 certificate names
141  * @a: Certificate name
142  * @b: Certificate name
143  * Returns: <0, 0, or >0 based on whether a is less than, equal to, or
144  * greater than b
145  */
146 int x509_name_compare(struct x509_name *a, struct x509_name *b)
147 {
148         int res;
149
150         if (!a && b)
151                 return -1;
152         if (a && !b)
153                 return 1;
154         if (!a && !b)
155                 return 0;
156
157         res = x509_str_compare(a->cn, b->cn);
158         if (res)
159                 return res;
160         res = x509_str_compare(a->c, b->c);
161         if (res)
162                 return res;
163         res = x509_str_compare(a->l, b->l);
164         if (res)
165                 return res;
166         res = x509_str_compare(a->st, b->st);
167         if (res)
168                 return res;
169         res = x509_str_compare(a->o, b->o);
170         if (res)
171                 return res;
172         res = x509_str_compare(a->ou, b->ou);
173         if (res)
174                 return res;
175         res = x509_str_compare(a->email, b->email);
176         if (res)
177                 return res;
178
179         return 0;
180 }
181
182
183 static int x509_parse_algorithm_identifier(
184         const u8 *buf, size_t len,
185         struct x509_algorithm_identifier *id, const u8 **next)
186 {
187         struct asn1_hdr hdr;
188         const u8 *pos, *end;
189
190         /*
191          * AlgorithmIdentifier ::= SEQUENCE {
192          *     algorithm            OBJECT IDENTIFIER,
193          *     parameters           ANY DEFINED BY algorithm OPTIONAL
194          * }
195          */
196
197         if (asn1_get_next(buf, len, &hdr) < 0 ||
198             hdr.class != ASN1_CLASS_UNIVERSAL ||
199             hdr.tag != ASN1_TAG_SEQUENCE) {
200                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
201                            "(AlgorithmIdentifier) - found class %d tag 0x%x",
202                            hdr.class, hdr.tag);
203                 return -1;
204         }
205         pos = hdr.payload;
206         end = pos + hdr.length;
207
208         if (end > buf + len)
209                 return -1;
210
211         *next = end;
212
213         if (asn1_get_oid(pos, end - pos, &id->oid, &pos))
214                 return -1;
215
216         /* TODO: optional parameters */
217
218         return 0;
219 }
220
221
222 static int x509_parse_public_key(const u8 *buf, size_t len,
223                                  struct x509_certificate *cert,
224                                  const u8 **next)
225 {
226         struct asn1_hdr hdr;
227         const u8 *pos, *end;
228
229         /*
230          * SubjectPublicKeyInfo ::= SEQUENCE {
231          *     algorithm            AlgorithmIdentifier,
232          *     subjectPublicKey     BIT STRING
233          * }
234          */
235
236         pos = buf;
237         end = buf + len;
238
239         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
240             hdr.class != ASN1_CLASS_UNIVERSAL ||
241             hdr.tag != ASN1_TAG_SEQUENCE) {
242                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
243                            "(SubjectPublicKeyInfo) - found class %d tag 0x%x",
244                            hdr.class, hdr.tag);
245                 return -1;
246         }
247         pos = hdr.payload;
248
249         if (pos + hdr.length > end)
250                 return -1;
251         end = pos + hdr.length;
252         *next = end;
253
254         if (x509_parse_algorithm_identifier(pos, end - pos,
255                                             &cert->public_key_alg, &pos))
256                 return -1;
257
258         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
259             hdr.class != ASN1_CLASS_UNIVERSAL ||
260             hdr.tag != ASN1_TAG_BITSTRING) {
261                 wpa_printf(MSG_DEBUG, "X509: Expected BITSTRING "
262                            "(subjectPublicKey) - found class %d tag 0x%x",
263                            hdr.class, hdr.tag);
264                 return -1;
265         }
266         if (hdr.length < 1)
267                 return -1;
268         pos = hdr.payload;
269         if (*pos) {
270                 wpa_printf(MSG_DEBUG, "X509: BITSTRING - %d unused bits",
271                            *pos);
272                 /*
273                  * TODO: should this be rejected? X.509 certificates are
274                  * unlikely to use such a construction. Now we would end up
275                  * including the extra bits in the buffer which may also be
276                  * ok.
277                  */
278         }
279         os_free(cert->public_key);
280         cert->public_key = os_malloc(hdr.length - 1);
281         if (cert->public_key == NULL) {
282                 wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for "
283                            "public key");
284                 return -1;
285         }
286         os_memcpy(cert->public_key, pos + 1, hdr.length - 1);
287         cert->public_key_len = hdr.length - 1;
288         wpa_hexdump(MSG_MSGDUMP, "X509: subjectPublicKey",
289                     cert->public_key, cert->public_key_len);
290
291         return 0;
292 }
293
294
295 static int x509_parse_name(const u8 *buf, size_t len, struct x509_name *name,
296                            const u8 **next)
297 {
298         struct asn1_hdr hdr;
299         const u8 *pos, *end, *set_pos, *set_end, *seq_pos, *seq_end;
300         struct asn1_oid oid;
301         char **fieldp;
302
303         /*
304          * Name ::= CHOICE { RDNSequence }
305          * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
306          * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
307          * AttributeTypeAndValue ::= SEQUENCE {
308          *     type     AttributeType,
309          *     value    AttributeValue
310          * }
311          * AttributeType ::= OBJECT IDENTIFIER
312          * AttributeValue ::= ANY DEFINED BY AttributeType
313          */
314
315         if (asn1_get_next(buf, len, &hdr) < 0 ||
316             hdr.class != ASN1_CLASS_UNIVERSAL ||
317             hdr.tag != ASN1_TAG_SEQUENCE) {
318                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
319                            "(Name / RDNSequencer) - found class %d tag 0x%x",
320                            hdr.class, hdr.tag);
321                 return -1;
322         }
323         pos = hdr.payload;
324
325         if (pos + hdr.length > buf + len)
326                 return -1;
327
328         end = *next = pos + hdr.length;
329
330         while (pos < end) {
331                 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
332                     hdr.class != ASN1_CLASS_UNIVERSAL ||
333                     hdr.tag != ASN1_TAG_SET) {
334                         wpa_printf(MSG_DEBUG, "X509: Expected SET "
335                                    "(RelativeDistinguishedName) - found class "
336                                    "%d tag 0x%x", hdr.class, hdr.tag);
337                         x509_free_name(name);
338                         return -1;
339                 }
340
341                 set_pos = hdr.payload;
342                 pos = set_end = hdr.payload + hdr.length;
343
344                 if (asn1_get_next(set_pos, set_end - set_pos, &hdr) < 0 ||
345                     hdr.class != ASN1_CLASS_UNIVERSAL ||
346                     hdr.tag != ASN1_TAG_SEQUENCE) {
347                         wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
348                                    "(AttributeTypeAndValue) - found class %d "
349                                    "tag 0x%x", hdr.class, hdr.tag);
350                         x509_free_name(name);
351                         return -1;
352                 }
353
354                 seq_pos = hdr.payload;
355                 seq_end = hdr.payload + hdr.length;
356
357                 if (asn1_get_oid(seq_pos, seq_end - seq_pos, &oid, &seq_pos)) {
358                         x509_free_name(name);
359                         return -1;
360                 }
361
362                 if (asn1_get_next(seq_pos, seq_end - seq_pos, &hdr) < 0 ||
363                     hdr.class != ASN1_CLASS_UNIVERSAL) {
364                         wpa_printf(MSG_DEBUG, "X509: Failed to parse "
365                                    "AttributeValue");
366                         x509_free_name(name);
367                         return -1;
368                 }
369
370                 /* RFC 3280:
371                  * MUST: country, organization, organizational-unit,
372                  * distinguished name qualifier, state or province name,
373                  * common name, serial number.
374                  * SHOULD: locality, title, surname, given name, initials,
375                  * pseudonym, generation qualifier.
376                  * MUST: domainComponent (RFC 2247).
377                  */
378                 fieldp = NULL;
379                 if (oid.len == 4 &&
380                     oid.oid[0] == 2 && oid.oid[1] == 5 && oid.oid[2] == 4) {
381                         /* id-at ::= 2.5.4 */
382                         switch (oid.oid[3]) {
383                         case 3:
384                                 /* commonName */
385                                 fieldp = &name->cn;
386                                 break;
387                         case 6:
388                                 /*  countryName */
389                                 fieldp = &name->c;
390                                 break;
391                         case 7:
392                                 /* localityName */
393                                 fieldp = &name->l;
394                                 break;
395                         case 8:
396                                 /* stateOrProvinceName */
397                                 fieldp = &name->st;
398                                 break;
399                         case 10:
400                                 /* organizationName */
401                                 fieldp = &name->o;
402                                 break;
403                         case 11:
404                                 /* organizationalUnitName */
405                                 fieldp = &name->ou;
406                                 break;
407                         }
408                 } else if (oid.len == 7 &&
409                            oid.oid[0] == 1 && oid.oid[1] == 2 &&
410                            oid.oid[2] == 840 && oid.oid[3] == 113549 &&
411                            oid.oid[4] == 1 && oid.oid[5] == 9 &&
412                            oid.oid[6] == 1) {
413                         /* 1.2.840.113549.1.9.1 - e-mailAddress */
414                         fieldp = &name->email;
415                 }
416
417                 if (fieldp == NULL) {
418                         wpa_hexdump(MSG_DEBUG, "X509: Unrecognized OID",
419                                     (u8 *) oid.oid,
420                                     oid.len * sizeof(oid.oid[0]));
421                         wpa_hexdump_ascii(MSG_MSGDUMP, "X509: Attribute Data",
422                                           hdr.payload, hdr.length);
423                         continue;
424                 }
425
426                 os_free(*fieldp);
427                 *fieldp = os_malloc(hdr.length + 1);
428                 if (*fieldp == NULL) {
429                         x509_free_name(name);
430                         return -1;
431                 }
432                 os_memcpy(*fieldp, hdr.payload, hdr.length);
433                 (*fieldp)[hdr.length] = '\0';
434         }
435
436         return 0;
437 }
438
439
440 /**
441  * x509_name_string - Convert an X.509 certificate name into a string
442  * @name: Name to convert
443  * @buf: Buffer for the string
444  * @len: Maximum buffer length
445  */
446 void x509_name_string(struct x509_name *name, char *buf, size_t len)
447 {
448         char *pos, *end;
449         int ret;
450
451         if (len == 0)
452                 return;
453
454         pos = buf;
455         end = buf + len;
456
457         if (name->c) {
458                 ret = os_snprintf(pos, end - pos, "C=%s, ", name->c);
459                 if (ret < 0 || ret >= end - pos)
460                         goto done;
461                 pos += ret;
462         }
463         if (name->st) {
464                 ret = os_snprintf(pos, end - pos, "ST=%s, ", name->st);
465                 if (ret < 0 || ret >= end - pos)
466                         goto done;
467                 pos += ret;
468         }
469         if (name->l) {
470                 ret = os_snprintf(pos, end - pos, "L=%s, ", name->l);
471                 if (ret < 0 || ret >= end - pos)
472                         goto done;
473                 pos += ret;
474         }
475         if (name->o) {
476                 ret = os_snprintf(pos, end - pos, "O=%s, ", name->o);
477                 if (ret < 0 || ret >= end - pos)
478                         goto done;
479                 pos += ret;
480         }
481         if (name->ou) {
482                 ret = os_snprintf(pos, end - pos, "OU=%s, ", name->ou);
483                 if (ret < 0 || ret >= end - pos)
484                         goto done;
485                 pos += ret;
486         }
487         if (name->cn) {
488                 ret = os_snprintf(pos, end - pos, "CN=%s, ", name->cn);
489                 if (ret < 0 || ret >= end - pos)
490                         goto done;
491                 pos += ret;
492         }
493
494         if (pos > buf + 1 && pos[-1] == ' ' && pos[-2] == ',') {
495                 *pos-- = '\0';
496                 *pos-- = '\0';
497         }
498
499         if (name->email) {
500                 ret = os_snprintf(pos, end - pos, "/emailAddress=%s",
501                                   name->email);
502                 if (ret < 0 || ret >= end - pos)
503                         goto done;
504                 pos += ret;
505         }
506
507 done:
508         end[-1] = '\0';
509 }
510
511
512 static int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag,
513                            os_time_t *val)
514 {
515         const char *pos;
516         int year, month, day, hour, min, sec;
517
518         /*
519          * Time ::= CHOICE {
520          *     utcTime        UTCTime,
521          *     generalTime    GeneralizedTime
522          * }
523          *
524          * UTCTime: YYMMDDHHMMSSZ
525          * GeneralizedTime: YYYYMMDDHHMMSSZ
526          */
527
528         pos = (const char *) buf;
529
530         switch (asn1_tag) {
531         case ASN1_TAG_UTCTIME:
532                 if (len != 13 || buf[12] != 'Z') {
533                         wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized "
534                                           "UTCTime format", buf, len);
535                         return -1;
536                 }
537                 if (sscanf(pos, "%02d", &year) != 1) {
538                         wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse "
539                                           "UTCTime year", buf, len);
540                         return -1;
541                 }
542                 if (year < 50)
543                         year += 2000;
544                 else
545                         year += 1900;
546                 pos += 2;
547                 break;
548         case ASN1_TAG_GENERALIZEDTIME:
549                 if (len != 15 || buf[14] != 'Z') {
550                         wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized "
551                                           "GeneralizedTime format", buf, len);
552                         return -1;
553                 }
554                 if (sscanf(pos, "%04d", &year) != 1) {
555                         wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse "
556                                           "GeneralizedTime year", buf, len);
557                         return -1;
558                 }
559                 pos += 4;
560                 break;
561         default:
562                 wpa_printf(MSG_DEBUG, "X509: Expected UTCTime or "
563                            "GeneralizedTime - found tag 0x%x", asn1_tag);
564                 return -1;
565         }
566
567         if (sscanf(pos, "%02d", &month) != 1) {
568                 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
569                                   "(month)", buf, len);
570                 return -1;
571         }
572         pos += 2;
573
574         if (sscanf(pos, "%02d", &day) != 1) {
575                 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
576                                   "(day)", buf, len);
577                 return -1;
578         }
579         pos += 2;
580
581         if (sscanf(pos, "%02d", &hour) != 1) {
582                 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
583                                   "(hour)", buf, len);
584                 return -1;
585         }
586         pos += 2;
587
588         if (sscanf(pos, "%02d", &min) != 1) {
589                 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
590                                   "(min)", buf, len);
591                 return -1;
592         }
593         pos += 2;
594
595         if (sscanf(pos, "%02d", &sec) != 1) {
596                 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
597                                   "(sec)", buf, len);
598                 return -1;
599         }
600
601         if (os_mktime(year, month, day, hour, min, sec, val) < 0) {
602                 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to convert Time",
603                                   buf, len);
604                 if (year < 1970) {
605                         /*
606                          * At least some test certificates have been configured
607                          * to use dates prior to 1970. Set the date to
608                          * beginning of 1970 to handle these case.
609                          */
610                         wpa_printf(MSG_DEBUG, "X509: Year=%d before epoch - "
611                                    "assume epoch as the time", year);
612                         *val = 0;
613                         return 0;
614                 }
615                 return -1;
616         }
617
618         return 0;
619 }
620
621
622 static int x509_parse_validity(const u8 *buf, size_t len,
623                                struct x509_certificate *cert, const u8 **next)
624 {
625         struct asn1_hdr hdr;
626         const u8 *pos;
627         size_t plen;
628
629         /*
630          * Validity ::= SEQUENCE {
631          *     notBefore      Time,
632          *     notAfter       Time
633          * }
634          *
635          * RFC 3280, 4.1.2.5:
636          * CAs conforming to this profile MUST always encode certificate
637          * validity dates through the year 2049 as UTCTime; certificate
638          * validity dates in 2050 or later MUST be encoded as GeneralizedTime.
639          */
640
641         if (asn1_get_next(buf, len, &hdr) < 0 ||
642             hdr.class != ASN1_CLASS_UNIVERSAL ||
643             hdr.tag != ASN1_TAG_SEQUENCE) {
644                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
645                            "(Validity) - found class %d tag 0x%x",
646                            hdr.class, hdr.tag);
647                 return -1;
648         }
649         pos = hdr.payload;
650         plen = hdr.length;
651
652         if (pos + plen > buf + len)
653                 return -1;
654
655         *next = pos + plen;
656
657         if (asn1_get_next(pos, plen, &hdr) < 0 ||
658             hdr.class != ASN1_CLASS_UNIVERSAL ||
659             x509_parse_time(hdr.payload, hdr.length, hdr.tag,
660                             &cert->not_before) < 0) {
661                 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notBefore "
662                                   "Time", hdr.payload, hdr.length);
663                 return -1;
664         }
665
666         pos = hdr.payload + hdr.length;
667         plen = *next - pos;
668
669         if (asn1_get_next(pos, plen, &hdr) < 0 ||
670             hdr.class != ASN1_CLASS_UNIVERSAL ||
671             x509_parse_time(hdr.payload, hdr.length, hdr.tag,
672                             &cert->not_after) < 0) {
673                 wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notAfter "
674                                   "Time", hdr.payload, hdr.length);
675                 return -1;
676         }
677
678         wpa_printf(MSG_MSGDUMP, "X509: Validity: notBefore: %lu notAfter: %lu",
679                    (unsigned long) cert->not_before,
680                    (unsigned long) cert->not_after);
681
682         return 0;
683 }
684
685
686 static int x509_id_ce_oid(struct asn1_oid *oid)
687 {
688         /* id-ce arc from X.509 for standard X.509v3 extensions */
689         return oid->len >= 4 &&
690                 oid->oid[0] == 2 /* joint-iso-ccitt */ &&
691                 oid->oid[1] == 5 /* ds */ &&
692                 oid->oid[2] == 29 /* id-ce */;
693 }
694
695
696 static int x509_parse_ext_key_usage(struct x509_certificate *cert,
697                                     const u8 *pos, size_t len)
698 {
699         struct asn1_hdr hdr;
700
701         /*
702          * KeyUsage ::= BIT STRING {
703          *     digitalSignature        (0),
704          *     nonRepudiation          (1),
705          *     keyEncipherment         (2),
706          *     dataEncipherment        (3),
707          *     keyAgreement            (4),
708          *     keyCertSign             (5),
709          *     cRLSign                 (6),
710          *     encipherOnly            (7),
711          *     decipherOnly            (8) }
712          */
713
714         if (asn1_get_next(pos, len, &hdr) < 0 ||
715             hdr.class != ASN1_CLASS_UNIVERSAL ||
716             hdr.tag != ASN1_TAG_BITSTRING ||
717             hdr.length < 1) {
718                 wpa_printf(MSG_DEBUG, "X509: Expected BIT STRING in "
719                            "KeyUsage; found %d tag 0x%x len %d",
720                            hdr.class, hdr.tag, hdr.length);
721                 return -1;
722         }
723
724         cert->extensions_present |= X509_EXT_KEY_USAGE;
725         cert->key_usage = asn1_bit_string_to_long(hdr.payload, hdr.length);
726
727         wpa_printf(MSG_DEBUG, "X509: KeyUsage 0x%lx", cert->key_usage);
728
729         return 0;
730 }
731
732
733 static int x509_parse_ext_basic_constraints(struct x509_certificate *cert,
734                                             const u8 *pos, size_t len)
735 {
736         struct asn1_hdr hdr;
737         unsigned long value;
738         size_t left;
739
740         /*
741          * BasicConstraints ::= SEQUENCE {
742          * cA                      BOOLEAN DEFAULT FALSE,
743          * pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
744          */
745
746         if (asn1_get_next(pos, len, &hdr) < 0 ||
747             hdr.class != ASN1_CLASS_UNIVERSAL ||
748             hdr.tag != ASN1_TAG_SEQUENCE) {
749                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE in "
750                            "BasicConstraints; found %d tag 0x%x",
751                            hdr.class, hdr.tag);
752                 return -1;
753         }
754
755         cert->extensions_present |= X509_EXT_BASIC_CONSTRAINTS;
756
757         if (hdr.length == 0)
758                 return 0;
759
760         if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
761             hdr.class != ASN1_CLASS_UNIVERSAL) {
762                 wpa_printf(MSG_DEBUG, "X509: Failed to parse "
763                            "BasicConstraints");
764                 return -1;
765         }
766
767         if (hdr.tag == ASN1_TAG_BOOLEAN) {
768                 if (hdr.length != 1) {
769                         wpa_printf(MSG_DEBUG, "X509: Unexpected "
770                                    "Boolean length (%u) in BasicConstraints",
771                                    hdr.length);
772                         return -1;
773                 }
774                 cert->ca = hdr.payload[0];
775
776                 if (hdr.payload + hdr.length == pos + len) {
777                         wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d",
778                                    cert->ca);
779                         return 0;
780                 }
781
782                 if (asn1_get_next(hdr.payload + hdr.length, len - hdr.length,
783                                   &hdr) < 0 ||
784                     hdr.class != ASN1_CLASS_UNIVERSAL) {
785                         wpa_printf(MSG_DEBUG, "X509: Failed to parse "
786                                    "BasicConstraints");
787                         return -1;
788                 }
789         }
790
791         if (hdr.tag != ASN1_TAG_INTEGER) {
792                 wpa_printf(MSG_DEBUG, "X509: Expected INTEGER in "
793                            "BasicConstraints; found class %d tag 0x%x",
794                            hdr.class, hdr.tag);
795                 return -1;
796         }
797
798         pos = hdr.payload;
799         left = hdr.length;
800         value = 0;
801         while (left) {
802                 value <<= 8;
803                 value |= *pos++;
804                 left--;
805         }
806
807         cert->path_len_constraint = value;
808         cert->extensions_present |= X509_EXT_PATH_LEN_CONSTRAINT;
809
810         wpa_printf(MSG_DEBUG, "X509: BasicConstraints - cA=%d "
811                    "pathLenConstraint=%lu",
812                    cert->ca, cert->path_len_constraint);
813
814         return 0;
815 }
816
817
818 static int x509_parse_extension_data(struct x509_certificate *cert,
819                                      struct asn1_oid *oid,
820                                      const u8 *pos, size_t len)
821 {
822         if (!x509_id_ce_oid(oid))
823                 return 1;
824
825         /* TODO: add other extensions required by RFC 3280, Ch 4.2:
826          * certificate policies (section 4.2.1.5)
827          * the subject alternative name (section 4.2.1.7)
828          * name constraints (section 4.2.1.11)
829          * policy constraints (section 4.2.1.12)
830          * extended key usage (section 4.2.1.13)
831          * inhibit any-policy (section 4.2.1.15)
832          */
833         switch (oid->oid[3]) {
834         case 15: /* id-ce-keyUsage */
835                 return x509_parse_ext_key_usage(cert, pos, len);
836         case 19: /* id-ce-basicConstraints */
837                 return x509_parse_ext_basic_constraints(cert, pos, len);
838         default:
839                 return 1;
840         }
841 }
842
843
844 static int x509_parse_extension(struct x509_certificate *cert,
845                                 const u8 *pos, size_t len, const u8 **next)
846 {
847         const u8 *end;
848         struct asn1_hdr hdr;
849         struct asn1_oid oid;
850         int critical_ext = 0, res;
851         char buf[80];
852
853         /*
854          * Extension  ::=  SEQUENCE  {
855          *     extnID      OBJECT IDENTIFIER,
856          *     critical    BOOLEAN DEFAULT FALSE,
857          *     extnValue   OCTET STRING
858          * }
859          */
860
861         if (asn1_get_next(pos, len, &hdr) < 0 ||
862             hdr.class != ASN1_CLASS_UNIVERSAL ||
863             hdr.tag != ASN1_TAG_SEQUENCE) {
864                 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header in "
865                            "Extensions: class %d tag 0x%x; expected SEQUENCE",
866                            hdr.class, hdr.tag);
867                 return -1;
868         }
869         pos = hdr.payload;
870         *next = end = pos + hdr.length;
871
872         if (asn1_get_oid(pos, end - pos, &oid, &pos) < 0) {
873                 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 data for "
874                            "Extension (expected OID)");
875                 return -1;
876         }
877
878         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
879             hdr.class != ASN1_CLASS_UNIVERSAL ||
880             (hdr.tag != ASN1_TAG_BOOLEAN &&
881              hdr.tag != ASN1_TAG_OCTETSTRING)) {
882                 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header in "
883                            "Extensions: class %d tag 0x%x; expected BOOLEAN "
884                            "or OCTET STRING", hdr.class, hdr.tag);
885                 return -1;
886         }
887
888         if (hdr.tag == ASN1_TAG_BOOLEAN) {
889                 if (hdr.length != 1) {
890                         wpa_printf(MSG_DEBUG, "X509: Unexpected "
891                                    "Boolean length (%u)", hdr.length);
892                         return -1;
893                 }
894                 critical_ext = hdr.payload[0];
895                 pos = hdr.payload;
896                 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
897                     (hdr.class != ASN1_CLASS_UNIVERSAL &&
898                      hdr.class != ASN1_CLASS_PRIVATE) ||
899                     hdr.tag != ASN1_TAG_OCTETSTRING) {
900                         wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header "
901                                    "in Extensions: class %d tag 0x%x; "
902                                    "expected OCTET STRING",
903                                    hdr.class, hdr.tag);
904                         return -1;
905                 }
906         }
907
908         asn1_oid_to_str(&oid, buf, sizeof(buf));
909         wpa_printf(MSG_DEBUG, "X509: Extension: extnID=%s critical=%d",
910                    buf, critical_ext);
911         wpa_hexdump(MSG_MSGDUMP, "X509: extnValue", hdr.payload, hdr.length);
912
913         res = x509_parse_extension_data(cert, &oid, hdr.payload, hdr.length);
914         if (res < 0)
915                 return res;
916         if (res == 1 && critical_ext) {
917                 wpa_printf(MSG_INFO, "X509: Unknown critical extension %s",
918                            buf);
919                 return -1;
920         }
921
922         return 0;
923 }
924
925
926 static int x509_parse_extensions(struct x509_certificate *cert,
927                                  const u8 *pos, size_t len)
928 {
929         const u8 *end;
930         struct asn1_hdr hdr;
931
932         /* Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension */
933
934         if (asn1_get_next(pos, len, &hdr) < 0 ||
935             hdr.class != ASN1_CLASS_UNIVERSAL ||
936             hdr.tag != ASN1_TAG_SEQUENCE) {
937                 wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 data "
938                            "for Extensions: class %d tag 0x%x; "
939                            "expected SEQUENCE", hdr.class, hdr.tag);
940                 return -1;
941         }
942
943         pos = hdr.payload;
944         end = pos + hdr.length;
945
946         while (pos < end) {
947                 if (x509_parse_extension(cert, pos, end - pos, &pos)
948                     < 0)
949                         return -1;
950         }
951
952         return 0;
953 }
954
955
956 static int x509_parse_tbs_certificate(const u8 *buf, size_t len,
957                                       struct x509_certificate *cert,
958                                       const u8 **next)
959 {
960         struct asn1_hdr hdr;
961         const u8 *pos, *end;
962         size_t left;
963         char sbuf[128];
964         unsigned long value;
965
966         /* tbsCertificate TBSCertificate ::= SEQUENCE */
967         if (asn1_get_next(buf, len, &hdr) < 0 ||
968             hdr.class != ASN1_CLASS_UNIVERSAL ||
969             hdr.tag != ASN1_TAG_SEQUENCE) {
970                 wpa_printf(MSG_DEBUG, "X509: tbsCertificate did not start "
971                            "with a valid SEQUENCE - found class %d tag 0x%x",
972                            hdr.class, hdr.tag);
973                 return -1;
974         }
975         pos = hdr.payload;
976         end = *next = pos + hdr.length;
977
978         /*
979          * version [0]  EXPLICIT Version DEFAULT v1
980          * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
981          */
982         if (asn1_get_next(pos, end - pos, &hdr) < 0)
983                 return -1;
984         pos = hdr.payload;
985
986         if (hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC) {
987                 if (asn1_get_next(pos, end - pos, &hdr) < 0)
988                         return -1;
989
990                 if (hdr.class != ASN1_CLASS_UNIVERSAL ||
991                     hdr.tag != ASN1_TAG_INTEGER) {
992                         wpa_printf(MSG_DEBUG, "X509: No INTEGER tag found for "
993                                    "version field - found class %d tag 0x%x",
994                                    hdr.class, hdr.tag);
995                         return -1;
996                 }
997                 if (hdr.length != 1) {
998                         wpa_printf(MSG_DEBUG, "X509: Unexpected version field "
999                                    "length %u (expected 1)", hdr.length);
1000                         return -1;
1001                 }
1002                 pos = hdr.payload;
1003                 left = hdr.length;
1004                 value = 0;
1005                 while (left) {
1006                         value <<= 8;
1007                         value |= *pos++;
1008                         left--;
1009                 }
1010
1011                 cert->version = value;
1012                 if (cert->version != X509_CERT_V1 &&
1013                     cert->version != X509_CERT_V2 &&
1014                     cert->version != X509_CERT_V3) {
1015                         wpa_printf(MSG_DEBUG, "X509: Unsupported version %d",
1016                                    cert->version + 1);
1017                         return -1;
1018                 }
1019
1020                 if (asn1_get_next(pos, end - pos, &hdr) < 0)
1021                         return -1;
1022         } else
1023                 cert->version = X509_CERT_V1;
1024         wpa_printf(MSG_MSGDUMP, "X509: Version X.509v%d", cert->version + 1);
1025
1026         /* serialNumber CertificateSerialNumber ::= INTEGER */
1027         if (hdr.class != ASN1_CLASS_UNIVERSAL ||
1028             hdr.tag != ASN1_TAG_INTEGER) {
1029                 wpa_printf(MSG_DEBUG, "X509: No INTEGER tag found for "
1030                            "serialNumber; class=%d tag=0x%x",
1031                            hdr.class, hdr.tag);
1032                 return -1;
1033         }
1034
1035         pos = hdr.payload;
1036         left = hdr.length;
1037         while (left) {
1038                 cert->serial_number <<= 8;
1039                 cert->serial_number |= *pos++;
1040                 left--;
1041         }
1042         wpa_printf(MSG_MSGDUMP, "X509: serialNumber %lu", cert->serial_number);
1043
1044         /* signature AlgorithmIdentifier */
1045         if (x509_parse_algorithm_identifier(pos, end - pos, &cert->signature,
1046                                             &pos))
1047                 return -1;
1048
1049         /* issuer Name */
1050         if (x509_parse_name(pos, end - pos, &cert->issuer, &pos))
1051                 return -1;
1052         x509_name_string(&cert->issuer, sbuf, sizeof(sbuf));
1053         wpa_printf(MSG_MSGDUMP, "X509: issuer %s", sbuf);
1054
1055         /* validity Validity */
1056         if (x509_parse_validity(pos, end - pos, cert, &pos))
1057                 return -1;
1058
1059         /* subject Name */
1060         if (x509_parse_name(pos, end - pos, &cert->subject, &pos))
1061                 return -1;
1062         x509_name_string(&cert->subject, sbuf, sizeof(sbuf));
1063         wpa_printf(MSG_MSGDUMP, "X509: subject %s", sbuf);
1064
1065         /* subjectPublicKeyInfo SubjectPublicKeyInfo */
1066         if (x509_parse_public_key(pos, end - pos, cert, &pos))
1067                 return -1;
1068
1069         if (pos == end)
1070                 return 0;
1071
1072         if (cert->version == X509_CERT_V1)
1073                 return 0;
1074
1075         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1076             hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1077                 wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific"
1078                            " tag to parse optional tbsCertificate "
1079                            "field(s); parsed class %d tag 0x%x",
1080                            hdr.class, hdr.tag);
1081                 return -1;
1082         }
1083
1084         if (hdr.tag == 1) {
1085                 /* issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL */
1086                 wpa_printf(MSG_DEBUG, "X509: issuerUniqueID");
1087                 /* TODO: parse UniqueIdentifier ::= BIT STRING */
1088
1089                 if (hdr.payload + hdr.length == end)
1090                         return 0;
1091
1092                 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1093                     hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1094                         wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific"
1095                                    " tag to parse optional tbsCertificate "
1096                                    "field(s); parsed class %d tag 0x%x",
1097                                    hdr.class, hdr.tag);
1098                         return -1;
1099                 }
1100         }
1101
1102         if (hdr.tag == 2) {
1103                 /* subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL */
1104                 wpa_printf(MSG_DEBUG, "X509: subjectUniqueID");
1105                 /* TODO: parse UniqueIdentifier ::= BIT STRING */
1106
1107                 if (hdr.payload + hdr.length == end)
1108                         return 0;
1109
1110                 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1111                     hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
1112                         wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific"
1113                                    " tag to parse optional tbsCertificate "
1114                                    "field(s); parsed class %d tag 0x%x",
1115                                    hdr.class, hdr.tag);
1116                         return -1;
1117                 }
1118         }
1119
1120         if (hdr.tag != 3) {
1121                 wpa_printf(MSG_DEBUG, "X509: Ignored unexpected "
1122                            "Context-Specific tag %d in optional "
1123                            "tbsCertificate fields", hdr.tag);
1124                 return 0;
1125         }
1126
1127         /* extensions      [3]  EXPLICIT Extensions OPTIONAL */
1128
1129         if (cert->version != X509_CERT_V3) {
1130                 wpa_printf(MSG_DEBUG, "X509: X.509%d certificate and "
1131                            "Extensions data which are only allowed for "
1132                            "version 3", cert->version + 1);
1133                 return -1;
1134         }
1135
1136         if (x509_parse_extensions(cert, hdr.payload, hdr.length) < 0)
1137                 return -1;
1138
1139         pos = hdr.payload + hdr.length;
1140         if (pos < end) {
1141                 wpa_hexdump(MSG_DEBUG,
1142                             "X509: Ignored extra tbsCertificate data",
1143                             pos, end - pos);
1144         }
1145
1146         return 0;
1147 }
1148
1149
1150 static int x509_rsadsi_oid(struct asn1_oid *oid)
1151 {
1152         return oid->len >= 4 &&
1153                 oid->oid[0] == 1 /* iso */ &&
1154                 oid->oid[1] == 2 /* member-body */ &&
1155                 oid->oid[2] == 840 /* us */ &&
1156                 oid->oid[3] == 113549 /* rsadsi */;
1157 }
1158
1159
1160 static int x509_pkcs_oid(struct asn1_oid *oid)
1161 {
1162         return oid->len >= 5 &&
1163                 x509_rsadsi_oid(oid) &&
1164                 oid->oid[4] == 1 /* pkcs */;
1165 }
1166
1167
1168 static int x509_digest_oid(struct asn1_oid *oid)
1169 {
1170         return oid->len >= 5 &&
1171                 x509_rsadsi_oid(oid) &&
1172                 oid->oid[4] == 2 /* digestAlgorithm */;
1173 }
1174
1175
1176 static int x509_sha1_oid(struct asn1_oid *oid)
1177 {
1178         return oid->len == 6 &&
1179                 oid->oid[0] == 1 /* iso */ &&
1180                 oid->oid[1] == 3 /* identified-organization */ &&
1181                 oid->oid[2] == 14 /* oiw */ &&
1182                 oid->oid[3] == 3 /* secsig */ &&
1183                 oid->oid[4] == 2 /* algorithms */ &&
1184                 oid->oid[5] == 26 /* id-sha1 */;
1185 }
1186
1187
1188 /**
1189  * x509_certificate_parse - Parse a X.509 certificate in DER format
1190  * @buf: Pointer to the X.509 certificate in DER format
1191  * @len: Buffer length
1192  * Returns: Pointer to the parsed certificate or %NULL on failure
1193  *
1194  * Caller is responsible for freeing the returned certificate by calling
1195  * x509_certificate_free().
1196  */
1197 struct x509_certificate * x509_certificate_parse(const u8 *buf, size_t len)
1198 {
1199         struct asn1_hdr hdr;
1200         const u8 *pos, *end, *hash_start;
1201         struct x509_certificate *cert;
1202
1203         cert = os_zalloc(sizeof(*cert) + len);
1204         if (cert == NULL)
1205                 return NULL;
1206         os_memcpy(cert + 1, buf, len);
1207         cert->cert_start = (u8 *) (cert + 1);
1208         cert->cert_len = len;
1209
1210         pos = buf;
1211         end = buf + len;
1212
1213         /* RFC 3280 - X.509 v3 certificate / ASN.1 DER */
1214
1215         /* Certificate ::= SEQUENCE */
1216         if (asn1_get_next(pos, len, &hdr) < 0 ||
1217             hdr.class != ASN1_CLASS_UNIVERSAL ||
1218             hdr.tag != ASN1_TAG_SEQUENCE) {
1219                 wpa_printf(MSG_DEBUG, "X509: Certificate did not start with "
1220                            "a valid SEQUENCE - found class %d tag 0x%x",
1221                            hdr.class, hdr.tag);
1222                 x509_certificate_free(cert);
1223                 return NULL;
1224         }
1225         pos = hdr.payload;
1226
1227         if (pos + hdr.length > end) {
1228                 x509_certificate_free(cert);
1229                 return NULL;
1230         }
1231
1232         if (pos + hdr.length < end) {
1233                 wpa_hexdump(MSG_MSGDUMP, "X509: Ignoring extra data after DER "
1234                             "encoded certificate",
1235                             pos + hdr.length, end - pos + hdr.length);
1236                 end = pos + hdr.length;
1237         }
1238
1239         hash_start = pos;
1240         cert->tbs_cert_start = cert->cert_start + (hash_start - buf);
1241         if (x509_parse_tbs_certificate(pos, end - pos, cert, &pos)) {
1242                 x509_certificate_free(cert);
1243                 return NULL;
1244         }
1245         cert->tbs_cert_len = pos - hash_start;
1246
1247         /* signatureAlgorithm AlgorithmIdentifier */
1248         if (x509_parse_algorithm_identifier(pos, end - pos,
1249                                             &cert->signature_alg, &pos)) {
1250                 x509_certificate_free(cert);
1251                 return NULL;
1252         }
1253
1254         /* signatureValue BIT STRING */
1255         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1256             hdr.class != ASN1_CLASS_UNIVERSAL ||
1257             hdr.tag != ASN1_TAG_BITSTRING) {
1258                 wpa_printf(MSG_DEBUG, "X509: Expected BITSTRING "
1259                            "(signatureValue) - found class %d tag 0x%x",
1260                            hdr.class, hdr.tag);
1261                 x509_certificate_free(cert);
1262                 return NULL;
1263         }
1264         if (hdr.length < 1) {
1265                 x509_certificate_free(cert);
1266                 return NULL;
1267         }
1268         pos = hdr.payload;
1269         if (*pos) {
1270                 wpa_printf(MSG_DEBUG, "X509: BITSTRING - %d unused bits",
1271                            *pos);
1272                 /* PKCS #1 v1.5 10.2.1:
1273                  * It is an error if the length in bits of the signature S is
1274                  * not a multiple of eight.
1275                  */
1276                 x509_certificate_free(cert);
1277                 return NULL;
1278         }
1279         os_free(cert->sign_value);
1280         cert->sign_value = os_malloc(hdr.length - 1);
1281         if (cert->sign_value == NULL) {
1282                 wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for "
1283                            "signatureValue");
1284                 x509_certificate_free(cert);
1285                 return NULL;
1286         }
1287         os_memcpy(cert->sign_value, pos + 1, hdr.length - 1);
1288         cert->sign_value_len = hdr.length - 1;
1289         wpa_hexdump(MSG_MSGDUMP, "X509: signature",
1290                     cert->sign_value, cert->sign_value_len);
1291
1292         return cert;
1293 }
1294
1295
1296 /**
1297  * x509_certificate_check_signature - Verify certificate signature
1298  * @issuer: Issuer certificate
1299  * @cert: Certificate to be verified
1300  * Returns: 0 if cert has a valid signature that was signed by the issuer,
1301  * -1 if not
1302  */
1303 int x509_certificate_check_signature(struct x509_certificate *issuer,
1304                                      struct x509_certificate *cert)
1305 {
1306         struct crypto_public_key *pk;
1307         u8 *data;
1308         const u8 *pos, *end, *next, *da_end;
1309         size_t data_len;
1310         struct asn1_hdr hdr;
1311         struct asn1_oid oid;
1312         u8 hash[20];
1313         size_t hash_len;
1314
1315         if (!x509_pkcs_oid(&cert->signature.oid) ||
1316             cert->signature.oid.len != 7 ||
1317             cert->signature.oid.oid[5] != 1 /* pkcs-1 */) {
1318                 wpa_printf(MSG_DEBUG, "X509: Unrecognized signature "
1319                            "algorithm");
1320                 return -1;
1321         }
1322
1323         pk = crypto_public_key_import(issuer->public_key,
1324                                       issuer->public_key_len);
1325         if (pk == NULL)
1326                 return -1;
1327
1328         data_len = cert->sign_value_len;
1329         data = os_malloc(data_len);
1330         if (data == NULL) {
1331                 crypto_public_key_free(pk);
1332                 return -1;
1333         }
1334
1335         if (crypto_public_key_decrypt_pkcs1(pk, cert->sign_value,
1336                                             cert->sign_value_len, data,
1337                                             &data_len) < 0) {
1338                 wpa_printf(MSG_DEBUG, "X509: Failed to decrypt signature");
1339                 crypto_public_key_free(pk);
1340                 os_free(data);
1341                 return -1;
1342         }
1343         crypto_public_key_free(pk);
1344
1345         wpa_hexdump(MSG_MSGDUMP, "X509: Signature data D", data, data_len);
1346
1347         /*
1348          * PKCS #1 v1.5, 10.1.2:
1349          *
1350          * DigestInfo ::= SEQUENCE {
1351          *     digestAlgorithm DigestAlgorithmIdentifier,
1352          *     digest Digest
1353          * }
1354          *
1355          * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1356          *
1357          * Digest ::= OCTET STRING
1358          *
1359          */
1360         if (asn1_get_next(data, data_len, &hdr) < 0 ||
1361             hdr.class != ASN1_CLASS_UNIVERSAL ||
1362             hdr.tag != ASN1_TAG_SEQUENCE) {
1363                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
1364                            "(DigestInfo) - found class %d tag 0x%x",
1365                            hdr.class, hdr.tag);
1366                 os_free(data);
1367                 return -1;
1368         }
1369
1370         pos = hdr.payload;
1371         end = pos + hdr.length;
1372
1373         /*
1374          * X.509:
1375          * AlgorithmIdentifier ::= SEQUENCE {
1376          *     algorithm            OBJECT IDENTIFIER,
1377          *     parameters           ANY DEFINED BY algorithm OPTIONAL
1378          * }
1379          */
1380
1381         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1382             hdr.class != ASN1_CLASS_UNIVERSAL ||
1383             hdr.tag != ASN1_TAG_SEQUENCE) {
1384                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
1385                            "(AlgorithmIdentifier) - found class %d tag 0x%x",
1386                            hdr.class, hdr.tag);
1387                 os_free(data);
1388                 return -1;
1389         }
1390         da_end = hdr.payload + hdr.length;
1391
1392         if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {
1393                 wpa_printf(MSG_DEBUG, "X509: Failed to parse digestAlgorithm");
1394                 os_free(data);
1395                 return -1;
1396         }
1397
1398         if (x509_sha1_oid(&oid)) {
1399                 if (cert->signature.oid.oid[6] !=
1400                     5 /* sha-1WithRSAEncryption */) {
1401                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA1 "
1402                                    "does not match with certificate "
1403                                    "signatureAlgorithm (%lu)",
1404                                    cert->signature.oid.oid[6]);
1405                         os_free(data);
1406                         return -1;
1407                 }
1408                 goto skip_digest_oid;
1409         }
1410
1411         if (!x509_digest_oid(&oid)) {
1412                 wpa_printf(MSG_DEBUG, "X509: Unrecognized digestAlgorithm");
1413                 os_free(data);
1414                 return -1;
1415         }
1416         switch (oid.oid[5]) {
1417         case 5: /* md5 */
1418                 if (cert->signature.oid.oid[6] != 4 /* md5WithRSAEncryption */)
1419                 {
1420                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm MD5 does "
1421                                    "not match with certificate "
1422                                    "signatureAlgorithm (%lu)",
1423                                    cert->signature.oid.oid[6]);
1424                         os_free(data);
1425                         return -1;
1426                 }
1427                 break;
1428         case 2: /* md2 */
1429         case 4: /* md4 */
1430         default:
1431                 wpa_printf(MSG_DEBUG, "X509: Unsupported digestAlgorithm "
1432                            "(%lu)", oid.oid[5]);
1433                 os_free(data);
1434                 return -1;
1435         }
1436
1437 skip_digest_oid:
1438         /* Digest ::= OCTET STRING */
1439         pos = da_end;
1440         end = data + data_len;
1441
1442         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1443             hdr.class != ASN1_CLASS_UNIVERSAL ||
1444             hdr.tag != ASN1_TAG_OCTETSTRING) {
1445                 wpa_printf(MSG_DEBUG, "X509: Expected OCTETSTRING "
1446                            "(Digest) - found class %d tag 0x%x",
1447                            hdr.class, hdr.tag);
1448                 os_free(data);
1449                 return -1;
1450         }
1451         wpa_hexdump(MSG_MSGDUMP, "X509: Decrypted Digest",
1452                     hdr.payload, hdr.length);
1453
1454         switch (cert->signature.oid.oid[6]) {
1455         case 4: /* md5WithRSAEncryption */
1456                 md5_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len,
1457                            hash);
1458                 hash_len = 16;
1459                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (MD5)",
1460                             hash, hash_len);
1461                 break;
1462         case 5: /* sha-1WithRSAEncryption */
1463                 sha1_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len,
1464                             hash);
1465                 hash_len = 20;
1466                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA1)",
1467                             hash, hash_len);
1468                 break;
1469         case 2: /* md2WithRSAEncryption */
1470         case 11: /* sha256WithRSAEncryption */
1471         case 12: /* sha384WithRSAEncryption */
1472         case 13: /* sha512WithRSAEncryption */
1473         default:
1474                 wpa_printf(MSG_INFO, "X509: Unsupported certificate signature "
1475                            "algorithm (%lu)", cert->signature.oid.oid[6]);
1476                 os_free(data);
1477                 return -1;
1478         }
1479
1480         if (hdr.length != hash_len ||
1481             os_memcmp(hdr.payload, hash, hdr.length) != 0) {
1482                 wpa_printf(MSG_INFO, "X509: Certificate Digest does not match "
1483                            "with calculated tbsCertificate hash");
1484                 os_free(data);
1485                 return -1;
1486         }
1487
1488         os_free(data);
1489
1490         wpa_printf(MSG_DEBUG, "X509: Certificate Digest matches with "
1491                    "calculated tbsCertificate hash");
1492
1493         return 0;
1494 }
1495
1496
1497 static int x509_valid_issuer(const struct x509_certificate *cert)
1498 {
1499         if ((cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS) &&
1500             !cert->ca) {
1501                 wpa_printf(MSG_DEBUG, "X509: Non-CA certificate used as an "
1502                            "issuer");
1503                 return -1;
1504         }
1505
1506         if (cert->version == X509_CERT_V3 &&
1507             !(cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS)) {
1508                 wpa_printf(MSG_DEBUG, "X509: v3 CA certificate did not "
1509                            "include BasicConstraints extension");
1510                 return -1;
1511         }
1512
1513         if ((cert->extensions_present & X509_EXT_KEY_USAGE) &&
1514             !(cert->key_usage & X509_KEY_USAGE_KEY_CERT_SIGN)) {
1515                 wpa_printf(MSG_DEBUG, "X509: Issuer certificate did not have "
1516                            "keyCertSign bit in Key Usage");
1517                 return -1;
1518         }
1519
1520         return 0;
1521 }
1522
1523
1524 /**
1525  * x509_certificate_chain_validate - Validate X.509 certificate chain
1526  * @trusted: List of trusted certificates
1527  * @chain: Certificate chain to be validated (first chain must be issued by
1528  * signed by the second certificate in the chain and so on)
1529  * @reason: Buffer for returning failure reason (X509_VALIDATE_*)
1530  * Returns: 0 if chain is valid, -1 if not
1531  */
1532 int x509_certificate_chain_validate(struct x509_certificate *trusted,
1533                                     struct x509_certificate *chain,
1534                                     int *reason)
1535 {
1536         long unsigned idx;
1537         int chain_trusted = 0;
1538         struct x509_certificate *cert, *trust;
1539         char buf[128];
1540         struct os_time now;
1541
1542         *reason = X509_VALIDATE_OK;
1543
1544         wpa_printf(MSG_DEBUG, "X509: Validate certificate chain");
1545         os_get_time(&now);
1546
1547         for (cert = chain, idx = 0; cert; cert = cert->next, idx++) {
1548                 x509_name_string(&cert->subject, buf, sizeof(buf)); 
1549                 wpa_printf(MSG_DEBUG, "X509: %lu: %s", idx, buf);
1550
1551                 if (chain_trusted)
1552                         continue;
1553
1554                 if ((unsigned long) now.sec <
1555                     (unsigned long) cert->not_before ||
1556                     (unsigned long) now.sec >
1557                     (unsigned long) cert->not_after) {
1558                         wpa_printf(MSG_INFO, "X509: Certificate not valid "
1559                                    "(now=%lu not_before=%lu not_after=%lu)",
1560                                    now.sec, cert->not_before, cert->not_after);
1561                         *reason = X509_VALIDATE_CERTIFICATE_EXPIRED;
1562                         return -1;
1563                 }
1564
1565                 if (cert->next) {
1566                         if (x509_name_compare(&cert->issuer,
1567                                               &cert->next->subject) != 0) {
1568                                 wpa_printf(MSG_DEBUG, "X509: Certificate "
1569                                            "chain issuer name mismatch");
1570                                 *reason = X509_VALIDATE_CERTIFICATE_UNKNOWN;
1571                                 return -1;
1572                         }
1573
1574                         if (x509_valid_issuer(cert->next) < 0) {
1575                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
1576                                 return -1;
1577                         }
1578
1579                         if ((cert->next->extensions_present &
1580                              X509_EXT_PATH_LEN_CONSTRAINT) &&
1581                             idx > cert->next->path_len_constraint) {
1582                                 wpa_printf(MSG_DEBUG, "X509: pathLenConstraint"
1583                                            " not met (idx=%lu issuer "
1584                                            "pathLenConstraint=%lu)", idx,
1585                                            cert->next->path_len_constraint);
1586                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
1587                                 return -1;
1588                         }
1589
1590                         if (x509_certificate_check_signature(cert->next, cert)
1591                             < 0) {
1592                                 wpa_printf(MSG_DEBUG, "X509: Invalid "
1593                                            "certificate signature within "
1594                                            "chain");
1595                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
1596                                 return -1;
1597                         }
1598                 }
1599
1600                 for (trust = trusted; trust; trust = trust->next) {
1601                         if (x509_name_compare(&cert->issuer, &trust->subject)
1602                             == 0)
1603                                 break;
1604                 }
1605
1606                 if (trust) {
1607                         wpa_printf(MSG_DEBUG, "X509: Found issuer from the "
1608                                    "list of trusted certificates");
1609                         if (x509_valid_issuer(trust) < 0) {
1610                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
1611                                 return -1;
1612                         }
1613
1614                         if (x509_certificate_check_signature(trust, cert) < 0)
1615                         {
1616                                 wpa_printf(MSG_DEBUG, "X509: Invalid "
1617                                            "certificate signature");
1618                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
1619                                 return -1;
1620                         }
1621
1622                         wpa_printf(MSG_DEBUG, "X509: Trusted certificate "
1623                                    "found to complete the chain");
1624                         chain_trusted = 1;
1625                 }
1626         }
1627
1628         if (!chain_trusted) {
1629                 wpa_printf(MSG_DEBUG, "X509: Did not find any of the issuers "
1630                            "from the list of trusted certificates");
1631                 if (trusted) {
1632                         *reason = X509_VALIDATE_UNKNOWN_CA;
1633                         return -1;
1634                 }
1635                 wpa_printf(MSG_DEBUG, "X509: Certificate chain validation "
1636                            "disabled - ignore unknown CA issue");
1637         }
1638
1639         wpa_printf(MSG_DEBUG, "X509: Certificate chain valid");
1640
1641         return 0;
1642 }
1643
1644
1645 /**
1646  * x509_certificate_get_subject - Get a certificate based on Subject name
1647  * @chain: Certificate chain to search through
1648  * @name: Subject name to search for
1649  * Returns: Pointer to the certificate with the given Subject name or
1650  * %NULL on failure
1651  */
1652 struct x509_certificate *
1653 x509_certificate_get_subject(struct x509_certificate *chain,
1654                              struct x509_name *name)
1655 {
1656         struct x509_certificate *cert;
1657
1658         for (cert = chain; cert; cert = cert->next) {
1659                 if (x509_name_compare(&cert->subject, name) == 0)
1660                         return cert;
1661         }
1662         return NULL;
1663 }
1664
1665
1666 /**
1667  * x509_certificate_self_signed - Is the certificate self-signed?
1668  * @cert: Certificate
1669  * Returns: 1 if certificate is self-signed, 0 if not
1670  */
1671 int x509_certificate_self_signed(struct x509_certificate *cert)
1672 {
1673         return x509_name_compare(&cert->issuer, &cert->subject) == 0;
1674 }
1675
1676 #endif /* CONFIG_INTERNAL_X509 */