Blame SOURCES/0001-EAP-TTLS-PEAP-peer-Fix-failure-when-using-session-ti.patch

919688
From 872609c15110d32ee2d306aeeeffdd4e42ef6fc6 Mon Sep 17 00:00:00 2001
919688
Message-Id: <872609c15110d32ee2d306aeeeffdd4e42ef6fc6.1627507211.git.davide.caratti@gmail.com>
919688
From: Alexander Clouter <alex@digriz.org.uk>
919688
Date: Fri, 16 Oct 2020 09:49:36 +0100
919688
Subject: [PATCH] EAP-TTLS/PEAP peer: Fix failure when using session tickets
919688
 under TLS 1.3
919688
919688
EAP peer does not expect data present when beginning the Phase 2 in
919688
EAP-{TTLS,PEAP} but in TLS 1.3 session tickets are sent after the
919688
handshake completes.
919688
919688
There are several strategies that can be used to handle this, but this
919688
patch picks up from the discussion[1] and implements the proposed use of
919688
SSL_MODE_AUTO_RETRY. SSL_MODE_AUTO_RETRY has already been enabled by
919688
default in OpenSSL 1.1.1, but it needs to be enabled for older versions.
919688
919688
The main OpenSSL wrapper change in tls_connection_decrypt() takes care
919688
of the new possible case with SSL_MODE_AUTO_RETRY for
919688
SSL_ERROR_WANT_READ to indicate that a non-application_data was
919688
processed. That is not really an error case with TLS 1.3, so allow it to
919688
complete and return an empty decrypted application data buffer.
919688
EAP-PEAP/TTLS processing can then use this to move ahead with starting
919688
Phase 2.
919688
919688
[1] https://www.spinics.net/lists/hostap/msg05376.html
919688
919688
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
919688
---
919688
 src/crypto/tls_openssl.c | 18 ++++++++++++++----
919688
 src/eap_peer/eap_peap.c  |  4 ++++
919688
 src/eap_peer/eap_ttls.c  |  5 +++++
919688
 3 files changed, 23 insertions(+), 4 deletions(-)
919688
919688
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
919688
index ef872c50e..345a35ee1 100644
919688
--- a/src/crypto/tls_openssl.c
919688
+++ b/src/crypto/tls_openssl.c
919688
@@ -1045,6 +1045,8 @@ void * tls_init(const struct tls_config *conf)
919688
 	SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv2);
919688
 	SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv3);
919688
 
919688
+	SSL_CTX_set_mode(ssl, SSL_MODE_AUTO_RETRY);
919688
+
919688
 #ifdef SSL_MODE_NO_AUTO_CHAIN
919688
 	/* Number of deployed use cases assume the default OpenSSL behavior of
919688
 	 * auto chaining the local certificate is in use. BoringSSL removed this
919688
@@ -4543,10 +4545,18 @@ struct wpabuf * tls_connection_decrypt(void *tls_ctx,
919688
 		return NULL;
919688
 	res = SSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf));
919688
 	if (res < 0) {
919688
-		tls_show_errors(MSG_INFO, __func__,
919688
-				"Decryption failed - SSL_read");
919688
-		wpabuf_free(buf);
919688
-		return NULL;
919688
+		int err = SSL_get_error(conn->ssl, res);
919688
+
919688
+		if (err == SSL_ERROR_WANT_READ) {
919688
+			wpa_printf(MSG_DEBUG,
919688
+				   "SSL: SSL_connect - want more data");
919688
+			res = 0;
919688
+		} else {
919688
+			tls_show_errors(MSG_INFO, __func__,
919688
+					"Decryption failed - SSL_read");
919688
+			wpabuf_free(buf);
919688
+			return NULL;
919688
+		}
919688
 	}
919688
 	wpabuf_put(buf, res);
919688
 
919688
diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
919688
index 7c3704369..a13428d37 100644
919688
--- a/src/eap_peer/eap_peap.c
919688
+++ b/src/eap_peer/eap_peap.c
919688
@@ -803,6 +803,10 @@ static int eap_peap_decrypt(struct eap_sm *sm, struct eap_peap_data *data,
919688
 	res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
919688
 	if (res)
919688
 		return res;
919688
+	if (wpabuf_len(in_decrypted) == 0) {
919688
+		wpabuf_free(in_decrypted);
919688
+		return 1;
919688
+	}
919688
 
919688
 continue_req:
919688
 	wpa_hexdump_buf(MSG_DEBUG, "EAP-PEAP: Decrypted Phase 2 EAP",
919688
diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c
919688
index 642d179c6..3bf1e97e6 100644
919688
--- a/src/eap_peer/eap_ttls.c
919688
+++ b/src/eap_peer/eap_ttls.c
919688
@@ -1441,6 +1441,7 @@ static int eap_ttls_decrypt(struct eap_sm *sm, struct eap_ttls_data *data,
919688
 
919688
 	if ((in_data == NULL || wpabuf_len(in_data) == 0) &&
919688
 	    data->phase2_start) {
919688
+start:
919688
 		return eap_ttls_phase2_start(sm, data, ret, identifier,
919688
 					     out_data);
919688
 	}
919688
@@ -1455,6 +1456,10 @@ static int eap_ttls_decrypt(struct eap_sm *sm, struct eap_ttls_data *data,
919688
 	retval = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
919688
 	if (retval)
919688
 		goto done;
919688
+	if (wpabuf_len(in_decrypted) == 0) {
919688
+		wpabuf_free(in_decrypted);
919688
+		goto start;
919688
+	}
919688
 
919688
 continue_req:
919688
 	data->phase2_start = 0;
919688
-- 
919688
2.31.1
919688