Merge branch 'vendor/ZLIB'
[dragonfly.git] / contrib / hostapd / src / tls / 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 static int x509_sha256_oid(struct asn1_oid *oid)
1189 {
1190         return oid->len == 9 &&
1191                 oid->oid[0] == 2 /* joint-iso-itu-t */ &&
1192                 oid->oid[1] == 16 /* country */ &&
1193                 oid->oid[2] == 840 /* us */ &&
1194                 oid->oid[3] == 1 /* organization */ &&
1195                 oid->oid[4] == 101 /* gov */ &&
1196                 oid->oid[5] == 3 /* csor */ &&
1197                 oid->oid[6] == 4 /* nistAlgorithm */ &&
1198                 oid->oid[7] == 2 /* hashAlgs */ &&
1199                 oid->oid[8] == 1 /* sha256 */;
1200 }
1201
1202
1203 /**
1204  * x509_certificate_parse - Parse a X.509 certificate in DER format
1205  * @buf: Pointer to the X.509 certificate in DER format
1206  * @len: Buffer length
1207  * Returns: Pointer to the parsed certificate or %NULL on failure
1208  *
1209  * Caller is responsible for freeing the returned certificate by calling
1210  * x509_certificate_free().
1211  */
1212 struct x509_certificate * x509_certificate_parse(const u8 *buf, size_t len)
1213 {
1214         struct asn1_hdr hdr;
1215         const u8 *pos, *end, *hash_start;
1216         struct x509_certificate *cert;
1217
1218         cert = os_zalloc(sizeof(*cert) + len);
1219         if (cert == NULL)
1220                 return NULL;
1221         os_memcpy(cert + 1, buf, len);
1222         cert->cert_start = (u8 *) (cert + 1);
1223         cert->cert_len = len;
1224
1225         pos = buf;
1226         end = buf + len;
1227
1228         /* RFC 3280 - X.509 v3 certificate / ASN.1 DER */
1229
1230         /* Certificate ::= SEQUENCE */
1231         if (asn1_get_next(pos, len, &hdr) < 0 ||
1232             hdr.class != ASN1_CLASS_UNIVERSAL ||
1233             hdr.tag != ASN1_TAG_SEQUENCE) {
1234                 wpa_printf(MSG_DEBUG, "X509: Certificate did not start with "
1235                            "a valid SEQUENCE - found class %d tag 0x%x",
1236                            hdr.class, hdr.tag);
1237                 x509_certificate_free(cert);
1238                 return NULL;
1239         }
1240         pos = hdr.payload;
1241
1242         if (pos + hdr.length > end) {
1243                 x509_certificate_free(cert);
1244                 return NULL;
1245         }
1246
1247         if (pos + hdr.length < end) {
1248                 wpa_hexdump(MSG_MSGDUMP, "X509: Ignoring extra data after DER "
1249                             "encoded certificate",
1250                             pos + hdr.length, end - pos + hdr.length);
1251                 end = pos + hdr.length;
1252         }
1253
1254         hash_start = pos;
1255         cert->tbs_cert_start = cert->cert_start + (hash_start - buf);
1256         if (x509_parse_tbs_certificate(pos, end - pos, cert, &pos)) {
1257                 x509_certificate_free(cert);
1258                 return NULL;
1259         }
1260         cert->tbs_cert_len = pos - hash_start;
1261
1262         /* signatureAlgorithm AlgorithmIdentifier */
1263         if (x509_parse_algorithm_identifier(pos, end - pos,
1264                                             &cert->signature_alg, &pos)) {
1265                 x509_certificate_free(cert);
1266                 return NULL;
1267         }
1268
1269         /* signatureValue BIT STRING */
1270         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1271             hdr.class != ASN1_CLASS_UNIVERSAL ||
1272             hdr.tag != ASN1_TAG_BITSTRING) {
1273                 wpa_printf(MSG_DEBUG, "X509: Expected BITSTRING "
1274                            "(signatureValue) - found class %d tag 0x%x",
1275                            hdr.class, hdr.tag);
1276                 x509_certificate_free(cert);
1277                 return NULL;
1278         }
1279         if (hdr.length < 1) {
1280                 x509_certificate_free(cert);
1281                 return NULL;
1282         }
1283         pos = hdr.payload;
1284         if (*pos) {
1285                 wpa_printf(MSG_DEBUG, "X509: BITSTRING - %d unused bits",
1286                            *pos);
1287                 /* PKCS #1 v1.5 10.2.1:
1288                  * It is an error if the length in bits of the signature S is
1289                  * not a multiple of eight.
1290                  */
1291                 x509_certificate_free(cert);
1292                 return NULL;
1293         }
1294         os_free(cert->sign_value);
1295         cert->sign_value = os_malloc(hdr.length - 1);
1296         if (cert->sign_value == NULL) {
1297                 wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for "
1298                            "signatureValue");
1299                 x509_certificate_free(cert);
1300                 return NULL;
1301         }
1302         os_memcpy(cert->sign_value, pos + 1, hdr.length - 1);
1303         cert->sign_value_len = hdr.length - 1;
1304         wpa_hexdump(MSG_MSGDUMP, "X509: signature",
1305                     cert->sign_value, cert->sign_value_len);
1306
1307         return cert;
1308 }
1309
1310
1311 /**
1312  * x509_certificate_check_signature - Verify certificate signature
1313  * @issuer: Issuer certificate
1314  * @cert: Certificate to be verified
1315  * Returns: 0 if cert has a valid signature that was signed by the issuer,
1316  * -1 if not
1317  */
1318 int x509_certificate_check_signature(struct x509_certificate *issuer,
1319                                      struct x509_certificate *cert)
1320 {
1321         struct crypto_public_key *pk;
1322         u8 *data;
1323         const u8 *pos, *end, *next, *da_end;
1324         size_t data_len;
1325         struct asn1_hdr hdr;
1326         struct asn1_oid oid;
1327         u8 hash[32];
1328         size_t hash_len;
1329
1330         if (!x509_pkcs_oid(&cert->signature.oid) ||
1331             cert->signature.oid.len != 7 ||
1332             cert->signature.oid.oid[5] != 1 /* pkcs-1 */) {
1333                 wpa_printf(MSG_DEBUG, "X509: Unrecognized signature "
1334                            "algorithm");
1335                 return -1;
1336         }
1337
1338         pk = crypto_public_key_import(issuer->public_key,
1339                                       issuer->public_key_len);
1340         if (pk == NULL)
1341                 return -1;
1342
1343         data_len = cert->sign_value_len;
1344         data = os_malloc(data_len);
1345         if (data == NULL) {
1346                 crypto_public_key_free(pk);
1347                 return -1;
1348         }
1349
1350         if (crypto_public_key_decrypt_pkcs1(pk, cert->sign_value,
1351                                             cert->sign_value_len, data,
1352                                             &data_len) < 0) {
1353                 wpa_printf(MSG_DEBUG, "X509: Failed to decrypt signature");
1354                 crypto_public_key_free(pk);
1355                 os_free(data);
1356                 return -1;
1357         }
1358         crypto_public_key_free(pk);
1359
1360         wpa_hexdump(MSG_MSGDUMP, "X509: Signature data D", data, data_len);
1361
1362         /*
1363          * PKCS #1 v1.5, 10.1.2:
1364          *
1365          * DigestInfo ::= SEQUENCE {
1366          *     digestAlgorithm DigestAlgorithmIdentifier,
1367          *     digest Digest
1368          * }
1369          *
1370          * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1371          *
1372          * Digest ::= OCTET STRING
1373          *
1374          */
1375         if (asn1_get_next(data, data_len, &hdr) < 0 ||
1376             hdr.class != ASN1_CLASS_UNIVERSAL ||
1377             hdr.tag != ASN1_TAG_SEQUENCE) {
1378                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
1379                            "(DigestInfo) - found class %d tag 0x%x",
1380                            hdr.class, hdr.tag);
1381                 os_free(data);
1382                 return -1;
1383         }
1384
1385         pos = hdr.payload;
1386         end = pos + hdr.length;
1387
1388         /*
1389          * X.509:
1390          * AlgorithmIdentifier ::= SEQUENCE {
1391          *     algorithm            OBJECT IDENTIFIER,
1392          *     parameters           ANY DEFINED BY algorithm OPTIONAL
1393          * }
1394          */
1395
1396         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1397             hdr.class != ASN1_CLASS_UNIVERSAL ||
1398             hdr.tag != ASN1_TAG_SEQUENCE) {
1399                 wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
1400                            "(AlgorithmIdentifier) - found class %d tag 0x%x",
1401                            hdr.class, hdr.tag);
1402                 os_free(data);
1403                 return -1;
1404         }
1405         da_end = hdr.payload + hdr.length;
1406
1407         if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {
1408                 wpa_printf(MSG_DEBUG, "X509: Failed to parse digestAlgorithm");
1409                 os_free(data);
1410                 return -1;
1411         }
1412
1413         if (x509_sha1_oid(&oid)) {
1414                 if (cert->signature.oid.oid[6] !=
1415                     5 /* sha-1WithRSAEncryption */) {
1416                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA1 "
1417                                    "does not match with certificate "
1418                                    "signatureAlgorithm (%lu)",
1419                                    cert->signature.oid.oid[6]);
1420                         os_free(data);
1421                         return -1;
1422                 }
1423                 goto skip_digest_oid;
1424         }
1425
1426         if (x509_sha256_oid(&oid)) {
1427                 if (cert->signature.oid.oid[6] !=
1428                     11 /* sha2561WithRSAEncryption */) {
1429                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm SHA256 "
1430                                    "does not match with certificate "
1431                                    "signatureAlgorithm (%lu)",
1432                                    cert->signature.oid.oid[6]);
1433                         os_free(data);
1434                         return -1;
1435                 }
1436                 goto skip_digest_oid;
1437         }
1438
1439         if (!x509_digest_oid(&oid)) {
1440                 wpa_printf(MSG_DEBUG, "X509: Unrecognized digestAlgorithm");
1441                 os_free(data);
1442                 return -1;
1443         }
1444         switch (oid.oid[5]) {
1445         case 5: /* md5 */
1446                 if (cert->signature.oid.oid[6] != 4 /* md5WithRSAEncryption */)
1447                 {
1448                         wpa_printf(MSG_DEBUG, "X509: digestAlgorithm MD5 does "
1449                                    "not match with certificate "
1450                                    "signatureAlgorithm (%lu)",
1451                                    cert->signature.oid.oid[6]);
1452                         os_free(data);
1453                         return -1;
1454                 }
1455                 break;
1456         case 2: /* md2 */
1457         case 4: /* md4 */
1458         default:
1459                 wpa_printf(MSG_DEBUG, "X509: Unsupported digestAlgorithm "
1460                            "(%lu)", oid.oid[5]);
1461                 os_free(data);
1462                 return -1;
1463         }
1464
1465 skip_digest_oid:
1466         /* Digest ::= OCTET STRING */
1467         pos = da_end;
1468         end = data + data_len;
1469
1470         if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1471             hdr.class != ASN1_CLASS_UNIVERSAL ||
1472             hdr.tag != ASN1_TAG_OCTETSTRING) {
1473                 wpa_printf(MSG_DEBUG, "X509: Expected OCTETSTRING "
1474                            "(Digest) - found class %d tag 0x%x",
1475                            hdr.class, hdr.tag);
1476                 os_free(data);
1477                 return -1;
1478         }
1479         wpa_hexdump(MSG_MSGDUMP, "X509: Decrypted Digest",
1480                     hdr.payload, hdr.length);
1481
1482         switch (cert->signature.oid.oid[6]) {
1483         case 4: /* md5WithRSAEncryption */
1484                 md5_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len,
1485                            hash);
1486                 hash_len = 16;
1487                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (MD5)",
1488                             hash, hash_len);
1489                 break;
1490         case 5: /* sha-1WithRSAEncryption */
1491                 sha1_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len,
1492                             hash);
1493                 hash_len = 20;
1494                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA1)",
1495                             hash, hash_len);
1496                 break;
1497         case 11: /* sha256WithRSAEncryption */
1498 #ifdef NEED_SHA256
1499                 sha256_vector(1, &cert->tbs_cert_start, &cert->tbs_cert_len,
1500                               hash);
1501                 hash_len = 32;
1502                 wpa_hexdump(MSG_MSGDUMP, "X509: Certificate hash (SHA256)",
1503                             hash, hash_len);
1504                 break;
1505 #else /* NEED_SHA256 */
1506                 wpa_printf(MSG_INFO, "X509: SHA256 support disabled");
1507                 os_free(data);
1508                 return -1;
1509 #endif /* NEED_SHA256 */
1510         case 2: /* md2WithRSAEncryption */
1511         case 12: /* sha384WithRSAEncryption */
1512         case 13: /* sha512WithRSAEncryption */
1513         default:
1514                 wpa_printf(MSG_INFO, "X509: Unsupported certificate signature "
1515                            "algorithm (%lu)", cert->signature.oid.oid[6]);
1516                 os_free(data);
1517                 return -1;
1518         }
1519
1520         if (hdr.length != hash_len ||
1521             os_memcmp(hdr.payload, hash, hdr.length) != 0) {
1522                 wpa_printf(MSG_INFO, "X509: Certificate Digest does not match "
1523                            "with calculated tbsCertificate hash");
1524                 os_free(data);
1525                 return -1;
1526         }
1527
1528         os_free(data);
1529
1530         wpa_printf(MSG_DEBUG, "X509: Certificate Digest matches with "
1531                    "calculated tbsCertificate hash");
1532
1533         return 0;
1534 }
1535
1536
1537 static int x509_valid_issuer(const struct x509_certificate *cert)
1538 {
1539         if ((cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS) &&
1540             !cert->ca) {
1541                 wpa_printf(MSG_DEBUG, "X509: Non-CA certificate used as an "
1542                            "issuer");
1543                 return -1;
1544         }
1545
1546         if (cert->version == X509_CERT_V3 &&
1547             !(cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS)) {
1548                 wpa_printf(MSG_DEBUG, "X509: v3 CA certificate did not "
1549                            "include BasicConstraints extension");
1550                 return -1;
1551         }
1552
1553         if ((cert->extensions_present & X509_EXT_KEY_USAGE) &&
1554             !(cert->key_usage & X509_KEY_USAGE_KEY_CERT_SIGN)) {
1555                 wpa_printf(MSG_DEBUG, "X509: Issuer certificate did not have "
1556                            "keyCertSign bit in Key Usage");
1557                 return -1;
1558         }
1559
1560         return 0;
1561 }
1562
1563
1564 /**
1565  * x509_certificate_chain_validate - Validate X.509 certificate chain
1566  * @trusted: List of trusted certificates
1567  * @chain: Certificate chain to be validated (first chain must be issued by
1568  * signed by the second certificate in the chain and so on)
1569  * @reason: Buffer for returning failure reason (X509_VALIDATE_*)
1570  * Returns: 0 if chain is valid, -1 if not
1571  */
1572 int x509_certificate_chain_validate(struct x509_certificate *trusted,
1573                                     struct x509_certificate *chain,
1574                                     int *reason)
1575 {
1576         long unsigned idx;
1577         int chain_trusted = 0;
1578         struct x509_certificate *cert, *trust;
1579         char buf[128];
1580         struct os_time now;
1581
1582         *reason = X509_VALIDATE_OK;
1583
1584         wpa_printf(MSG_DEBUG, "X509: Validate certificate chain");
1585         os_get_time(&now);
1586
1587         for (cert = chain, idx = 0; cert; cert = cert->next, idx++) {
1588                 x509_name_string(&cert->subject, buf, sizeof(buf)); 
1589                 wpa_printf(MSG_DEBUG, "X509: %lu: %s", idx, buf);
1590
1591                 if (chain_trusted)
1592                         continue;
1593
1594                 if ((unsigned long) now.sec <
1595                     (unsigned long) cert->not_before ||
1596                     (unsigned long) now.sec >
1597                     (unsigned long) cert->not_after) {
1598                         wpa_printf(MSG_INFO, "X509: Certificate not valid "
1599                                    "(now=%lu not_before=%lu not_after=%lu)",
1600                                    now.sec, cert->not_before, cert->not_after);
1601                         *reason = X509_VALIDATE_CERTIFICATE_EXPIRED;
1602                         return -1;
1603                 }
1604
1605                 if (cert->next) {
1606                         if (x509_name_compare(&cert->issuer,
1607                                               &cert->next->subject) != 0) {
1608                                 wpa_printf(MSG_DEBUG, "X509: Certificate "
1609                                            "chain issuer name mismatch");
1610                                 x509_name_string(&cert->issuer, buf,
1611                                                  sizeof(buf)); 
1612                                 wpa_printf(MSG_DEBUG, "X509: cert issuer: %s",
1613                                            buf);
1614                                 x509_name_string(&cert->next->subject, buf,
1615                                                  sizeof(buf)); 
1616                                 wpa_printf(MSG_DEBUG, "X509: next cert "
1617                                            "subject: %s", buf);
1618                                 *reason = X509_VALIDATE_CERTIFICATE_UNKNOWN;
1619                                 return -1;
1620                         }
1621
1622                         if (x509_valid_issuer(cert->next) < 0) {
1623                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
1624                                 return -1;
1625                         }
1626
1627                         if ((cert->next->extensions_present &
1628                              X509_EXT_PATH_LEN_CONSTRAINT) &&
1629                             idx > cert->next->path_len_constraint) {
1630                                 wpa_printf(MSG_DEBUG, "X509: pathLenConstraint"
1631                                            " not met (idx=%lu issuer "
1632                                            "pathLenConstraint=%lu)", idx,
1633                                            cert->next->path_len_constraint);
1634                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
1635                                 return -1;
1636                         }
1637
1638                         if (x509_certificate_check_signature(cert->next, cert)
1639                             < 0) {
1640                                 wpa_printf(MSG_DEBUG, "X509: Invalid "
1641                                            "certificate signature within "
1642                                            "chain");
1643                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
1644                                 return -1;
1645                         }
1646                 }
1647
1648                 for (trust = trusted; trust; trust = trust->next) {
1649                         if (x509_name_compare(&cert->issuer, &trust->subject)
1650                             == 0)
1651                                 break;
1652                 }
1653
1654                 if (trust) {
1655                         wpa_printf(MSG_DEBUG, "X509: Found issuer from the "
1656                                    "list of trusted certificates");
1657                         if (x509_valid_issuer(trust) < 0) {
1658                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
1659                                 return -1;
1660                         }
1661
1662                         if (x509_certificate_check_signature(trust, cert) < 0)
1663                         {
1664                                 wpa_printf(MSG_DEBUG, "X509: Invalid "
1665                                            "certificate signature");
1666                                 *reason = X509_VALIDATE_BAD_CERTIFICATE;
1667                                 return -1;
1668                         }
1669
1670                         wpa_printf(MSG_DEBUG, "X509: Trusted certificate "
1671                                    "found to complete the chain");
1672                         chain_trusted = 1;
1673                 }
1674         }
1675
1676         if (!chain_trusted) {
1677                 wpa_printf(MSG_DEBUG, "X509: Did not find any of the issuers "
1678                            "from the list of trusted certificates");
1679                 if (trusted) {
1680                         *reason = X509_VALIDATE_UNKNOWN_CA;
1681                         return -1;
1682                 }
1683                 wpa_printf(MSG_DEBUG, "X509: Certificate chain validation "
1684                            "disabled - ignore unknown CA issue");
1685         }
1686
1687         wpa_printf(MSG_DEBUG, "X509: Certificate chain valid");
1688
1689         return 0;
1690 }
1691
1692
1693 /**
1694  * x509_certificate_get_subject - Get a certificate based on Subject name
1695  * @chain: Certificate chain to search through
1696  * @name: Subject name to search for
1697  * Returns: Pointer to the certificate with the given Subject name or
1698  * %NULL on failure
1699  */
1700 struct x509_certificate *
1701 x509_certificate_get_subject(struct x509_certificate *chain,
1702                              struct x509_name *name)
1703 {
1704         struct x509_certificate *cert;
1705
1706         for (cert = chain; cert; cert = cert->next) {
1707                 if (x509_name_compare(&cert->subject, name) == 0)
1708                         return cert;
1709         }
1710         return NULL;
1711 }
1712
1713
1714 /**
1715  * x509_certificate_self_signed - Is the certificate self-signed?
1716  * @cert: Certificate
1717  * Returns: 1 if certificate is self-signed, 0 if not
1718  */
1719 int x509_certificate_self_signed(struct x509_certificate *cert)
1720 {
1721         return x509_name_compare(&cert->issuer, &cert->subject) == 0;
1722 }
1723
1724 #endif /* CONFIG_INTERNAL_X509 */