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