Home | History | Annotate | Download | only in tls
      1 /*
      2  * TLSv1 credentials
      3  * Copyright (c) 2006-2015, Jouni Malinen <j (at) 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 
     21 struct tlsv1_credentials * tlsv1_cred_alloc(void)
     22 {
     23 	struct tlsv1_credentials *cred;
     24 	cred = os_zalloc(sizeof(*cred));
     25 	return cred;
     26 }
     27 
     28 
     29 void 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 
     45 static 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 
     80 static const char *pem_cert_begin = "-----BEGIN CERTIFICATE-----";
     81 static const char *pem_cert_end = "-----END CERTIFICATE-----";
     82 static const char *pem_key_begin = "-----BEGIN RSA PRIVATE KEY-----";
     83 static const char *pem_key_end = "-----END RSA PRIVATE KEY-----";
     84 static const char *pem_key2_begin = "-----BEGIN PRIVATE KEY-----";
     85 static const char *pem_key2_end = "-----END PRIVATE KEY-----";
     86 static const char *pem_key_enc_begin = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
     87 static const char *pem_key_enc_end = "-----END ENCRYPTED PRIVATE KEY-----";
     88 
     89 
     90 static 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 
    107 static 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 
    157 static 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  */
    194 int 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  */
    258 int 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 
    266 static 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 
    305 static 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 
    335 static 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 
    345 static 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 
    357 static 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 
    369 static int is_oid_pkcs7_data(struct asn1_oid *oid)
    370 {
    371 	return is_oid_pkcs7(oid) && oid->oid[6] == 1 /* data */;
    372 }
    373 
    374 
    375 static 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 
    381 static 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 
    393 static 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 
    400 static 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 
    407 static 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 
    415 static int pkcs12_keybag(struct tlsv1_credentials *cred,
    416 			 const u8 *buf, size_t len)
    417 {
    418 	/* TODO */
    419 	return 0;
    420 }
    421 
    422 
    423 static 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 
    443 static 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 
    523 static 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 
    550 static 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 
    577 static 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 
    622 static 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 
    700 static 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 
    745 static 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 
    767 static 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 
    882 static 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 
    925 static 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 
   1062 static 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  */
   1092 int 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 
   1127 static 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_malloc(hdr.length);
   1170 	if (cred->dh_p == NULL)
   1171 		return -1;
   1172 	os_memcpy(cred->dh_p, hdr.payload, hdr.length);
   1173 	cred->dh_p_len = hdr.length;
   1174 	pos = hdr.payload + hdr.length;
   1175 
   1176 	/* base INTEGER */
   1177 	if (asn1_get_next(pos, end - pos, &hdr) < 0)
   1178 		return -1;
   1179 
   1180 	if (hdr.class != ASN1_CLASS_UNIVERSAL ||
   1181 	    hdr.tag != ASN1_TAG_INTEGER) {
   1182 		wpa_printf(MSG_DEBUG, "DH: No INTEGER tag found for g; "
   1183 			   "class=%d tag=0x%x", hdr.class, hdr.tag);
   1184 		return -1;
   1185 	}
   1186 
   1187 	wpa_hexdump(MSG_MSGDUMP, "DH: base (g)", hdr.payload, hdr.length);
   1188 	if (hdr.length == 0)
   1189 		return -1;
   1190 	os_free(cred->dh_g);
   1191 	cred->dh_g = os_malloc(hdr.length);
   1192 	if (cred->dh_g == NULL)
   1193 		return -1;
   1194 	os_memcpy(cred->dh_g, hdr.payload, hdr.length);
   1195 	cred->dh_g_len = hdr.length;
   1196 
   1197 	return 0;
   1198 }
   1199 
   1200 
   1201 static const char *pem_dhparams_begin = "-----BEGIN DH PARAMETERS-----";
   1202 static const char *pem_dhparams_end = "-----END DH PARAMETERS-----";
   1203 
   1204 
   1205 static int tlsv1_set_dhparams_blob(struct tlsv1_credentials *cred,
   1206 				   const u8 *buf, size_t len)
   1207 {
   1208 	const u8 *pos, *end;
   1209 	unsigned char *der;
   1210 	size_t der_len;
   1211 
   1212 	pos = search_tag(pem_dhparams_begin, buf, len);
   1213 	if (!pos) {
   1214 		wpa_printf(MSG_DEBUG, "TLSv1: No PEM dhparams tag found - "
   1215 			   "assume DER format");
   1216 		return tlsv1_set_dhparams_der(cred, buf, len);
   1217 	}
   1218 
   1219 	wpa_printf(MSG_DEBUG, "TLSv1: Converting PEM format dhparams into DER "
   1220 		   "format");
   1221 
   1222 	pos += os_strlen(pem_dhparams_begin);
   1223 	end = search_tag(pem_dhparams_end, pos, buf + len - pos);
   1224 	if (end == NULL) {
   1225 		wpa_printf(MSG_INFO, "TLSv1: Could not find PEM dhparams end "
   1226 			   "tag (%s)", pem_dhparams_end);
   1227 		return -1;
   1228 	}
   1229 
   1230 	der = base64_decode(pos, end - pos, &der_len);
   1231 	if (der == NULL) {
   1232 		wpa_printf(MSG_INFO, "TLSv1: Could not decode PEM dhparams");
   1233 		return -1;
   1234 	}
   1235 
   1236 	if (tlsv1_set_dhparams_der(cred, der, der_len) < 0) {
   1237 		wpa_printf(MSG_INFO, "TLSv1: Failed to parse PEM dhparams "
   1238 			   "DER conversion");
   1239 		os_free(der);
   1240 		return -1;
   1241 	}
   1242 
   1243 	os_free(der);
   1244 
   1245 	return 0;
   1246 }
   1247 
   1248 
   1249 /**
   1250  * tlsv1_set_dhparams - Set Diffie-Hellman parameters
   1251  * @cred: TLSv1 credentials from tlsv1_cred_alloc()
   1252  * @dh_file: File or reference name for the DH params in PEM or DER format
   1253  * @dh_blob: DH params as inlined data or %NULL if not used
   1254  * @dh_blob_len: dh_blob length
   1255  * Returns: 0 on success, -1 on failure
   1256  */
   1257 int tlsv1_set_dhparams(struct tlsv1_credentials *cred, const char *dh_file,
   1258 		       const u8 *dh_blob, size_t dh_blob_len)
   1259 {
   1260 	if (dh_blob)
   1261 		return tlsv1_set_dhparams_blob(cred, dh_blob, dh_blob_len);
   1262 
   1263 	if (dh_file) {
   1264 		u8 *buf;
   1265 		size_t len;
   1266 		int ret;
   1267 
   1268 		buf = (u8 *) os_readfile(dh_file, &len);
   1269 		if (buf == NULL) {
   1270 			wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'",
   1271 				   dh_file);
   1272 			return -1;
   1273 		}
   1274 
   1275 		ret = tlsv1_set_dhparams_blob(cred, buf, len);
   1276 		os_free(buf);
   1277 		return ret;
   1278 	}
   1279 
   1280 	return 0;
   1281 }
   1282