Home | History | Annotate | Line # | 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((const char *) 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((const char *) 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((const char *) 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 || !asn1_is_sequence(&hdr)) {
    459 		asn1_unexpected(&hdr, "PKCS #12: Expected SEQUENCE (CertBag)");
    460 		return -1;
    461 	}
    462 
    463 	pos = hdr.payload;
    464 	end = hdr.payload + hdr.length;
    465 
    466 	if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
    467 		wpa_printf(MSG_DEBUG,
    468 			   "PKCS #12: Failed to parse OID (certId)");
    469 		return -1;
    470 	}
    471 
    472 	asn1_oid_to_str(&oid, obuf, sizeof(obuf));
    473 	wpa_printf(MSG_DEBUG, "PKCS #12: certId %s", obuf);
    474 
    475 	if (!is_oid_pkcs9_x509_cert(&oid)) {
    476 		wpa_printf(MSG_DEBUG,
    477 			   "PKCS #12: Ignored unsupported certificate type (certId %s)",
    478 			   obuf);
    479 	}
    480 
    481 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
    482 	    !asn1_is_cs_tag(&hdr, 0)) {
    483 		asn1_unexpected(&hdr,
    484 				"PKCS #12: Expected [0] EXPLICIT (certValue)");
    485 		return -1;
    486 	}
    487 
    488 	if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
    489 	    !asn1_is_octetstring(&hdr)) {
    490 		asn1_unexpected(&hdr,
    491 				"PKCS #12: Expected OCTET STRING (x509Certificate)");
    492 		return -1;
    493 	}
    494 
    495 	wpa_hexdump(MSG_DEBUG, "PKCS #12: x509Certificate",
    496 		    hdr.payload, hdr.length);
    497 	if (cred->cert) {
    498 		struct x509_certificate *cert;
    499 
    500 		wpa_printf(MSG_DEBUG, "PKCS #12: Ignore extra certificate");
    501 		cert = x509_certificate_parse(hdr.payload, hdr.length);
    502 		if (!cert) {
    503 			wpa_printf(MSG_DEBUG,
    504 				   "PKCS #12: Failed to parse x509Certificate");
    505 			return 0;
    506 		}
    507 		x509_certificate_chain_free(cert);
    508 
    509 		return 0;
    510 	}
    511 	return tlsv1_set_cert(cred, NULL, hdr.payload, hdr.length);
    512 }
    513 
    514 
    515 static int pkcs12_parse_attr_friendly_name(const u8 *pos, const u8 *end)
    516 {
    517 	struct asn1_hdr hdr;
    518 
    519 	/*
    520 	 * RFC 2985, 5.5.1:
    521 	 * friendlyName ATTRIBUTE ::= {
    522 	 *         WITH SYNTAX BMPString (SIZE(1..pkcs-9-ub-friendlyName))
    523 	 *         EQUALITY MATCHING RULE caseIgnoreMatch
    524 	 *         SINGLE VALUE TRUE
    525 	 *          ID pkcs-9-at-friendlyName
    526 	 * }
    527 	 */
    528 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
    529 	    !asn1_is_bmpstring(&hdr)) {
    530 		asn1_unexpected(&hdr,
    531 				"PKCS #12: Expected BMPSTRING (friendlyName)");
    532 		return 0;
    533 	}
    534 	wpa_hexdump_ascii(MSG_DEBUG, "PKCS #12: friendlyName",
    535 			  hdr.payload, hdr.length);
    536 	return 0;
    537 }
    538 
    539 
    540 static int pkcs12_parse_attr_local_key_id(const u8 *pos, const u8 *end)
    541 {
    542 	struct asn1_hdr hdr;
    543 
    544 	/*
    545 	 * RFC 2985, 5.5.2:
    546 	 * localKeyId ATTRIBUTE ::= {
    547 	 *         WITH SYNTAX OCTET STRING
    548 	 *         EQUALITY MATCHING RULE octetStringMatch
    549 	 *         SINGLE VALUE TRUE
    550 	 *         ID pkcs-9-at-localKeyId
    551 	 * }
    552 	 */
    553 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
    554 	    !asn1_is_octetstring(&hdr)) {
    555 		asn1_unexpected(&hdr,
    556 				"PKCS #12: Expected OCTET STRING (localKeyID)");
    557 		return -1;
    558 	}
    559 	wpa_hexdump_key(MSG_DEBUG, "PKCS #12: localKeyID",
    560 			hdr.payload, hdr.length);
    561 	return 0;
    562 }
    563 
    564 
    565 static int pkcs12_parse_attr(const u8 *pos, size_t len)
    566 {
    567 	const u8 *end = pos + len;
    568 	struct asn1_hdr hdr;
    569 	struct asn1_oid a_oid;
    570 	char obuf[80];
    571 
    572 	/*
    573 	 * PKCS12Attribute ::= SEQUENCE {
    574 	 * attrId      ATTRIBUTE.&id ({PKCS12AttrSet}),
    575 	 * attrValues  SET OF ATTRIBUTE.&Type ({PKCS12AttrSet}{@attrId})
    576 	 * }
    577 	 */
    578 
    579 	if (asn1_get_oid(pos, end - pos, &a_oid, &pos)) {
    580 		wpa_printf(MSG_DEBUG, "PKCS #12: Failed to parse OID (attrId)");
    581 		return -1;
    582 	}
    583 
    584 	asn1_oid_to_str(&a_oid, obuf, sizeof(obuf));
    585 	wpa_printf(MSG_DEBUG, "PKCS #12: attrId %s", obuf);
    586 
    587 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_set(&hdr)) {
    588 		asn1_unexpected(&hdr, "PKCS #12: Expected SET (attrValues)");
    589 		return -1;
    590 	}
    591 	wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: attrValues",
    592 			hdr.payload, hdr.length);
    593 	pos = hdr.payload;
    594 	end = hdr.payload + hdr.length;
    595 
    596 	if (is_oid_pkcs9_friendly_name(&a_oid))
    597 		return pkcs12_parse_attr_friendly_name(pos, end);
    598 	if (is_oid_pkcs9_local_key_id(&a_oid))
    599 		return pkcs12_parse_attr_local_key_id(pos, end);
    600 
    601 	wpa_printf(MSG_DEBUG, "PKCS #12: Ignore unknown attribute");
    602 	return 0;
    603 }
    604 
    605 
    606 static int pkcs12_safebag(struct tlsv1_credentials *cred,
    607 			  const u8 *buf, size_t len, const char *passwd)
    608 {
    609 	struct asn1_hdr hdr;
    610 	struct asn1_oid oid;
    611 	char obuf[80];
    612 	const u8 *pos = buf, *end = buf + len;
    613 	const u8 *value;
    614 	size_t value_len;
    615 
    616 	wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: SafeBag", buf, len);
    617 
    618 	/* BAG-TYPE ::= TYPE-IDENTIFIER */
    619 	if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
    620 		wpa_printf(MSG_DEBUG,
    621 			   "PKCS #12: Failed to parse OID (BAG-TYPE)");
    622 		return -1;
    623 	}
    624 
    625 	asn1_oid_to_str(&oid, obuf, sizeof(obuf));
    626 	wpa_printf(MSG_DEBUG, "PKCS #12: BAG-TYPE %s", obuf);
    627 
    628 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
    629 	    !asn1_is_cs_tag(&hdr, 0)) {
    630 		asn1_unexpected(&hdr,
    631 				"PKCS #12: Expected [0] EXPLICIT (bagValue)");
    632 		return 0;
    633 	}
    634 	value = hdr.payload;
    635 	value_len = hdr.length;
    636 	wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: bagValue", value, value_len);
    637 	pos = hdr.payload + hdr.length;
    638 
    639 	if (pos < end) {
    640 		/* bagAttributes  SET OF PKCS12Attribute OPTIONAL */
    641 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
    642 		    !asn1_is_set(&hdr)) {
    643 			asn1_unexpected(&hdr,
    644 					"PKCS #12: Expected SET (bagAttributes)");
    645 			return -1;
    646 		}
    647 		wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: bagAttributes",
    648 				hdr.payload, hdr.length);
    649 
    650 		pos = hdr.payload;
    651 		end = hdr.payload + hdr.length;
    652 		while (pos < end) {
    653 			/* PKCS12Attribute ::= SEQUENCE */
    654 			if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
    655 			    !asn1_is_sequence(&hdr)) {
    656 				asn1_unexpected(&hdr,
    657 						"PKCS #12: Expected SEQUENCE (PKCS12Attribute)");
    658 				return -1;
    659 			}
    660 			if (pkcs12_parse_attr(hdr.payload, hdr.length) < 0)
    661 				return -1;
    662 			pos = hdr.payload + hdr.length;
    663 		}
    664 	}
    665 
    666 	if (pkcs12_is_bagtype_oid(&oid, 1))
    667 		return pkcs12_keybag(cred, value, value_len);
    668 	if (pkcs12_is_bagtype_oid(&oid, 2))
    669 		return pkcs12_pkcs8_keybag(cred, value, value_len, passwd);
    670 	if (pkcs12_is_bagtype_oid(&oid, 3))
    671 		return pkcs12_certbag(cred, value, value_len);
    672 
    673 	wpa_printf(MSG_DEBUG, "PKCS #12: Ignore unsupported BAG-TYPE");
    674 	return 0;
    675 }
    676 
    677 
    678 static int pkcs12_safecontents(struct tlsv1_credentials *cred,
    679 			       const u8 *buf, size_t len,
    680 			       const char *passwd)
    681 {
    682 	struct asn1_hdr hdr;
    683 	const u8 *pos, *end;
    684 
    685 	/* SafeContents ::= SEQUENCE OF SafeBag */
    686 	if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
    687 		asn1_unexpected(&hdr,
    688 				"PKCS #12: Expected SEQUENCE (SafeContents)");
    689 		return -1;
    690 	}
    691 	pos = hdr.payload;
    692 	end = hdr.payload + hdr.length;
    693 
    694 	/*
    695 	 * SafeBag ::= SEQUENCE {
    696 	 *   bagId          BAG-TYPE.&id ({PKCS12BagSet})
    697 	 *   bagValue       [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}),
    698 	 *   bagAttributes  SET OF PKCS12Attribute OPTIONAL
    699 	 * }
    700 	 */
    701 
    702 	while (pos < end) {
    703 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
    704 		    !asn1_is_sequence(&hdr)) {
    705 			asn1_unexpected(&hdr,
    706 					"PKCS #12: Expected SEQUENCE (SafeBag)");
    707 			return -1;
    708 		}
    709 		if (pkcs12_safebag(cred, hdr.payload, hdr.length, passwd) < 0)
    710 			return -1;
    711 		pos = hdr.payload + hdr.length;
    712 	}
    713 
    714 	return 0;
    715 }
    716 
    717 
    718 static int pkcs12_parse_content_data(struct tlsv1_credentials *cred,
    719 				     const u8 *pos, const u8 *end,
    720 				     const char *passwd)
    721 {
    722 	struct asn1_hdr hdr;
    723 
    724 	/* Data ::= OCTET STRING */
    725 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
    726 	    !asn1_is_octetstring(&hdr)) {
    727 		asn1_unexpected(&hdr, "PKCS #12: Expected OCTET STRING (Data)");
    728 		return -1;
    729 	}
    730 
    731 	wpa_hexdump(MSG_MSGDUMP, "PKCS #12: Data", hdr.payload, hdr.length);
    732 
    733 	return pkcs12_safecontents(cred, hdr.payload, hdr.length, passwd);
    734 }
    735 
    736 
    737 static int pkcs12_parse_content_enc_data(struct tlsv1_credentials *cred,
    738 					 const u8 *pos, const u8 *end,
    739 					 const char *passwd)
    740 {
    741 	struct asn1_hdr hdr;
    742 	struct asn1_oid oid;
    743 	char buf[80];
    744 	const u8 *enc_alg;
    745 	u8 *data;
    746 	size_t enc_alg_len, data_len;
    747 	int res = -1;
    748 
    749 	/*
    750 	 * EncryptedData ::= SEQUENCE {
    751 	 *   version Version,
    752 	 *   encryptedContentInfo EncryptedContentInfo }
    753 	 */
    754 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
    755 	    !asn1_is_sequence(&hdr)) {
    756 		asn1_unexpected(&hdr,
    757 				"PKCS #12: Expected SEQUENCE (EncryptedData)");
    758 		return 0;
    759 	}
    760 	pos = hdr.payload;
    761 
    762 	/* Version ::= INTEGER */
    763 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_integer(&hdr)) {
    764 		asn1_unexpected(&hdr,
    765 				"PKCS #12: No INTEGER tag found for version");
    766 		return -1;
    767 	}
    768 	if (hdr.length != 1 || hdr.payload[0] != 0) {
    769 		wpa_printf(MSG_DEBUG, "PKCS #12: Unrecognized PKCS #7 version");
    770 		return -1;
    771 	}
    772 	pos = hdr.payload + hdr.length;
    773 
    774 	wpa_hexdump(MSG_MSGDUMP, "PKCS #12: EncryptedContentInfo",
    775 		    pos, end - pos);
    776 
    777 	/*
    778 	 * EncryptedContentInfo ::= SEQUENCE {
    779 	 *   contentType ContentType,
    780 	 *   contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
    781 	 *   encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
    782 	 */
    783 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
    784 	    !asn1_is_sequence(&hdr)) {
    785 		asn1_unexpected(&hdr,
    786 				"PKCS #12: Expected SEQUENCE (EncryptedContentInfo)");
    787 		return -1;
    788 	}
    789 
    790 	pos = hdr.payload;
    791 	end = pos + hdr.length;
    792 
    793 	/* ContentType ::= OBJECT IDENTIFIER */
    794 	if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
    795 		wpa_printf(MSG_DEBUG,
    796 			   "PKCS #12: Could not find OBJECT IDENTIFIER (contentType)");
    797 		return -1;
    798 	}
    799 	asn1_oid_to_str(&oid, buf, sizeof(buf));
    800 	wpa_printf(MSG_DEBUG, "PKCS #12: EncryptedContentInfo::contentType %s",
    801 		   buf);
    802 
    803 	if (!is_oid_pkcs7_data(&oid)) {
    804 		wpa_printf(MSG_DEBUG,
    805 			   "PKCS #12: Unsupported EncryptedContentInfo::contentType %s",
    806 			   buf);
    807 		return 0;
    808 	}
    809 
    810 	/* ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier */
    811 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
    812 	    !asn1_is_sequence(&hdr)) {
    813 		asn1_unexpected(&hdr,
    814 				"PKCS #12: Expected SEQUENCE (ContentEncryptionAlgorithmIdentifier)");
    815 		return -1;
    816 	}
    817 	enc_alg = hdr.payload;
    818 	enc_alg_len = hdr.length;
    819 	pos = hdr.payload + hdr.length;
    820 
    821 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || hdr.constructed ||
    822 	    !asn1_is_cs_tag(&hdr, 0)) {
    823 		asn1_unexpected(&hdr,
    824 				"PKCS #12: Expected [0] IMPLICIT (encryptedContent)");
    825 		return -1;
    826 	}
    827 
    828 	/* EncryptedContent ::= OCTET STRING */
    829 	data = pkcs5_decrypt(enc_alg, enc_alg_len, hdr.payload, hdr.length,
    830 			     passwd, &data_len);
    831 	if (data) {
    832 		wpa_hexdump_key(MSG_MSGDUMP,
    833 				"PKCS #12: Decrypted encryptedContent",
    834 				data, data_len);
    835 		res = pkcs12_safecontents(cred, data, data_len, passwd);
    836 		os_free(data);
    837 	}
    838 
    839 	return res;
    840 }
    841 
    842 
    843 static int pkcs12_parse_content(struct tlsv1_credentials *cred,
    844 				const u8 *buf, size_t len,
    845 				const char *passwd)
    846 {
    847 	const u8 *pos = buf;
    848 	const u8 *end = buf + len;
    849 	struct asn1_oid oid;
    850 	char txt[80];
    851 	struct asn1_hdr hdr;
    852 
    853 	wpa_hexdump(MSG_MSGDUMP, "PKCS #12: ContentInfo", buf, len);
    854 
    855 	if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
    856 		wpa_printf(MSG_DEBUG,
    857 			   "PKCS #12: Could not find OBJECT IDENTIFIER (contentType)");
    858 		return 0;
    859 	}
    860 
    861 	asn1_oid_to_str(&oid, txt, sizeof(txt));
    862 	wpa_printf(MSG_DEBUG, "PKCS #12: contentType %s", txt);
    863 
    864 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
    865 	    !asn1_is_cs_tag(&hdr, 0)) {
    866 		asn1_unexpected(&hdr,
    867 				"PKCS #12: Expected [0] EXPLICIT (content)");
    868 		return 0;
    869 	}
    870 	pos = hdr.payload;
    871 
    872 	if (is_oid_pkcs7_data(&oid))
    873 		return pkcs12_parse_content_data(cred, pos, end, passwd);
    874 	if (is_oid_pkcs7_enc_data(&oid))
    875 		return pkcs12_parse_content_enc_data(cred, pos, end, passwd);
    876 
    877 	wpa_printf(MSG_DEBUG, "PKCS #12: Ignored unsupported contentType %s",
    878 		   txt);
    879 
    880 	return 0;
    881 }
    882 
    883 
    884 static int pkcs12_parse(struct tlsv1_credentials *cred,
    885 			const u8 *key, size_t len, const char *passwd)
    886 {
    887 	struct asn1_hdr hdr;
    888 	const u8 *pos, *end;
    889 	struct asn1_oid oid;
    890 	char buf[80];
    891 
    892 	/*
    893 	 * PFX ::= SEQUENCE {
    894 	 *     version     INTEGER {v3(3)}(v3,...),
    895 	 *     authSafe    ContentInfo,
    896 	 *     macData     MacData OPTIONAL
    897 	 * }
    898 	 */
    899 
    900 	if (asn1_get_next(key, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
    901 		asn1_unexpected(&hdr,
    902 				"PKCS #12: Expected SEQUENCE (PFX); assume PKCS #12 not used");
    903 		return -1;
    904 	}
    905 
    906 	pos = hdr.payload;
    907 	end = pos + hdr.length;
    908 
    909 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_integer(&hdr)) {
    910 		asn1_unexpected(&hdr,
    911 				"PKCS #12: No INTEGER tag found for version");
    912 		return -1;
    913 	}
    914 	if (hdr.length != 1 || hdr.payload[0] != 3) {
    915 		wpa_printf(MSG_DEBUG, "PKCS #12: Unrecognized version");
    916 		return -1;
    917 	}
    918 	pos = hdr.payload + hdr.length;
    919 
    920 	/*
    921 	 * ContentInfo ::= SEQUENCE {
    922 	 *   contentType ContentType,
    923 	 *   content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
    924 	 */
    925 
    926 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
    927 	    !asn1_is_sequence(&hdr)) {
    928 		asn1_unexpected(&hdr,
    929 				"PKCS #12: Expected SEQUENCE (authSafe); assume PKCS #12 not used");
    930 		return -1;
    931 	}
    932 
    933 	pos = hdr.payload;
    934 	end = pos + hdr.length;
    935 
    936 	/* ContentType ::= OBJECT IDENTIFIER */
    937 	if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
    938 		wpa_printf(MSG_DEBUG,
    939 			   "PKCS #12: Could not find OBJECT IDENTIFIER (contentType); assume PKCS #12 not used");
    940 		return -1;
    941 	}
    942 	asn1_oid_to_str(&oid, buf, sizeof(buf));
    943 	wpa_printf(MSG_DEBUG, "PKCS #12: contentType %s", buf);
    944 	if (!is_oid_pkcs7_data(&oid)) {
    945 		wpa_printf(MSG_DEBUG, "PKCS #12: Unsupported contentType %s",
    946 			   buf);
    947 		return -1;
    948 	}
    949 
    950 	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
    951 	    !asn1_is_cs_tag(&hdr, 0)) {
    952 		asn1_unexpected(&hdr,
    953 				"PKCS #12: Expected [0] EXPLICIT (content); assume PKCS #12 not used");
    954 		return -1;
    955 	}
    956 
    957 	pos = hdr.payload;
    958 
    959 	/* Data ::= OCTET STRING */
    960 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
    961 	    !asn1_is_octetstring(&hdr)) {
    962 		asn1_unexpected(&hdr,
    963 				"PKCS #12: Expected OCTET STRING (Data); assume PKCS #12 not used");
    964 		return -1;
    965 	}
    966 
    967 	/*
    968 	 * AuthenticatedSafe ::= SEQUENCE OF ContentInfo
    969 	 *     -- Data if unencrypted
    970 	 *     -- EncryptedData if password-encrypted
    971 	 *     -- EnvelopedData if public key-encrypted
    972 	 */
    973 	wpa_hexdump(MSG_MSGDUMP, "PKCS #12: Data content",
    974 		    hdr.payload, hdr.length);
    975 
    976 	if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
    977 	    !asn1_is_sequence(&hdr)) {
    978 		asn1_unexpected(&hdr,
    979 				"PKCS #12: Expected SEQUENCE within Data content; assume PKCS #12 not used");
    980 		return -1;
    981 	}
    982 
    983 	pos = hdr.payload;
    984 	end = pos + hdr.length;
    985 
    986 	while (end > pos) {
    987 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
    988 		    !asn1_is_sequence(&hdr)) {
    989 			asn1_unexpected(&hdr,
    990 					"PKCS #12: Expected SEQUENCE (ContentInfo); assume PKCS #12 not used");
    991 			return -1;
    992 		}
    993 		if (pkcs12_parse_content(cred, hdr.payload, hdr.length,
    994 					 passwd) < 0)
    995 			return -1;
    996 
    997 		pos = hdr.payload + hdr.length;
    998 	}
    999 
   1000 	return 0;
   1001 }
   1002 
   1003 #endif /* PKCS12_FUNCS */
   1004 
   1005 
   1006 static int tlsv1_set_key(struct tlsv1_credentials *cred,
   1007 			 const u8 *key, size_t len, const char *passwd)
   1008 {
   1009 	cred->key = crypto_private_key_import(key, len, passwd);
   1010 	if (cred->key == NULL)
   1011 		cred->key = tlsv1_set_key_pem(key, len);
   1012 	if (cred->key == NULL)
   1013 		cred->key = tlsv1_set_key_enc_pem(key, len, passwd);
   1014 #ifdef PKCS12_FUNCS
   1015 	if (!cred->key)
   1016 		pkcs12_parse(cred, key, len, passwd);
   1017 #endif /* PKCS12_FUNCS */
   1018 	if (cred->key == NULL) {
   1019 		wpa_printf(MSG_INFO, "TLSv1: Failed to parse private key");
   1020 		return -1;
   1021 	}
   1022 	return 0;
   1023 }
   1024 
   1025 
   1026 /**
   1027  * tlsv1_set_private_key - Set private key
   1028  * @cred: TLSv1 credentials from tlsv1_cred_alloc()
   1029  * @private_key: File or reference name for the key in PEM or DER format
   1030  * @private_key_passwd: Passphrase for decrypted private key, %NULL if no
   1031  * passphrase is used.
   1032  * @private_key_blob: private_key as inlined data or %NULL if not used
   1033  * @private_key_blob_len: private_key_blob length
   1034  * Returns: 0 on success, -1 on failure
   1035  */
   1036 int tlsv1_set_private_key(struct tlsv1_credentials *cred,
   1037 			  const char *private_key,
   1038 			  const char *private_key_passwd,
   1039 			  const u8 *private_key_blob,
   1040 			  size_t private_key_blob_len)
   1041 {
   1042 	crypto_private_key_free(cred->key);
   1043 	cred->key = NULL;
   1044 
   1045 	if (private_key_blob)
   1046 		return tlsv1_set_key(cred, private_key_blob,
   1047 				     private_key_blob_len,
   1048 				     private_key_passwd);
   1049 
   1050 	if (private_key) {
   1051 		u8 *buf;
   1052 		size_t len;
   1053 		int ret;
   1054 
   1055 		buf = (u8 *) os_readfile(private_key, &len);
   1056 		if (buf == NULL) {
   1057 			wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'",
   1058 				   private_key);
   1059 			return -1;
   1060 		}
   1061 
   1062 		ret = tlsv1_set_key(cred, buf, len, private_key_passwd);
   1063 		os_free(buf);
   1064 		return ret;
   1065 	}
   1066 
   1067 	return 0;
   1068 }
   1069 
   1070 
   1071 static int tlsv1_set_dhparams_der(struct tlsv1_credentials *cred,
   1072 				  const u8 *dh, size_t len)
   1073 {
   1074 	struct asn1_hdr hdr;
   1075 	const u8 *pos, *end;
   1076 
   1077 	pos = dh;
   1078 	end = dh + len;
   1079 
   1080 	/*
   1081 	 * DHParameter ::= SEQUENCE {
   1082 	 *   prime INTEGER, -- p
   1083 	 *   base INTEGER, -- g
   1084 	 *   privateValueLength INTEGER OPTIONAL }
   1085 	 */
   1086 
   1087 	/* DHParamer ::= SEQUENCE */
   1088 	if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
   1089 		asn1_unexpected(&hdr,
   1090 				"DH: DH parameters did not start with a valid SEQUENCE");
   1091 		return -1;
   1092 	}
   1093 	pos = hdr.payload;
   1094 
   1095 	/* prime INTEGER */
   1096 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
   1097 	    !asn1_is_integer(&hdr)) {
   1098 		asn1_unexpected(&hdr, "DH: No INTEGER tag found for p");
   1099 		return -1;
   1100 	}
   1101 
   1102 	wpa_hexdump(MSG_MSGDUMP, "DH: prime (p)", hdr.payload, hdr.length);
   1103 	if (hdr.length == 0)
   1104 		return -1;
   1105 	os_free(cred->dh_p);
   1106 	cred->dh_p = os_memdup(hdr.payload, hdr.length);
   1107 	if (cred->dh_p == NULL)
   1108 		return -1;
   1109 	cred->dh_p_len = hdr.length;
   1110 	pos = hdr.payload + hdr.length;
   1111 
   1112 	/* base INTEGER */
   1113 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
   1114 	    !asn1_is_integer(&hdr)) {
   1115 		asn1_unexpected(&hdr, "DH: No INTEGER tag found for g");
   1116 		return -1;
   1117 	}
   1118 
   1119 	wpa_hexdump(MSG_MSGDUMP, "DH: base (g)", hdr.payload, hdr.length);
   1120 	if (hdr.length == 0)
   1121 		return -1;
   1122 	os_free(cred->dh_g);
   1123 	cred->dh_g = os_memdup(hdr.payload, hdr.length);
   1124 	if (cred->dh_g == NULL)
   1125 		return -1;
   1126 	cred->dh_g_len = hdr.length;
   1127 
   1128 	return 0;
   1129 }
   1130 
   1131 
   1132 static const char *pem_dhparams_begin = "-----BEGIN DH PARAMETERS-----";
   1133 static const char *pem_dhparams_end = "-----END DH PARAMETERS-----";
   1134 
   1135 
   1136 static int tlsv1_set_dhparams_blob(struct tlsv1_credentials *cred,
   1137 				   const u8 *buf, size_t len)
   1138 {
   1139 	const u8 *pos, *end;
   1140 	unsigned char *der;
   1141 	size_t der_len;
   1142 
   1143 	pos = search_tag(pem_dhparams_begin, buf, len);
   1144 	if (!pos) {
   1145 		wpa_printf(MSG_DEBUG, "TLSv1: No PEM dhparams tag found - "
   1146 			   "assume DER format");
   1147 		return tlsv1_set_dhparams_der(cred, buf, len);
   1148 	}
   1149 
   1150 	wpa_printf(MSG_DEBUG, "TLSv1: Converting PEM format dhparams into DER "
   1151 		   "format");
   1152 
   1153 	pos += os_strlen(pem_dhparams_begin);
   1154 	end = search_tag(pem_dhparams_end, pos, buf + len - pos);
   1155 	if (end == NULL) {
   1156 		wpa_printf(MSG_INFO, "TLSv1: Could not find PEM dhparams end "
   1157 			   "tag (%s)", pem_dhparams_end);
   1158 		return -1;
   1159 	}
   1160 
   1161 	der = base64_decode((const char *) pos, end - pos, &der_len);
   1162 	if (der == NULL) {
   1163 		wpa_printf(MSG_INFO, "TLSv1: Could not decode PEM dhparams");
   1164 		return -1;
   1165 	}
   1166 
   1167 	if (tlsv1_set_dhparams_der(cred, der, der_len) < 0) {
   1168 		wpa_printf(MSG_INFO, "TLSv1: Failed to parse PEM dhparams "
   1169 			   "DER conversion");
   1170 		os_free(der);
   1171 		return -1;
   1172 	}
   1173 
   1174 	os_free(der);
   1175 
   1176 	return 0;
   1177 }
   1178 
   1179 
   1180 /**
   1181  * tlsv1_set_dhparams - Set Diffie-Hellman parameters
   1182  * @cred: TLSv1 credentials from tlsv1_cred_alloc()
   1183  * @dh_file: File or reference name for the DH params in PEM or DER format
   1184  * @dh_blob: DH params as inlined data or %NULL if not used
   1185  * @dh_blob_len: dh_blob length
   1186  * Returns: 0 on success, -1 on failure
   1187  */
   1188 int tlsv1_set_dhparams(struct tlsv1_credentials *cred, const char *dh_file,
   1189 		       const u8 *dh_blob, size_t dh_blob_len)
   1190 {
   1191 	if (dh_blob)
   1192 		return tlsv1_set_dhparams_blob(cred, dh_blob, dh_blob_len);
   1193 
   1194 	if (dh_file) {
   1195 		u8 *buf;
   1196 		size_t len;
   1197 		int ret;
   1198 
   1199 		buf = (u8 *) os_readfile(dh_file, &len);
   1200 		if (buf == NULL) {
   1201 			wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'",
   1202 				   dh_file);
   1203 			return -1;
   1204 		}
   1205 
   1206 		ret = tlsv1_set_dhparams_blob(cred, buf, len);
   1207 		os_free(buf);
   1208 		return ret;
   1209 	}
   1210 
   1211 	return 0;
   1212 }
   1213