x509v3.c revision 252726
1174982Salc/*
2174982Salc * X.509v3 certificate parsing and processing (RFC 3280 profile)
3174982Salc * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
4174982Salc *
5174982Salc * This software may be distributed under the terms of the BSD license.
6174982Salc * See README for more details.
7174982Salc */
8174982Salc
9174982Salc#include "includes.h"
10174982Salc
11174982Salc#include "common.h"
12174982Salc#include "crypto/crypto.h"
13174982Salc#include "asn1.h"
14174982Salc#include "x509v3.h"
15174982Salc
16174982Salc
17174982Salcstatic void x509_free_name(struct x509_name *name)
18174982Salc{
19174982Salc	size_t i;
20174982Salc
21174982Salc	for (i = 0; i < name->num_attr; i++) {
22174982Salc		os_free(name->attr[i].value);
23174982Salc		name->attr[i].value = NULL;
24174982Salc		name->attr[i].type = X509_NAME_ATTR_NOT_USED;
25174982Salc	}
26174982Salc	name->num_attr = 0;
27174982Salc	os_free(name->email);
28174982Salc	name->email = NULL;
29174982Salc
30174982Salc	os_free(name->alt_email);
31174982Salc	os_free(name->dns);
32174982Salc	os_free(name->uri);
33174982Salc	os_free(name->ip);
34174982Salc	name->alt_email = name->dns = name->uri = NULL;
35174982Salc	name->ip = NULL;
36174982Salc	name->ip_len = 0;
37174982Salc	os_memset(&name->rid, 0, sizeof(name->rid));
38174982Salc}
39174982Salc
40174982Salc
41174982Salc/**
42174982Salc * x509_certificate_free - Free an X.509 certificate
43174982Salc * @cert: Certificate to be freed
44174982Salc */
45174982Salcvoid x509_certificate_free(struct x509_certificate *cert)
46174982Salc{
47174982Salc	if (cert == NULL)
48174982Salc		return;
49174982Salc	if (cert->next) {
50174982Salc		wpa_printf(MSG_DEBUG, "X509: x509_certificate_free: cer=%p "
51174982Salc			   "was still on a list (next=%p)\n",
52174982Salc			   cert, cert->next);
53174982Salc	}
54174982Salc	x509_free_name(&cert->issuer);
55174982Salc	x509_free_name(&cert->subject);
56174982Salc	os_free(cert->public_key);
57174982Salc	os_free(cert->sign_value);
58174982Salc	os_free(cert);
59174982Salc}
60174982Salc
61174982Salc
62174982Salc/**
63174982Salc * x509_certificate_free - Free an X.509 certificate chain
64174982Salc * @cert: Pointer to the first certificate in the chain
65174982Salc */
66174982Salcvoid x509_certificate_chain_free(struct x509_certificate *cert)
67174982Salc{
68174982Salc	struct x509_certificate *next;
69174982Salc
70174982Salc	while (cert) {
71174982Salc		next = cert->next;
72174982Salc		cert->next = NULL;
73174982Salc		x509_certificate_free(cert);
74174982Salc		cert = next;
75174982Salc	}
76174982Salc}
77174982Salc
78174982Salc
79174982Salcstatic int x509_whitespace(char c)
80174982Salc{
81174982Salc	return c == ' ' || c == '\t';
82174982Salc}
83174982Salc
84174982Salc
85174982Salcstatic void x509_str_strip_whitespace(char *a)
86174982Salc{
87174982Salc	char *ipos, *opos;
88174982Salc	int remove_whitespace = 1;
89174982Salc
90174982Salc	ipos = opos = a;
91174982Salc
92174982Salc	while (*ipos) {
93174982Salc		if (remove_whitespace && x509_whitespace(*ipos))
94174982Salc			ipos++;
95174982Salc		else {
96174982Salc			remove_whitespace = x509_whitespace(*ipos);
97174982Salc			*opos++ = *ipos++;
98174982Salc		}
99174982Salc	}
100174982Salc
101174982Salc	*opos-- = '\0';
102174982Salc	if (opos > a && x509_whitespace(*opos))
103174982Salc		*opos = '\0';
104174982Salc}
105174982Salc
106174982Salc
107174982Salcstatic int x509_str_compare(const char *a, const char *b)
108174982Salc{
109174982Salc	char *aa, *bb;
110174982Salc	int ret;
111174982Salc
112174982Salc	if (!a && b)
113174982Salc		return -1;
114174982Salc	if (a && !b)
115174982Salc		return 1;
116174982Salc	if (!a && !b)
117174982Salc		return 0;
118174982Salc
119174982Salc	aa = os_strdup(a);
120174982Salc	bb = os_strdup(b);
121174982Salc
122174982Salc	if (aa == NULL || bb == NULL) {
123174982Salc		os_free(aa);
124174982Salc		os_free(bb);
125174982Salc		return os_strcasecmp(a, b);
126174982Salc	}
127174982Salc
128174982Salc	x509_str_strip_whitespace(aa);
129174982Salc	x509_str_strip_whitespace(bb);
130174982Salc
131174982Salc	ret = os_strcasecmp(aa, bb);
132174982Salc
133174982Salc	os_free(aa);
134174982Salc	os_free(bb);
135174982Salc
136174982Salc	return ret;
137174982Salc}
138174982Salc
139174982Salc
140174982Salc/**
141174982Salc * x509_name_compare - Compare X.509 certificate names
142174982Salc * @a: Certificate name
143174982Salc * @b: Certificate name
144174982Salc * Returns: <0, 0, or >0 based on whether a is less than, equal to, or
145174982Salc * greater than b
146174982Salc */
147174982Salcint x509_name_compare(struct x509_name *a, struct x509_name *b)
148174982Salc{
149174982Salc	int res;
150174982Salc	size_t i;
151174982Salc
152174982Salc	if (!a && b)
153174982Salc		return -1;
154174982Salc	if (a && !b)
155174982Salc		return 1;
156174982Salc	if (!a && !b)
157174982Salc		return 0;
158174982Salc	if (a->num_attr < b->num_attr)
159174982Salc		return -1;
160174982Salc	if (a->num_attr > b->num_attr)
161174982Salc		return 1;
162174982Salc
163174982Salc	for (i = 0; i < a->num_attr; i++) {
164174982Salc		if (a->attr[i].type < b->attr[i].type)
165174982Salc			return -1;
166174982Salc		if (a->attr[i].type > b->attr[i].type)
167174982Salc			return -1;
168174982Salc		res = x509_str_compare(a->attr[i].value, b->attr[i].value);
169174982Salc		if (res)
170174982Salc			return res;
171174982Salc	}
172174982Salc	res = x509_str_compare(a->email, b->email);
173174982Salc	if (res)
174174982Salc		return res;
175174982Salc
176174982Salc	return 0;
177174982Salc}
178174982Salc
179174982Salc
180174982Salcstatic int x509_parse_algorithm_identifier(
181174982Salc	const u8 *buf, size_t len,
182174982Salc	struct x509_algorithm_identifier *id, const u8 **next)
183174982Salc{
184174982Salc	struct asn1_hdr hdr;
185174982Salc	const u8 *pos, *end;
186174982Salc
187174982Salc	/*
188174982Salc	 * AlgorithmIdentifier ::= SEQUENCE {
189174982Salc	 *     algorithm            OBJECT IDENTIFIER,
190174982Salc	 *     parameters           ANY DEFINED BY algorithm OPTIONAL
191174982Salc	 * }
192174982Salc	 */
193174982Salc
194174982Salc	if (asn1_get_next(buf, len, &hdr) < 0 ||
195174982Salc	    hdr.class != ASN1_CLASS_UNIVERSAL ||
196174982Salc	    hdr.tag != ASN1_TAG_SEQUENCE) {
197174982Salc		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
198174982Salc			   "(AlgorithmIdentifier) - found class %d tag 0x%x",
199174982Salc			   hdr.class, hdr.tag);
200174982Salc		return -1;
201174982Salc	}
202174982Salc	pos = hdr.payload;
203174982Salc	end = pos + hdr.length;
204174982Salc
205174982Salc	if (end > buf + len)
206174982Salc		return -1;
207174982Salc
208174982Salc	*next = end;
209174982Salc
210174982Salc	if (asn1_get_oid(pos, end - pos, &id->oid, &pos))
211174982Salc		return -1;
212174982Salc
213174982Salc	/* TODO: optional parameters */
214174982Salc
215174982Salc	return 0;
216174982Salc}
217174982Salc
218174982Salc
219174982Salcstatic int x509_parse_public_key(const u8 *buf, size_t len,
220174982Salc				 struct x509_certificate *cert,
221174982Salc				 const u8 **next)
222174982Salc{
223174982Salc	struct asn1_hdr hdr;
224174982Salc	const u8 *pos, *end;
225174982Salc
226174982Salc	/*
227174982Salc	 * SubjectPublicKeyInfo ::= SEQUENCE {
228174982Salc	 *     algorithm            AlgorithmIdentifier,
229174982Salc	 *     subjectPublicKey     BIT STRING
230174982Salc	 * }
231174982Salc	 */
232174982Salc
233174982Salc	pos = buf;
234174982Salc	end = buf + len;
235174982Salc
236174982Salc	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
237174982Salc	    hdr.class != ASN1_CLASS_UNIVERSAL ||
238174982Salc	    hdr.tag != ASN1_TAG_SEQUENCE) {
239174982Salc		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
240174982Salc			   "(SubjectPublicKeyInfo) - found class %d tag 0x%x",
241174982Salc			   hdr.class, hdr.tag);
242174982Salc		return -1;
243174982Salc	}
244174982Salc	pos = hdr.payload;
245174982Salc
246174982Salc	if (pos + hdr.length > end)
247174982Salc		return -1;
248174982Salc	end = pos + hdr.length;
249174982Salc	*next = end;
250174982Salc
251174982Salc	if (x509_parse_algorithm_identifier(pos, end - pos,
252174982Salc					    &cert->public_key_alg, &pos))
253174982Salc		return -1;
254174982Salc
255174982Salc	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
256174982Salc	    hdr.class != ASN1_CLASS_UNIVERSAL ||
257174982Salc	    hdr.tag != ASN1_TAG_BITSTRING) {
258174982Salc		wpa_printf(MSG_DEBUG, "X509: Expected BITSTRING "
259174982Salc			   "(subjectPublicKey) - found class %d tag 0x%x",
260174982Salc			   hdr.class, hdr.tag);
261174982Salc		return -1;
262174982Salc	}
263174982Salc	if (hdr.length < 1)
264174982Salc		return -1;
265174982Salc	pos = hdr.payload;
266174982Salc	if (*pos) {
267174982Salc		wpa_printf(MSG_DEBUG, "X509: BITSTRING - %d unused bits",
268174982Salc			   *pos);
269174982Salc		/*
270174982Salc		 * TODO: should this be rejected? X.509 certificates are
271174982Salc		 * unlikely to use such a construction. Now we would end up
272174982Salc		 * including the extra bits in the buffer which may also be
273174982Salc		 * ok.
274174982Salc		 */
275174982Salc	}
276174982Salc	os_free(cert->public_key);
277174982Salc	cert->public_key = os_malloc(hdr.length - 1);
278174982Salc	if (cert->public_key == NULL) {
279174982Salc		wpa_printf(MSG_DEBUG, "X509: Failed to allocate memory for "
280174982Salc			   "public key");
281174982Salc		return -1;
282174982Salc	}
283174982Salc	os_memcpy(cert->public_key, pos + 1, hdr.length - 1);
284174982Salc	cert->public_key_len = hdr.length - 1;
285174982Salc	wpa_hexdump(MSG_MSGDUMP, "X509: subjectPublicKey",
286174982Salc		    cert->public_key, cert->public_key_len);
287174982Salc
288174982Salc	return 0;
289174982Salc}
290174982Salc
291174982Salc
292174982Salcstatic int x509_parse_name(const u8 *buf, size_t len, struct x509_name *name,
293174982Salc			   const u8 **next)
294174982Salc{
295174982Salc	struct asn1_hdr hdr;
296174982Salc	const u8 *pos, *end, *set_pos, *set_end, *seq_pos, *seq_end;
297174982Salc	struct asn1_oid oid;
298174982Salc	char *val;
299174982Salc
300174982Salc	/*
301174982Salc	 * Name ::= CHOICE { RDNSequence }
302174982Salc	 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
303174982Salc	 * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
304174982Salc	 * AttributeTypeAndValue ::= SEQUENCE {
305174982Salc	 *     type     AttributeType,
306174982Salc	 *     value    AttributeValue
307174982Salc	 * }
308174982Salc	 * AttributeType ::= OBJECT IDENTIFIER
309174982Salc	 * AttributeValue ::= ANY DEFINED BY AttributeType
310174982Salc	 */
311174982Salc
312174982Salc	if (asn1_get_next(buf, len, &hdr) < 0 ||
313174982Salc	    hdr.class != ASN1_CLASS_UNIVERSAL ||
314174982Salc	    hdr.tag != ASN1_TAG_SEQUENCE) {
315174982Salc		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
316174982Salc			   "(Name / RDNSequencer) - found class %d tag 0x%x",
317174982Salc			   hdr.class, hdr.tag);
318174982Salc		return -1;
319174982Salc	}
320174982Salc	pos = hdr.payload;
321174982Salc
322174982Salc	if (pos + hdr.length > buf + len)
323174982Salc		return -1;
324174982Salc
325174982Salc	end = *next = pos + hdr.length;
326174982Salc
327174982Salc	while (pos < end) {
328174982Salc		enum x509_name_attr_type type;
329174982Salc
330174982Salc		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
331174982Salc		    hdr.class != ASN1_CLASS_UNIVERSAL ||
332174982Salc		    hdr.tag != ASN1_TAG_SET) {
333174982Salc			wpa_printf(MSG_DEBUG, "X509: Expected SET "
334174982Salc				   "(RelativeDistinguishedName) - found class "
335174982Salc				   "%d tag 0x%x", hdr.class, hdr.tag);
336174982Salc			x509_free_name(name);
337174982Salc			return -1;
338174982Salc		}
339174982Salc
340174982Salc		set_pos = hdr.payload;
341174982Salc		pos = set_end = hdr.payload + hdr.length;
342174982Salc
343174982Salc		if (asn1_get_next(set_pos, set_end - set_pos, &hdr) < 0 ||
344174982Salc		    hdr.class != ASN1_CLASS_UNIVERSAL ||
345174982Salc		    hdr.tag != ASN1_TAG_SEQUENCE) {
346174982Salc			wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
347174982Salc				   "(AttributeTypeAndValue) - found class %d "
348174982Salc				   "tag 0x%x", hdr.class, hdr.tag);
349174982Salc			x509_free_name(name);
350174982Salc			return -1;
351174982Salc		}
352174982Salc
353174982Salc		seq_pos = hdr.payload;
354174982Salc		seq_end = hdr.payload + hdr.length;
355174982Salc
356174982Salc		if (asn1_get_oid(seq_pos, seq_end - seq_pos, &oid, &seq_pos)) {
357174982Salc			x509_free_name(name);
358174982Salc			return -1;
359174982Salc		}
360174982Salc
361174982Salc		if (asn1_get_next(seq_pos, seq_end - seq_pos, &hdr) < 0 ||
362174982Salc		    hdr.class != ASN1_CLASS_UNIVERSAL) {
363174982Salc			wpa_printf(MSG_DEBUG, "X509: Failed to parse "
364174982Salc				   "AttributeValue");
365174982Salc			x509_free_name(name);
366174982Salc			return -1;
367174982Salc		}
368174982Salc
369174982Salc		/* RFC 3280:
370174982Salc		 * MUST: country, organization, organizational-unit,
371174982Salc		 * distinguished name qualifier, state or province name,
372174982Salc		 * common name, serial number.
373174982Salc		 * SHOULD: locality, title, surname, given name, initials,
374174982Salc		 * pseudonym, generation qualifier.
375174982Salc		 * MUST: domainComponent (RFC 2247).
376174982Salc		 */
377174982Salc		type = X509_NAME_ATTR_NOT_USED;
378174982Salc		if (oid.len == 4 &&
379174982Salc		    oid.oid[0] == 2 && oid.oid[1] == 5 && oid.oid[2] == 4) {
380174982Salc			/* id-at ::= 2.5.4 */
381174982Salc			switch (oid.oid[3]) {
382174982Salc			case 3:
383174982Salc				/* commonName */
384174982Salc				type = X509_NAME_ATTR_CN;
385174982Salc				break;
386174982Salc			case 6:
387174982Salc				/*  countryName */
388174982Salc				type = X509_NAME_ATTR_C;
389174982Salc				break;
390174982Salc			case 7:
391174982Salc				/* localityName */
392174982Salc				type = X509_NAME_ATTR_L;
393174982Salc				break;
394174982Salc			case 8:
395174982Salc				/* stateOrProvinceName */
396174982Salc				type = X509_NAME_ATTR_ST;
397174982Salc				break;
398174982Salc			case 10:
399174982Salc				/* organizationName */
400174982Salc				type = X509_NAME_ATTR_O;
401174982Salc				break;
402174982Salc			case 11:
403174982Salc				/* organizationalUnitName */
404174982Salc				type = X509_NAME_ATTR_OU;
405174982Salc				break;
406174982Salc			}
407174982Salc		} else if (oid.len == 7 &&
408174982Salc			   oid.oid[0] == 1 && oid.oid[1] == 2 &&
409174982Salc			   oid.oid[2] == 840 && oid.oid[3] == 113549 &&
410174982Salc			   oid.oid[4] == 1 && oid.oid[5] == 9 &&
411174982Salc			   oid.oid[6] == 1) {
412174982Salc			/* 1.2.840.113549.1.9.1 - e-mailAddress */
413174982Salc			os_free(name->email);
414174982Salc			name->email = os_malloc(hdr.length + 1);
415174982Salc			if (name->email == NULL) {
416174982Salc				x509_free_name(name);
417174982Salc				return -1;
418174982Salc			}
419174982Salc			os_memcpy(name->email, hdr.payload, hdr.length);
420174982Salc			name->email[hdr.length] = '\0';
421174982Salc			continue;
422174982Salc		} else if (oid.len == 7 &&
423174982Salc			   oid.oid[0] == 0 && oid.oid[1] == 9 &&
424174982Salc			   oid.oid[2] == 2342 && oid.oid[3] == 19200300 &&
425174982Salc			   oid.oid[4] == 100 && oid.oid[5] == 1 &&
426174982Salc			   oid.oid[6] == 25) {
427174982Salc			/* 0.9.2342.19200300.100.1.25 - domainComponent */
428174982Salc			type = X509_NAME_ATTR_DC;
429174982Salc		}
430174982Salc
431174982Salc		if (type == X509_NAME_ATTR_NOT_USED) {
432174982Salc			wpa_hexdump(MSG_DEBUG, "X509: Unrecognized OID",
433174982Salc				    (u8 *) oid.oid,
434174982Salc				    oid.len * sizeof(oid.oid[0]));
435174982Salc			wpa_hexdump_ascii(MSG_MSGDUMP, "X509: Attribute Data",
436174982Salc					  hdr.payload, hdr.length);
437174982Salc			continue;
438174982Salc		}
439174982Salc
440174982Salc		if (name->num_attr == X509_MAX_NAME_ATTRIBUTES) {
441174982Salc			wpa_printf(MSG_INFO, "X509: Too many Name attributes");
442174982Salc			x509_free_name(name);
443174982Salc			return -1;
444174982Salc		}
445174982Salc
446174982Salc		val = os_malloc(hdr.length + 1);
447174982Salc		if (val == NULL) {
448174982Salc			x509_free_name(name);
449174982Salc			return -1;
450174982Salc		}
451174982Salc		os_memcpy(val, hdr.payload, hdr.length);
452174982Salc		val[hdr.length] = '\0';
453174982Salc		if (os_strlen(val) != hdr.length) {
454174982Salc			wpa_printf(MSG_INFO, "X509: Reject certificate with "
455174982Salc				   "embedded NUL byte in a string (%s[NUL])",
456174982Salc				   val);
457174982Salc			x509_free_name(name);
458174982Salc			return -1;
459174982Salc		}
460174982Salc
461174982Salc		name->attr[name->num_attr].type = type;
462174982Salc		name->attr[name->num_attr].value = val;
463174982Salc		name->num_attr++;
464174982Salc	}
465174982Salc
466174982Salc	return 0;
467174982Salc}
468174982Salc
469174982Salc
470174982Salcstatic char * x509_name_attr_str(enum x509_name_attr_type type)
471174982Salc{
472174982Salc	switch (type) {
473174982Salc	case X509_NAME_ATTR_NOT_USED:
474174982Salc		return "[N/A]";
475174982Salc	case X509_NAME_ATTR_DC:
476174982Salc		return "DC";
477174982Salc	case X509_NAME_ATTR_CN:
478174982Salc		return "CN";
479174982Salc	case X509_NAME_ATTR_C:
480174982Salc		return "C";
481174982Salc	case X509_NAME_ATTR_L:
482174982Salc		return "L";
483174982Salc	case X509_NAME_ATTR_ST:
484174982Salc		return "ST";
485174982Salc	case X509_NAME_ATTR_O:
486174982Salc		return "O";
487174982Salc	case X509_NAME_ATTR_OU:
488174982Salc		return "OU";
489174982Salc	}
490174982Salc	return "?";
491174982Salc}
492174982Salc
493174982Salc
494174982Salc/**
495174982Salc * x509_name_string - Convert an X.509 certificate name into a string
496174982Salc * @name: Name to convert
497174982Salc * @buf: Buffer for the string
498174982Salc * @len: Maximum buffer length
499174982Salc */
500174982Salcvoid x509_name_string(struct x509_name *name, char *buf, size_t len)
501174982Salc{
502174982Salc	char *pos, *end;
503174982Salc	int ret;
504174982Salc	size_t i;
505174982Salc
506174982Salc	if (len == 0)
507174982Salc		return;
508174982Salc
509174982Salc	pos = buf;
510174982Salc	end = buf + len;
511174982Salc
512174982Salc	for (i = 0; i < name->num_attr; i++) {
513174982Salc		ret = os_snprintf(pos, end - pos, "%s=%s, ",
514174982Salc				  x509_name_attr_str(name->attr[i].type),
515174982Salc				  name->attr[i].value);
516174982Salc		if (ret < 0 || ret >= end - pos)
517174982Salc			goto done;
518174982Salc		pos += ret;
519174982Salc	}
520174982Salc
521174982Salc	if (pos > buf + 1 && pos[-1] == ' ' && pos[-2] == ',') {
522174982Salc		pos--;
523174982Salc		*pos = '\0';
524174982Salc		pos--;
525174982Salc		*pos = '\0';
526174982Salc	}
527174982Salc
528174982Salc	if (name->email) {
529174982Salc		ret = os_snprintf(pos, end - pos, "/emailAddress=%s",
530174982Salc				  name->email);
531174982Salc		if (ret < 0 || ret >= end - pos)
532174982Salc			goto done;
533174982Salc		pos += ret;
534174982Salc	}
535174982Salc
536174982Salcdone:
537174982Salc	end[-1] = '\0';
538174982Salc}
539174982Salc
540174982Salc
541174982Salcstatic int x509_parse_time(const u8 *buf, size_t len, u8 asn1_tag,
542174982Salc			   os_time_t *val)
543174982Salc{
544174982Salc	const char *pos;
545174982Salc	int year, month, day, hour, min, sec;
546174982Salc
547174982Salc	/*
548174982Salc	 * Time ::= CHOICE {
549174982Salc	 *     utcTime        UTCTime,
550174982Salc	 *     generalTime    GeneralizedTime
551174982Salc	 * }
552174982Salc	 *
553174982Salc	 * UTCTime: YYMMDDHHMMSSZ
554174982Salc	 * GeneralizedTime: YYYYMMDDHHMMSSZ
555174982Salc	 */
556174982Salc
557174982Salc	pos = (const char *) buf;
558174982Salc
559174982Salc	switch (asn1_tag) {
560174982Salc	case ASN1_TAG_UTCTIME:
561174982Salc		if (len != 13 || buf[12] != 'Z') {
562174982Salc			wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized "
563174982Salc					  "UTCTime format", buf, len);
564174982Salc			return -1;
565174982Salc		}
566174982Salc		if (sscanf(pos, "%02d", &year) != 1) {
567174982Salc			wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse "
568174982Salc					  "UTCTime year", buf, len);
569174982Salc			return -1;
570174982Salc		}
571174982Salc		if (year < 50)
572174982Salc			year += 2000;
573174982Salc		else
574174982Salc			year += 1900;
575174982Salc		pos += 2;
576174982Salc		break;
577174982Salc	case ASN1_TAG_GENERALIZEDTIME:
578174982Salc		if (len != 15 || buf[14] != 'Z') {
579174982Salc			wpa_hexdump_ascii(MSG_DEBUG, "X509: Unrecognized "
580174982Salc					  "GeneralizedTime format", buf, len);
581174982Salc			return -1;
582174982Salc		}
583174982Salc		if (sscanf(pos, "%04d", &year) != 1) {
584174982Salc			wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse "
585174982Salc					  "GeneralizedTime year", buf, len);
586174982Salc			return -1;
587174982Salc		}
588174982Salc		pos += 4;
589174982Salc		break;
590174982Salc	default:
591174982Salc		wpa_printf(MSG_DEBUG, "X509: Expected UTCTime or "
592174982Salc			   "GeneralizedTime - found tag 0x%x", asn1_tag);
593174982Salc		return -1;
594174982Salc	}
595174982Salc
596174982Salc	if (sscanf(pos, "%02d", &month) != 1) {
597174982Salc		wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
598174982Salc				  "(month)", buf, len);
599174982Salc		return -1;
600174982Salc	}
601174982Salc	pos += 2;
602174982Salc
603174982Salc	if (sscanf(pos, "%02d", &day) != 1) {
604174982Salc		wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
605174982Salc				  "(day)", buf, len);
606174982Salc		return -1;
607174982Salc	}
608174982Salc	pos += 2;
609174982Salc
610174982Salc	if (sscanf(pos, "%02d", &hour) != 1) {
611174982Salc		wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
612174982Salc				  "(hour)", buf, len);
613174982Salc		return -1;
614174982Salc	}
615174982Salc	pos += 2;
616174982Salc
617174982Salc	if (sscanf(pos, "%02d", &min) != 1) {
618174982Salc		wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
619174982Salc				  "(min)", buf, len);
620174982Salc		return -1;
621174982Salc	}
622174982Salc	pos += 2;
623174982Salc
624174982Salc	if (sscanf(pos, "%02d", &sec) != 1) {
625174982Salc		wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse Time "
626174982Salc				  "(sec)", buf, len);
627174982Salc		return -1;
628174982Salc	}
629174982Salc
630174982Salc	if (os_mktime(year, month, day, hour, min, sec, val) < 0) {
631174982Salc		wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to convert Time",
632174982Salc				  buf, len);
633174982Salc		if (year < 1970) {
634174982Salc			/*
635174982Salc			 * At least some test certificates have been configured
636174982Salc			 * to use dates prior to 1970. Set the date to
637174982Salc			 * beginning of 1970 to handle these case.
638174982Salc			 */
639174982Salc			wpa_printf(MSG_DEBUG, "X509: Year=%d before epoch - "
640174982Salc				   "assume epoch as the time", year);
641174982Salc			*val = 0;
642174982Salc			return 0;
643174982Salc		}
644174982Salc		return -1;
645174982Salc	}
646174982Salc
647174982Salc	return 0;
648174982Salc}
649174982Salc
650174982Salc
651174982Salcstatic int x509_parse_validity(const u8 *buf, size_t len,
652174982Salc			       struct x509_certificate *cert, const u8 **next)
653174982Salc{
654174982Salc	struct asn1_hdr hdr;
655174982Salc	const u8 *pos;
656174982Salc	size_t plen;
657174982Salc
658174982Salc	/*
659174982Salc	 * Validity ::= SEQUENCE {
660174982Salc	 *     notBefore      Time,
661174982Salc	 *     notAfter       Time
662174982Salc	 * }
663174982Salc	 *
664174982Salc	 * RFC 3280, 4.1.2.5:
665174982Salc	 * CAs conforming to this profile MUST always encode certificate
666174982Salc	 * validity dates through the year 2049 as UTCTime; certificate
667174982Salc	 * validity dates in 2050 or later MUST be encoded as GeneralizedTime.
668174982Salc	 */
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