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