x509v3.c revision 351611
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
17void 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 */
45void 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 */
67void 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
80static int x509_whitespace(char c)
81{
82	return c == ' ' || c == '\t';
83}
84
85
86static 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
108static 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 */
148int 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
181int 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
219static 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
291int 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
468static 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 */
498void 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
534done:
535	if (pos < end)
536		*pos = '\0';
537	end[-1] = '\0';
538}
539
540
541static 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
557static 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
575int 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
692static 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
756static 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
766static 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
775static 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
812static 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
893static 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
915static 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
937static 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
961static 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
975static 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
991static 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
1069static 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
1096static 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
1123static 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
1136static 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
1145static 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
1154static 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
1163static 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
1172static 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
1229static 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
1259static 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
1336static 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
1366static 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
1571static 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
1581static 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
1589static 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
1597int 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
1609static 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
1623int x509_sha256_oid(struct asn1_oid *oid)
1624{
1625	return x509_sha2_oid(oid) &&
1626		oid->oid[8] == 1 /* sha256 */;
1627}
1628
1629
1630int x509_sha384_oid(struct asn1_oid *oid)
1631{
1632	return x509_sha2_oid(oid) &&
1633		oid->oid[8] == 2 /* sha384 */;
1634}
1635
1636
1637int 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 */
1653struct 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 */
1758int 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
1767int 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
1940skip_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
2022static 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 */
2057int 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 */
2188struct x509_certificate *
2189x509_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 */
2207int x509_certificate_self_signed(struct x509_certificate *cert)
2208{
2209	return x509_name_compare(&cert->issuer, &cert->subject) == 0;
2210}
2211