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