1/*
2 * TLSv1 credentials
3 * Copyright (c) 2006-2015, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9#include "includes.h"
10
11#include "common.h"
12#include "base64.h"
13#include "crypto/crypto.h"
14#include "crypto/sha1.h"
15#include "pkcs5.h"
16#include "pkcs8.h"
17#include "x509v3.h"
18#include "tlsv1_cred.h"
19
20
21struct tlsv1_credentials * tlsv1_cred_alloc(void)
22{
23	struct tlsv1_credentials *cred;
24	cred = os_zalloc(sizeof(*cred));
25	return cred;
26}
27
28
29void tlsv1_cred_free(struct tlsv1_credentials *cred)
30{
31	if (cred == NULL)
32		return;
33
34	x509_certificate_chain_free(cred->trusted_certs);
35	x509_certificate_chain_free(cred->cert);
36	crypto_private_key_free(cred->key);
37	os_free(cred->dh_p);
38	os_free(cred->dh_g);
39	os_free(cred->ocsp_stapling_response);
40	os_free(cred->ocsp_stapling_response_multi);
41	os_free(cred);
42}
43
44
45static int tlsv1_add_cert_der(struct x509_certificate **chain,
46			      const u8 *buf, size_t len)
47{
48	struct x509_certificate *cert, *p;
49	char name[128];
50
51	cert = x509_certificate_parse(buf, len);
52	if (cert == NULL) {
53		wpa_printf(MSG_INFO, "TLSv1: %s - failed to parse certificate",
54			   __func__);
55		return -1;
56	}
57
58	p = *chain;
59	while (p && p->next)
60		p = p->next;
61	if (p && x509_name_compare(&cert->subject, &p->issuer) == 0) {
62		/*
63		 * The new certificate is the issuer of the last certificate in
64		 * the chain - add the new certificate to the end.
65		 */
66		p->next = cert;
67	} else {
68		/* Add to the beginning of the chain */
69		cert->next = *chain;
70		*chain = cert;
71	}
72
73	x509_name_string(&cert->subject, name, sizeof(name));
74	wpa_printf(MSG_DEBUG, "TLSv1: Added certificate: %s", name);
75
76	return 0;
77}
78
79
80static const char *pem_cert_begin = "-----BEGIN CERTIFICATE-----";
81static const char *pem_cert_end = "-----END CERTIFICATE-----";
82static const char *pem_key_begin = "-----BEGIN RSA PRIVATE KEY-----";
83static const char *pem_key_end = "-----END RSA PRIVATE KEY-----";
84static const char *pem_key2_begin = "-----BEGIN PRIVATE KEY-----";
85static const char *pem_key2_end = "-----END PRIVATE KEY-----";
86static const char *pem_key_enc_begin = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
87static const char *pem_key_enc_end = "-----END ENCRYPTED PRIVATE KEY-----";
88
89
90static const u8 * search_tag(const char *tag, const u8 *buf, size_t len)
91{
92	size_t i, plen;
93
94	plen = os_strlen(tag);
95	if (len < plen)
96		return NULL;
97
98	for (i = 0; i < len - plen; i++) {
99		if (os_memcmp(buf + i, tag, plen) == 0)
100			return buf + i;
101	}
102
103	return NULL;
104}
105
106
107static int tlsv1_add_cert(struct x509_certificate **chain,
108			  const u8 *buf, size_t len)
109{
110	const u8 *pos, *end;
111	unsigned char *der;
112	size_t der_len;
113
114	pos = search_tag(pem_cert_begin, buf, len);
115	if (!pos) {
116		wpa_printf(MSG_DEBUG, "TLSv1: No PEM certificate tag found - "
117			   "assume DER format");
118		return tlsv1_add_cert_der(chain, buf, len);
119	}
120
121	wpa_printf(MSG_DEBUG, "TLSv1: Converting PEM format certificate into "
122		   "DER format");
123
124	while (pos) {
125		pos += os_strlen(pem_cert_begin);
126		end = search_tag(pem_cert_end, pos, buf + len - pos);
127		if (end == NULL) {
128			wpa_printf(MSG_INFO, "TLSv1: Could not find PEM "
129				   "certificate end tag (%s)", pem_cert_end);
130			return -1;
131		}
132
133		der = base64_decode(pos, end - pos, &der_len);
134		if (der == NULL) {
135			wpa_printf(MSG_INFO, "TLSv1: Could not decode PEM "
136				   "certificate");
137			return -1;
138		}
139
140		if (tlsv1_add_cert_der(chain, der, der_len) < 0) {
141			wpa_printf(MSG_INFO, "TLSv1: Failed to parse PEM "
142				   "certificate after DER conversion");
143			os_free(der);
144			return -1;
145		}
146
147		os_free(der);
148
149		end += os_strlen(pem_cert_end);
150		pos = search_tag(pem_cert_begin, end, buf + len - end);
151	}
152
153	return 0;
154}
155
156
157static int tlsv1_set_cert_chain(struct x509_certificate **chain,
158				const char *cert, const u8 *cert_blob,
159				size_t cert_blob_len)
160{
161	if (cert_blob)
162		return tlsv1_add_cert(chain, cert_blob, cert_blob_len);
163
164	if (cert) {
165		u8 *buf;
166		size_t len;
167		int ret;
168
169		buf = (u8 *) os_readfile(cert, &len);
170		if (buf == NULL) {
171			wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'",
172				   cert);
173			return -1;
174		}
175
176		ret = tlsv1_add_cert(chain, buf, len);
177		os_free(buf);
178		return ret;
179	}
180
181	return 0;
182}
183
184
185/**
186 * tlsv1_set_ca_cert - Set trusted CA certificate(s)
187 * @cred: TLSv1 credentials from tlsv1_cred_alloc()
188 * @cert: File or reference name for X.509 certificate in PEM or DER format
189 * @cert_blob: cert as inlined data or %NULL if not used
190 * @cert_blob_len: ca_cert_blob length
191 * @path: Path to CA certificates (not yet supported)
192 * Returns: 0 on success, -1 on failure
193 */
194int tlsv1_set_ca_cert(struct tlsv1_credentials *cred, const char *cert,
195		      const u8 *cert_blob, size_t cert_blob_len,
196		      const char *path)
197{
198	if (cert && os_strncmp(cert, "hash://", 7) == 0) {
199		const char *pos = cert + 7;
200		if (os_strncmp(pos, "server/sha256/", 14) != 0) {
201			wpa_printf(MSG_DEBUG,
202				   "TLSv1: Unsupported ca_cert hash value '%s'",
203				   cert);
204			return -1;
205		}
206		pos += 14;
207		if (os_strlen(pos) != 32 * 2) {
208			wpa_printf(MSG_DEBUG,
209				   "TLSv1: Unexpected SHA256 hash length in ca_cert '%s'",
210				   cert);
211			return -1;
212		}
213		if (hexstr2bin(pos, cred->srv_cert_hash, 32) < 0) {
214			wpa_printf(MSG_DEBUG,
215				   "TLSv1: Invalid SHA256 hash value in ca_cert '%s'",
216				   cert);
217			return -1;
218		}
219		cred->server_cert_only = 1;
220		cred->ca_cert_verify = 0;
221		wpa_printf(MSG_DEBUG,
222			   "TLSv1: Checking only server certificate match");
223		return 0;
224	}
225
226	if (cert && os_strncmp(cert, "probe://", 8) == 0) {
227		cred->cert_probe = 1;
228		cred->ca_cert_verify = 0;
229		wpa_printf(MSG_DEBUG, "TLSv1: Only probe server certificate");
230		return 0;
231	}
232
233	cred->ca_cert_verify = cert || cert_blob || path;
234
235	if (tlsv1_set_cert_chain(&cred->trusted_certs, cert,
236				 cert_blob, cert_blob_len) < 0)
237		return -1;
238
239	if (path) {
240		/* TODO: add support for reading number of certificate files */
241		wpa_printf(MSG_INFO, "TLSv1: Use of CA certificate directory "
242			   "not yet supported");
243		return -1;
244	}
245
246	return 0;
247}
248
249
250/**
251 * tlsv1_set_cert - Set certificate
252 * @cred: TLSv1 credentials from tlsv1_cred_alloc()
253 * @cert: File or reference name for X.509 certificate in PEM or DER format
254 * @cert_blob: cert as inlined data or %NULL if not used
255 * @cert_blob_len: cert_blob length
256 * Returns: 0 on success, -1 on failure
257 */
258int tlsv1_set_cert(struct tlsv1_credentials *cred, const char *cert,
259		   const u8 *cert_blob, size_t cert_blob_len)
260{
261	return tlsv1_set_cert_chain(&cred->cert, cert,
262				    cert_blob, cert_blob_len);
263}
264
265
266static struct crypto_private_key * tlsv1_set_key_pem(const u8 *key, size_t len)
267{
268	const u8 *pos, *end;
269	unsigned char *der;
270	size_t der_len;
271	struct crypto_private_key *pkey;
272
273	pos = search_tag(pem_key_begin, key, len);
274	if (!pos) {
275		pos = search_tag(pem_key2_begin, key, len);
276		if (!pos)
277			return NULL;
278		pos += os_strlen(pem_key2_begin);
279		end = search_tag(pem_key2_end, pos, key + len - pos);
280		if (!end)
281			return NULL;
282	} else {
283		const u8 *pos2;
284		pos += os_strlen(pem_key_begin);
285		end = search_tag(pem_key_end, pos, key + len - pos);
286		if (!end)
287			return NULL;
288		pos2 = search_tag("Proc-Type: 4,ENCRYPTED", pos, end - pos);
289		if (pos2) {
290			wpa_printf(MSG_DEBUG, "TLSv1: Unsupported private key "
291				   "format (Proc-Type/DEK-Info)");
292			return NULL;
293		}
294	}
295
296	der = base64_decode(pos, end - pos, &der_len);
297	if (!der)
298		return NULL;
299	pkey = crypto_private_key_import(der, der_len, NULL);
300	os_free(der);
301	return pkey;
302}
303
304
305static struct crypto_private_key * tlsv1_set_key_enc_pem(const u8 *key,
306							 size_t len,
307							 const char *passwd)
308{
309	const u8 *pos, *end;
310	unsigned char *der;
311	size_t der_len;
312	struct crypto_private_key *pkey;
313
314	if (passwd == NULL)
315		return NULL;
316	pos = search_tag(pem_key_enc_begin, key, len);
317	if (!pos)
318		return NULL;
319	pos += os_strlen(pem_key_enc_begin);
320	end = search_tag(pem_key_enc_end, pos, key + len - pos);
321	if (!end)
322		return NULL;
323
324	der = base64_decode(pos, end - pos, &der_len);
325	if (!der)
326		return NULL;
327	pkey = crypto_private_key_import(der, der_len, passwd);
328	os_free(der);
329	return pkey;
330}
331
332
333#ifdef PKCS12_FUNCS
334
335static int oid_is_rsadsi(struct asn1_oid *oid)
336{
337	return oid->len >= 4 &&
338		oid->oid[0] == 1 /* iso */ &&
339		oid->oid[1] == 2 /* member-body */ &&
340		oid->oid[2] == 840 /* us */ &&
341		oid->oid[3] == 113549 /* rsadsi */;
342}
343
344
345static int pkcs12_is_bagtype_oid(struct asn1_oid *oid, unsigned long type)
346{
347	return oid->len == 9 &&
348		oid_is_rsadsi(oid) &&
349		oid->oid[4] == 1 /* pkcs */ &&
350		oid->oid[5] == 12 /* pkcs-12 */ &&
351		oid->oid[6] == 10 &&
352		oid->oid[7] == 1 /* bagtypes */ &&
353		oid->oid[8] == type;
354}
355
356
357static int is_oid_pkcs7(struct asn1_oid *oid)
358{
359	return oid->len == 7 &&
360		oid->oid[0] == 1 /* iso */ &&
361		oid->oid[1] == 2 /* member-body */ &&
362		oid->oid[2] == 840 /* us */ &&
363		oid->oid[3] == 113549 /* rsadsi */ &&
364		oid->oid[4] == 1 /* pkcs */ &&
365		oid->oid[5] == 7 /* pkcs-7 */;
366}
367
368
369static int is_oid_pkcs7_data(struct asn1_oid *oid)
370{
371	return is_oid_pkcs7(oid) && oid->oid[6] == 1 /* data */;
372}
373
374
375static int is_oid_pkcs7_enc_data(struct asn1_oid *oid)
376{
377	return is_oid_pkcs7(oid) && oid->oid[6] == 6 /* encryptedData */;
378}
379
380
381static int is_oid_pkcs9(struct asn1_oid *oid)
382{
383	return oid->len >= 6 &&
384		oid->oid[0] == 1 /* iso */ &&
385		oid->oid[1] == 2 /* member-body */ &&
386		oid->oid[2] == 840 /* us */ &&
387		oid->oid[3] == 113549 /* rsadsi */ &&
388		oid->oid[4] == 1 /* pkcs */ &&
389		oid->oid[5] == 9 /* pkcs-9 */;
390}
391
392
393static int is_oid_pkcs9_friendly_name(struct asn1_oid *oid)
394{
395	return oid->len == 7 && is_oid_pkcs9(oid) &&
396		oid->oid[6] == 20;
397}
398
399
400static int is_oid_pkcs9_local_key_id(struct asn1_oid *oid)
401{
402	return oid->len == 7 && is_oid_pkcs9(oid) &&
403		oid->oid[6] == 21;
404}
405
406
407static int is_oid_pkcs9_x509_cert(struct asn1_oid *oid)
408{
409	return oid->len == 8 && is_oid_pkcs9(oid) &&
410		oid->oid[6] == 22 /* certTypes */ &&
411		oid->oid[7] == 1 /* x509Certificate */;
412}
413
414
415static int pkcs12_keybag(struct tlsv1_credentials *cred,
416			 const u8 *buf, size_t len)
417{
418	/* TODO */
419	return 0;
420}
421
422
423static int pkcs12_pkcs8_keybag(struct tlsv1_credentials *cred,
424			       const u8 *buf, size_t len,
425			       const char *passwd)
426{
427	struct crypto_private_key *key;
428
429	/* PKCS8ShroudedKeyBag ::= EncryptedPrivateKeyInfo */
430	key = pkcs8_enc_key_import(buf, len, passwd);
431	if (!key)
432		return -1;
433
434	wpa_printf(MSG_DEBUG,
435		   "PKCS #12: Successfully decrypted PKCS8ShroudedKeyBag");
436	crypto_private_key_free(cred->key);
437	cred->key = key;
438
439	return 0;
440}
441
442
443static int pkcs12_certbag(struct tlsv1_credentials *cred,
444			  const u8 *buf, size_t len)
445{
446	struct asn1_hdr hdr;
447	struct asn1_oid oid;
448	char obuf[80];
449	const u8 *pos, *end;
450
451	/*
452	 * CertBag ::= SEQUENCE {
453	 *     certId      BAG-TYPE.&id   ({CertTypes}),
454	 *     certValue   [0] EXPLICIT BAG-TYPE.&Type ({CertTypes}{@certId})
455	 * }
456	 */
457
458	if (asn1_get_next(buf, len, &hdr) < 0 ||
459	    hdr.class != ASN1_CLASS_UNIVERSAL ||
460	    hdr.tag != ASN1_TAG_SEQUENCE) {
461		wpa_printf(MSG_DEBUG,
462			   "PKCS #12: Expected SEQUENCE (CertBag) - found class %d tag 0x%x",
463			   hdr.class, hdr.tag);
464		return -1;
465	}
466
467	pos = hdr.payload;
468	end = hdr.payload + hdr.length;
469
470	if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
471		wpa_printf(MSG_DEBUG,
472			   "PKCS #12: Failed to parse OID (certId)");
473		return -1;
474	}
475
476	asn1_oid_to_str(&oid, obuf, sizeof(obuf));
477	wpa_printf(MSG_DEBUG, "PKCS #12: certId %s", obuf);
478
479	if (!is_oid_pkcs9_x509_cert(&oid)) {
480		wpa_printf(MSG_DEBUG,
481			   "PKCS #12: Ignored unsupported certificate type (certId %s)",
482			   obuf);
483	}
484
485	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
486	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
487	    hdr.tag != 0) {
488		wpa_printf(MSG_DEBUG,
489			   "PKCS #12: Expected [0] EXPLICIT (certValue) - found class %d tag 0x%x",
490			   hdr.class, hdr.tag);
491		return -1;
492	}
493
494	if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
495	    hdr.class != ASN1_CLASS_UNIVERSAL ||
496	    hdr.tag != ASN1_TAG_OCTETSTRING) {
497		wpa_printf(MSG_DEBUG,
498			   "PKCS #12: Expected OCTET STRING (x509Certificate) - found class %d tag 0x%x",
499			   hdr.class, hdr.tag);
500		return -1;
501	}
502
503	wpa_hexdump(MSG_DEBUG, "PKCS #12: x509Certificate",
504		    hdr.payload, hdr.length);
505	if (cred->cert) {
506		struct x509_certificate *cert;
507
508		wpa_printf(MSG_DEBUG, "PKCS #12: Ignore extra certificate");
509		cert = x509_certificate_parse(hdr.payload, hdr.length);
510		if (!cert) {
511			wpa_printf(MSG_DEBUG,
512				   "PKCS #12: Failed to parse x509Certificate");
513			return 0;
514		}
515		x509_certificate_chain_free(cert);
516
517		return 0;
518	}
519	return tlsv1_set_cert(cred, NULL, hdr.payload, hdr.length);
520}
521
522
523static int pkcs12_parse_attr_friendly_name(const u8 *pos, const u8 *end)
524{
525	struct asn1_hdr hdr;
526
527	/*
528	 * RFC 2985, 5.5.1:
529	 * friendlyName ATTRIBUTE ::= {
530	 *         WITH SYNTAX BMPString (SIZE(1..pkcs-9-ub-friendlyName))
531	 *         EQUALITY MATCHING RULE caseIgnoreMatch
532	 *         SINGLE VALUE TRUE
533	 *          ID pkcs-9-at-friendlyName
534	 * }
535	 */
536	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
537	    hdr.class != ASN1_CLASS_UNIVERSAL ||
538	    hdr.tag != ASN1_TAG_BMPSTRING) {
539		wpa_printf(MSG_DEBUG,
540			   "PKCS #12: Expected BMPSTRING (friendlyName) - found class %d tag 0x%x",
541			   hdr.class, hdr.tag);
542		return 0;
543	}
544	wpa_hexdump_ascii(MSG_DEBUG, "PKCS #12: friendlyName",
545			  hdr.payload, hdr.length);
546	return 0;
547}
548
549
550static int pkcs12_parse_attr_local_key_id(const u8 *pos, const u8 *end)
551{
552	struct asn1_hdr hdr;
553
554	/*
555	 * RFC 2985, 5.5.2:
556	 * localKeyId ATTRIBUTE ::= {
557	 *         WITH SYNTAX OCTET STRING
558	 *         EQUALITY MATCHING RULE octetStringMatch
559	 *         SINGLE VALUE TRUE
560	 *         ID pkcs-9-at-localKeyId
561	 * }
562	 */
563	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
564	    hdr.class != ASN1_CLASS_UNIVERSAL ||
565	    hdr.tag != ASN1_TAG_OCTETSTRING) {
566		wpa_printf(MSG_DEBUG,
567			   "PKCS #12: Expected OCTET STRING (localKeyID) - found class %d tag 0x%x",
568			   hdr.class, hdr.tag);
569		return -1;
570	}
571	wpa_hexdump_key(MSG_DEBUG, "PKCS #12: localKeyID",
572			hdr.payload, hdr.length);
573	return 0;
574}
575
576
577static int pkcs12_parse_attr(const u8 *pos, size_t len)
578{
579	const u8 *end = pos + len;
580	struct asn1_hdr hdr;
581	struct asn1_oid a_oid;
582	char obuf[80];
583
584	/*
585	 * PKCS12Attribute ::= SEQUENCE {
586	 * attrId      ATTRIBUTE.&id ({PKCS12AttrSet}),
587	 * attrValues  SET OF ATTRIBUTE.&Type ({PKCS12AttrSet}{@attrId})
588	 * }
589	 */
590
591	if (asn1_get_oid(pos, end - pos, &a_oid, &pos)) {
592		wpa_printf(MSG_DEBUG, "PKCS #12: Failed to parse OID (attrId)");
593		return -1;
594	}
595
596	asn1_oid_to_str(&a_oid, obuf, sizeof(obuf));
597	wpa_printf(MSG_DEBUG, "PKCS #12: attrId %s", obuf);
598
599	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
600	    hdr.class != ASN1_CLASS_UNIVERSAL ||
601	    hdr.tag != ASN1_TAG_SET) {
602		wpa_printf(MSG_DEBUG,
603			   "PKCS #12: Expected SET (attrValues) - found class %d tag 0x%x",
604			   hdr.class, hdr.tag);
605		return -1;
606	}
607	wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: attrValues",
608			hdr.payload, hdr.length);
609	pos = hdr.payload;
610	end = hdr.payload + hdr.length;
611
612	if (is_oid_pkcs9_friendly_name(&a_oid))
613		return pkcs12_parse_attr_friendly_name(pos, end);
614	if (is_oid_pkcs9_local_key_id(&a_oid))
615		return pkcs12_parse_attr_local_key_id(pos, end);
616
617	wpa_printf(MSG_DEBUG, "PKCS #12: Ignore unknown attribute");
618	return 0;
619}
620
621
622static int pkcs12_safebag(struct tlsv1_credentials *cred,
623			  const u8 *buf, size_t len, const char *passwd)
624{
625	struct asn1_hdr hdr;
626	struct asn1_oid oid;
627	char obuf[80];
628	const u8 *pos = buf, *end = buf + len;
629	const u8 *value;
630	size_t value_len;
631
632	wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: SafeBag", buf, len);
633
634	/* BAG-TYPE ::= TYPE-IDENTIFIER */
635	if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
636		wpa_printf(MSG_DEBUG,
637			   "PKCS #12: Failed to parse OID (BAG-TYPE)");
638		return -1;
639	}
640
641	asn1_oid_to_str(&oid, obuf, sizeof(obuf));
642	wpa_printf(MSG_DEBUG, "PKCS #12: BAG-TYPE %s", obuf);
643
644	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
645	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
646	    hdr.tag != 0) {
647		wpa_printf(MSG_DEBUG,
648			   "PKCS #12: Expected [0] EXPLICIT (bagValue) - found class %d tag 0x%x",
649			   hdr.class, hdr.tag);
650		return 0;
651	}
652	value = hdr.payload;
653	value_len = hdr.length;
654	wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: bagValue", value, value_len);
655	pos = hdr.payload + hdr.length;
656
657	if (pos < end) {
658		/* bagAttributes  SET OF PKCS12Attribute OPTIONAL */
659		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
660		    hdr.class != ASN1_CLASS_UNIVERSAL ||
661		    hdr.tag != ASN1_TAG_SET) {
662			wpa_printf(MSG_DEBUG,
663				   "PKCS #12: Expected SET (bagAttributes) - found class %d tag 0x%x",
664				   hdr.class, hdr.tag);
665			return -1;
666		}
667		wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: bagAttributes",
668				hdr.payload, hdr.length);
669
670		pos = hdr.payload;
671		end = hdr.payload + hdr.length;
672		while (pos < end) {
673			/* PKCS12Attribute ::= SEQUENCE */
674			if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
675			    hdr.class != ASN1_CLASS_UNIVERSAL ||
676			    hdr.tag != ASN1_TAG_SEQUENCE) {
677				wpa_printf(MSG_DEBUG,
678					   "PKCS #12: Expected SEQUENCE (PKCS12Attribute) - found class %d tag 0x%x",
679					   hdr.class, hdr.tag);
680				return -1;
681			}
682			if (pkcs12_parse_attr(hdr.payload, hdr.length) < 0)
683				return -1;
684			pos = hdr.payload + hdr.length;
685		}
686	}
687
688	if (pkcs12_is_bagtype_oid(&oid, 1))
689		return pkcs12_keybag(cred, value, value_len);
690	if (pkcs12_is_bagtype_oid(&oid, 2))
691		return pkcs12_pkcs8_keybag(cred, value, value_len, passwd);
692	if (pkcs12_is_bagtype_oid(&oid, 3))
693		return pkcs12_certbag(cred, value, value_len);
694
695	wpa_printf(MSG_DEBUG, "PKCS #12: Ignore unsupported BAG-TYPE");
696	return 0;
697}
698
699
700static int pkcs12_safecontents(struct tlsv1_credentials *cred,
701			       const u8 *buf, size_t len,
702			       const char *passwd)
703{
704	struct asn1_hdr hdr;
705	const u8 *pos, *end;
706
707	/* SafeContents ::= SEQUENCE OF SafeBag */
708	if (asn1_get_next(buf, len, &hdr) < 0 ||
709	    hdr.class != ASN1_CLASS_UNIVERSAL ||
710	    hdr.tag != ASN1_TAG_SEQUENCE) {
711		wpa_printf(MSG_DEBUG,
712			   "PKCS #12: Expected SEQUENCE (SafeContents) - found class %d tag 0x%x",
713			   hdr.class, hdr.tag);
714		return -1;
715	}
716	pos = hdr.payload;
717	end = hdr.payload + hdr.length;
718
719	/*
720	 * SafeBag ::= SEQUENCE {
721	 *   bagId          BAG-TYPE.&id ({PKCS12BagSet})
722	 *   bagValue       [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}),
723	 *   bagAttributes  SET OF PKCS12Attribute OPTIONAL
724	 * }
725	 */
726
727	while (pos < end) {
728		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
729		    hdr.class != ASN1_CLASS_UNIVERSAL ||
730		    hdr.tag != ASN1_TAG_SEQUENCE) {
731			wpa_printf(MSG_DEBUG,
732				   "PKCS #12: Expected SEQUENCE (SafeBag) - found class %d tag 0x%x",
733				   hdr.class, hdr.tag);
734			return -1;
735		}
736		if (pkcs12_safebag(cred, hdr.payload, hdr.length, passwd) < 0)
737			return -1;
738		pos = hdr.payload + hdr.length;
739	}
740
741	return 0;
742}
743
744
745static int pkcs12_parse_content_data(struct tlsv1_credentials *cred,
746				     const u8 *pos, const u8 *end,
747				     const char *passwd)
748{
749	struct asn1_hdr hdr;
750
751	/* Data ::= OCTET STRING */
752	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
753	    hdr.class != ASN1_CLASS_UNIVERSAL ||
754	    hdr.tag != ASN1_TAG_OCTETSTRING) {
755		wpa_printf(MSG_DEBUG,
756			   "PKCS #12: Expected OCTET STRING (Data) - found class %d tag 0x%x",
757			   hdr.class, hdr.tag);
758		return -1;
759	}
760
761	wpa_hexdump(MSG_MSGDUMP, "PKCS #12: Data", hdr.payload, hdr.length);
762
763	return pkcs12_safecontents(cred, hdr.payload, hdr.length, passwd);
764}
765
766
767static int pkcs12_parse_content_enc_data(struct tlsv1_credentials *cred,
768					 const u8 *pos, const u8 *end,
769					 const char *passwd)
770{
771	struct asn1_hdr hdr;
772	struct asn1_oid oid;
773	char buf[80];
774	const u8 *enc_alg;
775	u8 *data;
776	size_t enc_alg_len, data_len;
777	int res = -1;
778
779	/*
780	 * EncryptedData ::= SEQUENCE {
781	 *   version Version,
782	 *   encryptedContentInfo EncryptedContentInfo }
783	 */
784	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
785	    hdr.class != ASN1_CLASS_UNIVERSAL ||
786	    hdr.tag != ASN1_TAG_SEQUENCE) {
787		wpa_printf(MSG_DEBUG,
788			   "PKCS #12: Expected SEQUENCE (EncryptedData) - found class %d tag 0x%x",
789			   hdr.class, hdr.tag);
790		return 0;
791	}
792	pos = hdr.payload;
793
794	/* Version ::= INTEGER */
795	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
796	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
797		wpa_printf(MSG_DEBUG,
798			   "PKCS #12: No INTEGER tag found for version; class=%d tag=0x%x",
799			   hdr.class, hdr.tag);
800		return -1;
801	}
802	if (hdr.length != 1 || hdr.payload[0] != 0) {
803		wpa_printf(MSG_DEBUG, "PKCS #12: Unrecognized PKCS #7 version");
804		return -1;
805	}
806	pos = hdr.payload + hdr.length;
807
808	wpa_hexdump(MSG_MSGDUMP, "PKCS #12: EncryptedContentInfo",
809		    pos, end - pos);
810
811	/*
812	 * EncryptedContentInfo ::= SEQUENCE {
813	 *   contentType ContentType,
814	 *   contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
815	 *   encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
816	 */
817	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
818	    hdr.class != ASN1_CLASS_UNIVERSAL ||
819	    hdr.tag != ASN1_TAG_SEQUENCE) {
820		wpa_printf(MSG_DEBUG,
821			   "PKCS #12: Expected SEQUENCE (EncryptedContentInfo) - found class %d tag 0x%x",
822			   hdr.class, hdr.tag);
823		return -1;
824	}
825
826	pos = hdr.payload;
827	end = pos + hdr.length;
828
829	/* ContentType ::= OBJECT IDENTIFIER */
830	if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
831		wpa_printf(MSG_DEBUG,
832			   "PKCS #12: Could not find OBJECT IDENTIFIER (contentType)");
833		return -1;
834	}
835	asn1_oid_to_str(&oid, buf, sizeof(buf));
836	wpa_printf(MSG_DEBUG, "PKCS #12: EncryptedContentInfo::contentType %s",
837		   buf);
838
839	if (!is_oid_pkcs7_data(&oid)) {
840		wpa_printf(MSG_DEBUG,
841			   "PKCS #12: Unsupported EncryptedContentInfo::contentType %s",
842			   buf);
843		return 0;
844	}
845
846	/* ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier */
847	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
848	    hdr.class != ASN1_CLASS_UNIVERSAL ||
849	    hdr.tag != ASN1_TAG_SEQUENCE) {
850		wpa_printf(MSG_DEBUG, "PKCS #12: Expected SEQUENCE (ContentEncryptionAlgorithmIdentifier) - found class %d tag 0x%x",
851			   hdr.class, hdr.tag);
852		return -1;
853	}
854	enc_alg = hdr.payload;
855	enc_alg_len = hdr.length;
856	pos = hdr.payload + hdr.length;
857
858	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
859	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
860	    hdr.tag != 0) {
861		wpa_printf(MSG_DEBUG,
862			   "PKCS #12: Expected [0] IMPLICIT (encryptedContent) - found class %d tag 0x%x",
863			   hdr.class, hdr.tag);
864		return -1;
865	}
866
867	/* EncryptedContent ::= OCTET STRING */
868	data = pkcs5_decrypt(enc_alg, enc_alg_len, hdr.payload, hdr.length,
869			     passwd, &data_len);
870	if (data) {
871		wpa_hexdump_key(MSG_MSGDUMP,
872				"PKCS #12: Decrypted encryptedContent",
873				data, data_len);
874		res = pkcs12_safecontents(cred, data, data_len, passwd);
875		os_free(data);
876	}
877
878	return res;
879}
880
881
882static int pkcs12_parse_content(struct tlsv1_credentials *cred,
883				const u8 *buf, size_t len,
884				const char *passwd)
885{
886	const u8 *pos = buf;
887	const u8 *end = buf + len;
888	struct asn1_oid oid;
889	char txt[80];
890	struct asn1_hdr hdr;
891
892	wpa_hexdump(MSG_MSGDUMP, "PKCS #12: ContentInfo", buf, len);
893
894	if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
895		wpa_printf(MSG_DEBUG,
896			   "PKCS #12: Could not find OBJECT IDENTIFIER (contentType)");
897		return 0;
898	}
899
900	asn1_oid_to_str(&oid, txt, sizeof(txt));
901	wpa_printf(MSG_DEBUG, "PKCS #12: contentType %s", txt);
902
903	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
904	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
905	    hdr.tag != 0) {
906		wpa_printf(MSG_DEBUG,
907			   "PKCS #12: Expected [0] EXPLICIT (content) - found class %d tag 0x%x",
908			   hdr.class, hdr.tag);
909		return 0;
910	}
911	pos = hdr.payload;
912
913	if (is_oid_pkcs7_data(&oid))
914		return pkcs12_parse_content_data(cred, pos, end, passwd);
915	if (is_oid_pkcs7_enc_data(&oid))
916		return pkcs12_parse_content_enc_data(cred, pos, end, passwd);
917
918	wpa_printf(MSG_DEBUG, "PKCS #12: Ignored unsupported contentType %s",
919		   txt);
920
921	return 0;
922}
923
924
925static int pkcs12_parse(struct tlsv1_credentials *cred,
926			const u8 *key, size_t len, const char *passwd)
927{
928	struct asn1_hdr hdr;
929	const u8 *pos, *end;
930	struct asn1_oid oid;
931	char buf[80];
932
933	/*
934	 * PFX ::= SEQUENCE {
935	 *     version     INTEGER {v3(3)}(v3,...),
936	 *     authSafe    ContentInfo,
937	 *     macData     MacData OPTIONAL
938	 * }
939	 */
940
941	if (asn1_get_next(key, len, &hdr) < 0 ||
942	    hdr.class != ASN1_CLASS_UNIVERSAL ||
943	    hdr.tag != ASN1_TAG_SEQUENCE) {
944		wpa_printf(MSG_DEBUG,
945			   "PKCS #12: Expected SEQUENCE (PFX) - found class %d tag 0x%x; assume PKCS #12 not used",
946			   hdr.class, hdr.tag);
947		return -1;
948	}
949
950	pos = hdr.payload;
951	end = pos + hdr.length;
952
953	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
954	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
955		wpa_printf(MSG_DEBUG,
956			   "PKCS #12: No INTEGER tag found for version; class=%d tag=0x%x",
957			   hdr.class, hdr.tag);
958		return -1;
959	}
960	if (hdr.length != 1 || hdr.payload[0] != 3) {
961		wpa_printf(MSG_DEBUG, "PKCS #12: Unrecognized version");
962		return -1;
963	}
964	pos = hdr.payload + hdr.length;
965
966	/*
967	 * ContentInfo ::= SEQUENCE {
968	 *   contentType ContentType,
969	 *   content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
970	 */
971
972	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
973	    hdr.class != ASN1_CLASS_UNIVERSAL ||
974	    hdr.tag != ASN1_TAG_SEQUENCE) {
975		wpa_printf(MSG_DEBUG,
976			   "PKCS #12: Expected SEQUENCE (authSafe) - found class %d tag 0x%x; assume PKCS #12 not used",
977			   hdr.class, hdr.tag);
978		return -1;
979	}
980
981	pos = hdr.payload;
982	end = pos + hdr.length;
983
984	/* ContentType ::= OBJECT IDENTIFIER */
985	if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
986		wpa_printf(MSG_DEBUG,
987			   "PKCS #12: Could not find OBJECT IDENTIFIER (contentType); assume PKCS #12 not used");
988		return -1;
989	}
990	asn1_oid_to_str(&oid, buf, sizeof(buf));
991	wpa_printf(MSG_DEBUG, "PKCS #12: contentType %s", buf);
992	if (!is_oid_pkcs7_data(&oid)) {
993		wpa_printf(MSG_DEBUG, "PKCS #12: Unsupported contentType %s",
994			   buf);
995		return -1;
996	}
997
998	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
999	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
1000	    hdr.tag != 0) {
1001		wpa_printf(MSG_DEBUG,
1002			   "PKCS #12: Expected [0] EXPLICIT (content) - found class %d tag 0x%x; assume PKCS #12 not used",
1003			   hdr.class, hdr.tag);
1004		return -1;
1005	}
1006
1007	pos = hdr.payload;
1008
1009	/* Data ::= OCTET STRING */
1010	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1011	    hdr.class != ASN1_CLASS_UNIVERSAL ||
1012	    hdr.tag != ASN1_TAG_OCTETSTRING) {
1013		wpa_printf(MSG_DEBUG,
1014			   "PKCS #12: Expected OCTET STRING (Data) - found class %d tag 0x%x; assume PKCS #12 not used",
1015			   hdr.class, hdr.tag);
1016		return -1;
1017	}
1018
1019	/*
1020	 * AuthenticatedSafe ::= SEQUENCE OF ContentInfo
1021	 *     -- Data if unencrypted
1022	 *     -- EncryptedData if password-encrypted
1023	 *     -- EnvelopedData if public key-encrypted
1024	 */
1025	wpa_hexdump(MSG_MSGDUMP, "PKCS #12: Data content",
1026		    hdr.payload, hdr.length);
1027
1028	if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
1029	    hdr.class != ASN1_CLASS_UNIVERSAL ||
1030	    hdr.tag != ASN1_TAG_SEQUENCE) {
1031		wpa_printf(MSG_DEBUG,
1032			   "PKCS #12: Expected SEQUENCE within Data content - found class %d tag 0x%x; assume PKCS #12 not used",
1033			   hdr.class, hdr.tag);
1034		return -1;
1035	}
1036
1037	pos = hdr.payload;
1038	end = pos + hdr.length;
1039
1040	while (end > pos) {
1041		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
1042		    hdr.class != ASN1_CLASS_UNIVERSAL ||
1043		    hdr.tag != ASN1_TAG_SEQUENCE) {
1044			wpa_printf(MSG_DEBUG,
1045				   "PKCS #12: Expected SEQUENCE (ContentInfo) - found class %d tag 0x%x; assume PKCS #12 not used",
1046				   hdr.class, hdr.tag);
1047			return -1;
1048		}
1049		if (pkcs12_parse_content(cred, hdr.payload, hdr.length,
1050					 passwd) < 0)
1051			return -1;
1052
1053		pos = hdr.payload + hdr.length;
1054	}
1055
1056	return 0;
1057}
1058
1059#endif /* PKCS12_FUNCS */
1060
1061
1062static int tlsv1_set_key(struct tlsv1_credentials *cred,
1063			 const u8 *key, size_t len, const char *passwd)
1064{
1065	cred->key = crypto_private_key_import(key, len, passwd);
1066	if (cred->key == NULL)
1067		cred->key = tlsv1_set_key_pem(key, len);
1068	if (cred->key == NULL)
1069		cred->key = tlsv1_set_key_enc_pem(key, len, passwd);
1070#ifdef PKCS12_FUNCS
1071	if (!cred->key)
1072		pkcs12_parse(cred, key, len, passwd);
1073#endif /* PKCS12_FUNCS */
1074	if (cred->key == NULL) {
1075		wpa_printf(MSG_INFO, "TLSv1: Failed to parse private key");
1076		return -1;
1077	}
1078	return 0;
1079}
1080
1081
1082/**
1083 * tlsv1_set_private_key - Set private key
1084 * @cred: TLSv1 credentials from tlsv1_cred_alloc()
1085 * @private_key: File or reference name for the key in PEM or DER format
1086 * @private_key_passwd: Passphrase for decrypted private key, %NULL if no
1087 * passphrase is used.
1088 * @private_key_blob: private_key as inlined data or %NULL if not used
1089 * @private_key_blob_len: private_key_blob length
1090 * Returns: 0 on success, -1 on failure
1091 */
1092int tlsv1_set_private_key(struct tlsv1_credentials *cred,
1093			  const char *private_key,
1094			  const char *private_key_passwd,
1095			  const u8 *private_key_blob,
1096			  size_t private_key_blob_len)
1097{
1098	crypto_private_key_free(cred->key);
1099	cred->key = NULL;
1100
1101	if (private_key_blob)
1102		return tlsv1_set_key(cred, private_key_blob,
1103				     private_key_blob_len,
1104				     private_key_passwd);
1105
1106	if (private_key) {
1107		u8 *buf;
1108		size_t len;
1109		int ret;
1110
1111		buf = (u8 *) os_readfile(private_key, &len);
1112		if (buf == NULL) {
1113			wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'",
1114				   private_key);
1115			return -1;
1116		}
1117
1118		ret = tlsv1_set_key(cred, buf, len, private_key_passwd);
1119		os_free(buf);
1120		return ret;
1121	}
1122
1123	return 0;
1124}
1125
1126
1127static int tlsv1_set_dhparams_der(struct tlsv1_credentials *cred,
1128				  const u8 *dh, size_t len)
1129{
1130	struct asn1_hdr hdr;
1131	const u8 *pos, *end;
1132
1133	pos = dh;
1134	end = dh + len;
1135
1136	/*
1137	 * DHParameter ::= SEQUENCE {
1138	 *   prime INTEGER, -- p
1139	 *   base INTEGER, -- g
1140	 *   privateValueLength INTEGER OPTIONAL }
1141	 */
1142
1143	/* DHParamer ::= SEQUENCE */
1144	if (asn1_get_next(pos, len, &hdr) < 0 ||
1145	    hdr.class != ASN1_CLASS_UNIVERSAL ||
1146	    hdr.tag != ASN1_TAG_SEQUENCE) {
1147		wpa_printf(MSG_DEBUG, "DH: DH parameters did not start with a "
1148			   "valid SEQUENCE - found class %d tag 0x%x",
1149			   hdr.class, hdr.tag);
1150		return -1;
1151	}
1152	pos = hdr.payload;
1153
1154	/* prime INTEGER */
1155	if (asn1_get_next(pos, end - pos, &hdr) < 0)
1156		return -1;
1157
1158	if (hdr.class != ASN1_CLASS_UNIVERSAL ||
1159	    hdr.tag != ASN1_TAG_INTEGER) {
1160		wpa_printf(MSG_DEBUG, "DH: No INTEGER tag found for p; "
1161			   "class=%d tag=0x%x", hdr.class, hdr.tag);
1162		return -1;
1163	}
1164
1165	wpa_hexdump(MSG_MSGDUMP, "DH: prime (p)", hdr.payload, hdr.length);
1166	if (hdr.length == 0)
1167		return -1;
1168	os_free(cred->dh_p);
1169	cred->dh_p = os_memdup(hdr.payload, hdr.length);
1170	if (cred->dh_p == NULL)
1171		return -1;
1172	cred->dh_p_len = hdr.length;
1173	pos = hdr.payload + hdr.length;
1174
1175	/* base INTEGER */
1176	if (asn1_get_next(pos, end - pos, &hdr) < 0)
1177		return -1;
1178
1179	if (hdr.class != ASN1_CLASS_UNIVERSAL ||
1180	    hdr.tag != ASN1_TAG_INTEGER) {
1181		wpa_printf(MSG_DEBUG, "DH: No INTEGER tag found for g; "
1182			   "class=%d tag=0x%x", hdr.class, hdr.tag);
1183		return -1;
1184	}
1185
1186	wpa_hexdump(MSG_MSGDUMP, "DH: base (g)", hdr.payload, hdr.length);
1187	if (hdr.length == 0)
1188		return -1;
1189	os_free(cred->dh_g);
1190	cred->dh_g = os_memdup(hdr.payload, hdr.length);
1191	if (cred->dh_g == NULL)
1192		return -1;
1193	cred->dh_g_len = hdr.length;
1194
1195	return 0;
1196}
1197
1198
1199static const char *pem_dhparams_begin = "-----BEGIN DH PARAMETERS-----";
1200static const char *pem_dhparams_end = "-----END DH PARAMETERS-----";
1201
1202
1203static int tlsv1_set_dhparams_blob(struct tlsv1_credentials *cred,
1204				   const u8 *buf, size_t len)
1205{
1206	const u8 *pos, *end;
1207	unsigned char *der;
1208	size_t der_len;
1209
1210	pos = search_tag(pem_dhparams_begin, buf, len);
1211	if (!pos) {
1212		wpa_printf(MSG_DEBUG, "TLSv1: No PEM dhparams tag found - "
1213			   "assume DER format");
1214		return tlsv1_set_dhparams_der(cred, buf, len);
1215	}
1216
1217	wpa_printf(MSG_DEBUG, "TLSv1: Converting PEM format dhparams into DER "
1218		   "format");
1219
1220	pos += os_strlen(pem_dhparams_begin);
1221	end = search_tag(pem_dhparams_end, pos, buf + len - pos);
1222	if (end == NULL) {
1223		wpa_printf(MSG_INFO, "TLSv1: Could not find PEM dhparams end "
1224			   "tag (%s)", pem_dhparams_end);
1225		return -1;
1226	}
1227
1228	der = base64_decode(pos, end - pos, &der_len);
1229	if (der == NULL) {
1230		wpa_printf(MSG_INFO, "TLSv1: Could not decode PEM dhparams");
1231		return -1;
1232	}
1233
1234	if (tlsv1_set_dhparams_der(cred, der, der_len) < 0) {
1235		wpa_printf(MSG_INFO, "TLSv1: Failed to parse PEM dhparams "
1236			   "DER conversion");
1237		os_free(der);
1238		return -1;
1239	}
1240
1241	os_free(der);
1242
1243	return 0;
1244}
1245
1246
1247/**
1248 * tlsv1_set_dhparams - Set Diffie-Hellman parameters
1249 * @cred: TLSv1 credentials from tlsv1_cred_alloc()
1250 * @dh_file: File or reference name for the DH params in PEM or DER format
1251 * @dh_blob: DH params as inlined data or %NULL if not used
1252 * @dh_blob_len: dh_blob length
1253 * Returns: 0 on success, -1 on failure
1254 */
1255int tlsv1_set_dhparams(struct tlsv1_credentials *cred, const char *dh_file,
1256		       const u8 *dh_blob, size_t dh_blob_len)
1257{
1258	if (dh_blob)
1259		return tlsv1_set_dhparams_blob(cred, dh_blob, dh_blob_len);
1260
1261	if (dh_file) {
1262		u8 *buf;
1263		size_t len;
1264		int ret;
1265
1266		buf = (u8 *) os_readfile(dh_file, &len);
1267		if (buf == NULL) {
1268			wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'",
1269				   dh_file);
1270			return -1;
1271		}
1272
1273		ret = tlsv1_set_dhparams_blob(cred, buf, len);
1274		os_free(buf);
1275		return ret;
1276	}
1277
1278	return 0;
1279}
1280