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