3 * Copyright (c) 2006-2015, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
13 #include "crypto/crypto.h"
14 #include "crypto/sha1.h"
18 #include "tlsv1_cred.h"
21 struct tlsv1_credentials * tlsv1_cred_alloc(void)
23 struct tlsv1_credentials *cred;
24 cred = os_zalloc(sizeof(*cred));
29 void tlsv1_cred_free(struct tlsv1_credentials *cred)
34 x509_certificate_chain_free(cred->trusted_certs);
35 x509_certificate_chain_free(cred->cert);
36 crypto_private_key_free(cred->key);
39 os_free(cred->ocsp_stapling_response);
40 os_free(cred->ocsp_stapling_response_multi);
45 static int tlsv1_add_cert_der(struct x509_certificate **chain,
46 const u8 *buf, size_t len)
48 struct x509_certificate *cert, *p;
51 cert = x509_certificate_parse(buf, len);
53 wpa_printf(MSG_INFO, "TLSv1: %s - failed to parse certificate",
61 if (p && x509_name_compare(&cert->subject, &p->issuer) == 0) {
63 * The new certificate is the issuer of the last certificate in
64 * the chain - add the new certificate to the end.
68 /* Add to the beginning of the chain */
73 x509_name_string(&cert->subject, name, sizeof(name));
74 wpa_printf(MSG_DEBUG, "TLSv1: Added certificate: %s", name);
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-----";
90 static const u8 * search_tag(const char *tag, const u8 *buf, size_t len)
94 plen = os_strlen(tag);
98 for (i = 0; i < len - plen; i++) {
99 if (os_memcmp(buf + i, tag, plen) == 0)
107 static int tlsv1_add_cert(struct x509_certificate **chain,
108 const u8 *buf, size_t len)
114 pos = search_tag(pem_cert_begin, buf, len);
116 wpa_printf(MSG_DEBUG, "TLSv1: No PEM certificate tag found - "
117 "assume DER format");
118 return tlsv1_add_cert_der(chain, buf, len);
121 wpa_printf(MSG_DEBUG, "TLSv1: Converting PEM format certificate into "
125 pos += os_strlen(pem_cert_begin);
126 end = search_tag(pem_cert_end, pos, buf + len - pos);
128 wpa_printf(MSG_INFO, "TLSv1: Could not find PEM "
129 "certificate end tag (%s)", pem_cert_end);
133 der = base64_decode(pos, end - pos, &der_len);
135 wpa_printf(MSG_INFO, "TLSv1: Could not decode PEM "
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");
149 end += os_strlen(pem_cert_end);
150 pos = search_tag(pem_cert_begin, end, buf + len - end);
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)
162 return tlsv1_add_cert(chain, cert_blob, cert_blob_len);
169 buf = (u8 *) os_readfile(cert, &len);
171 wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'",
176 ret = tlsv1_add_cert(chain, buf, len);
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
194 int tlsv1_set_ca_cert(struct tlsv1_credentials *cred, const char *cert,
195 const u8 *cert_blob, size_t cert_blob_len,
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'",
207 if (os_strlen(pos) != 32 * 2) {
208 wpa_printf(MSG_DEBUG,
209 "TLSv1: Unexpected SHA256 hash length in ca_cert '%s'",
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'",
219 cred->server_cert_only = 1;
220 cred->ca_cert_verify = 0;
221 wpa_printf(MSG_DEBUG,
222 "TLSv1: Checking only server certificate match");
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");
233 cred->ca_cert_verify = cert || cert_blob || path;
235 if (tlsv1_set_cert_chain(&cred->trusted_certs, cert,
236 cert_blob, cert_blob_len) < 0)
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");
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
258 int tlsv1_set_cert(struct tlsv1_credentials *cred, const char *cert,
259 const u8 *cert_blob, size_t cert_blob_len)
261 return tlsv1_set_cert_chain(&cred->cert, cert,
262 cert_blob, cert_blob_len);
266 static struct crypto_private_key * tlsv1_set_key_pem(const u8 *key, size_t len)
271 struct crypto_private_key *pkey;
273 pos = search_tag(pem_key_begin, key, len);
275 pos = search_tag(pem_key2_begin, key, len);
278 pos += os_strlen(pem_key2_begin);
279 end = search_tag(pem_key2_end, pos, key + len - pos);
284 pos += os_strlen(pem_key_begin);
285 end = search_tag(pem_key_end, pos, key + len - pos);
288 pos2 = search_tag("Proc-Type: 4,ENCRYPTED", pos, end - pos);
290 wpa_printf(MSG_DEBUG, "TLSv1: Unsupported private key "
291 "format (Proc-Type/DEK-Info)");
296 der = base64_decode(pos, end - pos, &der_len);
299 pkey = crypto_private_key_import(der, der_len, NULL);
305 static struct crypto_private_key * tlsv1_set_key_enc_pem(const u8 *key,
312 struct crypto_private_key *pkey;
316 pos = search_tag(pem_key_enc_begin, key, len);
319 pos += os_strlen(pem_key_enc_begin);
320 end = search_tag(pem_key_enc_end, pos, key + len - pos);
324 der = base64_decode(pos, end - pos, &der_len);
327 pkey = crypto_private_key_import(der, der_len, passwd);
335 static int oid_is_rsadsi(struct asn1_oid *oid)
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 */;
345 static int pkcs12_is_bagtype_oid(struct asn1_oid *oid, unsigned long type)
347 return oid->len == 9 &&
348 oid_is_rsadsi(oid) &&
349 oid->oid[4] == 1 /* pkcs */ &&
350 oid->oid[5] == 12 /* pkcs-12 */ &&
352 oid->oid[7] == 1 /* bagtypes */ &&
357 static int is_oid_pkcs7(struct asn1_oid *oid)
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 */;
369 static int is_oid_pkcs7_data(struct asn1_oid *oid)
371 return is_oid_pkcs7(oid) && oid->oid[6] == 1 /* data */;
375 static int is_oid_pkcs7_enc_data(struct asn1_oid *oid)
377 return is_oid_pkcs7(oid) && oid->oid[6] == 6 /* encryptedData */;
381 static int is_oid_pkcs9(struct asn1_oid *oid)
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 */;
393 static int is_oid_pkcs9_friendly_name(struct asn1_oid *oid)
395 return oid->len == 7 && is_oid_pkcs9(oid) &&
400 static int is_oid_pkcs9_local_key_id(struct asn1_oid *oid)
402 return oid->len == 7 && is_oid_pkcs9(oid) &&
407 static int is_oid_pkcs9_x509_cert(struct asn1_oid *oid)
409 return oid->len == 8 && is_oid_pkcs9(oid) &&
410 oid->oid[6] == 22 /* certTypes */ &&
411 oid->oid[7] == 1 /* x509Certificate */;
415 static int pkcs12_keybag(struct tlsv1_credentials *cred,
416 const u8 *buf, size_t len)
423 static int pkcs12_pkcs8_keybag(struct tlsv1_credentials *cred,
424 const u8 *buf, size_t len,
427 struct crypto_private_key *key;
429 /* PKCS8ShroudedKeyBag ::= EncryptedPrivateKeyInfo */
430 key = pkcs8_enc_key_import(buf, len, passwd);
434 wpa_printf(MSG_DEBUG,
435 "PKCS #12: Successfully decrypted PKCS8ShroudedKeyBag");
436 crypto_private_key_free(cred->key);
443 static int pkcs12_certbag(struct tlsv1_credentials *cred,
444 const u8 *buf, size_t len)
452 * CertBag ::= SEQUENCE {
453 * certId BAG-TYPE.&id ({CertTypes}),
454 * certValue [0] EXPLICIT BAG-TYPE.&Type ({CertTypes}{@certId})
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",
468 end = hdr.payload + hdr.length;
470 if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
471 wpa_printf(MSG_DEBUG,
472 "PKCS #12: Failed to parse OID (certId)");
476 asn1_oid_to_str(&oid, obuf, sizeof(obuf));
477 wpa_printf(MSG_DEBUG, "PKCS #12: certId %s", obuf);
479 if (!is_oid_pkcs9_x509_cert(&oid)) {
480 wpa_printf(MSG_DEBUG,
481 "PKCS #12: Ignored unsupported certificate type (certId %s)",
485 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
486 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
488 wpa_printf(MSG_DEBUG,
489 "PKCS #12: Expected [0] EXPLICIT (certValue) - found class %d tag 0x%x",
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",
503 wpa_hexdump(MSG_DEBUG, "PKCS #12: x509Certificate",
504 hdr.payload, hdr.length);
506 struct x509_certificate *cert;
508 wpa_printf(MSG_DEBUG, "PKCS #12: Ignore extra certificate");
509 cert = x509_certificate_parse(hdr.payload, hdr.length);
511 wpa_printf(MSG_DEBUG,
512 "PKCS #12: Failed to parse x509Certificate");
515 x509_certificate_chain_free(cert);
519 return tlsv1_set_cert(cred, NULL, hdr.payload, hdr.length);
523 static int pkcs12_parse_attr_friendly_name(const u8 *pos, const u8 *end)
529 * friendlyName ATTRIBUTE ::= {
530 * WITH SYNTAX BMPString (SIZE(1..pkcs-9-ub-friendlyName))
531 * EQUALITY MATCHING RULE caseIgnoreMatch
533 * ID pkcs-9-at-friendlyName
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",
544 wpa_hexdump_ascii(MSG_DEBUG, "PKCS #12: friendlyName",
545 hdr.payload, hdr.length);
550 static int pkcs12_parse_attr_local_key_id(const u8 *pos, const u8 *end)
556 * localKeyId ATTRIBUTE ::= {
557 * WITH SYNTAX OCTET STRING
558 * EQUALITY MATCHING RULE octetStringMatch
560 * ID pkcs-9-at-localKeyId
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",
571 wpa_hexdump_key(MSG_DEBUG, "PKCS #12: localKeyID",
572 hdr.payload, hdr.length);
577 static int pkcs12_parse_attr(const u8 *pos, size_t len)
579 const u8 *end = pos + len;
581 struct asn1_oid a_oid;
585 * PKCS12Attribute ::= SEQUENCE {
586 * attrId ATTRIBUTE.&id ({PKCS12AttrSet}),
587 * attrValues SET OF ATTRIBUTE.&Type ({PKCS12AttrSet}{@attrId})
591 if (asn1_get_oid(pos, end - pos, &a_oid, &pos)) {
592 wpa_printf(MSG_DEBUG, "PKCS #12: Failed to parse OID (attrId)");
596 asn1_oid_to_str(&a_oid, obuf, sizeof(obuf));
597 wpa_printf(MSG_DEBUG, "PKCS #12: attrId %s", obuf);
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",
607 wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: attrValues",
608 hdr.payload, hdr.length);
610 end = hdr.payload + hdr.length;
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);
617 wpa_printf(MSG_DEBUG, "PKCS #12: Ignore unknown attribute");
622 static int pkcs12_safebag(struct tlsv1_credentials *cred,
623 const u8 *buf, size_t len, const char *passwd)
628 const u8 *pos = buf, *end = buf + len;
632 wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: SafeBag", buf, len);
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)");
641 asn1_oid_to_str(&oid, obuf, sizeof(obuf));
642 wpa_printf(MSG_DEBUG, "PKCS #12: BAG-TYPE %s", obuf);
644 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
645 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
647 wpa_printf(MSG_DEBUG,
648 "PKCS #12: Expected [0] EXPLICIT (bagValue) - found class %d tag 0x%x",
653 value_len = hdr.length;
654 wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: bagValue", value, value_len);
655 pos = hdr.payload + hdr.length;
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",
667 wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: bagAttributes",
668 hdr.payload, hdr.length);
671 end = hdr.payload + hdr.length;
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",
682 if (pkcs12_parse_attr(hdr.payload, hdr.length) < 0)
684 pos = hdr.payload + hdr.length;
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);
695 wpa_printf(MSG_DEBUG, "PKCS #12: Ignore unsupported BAG-TYPE");
700 static int pkcs12_safecontents(struct tlsv1_credentials *cred,
701 const u8 *buf, size_t len,
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",
717 end = hdr.payload + hdr.length;
720 * SafeBag ::= SEQUENCE {
721 * bagId BAG-TYPE.&id ({PKCS12BagSet})
722 * bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}),
723 * bagAttributes SET OF PKCS12Attribute OPTIONAL
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",
736 if (pkcs12_safebag(cred, hdr.payload, hdr.length, passwd) < 0)
738 pos = hdr.payload + hdr.length;
745 static int pkcs12_parse_content_data(struct tlsv1_credentials *cred,
746 const u8 *pos, const u8 *end,
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",
761 wpa_hexdump(MSG_MSGDUMP, "PKCS #12: Data", hdr.payload, hdr.length);
763 return pkcs12_safecontents(cred, hdr.payload, hdr.length, passwd);
767 static int pkcs12_parse_content_enc_data(struct tlsv1_credentials *cred,
768 const u8 *pos, const u8 *end,
776 size_t enc_alg_len, data_len;
780 * EncryptedData ::= SEQUENCE {
782 * encryptedContentInfo EncryptedContentInfo }
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",
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",
802 if (hdr.length != 1 || hdr.payload[0] != 0) {
803 wpa_printf(MSG_DEBUG, "PKCS #12: Unrecognized PKCS #7 version");
806 pos = hdr.payload + hdr.length;
808 wpa_hexdump(MSG_MSGDUMP, "PKCS #12: EncryptedContentInfo",
812 * EncryptedContentInfo ::= SEQUENCE {
813 * contentType ContentType,
814 * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
815 * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
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",
827 end = pos + hdr.length;
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)");
835 asn1_oid_to_str(&oid, buf, sizeof(buf));
836 wpa_printf(MSG_DEBUG, "PKCS #12: EncryptedContentInfo::contentType %s",
839 if (!is_oid_pkcs7_data(&oid)) {
840 wpa_printf(MSG_DEBUG,
841 "PKCS #12: Unsupported EncryptedContentInfo::contentType %s",
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",
854 enc_alg = hdr.payload;
855 enc_alg_len = hdr.length;
856 pos = hdr.payload + hdr.length;
858 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
859 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
861 wpa_printf(MSG_DEBUG,
862 "PKCS #12: Expected [0] IMPLICIT (encryptedContent) - found class %d tag 0x%x",
867 /* EncryptedContent ::= OCTET STRING */
868 data = pkcs5_decrypt(enc_alg, enc_alg_len, hdr.payload, hdr.length,
871 wpa_hexdump_key(MSG_MSGDUMP,
872 "PKCS #12: Decrypted encryptedContent",
874 res = pkcs12_safecontents(cred, data, data_len, passwd);
882 static int pkcs12_parse_content(struct tlsv1_credentials *cred,
883 const u8 *buf, size_t len,
887 const u8 *end = buf + len;
892 wpa_hexdump(MSG_MSGDUMP, "PKCS #12: ContentInfo", buf, len);
894 if (asn1_get_oid(pos, end - pos, &oid, &pos)) {
895 wpa_printf(MSG_DEBUG,
896 "PKCS #12: Could not find OBJECT IDENTIFIER (contentType)");
900 asn1_oid_to_str(&oid, txt, sizeof(txt));
901 wpa_printf(MSG_DEBUG, "PKCS #12: contentType %s", txt);
903 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
904 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
906 wpa_printf(MSG_DEBUG,
907 "PKCS #12: Expected [0] EXPLICIT (content) - found class %d tag 0x%x",
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);
918 wpa_printf(MSG_DEBUG, "PKCS #12: Ignored unsupported contentType %s",
925 static int pkcs12_parse(struct tlsv1_credentials *cred,
926 const u8 *key, size_t len, const char *passwd)
935 * version INTEGER {v3(3)}(v3,...),
936 * authSafe ContentInfo,
937 * macData MacData OPTIONAL
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",
951 end = pos + hdr.length;
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",
960 if (hdr.length != 1 || hdr.payload[0] != 3) {
961 wpa_printf(MSG_DEBUG, "PKCS #12: Unrecognized version");
964 pos = hdr.payload + hdr.length;
967 * ContentInfo ::= SEQUENCE {
968 * contentType ContentType,
969 * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
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",
982 end = pos + hdr.length;
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");
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",
998 if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
999 hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
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);
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);
1020 * AuthenticatedSafe ::= SEQUENCE OF ContentInfo
1021 * -- Data if unencrypted
1022 * -- EncryptedData if password-encrypted
1023 * -- EnvelopedData if public key-encrypted
1025 wpa_hexdump(MSG_MSGDUMP, "PKCS #12: Data content",
1026 hdr.payload, hdr.length);
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);
1038 end = pos + hdr.length;
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);
1049 if (pkcs12_parse_content(cred, hdr.payload, hdr.length,
1053 pos = hdr.payload + hdr.length;
1059 #endif /* PKCS12_FUNCS */
1062 static int tlsv1_set_key(struct tlsv1_credentials *cred,
1063 const u8 *key, size_t len, const char *passwd)
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);
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");
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
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)
1098 crypto_private_key_free(cred->key);
1101 if (private_key_blob)
1102 return tlsv1_set_key(cred, private_key_blob,
1103 private_key_blob_len,
1104 private_key_passwd);
1111 buf = (u8 *) os_readfile(private_key, &len);
1113 wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'",
1118 ret = tlsv1_set_key(cred, buf, len, private_key_passwd);
1127 static int tlsv1_set_dhparams_der(struct tlsv1_credentials *cred,
1128 const u8 *dh, size_t len)
1130 struct asn1_hdr hdr;
1131 const u8 *pos, *end;
1137 * DHParameter ::= SEQUENCE {
1138 * prime INTEGER, -- p
1139 * base INTEGER, -- g
1140 * privateValueLength INTEGER OPTIONAL }
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);
1155 if (asn1_get_next(pos, end - pos, &hdr) < 0)
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);
1165 wpa_hexdump(MSG_MSGDUMP, "DH: prime (p)", hdr.payload, hdr.length);
1166 if (hdr.length == 0)
1168 os_free(cred->dh_p);
1169 cred->dh_p = os_memdup(hdr.payload, hdr.length);
1170 if (cred->dh_p == NULL)
1172 cred->dh_p_len = hdr.length;
1173 pos = hdr.payload + hdr.length;
1176 if (asn1_get_next(pos, end - pos, &hdr) < 0)
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);
1186 wpa_hexdump(MSG_MSGDUMP, "DH: base (g)", hdr.payload, hdr.length);
1187 if (hdr.length == 0)
1189 os_free(cred->dh_g);
1190 cred->dh_g = os_memdup(hdr.payload, hdr.length);
1191 if (cred->dh_g == NULL)
1193 cred->dh_g_len = hdr.length;
1199 static const char *pem_dhparams_begin = "-----BEGIN DH PARAMETERS-----";
1200 static const char *pem_dhparams_end = "-----END DH PARAMETERS-----";
1203 static int tlsv1_set_dhparams_blob(struct tlsv1_credentials *cred,
1204 const u8 *buf, size_t len)
1206 const u8 *pos, *end;
1210 pos = search_tag(pem_dhparams_begin, buf, len);
1212 wpa_printf(MSG_DEBUG, "TLSv1: No PEM dhparams tag found - "
1213 "assume DER format");
1214 return tlsv1_set_dhparams_der(cred, buf, len);
1217 wpa_printf(MSG_DEBUG, "TLSv1: Converting PEM format dhparams into DER "
1220 pos += os_strlen(pem_dhparams_begin);
1221 end = search_tag(pem_dhparams_end, pos, buf + len - pos);
1223 wpa_printf(MSG_INFO, "TLSv1: Could not find PEM dhparams end "
1224 "tag (%s)", pem_dhparams_end);
1228 der = base64_decode(pos, end - pos, &der_len);
1230 wpa_printf(MSG_INFO, "TLSv1: Could not decode PEM dhparams");
1234 if (tlsv1_set_dhparams_der(cred, der, der_len) < 0) {
1235 wpa_printf(MSG_INFO, "TLSv1: Failed to parse PEM dhparams "
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
1255 int tlsv1_set_dhparams(struct tlsv1_credentials *cred, const char *dh_file,
1256 const u8 *dh_blob, size_t dh_blob_len)
1259 return tlsv1_set_dhparams_blob(cred, dh_blob, dh_blob_len);
1266 buf = (u8 *) os_readfile(dh_file, &len);
1268 wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'",
1273 ret = tlsv1_set_dhparams_blob(cred, buf, len);