summaryrefslogtreecommitdiffstats
path: root/patches
diff options
context:
space:
mode:
authorMichael Olbrich <m.olbrich@pengutronix.de>2018-11-16 18:37:04 +0100
committerMichael Olbrich <m.olbrich@pengutronix.de>2018-11-17 19:00:12 +0100
commit0ffcfcaa32b49a20ed36dd8fcb85d489fde0acc1 (patch)
treec763338f2b24814997dc74afce04fcca1815e936 /patches
parent19475258209dd537a9f123ab935c41fa7747c54f (diff)
downloadptxdist-0ffcfcaa32b49a20ed36dd8fcb85d489fde0acc1.tar.gz
ptxdist-0ffcfcaa32b49a20ed36dd8fcb85d489fde0acc1.tar.xz
hostapd/wpa_supplicant: add security and ssl fixes
Add CVE-2018-14526 fix and upstream patches that will be needed for OpenSSL 1.1.x. Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
Diffstat (limited to 'patches')
-rw-r--r--patches/hostapd-2.6/0008-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch44
-rw-r--r--patches/hostapd-2.6/0009-Fix-pem-decryption.patch257
-rw-r--r--patches/hostapd-2.6/series4
-rw-r--r--patches/wpa_supplicant-2.6/0009-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch44
-rw-r--r--patches/wpa_supplicant-2.6/0010-Fix-pem-decryption.patch257
-rw-r--r--patches/wpa_supplicant-2.6/series4
6 files changed, 608 insertions, 2 deletions
diff --git a/patches/hostapd-2.6/0008-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch b/patches/hostapd-2.6/0008-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch
new file mode 100644
index 000000000..eb08d5d6c
--- /dev/null
+++ b/patches/hostapd-2.6/0008-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch
@@ -0,0 +1,44 @@
+From: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
+Date: Sun, 15 Jul 2018 01:25:53 +0200
+Subject: [PATCH] WPA: Ignore unauthenticated encrypted EAPOL-Key data
+
+Ignore unauthenticated encrypted EAPOL-Key data in supplicant
+processing. When using WPA2, these are frames that have the Encrypted
+flag set, but not the MIC flag.
+
+When using WPA2, EAPOL-Key frames that had the Encrypted flag set but
+not the MIC flag, had their data field decrypted without first verifying
+the MIC. In case the data field was encrypted using RC4 (i.e., when
+negotiating TKIP as the pairwise cipher), this meant that
+unauthenticated but decrypted data would then be processed. An adversary
+could abuse this as a decryption oracle to recover sensitive information
+in the data field of EAPOL-Key messages (e.g., the group key).
+(CVE-2018-14526)
+
+Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
+---
+ src/rsn_supp/wpa.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
+index 2a53c6f4a55f..dcd75272151f 100644
+--- a/src/rsn_supp/wpa.c
++++ b/src/rsn_supp/wpa.c
+@@ -2072,6 +2072,17 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
+
+ if ((sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) &&
+ (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
++ /*
++ * Only decrypt the Key Data field if the frame's authenticity
++ * was verified. When using AES-SIV (FILS), the MIC flag is not
++ * set, so this check should only be performed if mic_len != 0
++ * which is the case in this code branch.
++ */
++ if (!(key_info & WPA_KEY_INFO_MIC)) {
++ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
++ "WPA: Ignore EAPOL-Key with encrypted but unauthenticated data");
++ goto out;
++ }
+ if (wpa_supplicant_decrypt_key_data(sm, key, ver, key_data,
+ &key_data_len))
+ goto out;
diff --git a/patches/hostapd-2.6/0009-Fix-pem-decryption.patch b/patches/hostapd-2.6/0009-Fix-pem-decryption.patch
new file mode 100644
index 000000000..54186cdc7
--- /dev/null
+++ b/patches/hostapd-2.6/0009-Fix-pem-decryption.patch
@@ -0,0 +1,257 @@
+From: Michael Olbrich <m.olbrich@pengutronix.de>
+Date: Fri, 16 Nov 2018 18:31:17 +0100
+Subject: [PATCH] Fix pem decryption
+
+Combinded upstream patches for OpenSSL 1.1.x. Taken from Debian.
+
+From 63942cf0f309e067bc5bfef95194bd17e48bf5ef Mon Sep 17 00:00:00 2001
+From: David Benjamin <davidben@google.com>
+Date: Mon, 18 Sep 2017 11:47:47 -0400
+Subject: OpenSSL: Avoid SSL*_use_default_passwd_cb()
+
+These functions are a bit awkward to use for one-off file loads, as
+suggested by the tls_clear_default_passwd_cb() logic. There was also
+some historical mess with OpenSSL versions and either not having per-SSL
+settings, having per-SSL settings but ignoring them, and requiring the
+per-SSL settings.
+
+Instead, loading the key with the lower-level functions seems a bit
+tidier and also allows abstracting away trying both formats, one after
+another.
+
+Signed-off-by: David Benjamin <davidben@google.com>
+--
+From 149143e31dcb4e713c27eba63b07d09cdd8ae3cb Mon Sep 17 00:00:00 2001
+From: David Benjamin <davidben@google.com>
+Date: Mon, 18 Sep 2017 00:33:43 -0400
+Subject: OpenSSL: Remove unnecessary os_strdup() from password callback
+
+There's no need to make an extra copy of private_key_passwd for
+SSL_{CTX_,}set_default_passwd_cb().
+
+Signed-off-by: David Benjamin <davidben@google.com>
+--
+From 89971d8b1e328a2f79699c953625d1671fd40384 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Mon, 17 Jul 2017 12:06:17 +0300
+Subject: OpenSSL: Clear default_passwd_cb more thoroughly
+
+Previously, the pointer to strdup passwd was left in OpenSSL library
+default_passwd_cb_userdata and even the default_passwd_cb was left set
+on an error path. To avoid unexpected behavior if something were to
+manage to use there pointers, clear them explicitly once done with
+loading of the private key.
+
+Signed-off-by: Jouni Malinen <j@w1.fi>
+---
+ src/crypto/tls_openssl.c | 133 ++++++++++++++++++++++++-----------------------
+ 1 file changed, 67 insertions(+), 66 deletions(-)
+
+diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
+index 23ac64b48cd9..2cd377a432e1 100644
+--- a/src/crypto/tls_openssl.c
++++ b/src/crypto/tls_openssl.c
+@@ -2430,16 +2430,6 @@ static int tls_global_client_cert(struct tls_data *data,
+ }
+
+
+-static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
+-{
+- if (password == NULL) {
+- return 0;
+- }
+- os_strlcpy(buf, (char *) password, size);
+- return os_strlen(buf);
+-}
+-
+-
+ #ifdef PKCS12_FUNCS
+ static int tls_parse_pkcs12(struct tls_data *data, SSL *ssl, PKCS12 *p12,
+ const char *passwd)
+@@ -2758,6 +2748,64 @@ static int tls_connection_engine_private_key(struct tls_connection *conn)
+ }
+
+
++#ifndef OPENSSL_NO_STDIO
++static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
++{
++ if (!password)
++ return 0;
++ os_strlcpy(buf, (const char *) password, size);
++ return os_strlen(buf);
++}
++#endif /* OPENSSL_NO_STDIO */
++
++
++static int tls_use_private_key_file(struct tls_data *data, SSL *ssl,
++ const char *private_key,
++ const char *private_key_passwd)
++{
++#ifndef OPENSSL_NO_STDIO
++ BIO *bio;
++ EVP_PKEY *pkey;
++ int ret;
++
++ /* First try ASN.1 (DER). */
++ bio = BIO_new_file(private_key, "r");
++ if (!bio)
++ return -1;
++ pkey = d2i_PrivateKey_bio(bio, NULL);
++ BIO_free(bio);
++
++ if (pkey) {
++ wpa_printf(MSG_DEBUG, "OpenSSL: %s (DER) --> loaded", __func__);
++ } else {
++ /* Try PEM with the provided password. */
++ bio = BIO_new_file(private_key, "r");
++ if (!bio)
++ return -1;
++ pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_passwd_cb,
++ (void *) private_key_passwd);
++ BIO_free(bio);
++ if (!pkey)
++ return -1;
++ wpa_printf(MSG_DEBUG, "OpenSSL: %s (PEM) --> loaded", __func__);
++ /* Clear errors from the previous failed load. */
++ ERR_clear_error();
++ }
++
++ if (ssl)
++ ret = SSL_use_PrivateKey(ssl, pkey);
++ else
++ ret = SSL_CTX_use_PrivateKey(data->ssl, pkey);
++
++ EVP_PKEY_free(pkey);
++ return ret == 1 ? 0 : -1;
++#else /* OPENSSL_NO_STDIO */
++ wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
++ return -1;
++#endif /* OPENSSL_NO_STDIO */
++}
++
++
+ static int tls_connection_private_key(struct tls_data *data,
+ struct tls_connection *conn,
+ const char *private_key,
+@@ -2765,23 +2813,11 @@ static int tls_connection_private_key(struct tls_data *data,
+ const u8 *private_key_blob,
+ size_t private_key_blob_len)
+ {
+- SSL_CTX *ssl_ctx = data->ssl;
+- char *passwd;
+ int ok;
+
+ if (private_key == NULL && private_key_blob == NULL)
+ return 0;
+
+- if (private_key_passwd) {
+- passwd = os_strdup(private_key_passwd);
+- if (passwd == NULL)
+- return -1;
+- } else
+- passwd = NULL;
+-
+- SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
+- SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
+-
+ ok = 0;
+ while (private_key_blob) {
+ if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, conn->ssl,
+@@ -2812,7 +2848,8 @@ static int tls_connection_private_key(struct tls_data *data,
+ }
+
+ if (tls_read_pkcs12_blob(data, conn->ssl, private_key_blob,
+- private_key_blob_len, passwd) == 0) {
++ private_key_blob_len,
++ private_key_passwd) == 0) {
+ wpa_printf(MSG_DEBUG, "OpenSSL: PKCS#12 as blob --> "
+ "OK");
+ ok = 1;
+@@ -2823,29 +2860,14 @@ static int tls_connection_private_key(struct tls_data *data,
+ }
+
+ while (!ok && private_key) {
+-#ifndef OPENSSL_NO_STDIO
+- if (SSL_use_PrivateKey_file(conn->ssl, private_key,
+- SSL_FILETYPE_ASN1) == 1) {
+- wpa_printf(MSG_DEBUG, "OpenSSL: "
+- "SSL_use_PrivateKey_File (DER) --> OK");
+- ok = 1;
+- break;
+- }
+-
+- if (SSL_use_PrivateKey_file(conn->ssl, private_key,
+- SSL_FILETYPE_PEM) == 1) {
+- wpa_printf(MSG_DEBUG, "OpenSSL: "
+- "SSL_use_PrivateKey_File (PEM) --> OK");
++ if (tls_use_private_key_file(data, conn->ssl, private_key,
++ private_key_passwd) == 0) {
+ ok = 1;
+ break;
+ }
+-#else /* OPENSSL_NO_STDIO */
+- wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO",
+- __func__);
+-#endif /* OPENSSL_NO_STDIO */
+
+- if (tls_read_pkcs12(data, conn->ssl, private_key, passwd)
+- == 0) {
++ if (tls_read_pkcs12(data, conn->ssl, private_key,
++ private_key_passwd) == 0) {
+ wpa_printf(MSG_DEBUG, "OpenSSL: Reading PKCS#12 file "
+ "--> OK");
+ ok = 1;
+@@ -2865,12 +2887,9 @@ static int tls_connection_private_key(struct tls_data *data,
+ if (!ok) {
+ tls_show_errors(MSG_INFO, __func__,
+ "Failed to load private key");
+- os_free(passwd);
+ return -1;
+ }
+ ERR_clear_error();
+- SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
+- os_free(passwd);
+
+ if (!SSL_check_private_key(conn->ssl)) {
+ tls_show_errors(MSG_INFO, __func__, "Private key failed "
+@@ -2888,37 +2907,19 @@ static int tls_global_private_key(struct tls_data *data,
+ const char *private_key_passwd)
+ {
+ SSL_CTX *ssl_ctx = data->ssl;
+- char *passwd;
+
+ if (private_key == NULL)
+ return 0;
+
+- if (private_key_passwd) {
+- passwd = os_strdup(private_key_passwd);
+- if (passwd == NULL)
+- return -1;
+- } else
+- passwd = NULL;
+-
+- SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
+- SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
+- if (
+-#ifndef OPENSSL_NO_STDIO
+- SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
+- SSL_FILETYPE_ASN1) != 1 &&
+- SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
+- SSL_FILETYPE_PEM) != 1 &&
+-#endif /* OPENSSL_NO_STDIO */
+- tls_read_pkcs12(data, NULL, private_key, passwd)) {
++ if (tls_use_private_key_file(data, NULL, private_key,
++ private_key_passwd) &&
++ tls_read_pkcs12(data, NULL, private_key, private_key_passwd)) {
+ tls_show_errors(MSG_INFO, __func__,
+ "Failed to load private key");
+- os_free(passwd);
+ ERR_clear_error();
+ return -1;
+ }
+- os_free(passwd);
+ ERR_clear_error();
+- SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
+
+ if (!SSL_CTX_check_private_key(ssl_ctx)) {
+ tls_show_errors(MSG_INFO, __func__,
diff --git a/patches/hostapd-2.6/series b/patches/hostapd-2.6/series
index f06dbd3fb..063f300e5 100644
--- a/patches/hostapd-2.6/series
+++ b/patches/hostapd-2.6/series
@@ -7,4 +7,6 @@
0005-Fix-PTK-rekeying-to-generate-a-new-ANonce.patch
0006-TDLS-Reject-TPK-TK-reconfiguration.patch
0007-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch
-# 4cd51a35a950def3c205b609b9c255c5 - git-ptx-patches magic
+0008-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch
+0009-Fix-pem-decryption.patch
+# 9d5b8f3b90aeb56b9612b2ed9201fe22 - git-ptx-patches magic
diff --git a/patches/wpa_supplicant-2.6/0009-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch b/patches/wpa_supplicant-2.6/0009-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch
new file mode 100644
index 000000000..eb08d5d6c
--- /dev/null
+++ b/patches/wpa_supplicant-2.6/0009-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch
@@ -0,0 +1,44 @@
+From: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
+Date: Sun, 15 Jul 2018 01:25:53 +0200
+Subject: [PATCH] WPA: Ignore unauthenticated encrypted EAPOL-Key data
+
+Ignore unauthenticated encrypted EAPOL-Key data in supplicant
+processing. When using WPA2, these are frames that have the Encrypted
+flag set, but not the MIC flag.
+
+When using WPA2, EAPOL-Key frames that had the Encrypted flag set but
+not the MIC flag, had their data field decrypted without first verifying
+the MIC. In case the data field was encrypted using RC4 (i.e., when
+negotiating TKIP as the pairwise cipher), this meant that
+unauthenticated but decrypted data would then be processed. An adversary
+could abuse this as a decryption oracle to recover sensitive information
+in the data field of EAPOL-Key messages (e.g., the group key).
+(CVE-2018-14526)
+
+Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
+---
+ src/rsn_supp/wpa.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
+index 2a53c6f4a55f..dcd75272151f 100644
+--- a/src/rsn_supp/wpa.c
++++ b/src/rsn_supp/wpa.c
+@@ -2072,6 +2072,17 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
+
+ if ((sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) &&
+ (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
++ /*
++ * Only decrypt the Key Data field if the frame's authenticity
++ * was verified. When using AES-SIV (FILS), the MIC flag is not
++ * set, so this check should only be performed if mic_len != 0
++ * which is the case in this code branch.
++ */
++ if (!(key_info & WPA_KEY_INFO_MIC)) {
++ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
++ "WPA: Ignore EAPOL-Key with encrypted but unauthenticated data");
++ goto out;
++ }
+ if (wpa_supplicant_decrypt_key_data(sm, key, ver, key_data,
+ &key_data_len))
+ goto out;
diff --git a/patches/wpa_supplicant-2.6/0010-Fix-pem-decryption.patch b/patches/wpa_supplicant-2.6/0010-Fix-pem-decryption.patch
new file mode 100644
index 000000000..54186cdc7
--- /dev/null
+++ b/patches/wpa_supplicant-2.6/0010-Fix-pem-decryption.patch
@@ -0,0 +1,257 @@
+From: Michael Olbrich <m.olbrich@pengutronix.de>
+Date: Fri, 16 Nov 2018 18:31:17 +0100
+Subject: [PATCH] Fix pem decryption
+
+Combinded upstream patches for OpenSSL 1.1.x. Taken from Debian.
+
+From 63942cf0f309e067bc5bfef95194bd17e48bf5ef Mon Sep 17 00:00:00 2001
+From: David Benjamin <davidben@google.com>
+Date: Mon, 18 Sep 2017 11:47:47 -0400
+Subject: OpenSSL: Avoid SSL*_use_default_passwd_cb()
+
+These functions are a bit awkward to use for one-off file loads, as
+suggested by the tls_clear_default_passwd_cb() logic. There was also
+some historical mess with OpenSSL versions and either not having per-SSL
+settings, having per-SSL settings but ignoring them, and requiring the
+per-SSL settings.
+
+Instead, loading the key with the lower-level functions seems a bit
+tidier and also allows abstracting away trying both formats, one after
+another.
+
+Signed-off-by: David Benjamin <davidben@google.com>
+--
+From 149143e31dcb4e713c27eba63b07d09cdd8ae3cb Mon Sep 17 00:00:00 2001
+From: David Benjamin <davidben@google.com>
+Date: Mon, 18 Sep 2017 00:33:43 -0400
+Subject: OpenSSL: Remove unnecessary os_strdup() from password callback
+
+There's no need to make an extra copy of private_key_passwd for
+SSL_{CTX_,}set_default_passwd_cb().
+
+Signed-off-by: David Benjamin <davidben@google.com>
+--
+From 89971d8b1e328a2f79699c953625d1671fd40384 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Mon, 17 Jul 2017 12:06:17 +0300
+Subject: OpenSSL: Clear default_passwd_cb more thoroughly
+
+Previously, the pointer to strdup passwd was left in OpenSSL library
+default_passwd_cb_userdata and even the default_passwd_cb was left set
+on an error path. To avoid unexpected behavior if something were to
+manage to use there pointers, clear them explicitly once done with
+loading of the private key.
+
+Signed-off-by: Jouni Malinen <j@w1.fi>
+---
+ src/crypto/tls_openssl.c | 133 ++++++++++++++++++++++++-----------------------
+ 1 file changed, 67 insertions(+), 66 deletions(-)
+
+diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
+index 23ac64b48cd9..2cd377a432e1 100644
+--- a/src/crypto/tls_openssl.c
++++ b/src/crypto/tls_openssl.c
+@@ -2430,16 +2430,6 @@ static int tls_global_client_cert(struct tls_data *data,
+ }
+
+
+-static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
+-{
+- if (password == NULL) {
+- return 0;
+- }
+- os_strlcpy(buf, (char *) password, size);
+- return os_strlen(buf);
+-}
+-
+-
+ #ifdef PKCS12_FUNCS
+ static int tls_parse_pkcs12(struct tls_data *data, SSL *ssl, PKCS12 *p12,
+ const char *passwd)
+@@ -2758,6 +2748,64 @@ static int tls_connection_engine_private_key(struct tls_connection *conn)
+ }
+
+
++#ifndef OPENSSL_NO_STDIO
++static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
++{
++ if (!password)
++ return 0;
++ os_strlcpy(buf, (const char *) password, size);
++ return os_strlen(buf);
++}
++#endif /* OPENSSL_NO_STDIO */
++
++
++static int tls_use_private_key_file(struct tls_data *data, SSL *ssl,
++ const char *private_key,
++ const char *private_key_passwd)
++{
++#ifndef OPENSSL_NO_STDIO
++ BIO *bio;
++ EVP_PKEY *pkey;
++ int ret;
++
++ /* First try ASN.1 (DER). */
++ bio = BIO_new_file(private_key, "r");
++ if (!bio)
++ return -1;
++ pkey = d2i_PrivateKey_bio(bio, NULL);
++ BIO_free(bio);
++
++ if (pkey) {
++ wpa_printf(MSG_DEBUG, "OpenSSL: %s (DER) --> loaded", __func__);
++ } else {
++ /* Try PEM with the provided password. */
++ bio = BIO_new_file(private_key, "r");
++ if (!bio)
++ return -1;
++ pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_passwd_cb,
++ (void *) private_key_passwd);
++ BIO_free(bio);
++ if (!pkey)
++ return -1;
++ wpa_printf(MSG_DEBUG, "OpenSSL: %s (PEM) --> loaded", __func__);
++ /* Clear errors from the previous failed load. */
++ ERR_clear_error();
++ }
++
++ if (ssl)
++ ret = SSL_use_PrivateKey(ssl, pkey);
++ else
++ ret = SSL_CTX_use_PrivateKey(data->ssl, pkey);
++
++ EVP_PKEY_free(pkey);
++ return ret == 1 ? 0 : -1;
++#else /* OPENSSL_NO_STDIO */
++ wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);
++ return -1;
++#endif /* OPENSSL_NO_STDIO */
++}
++
++
+ static int tls_connection_private_key(struct tls_data *data,
+ struct tls_connection *conn,
+ const char *private_key,
+@@ -2765,23 +2813,11 @@ static int tls_connection_private_key(struct tls_data *data,
+ const u8 *private_key_blob,
+ size_t private_key_blob_len)
+ {
+- SSL_CTX *ssl_ctx = data->ssl;
+- char *passwd;
+ int ok;
+
+ if (private_key == NULL && private_key_blob == NULL)
+ return 0;
+
+- if (private_key_passwd) {
+- passwd = os_strdup(private_key_passwd);
+- if (passwd == NULL)
+- return -1;
+- } else
+- passwd = NULL;
+-
+- SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
+- SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
+-
+ ok = 0;
+ while (private_key_blob) {
+ if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, conn->ssl,
+@@ -2812,7 +2848,8 @@ static int tls_connection_private_key(struct tls_data *data,
+ }
+
+ if (tls_read_pkcs12_blob(data, conn->ssl, private_key_blob,
+- private_key_blob_len, passwd) == 0) {
++ private_key_blob_len,
++ private_key_passwd) == 0) {
+ wpa_printf(MSG_DEBUG, "OpenSSL: PKCS#12 as blob --> "
+ "OK");
+ ok = 1;
+@@ -2823,29 +2860,14 @@ static int tls_connection_private_key(struct tls_data *data,
+ }
+
+ while (!ok && private_key) {
+-#ifndef OPENSSL_NO_STDIO
+- if (SSL_use_PrivateKey_file(conn->ssl, private_key,
+- SSL_FILETYPE_ASN1) == 1) {
+- wpa_printf(MSG_DEBUG, "OpenSSL: "
+- "SSL_use_PrivateKey_File (DER) --> OK");
+- ok = 1;
+- break;
+- }
+-
+- if (SSL_use_PrivateKey_file(conn->ssl, private_key,
+- SSL_FILETYPE_PEM) == 1) {
+- wpa_printf(MSG_DEBUG, "OpenSSL: "
+- "SSL_use_PrivateKey_File (PEM) --> OK");
++ if (tls_use_private_key_file(data, conn->ssl, private_key,
++ private_key_passwd) == 0) {
+ ok = 1;
+ break;
+ }
+-#else /* OPENSSL_NO_STDIO */
+- wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO",
+- __func__);
+-#endif /* OPENSSL_NO_STDIO */
+
+- if (tls_read_pkcs12(data, conn->ssl, private_key, passwd)
+- == 0) {
++ if (tls_read_pkcs12(data, conn->ssl, private_key,
++ private_key_passwd) == 0) {
+ wpa_printf(MSG_DEBUG, "OpenSSL: Reading PKCS#12 file "
+ "--> OK");
+ ok = 1;
+@@ -2865,12 +2887,9 @@ static int tls_connection_private_key(struct tls_data *data,
+ if (!ok) {
+ tls_show_errors(MSG_INFO, __func__,
+ "Failed to load private key");
+- os_free(passwd);
+ return -1;
+ }
+ ERR_clear_error();
+- SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
+- os_free(passwd);
+
+ if (!SSL_check_private_key(conn->ssl)) {
+ tls_show_errors(MSG_INFO, __func__, "Private key failed "
+@@ -2888,37 +2907,19 @@ static int tls_global_private_key(struct tls_data *data,
+ const char *private_key_passwd)
+ {
+ SSL_CTX *ssl_ctx = data->ssl;
+- char *passwd;
+
+ if (private_key == NULL)
+ return 0;
+
+- if (private_key_passwd) {
+- passwd = os_strdup(private_key_passwd);
+- if (passwd == NULL)
+- return -1;
+- } else
+- passwd = NULL;
+-
+- SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb);
+- SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd);
+- if (
+-#ifndef OPENSSL_NO_STDIO
+- SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
+- SSL_FILETYPE_ASN1) != 1 &&
+- SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key,
+- SSL_FILETYPE_PEM) != 1 &&
+-#endif /* OPENSSL_NO_STDIO */
+- tls_read_pkcs12(data, NULL, private_key, passwd)) {
++ if (tls_use_private_key_file(data, NULL, private_key,
++ private_key_passwd) &&
++ tls_read_pkcs12(data, NULL, private_key, private_key_passwd)) {
+ tls_show_errors(MSG_INFO, __func__,
+ "Failed to load private key");
+- os_free(passwd);
+ ERR_clear_error();
+ return -1;
+ }
+- os_free(passwd);
+ ERR_clear_error();
+- SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL);
+
+ if (!SSL_CTX_check_private_key(ssl_ctx)) {
+ tls_show_errors(MSG_INFO, __func__,
diff --git a/patches/wpa_supplicant-2.6/series b/patches/wpa_supplicant-2.6/series
index 3c956cfa2..5cdd51036 100644
--- a/patches/wpa_supplicant-2.6/series
+++ b/patches/wpa_supplicant-2.6/series
@@ -8,4 +8,6 @@
0006-TDLS-Reject-TPK-TK-reconfiguration.patch
0007-WNM-Ignore-WNM-Sleep-Mode-Response-without-pending-r.patch
0008-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch
-# bb28bfc4d47846ceb41bca8b4bc07edd - git-ptx-patches magic
+0009-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch
+0010-Fix-pem-decryption.patch
+# e29c4cb2c2ffbc71ae328176596ddb22 - git-ptx-patches magic