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