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