From 4ce5fb470839608c73f5cf877e615498e716a949 Mon Sep 17 00:00:00 2001 From: dillon_chen Date: Thu, 25 Apr 2024 17:37:36 +0800 Subject: [PATCH] fix CVE-2023-52160 (cherry picked from commit 8c399bada8780bd8babac18c7f83e19a6198a8ec) --- CVE-2023-52160.patch | 219 +++++++++++++++++++++++++++++++++++++++++++ wpa_supplicant.spec | 9 +- 2 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 CVE-2023-52160.patch diff --git a/CVE-2023-52160.patch b/CVE-2023-52160.patch new file mode 100644 index 0000000..892394a --- /dev/null +++ b/CVE-2023-52160.patch @@ -0,0 +1,219 @@ +From: Jouni Malinen +Date: Sat, 8 Jul 2023 19:55:32 +0300 +Subject: PEAP client: Update Phase 2 authentication requirements + +The previous PEAP client behavior allowed the server to skip Phase 2 +authentication with the expectation that the server was authenticated +during Phase 1 through TLS server certificate validation. Various PEAP +specifications are not exactly clear on what the behavior on this front +is supposed to be and as such, this ended up being more flexible than +the TTLS/FAST/TEAP cases. However, this is not really ideal when +unfortunately common misconfiguration of PEAP is used in deployed +devices where the server trust root (ca_cert) is not configured or the +user has an easy option for allowing this validation step to be skipped. + +Change the default PEAP client behavior to be to require Phase 2 +authentication to be successfully completed for cases where TLS session +resumption is not used and the client certificate has not been +configured. Those two exceptions are the main cases where a deployed +authentication server might skip Phase 2 and as such, where a more +strict default behavior could result in undesired interoperability +issues. Requiring Phase 2 authentication will end up disabling TLS +session resumption automatically to avoid interoperability issues. + +Allow Phase 2 authentication behavior to be configured with a new phase1 +configuration parameter option: +'phase2_auth' option can be used to control Phase 2 (i.e., within TLS +tunnel) behavior for PEAP: + * 0 = do not require Phase 2 authentication + * 1 = require Phase 2 authentication when client certificate + (private_key/client_cert) is no used and TLS session resumption was + not used (default) + * 2 = require Phase 2 authentication in all cases + +Signed-off-by: Jouni Malinen +--- + src/eap_peer/eap_config.h | 8 ++++++++ + src/eap_peer/eap_peap.c | 40 +++++++++++++++++++++++++++++++++++--- + src/eap_peer/eap_tls_common.c | 6 ++++++ + src/eap_peer/eap_tls_common.h | 5 +++++ + src/utils/includes.h | 1 + + wpa_supplicant/wpa_supplicant.conf | 7 +++++++ + 6 files changed, 64 insertions(+), 3 deletions(-) + +diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h +index d416afd..f803488 100644 +--- a/src/eap_peer/eap_config.h ++++ b/src/eap_peer/eap_config.h +@@ -419,6 +419,14 @@ struct eap_peer_config { + * 1 = use cryptobinding if server supports it + * 2 = require cryptobinding + * ++ * phase2_auth option can be used to control Phase 2 (i.e., within TLS ++ * tunnel) behavior for PEAP: ++ * 0 = do not require Phase 2 authentication ++ * 1 = require Phase 2 authentication when client certificate ++ * (private_key/client_cert) is no used and TLS session resumption was ++ * not used (default) ++ * 2 = require Phase 2 authentication in all cases ++ * + * EAP-WSC (WPS) uses following options: pin=Device_Password and + * uuid=Device_UUID + * +diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c +index 34075b1..79a36b0 100644 +--- a/src/eap_peer/eap_peap.c ++++ b/src/eap_peer/eap_peap.c +@@ -67,6 +67,7 @@ struct eap_peap_data { + u8 cmk[20]; + int soh; /* Whether IF-TNCCS-SOH (Statement of Health; Microsoft NAP) + * is enabled. */ ++ enum { NO_AUTH, FOR_INITIAL, ALWAYS } phase2_auth; + }; + + +@@ -114,6 +115,19 @@ static void eap_peap_parse_phase1(struct eap_peap_data *data, + wpa_printf(MSG_DEBUG, "EAP-PEAP: Require cryptobinding"); + } + ++ if (os_strstr(phase1, "phase2_auth=0")) { ++ data->phase2_auth = NO_AUTH; ++ wpa_printf(MSG_DEBUG, ++ "EAP-PEAP: Do not require Phase 2 authentication"); ++ } else if (os_strstr(phase1, "phase2_auth=1")) { ++ data->phase2_auth = FOR_INITIAL; ++ wpa_printf(MSG_DEBUG, ++ "EAP-PEAP: Require Phase 2 authentication for initial connection"); ++ } else if (os_strstr(phase1, "phase2_auth=2")) { ++ data->phase2_auth = ALWAYS; ++ wpa_printf(MSG_DEBUG, ++ "EAP-PEAP: Require Phase 2 authentication for all cases"); ++ } + #ifdef EAP_TNC + if (os_strstr(phase1, "tnc=soh2")) { + data->soh = 2; +@@ -142,6 +156,7 @@ static void * eap_peap_init(struct eap_sm *sm) + data->force_peap_version = -1; + data->peap_outer_success = 2; + data->crypto_binding = OPTIONAL_BINDING; ++ data->phase2_auth = FOR_INITIAL; + + if (config && config->phase1) + eap_peap_parse_phase1(data, config->phase1); +@@ -451,6 +466,20 @@ static int eap_tlv_validate_cryptobinding(struct eap_sm *sm, + } + + ++static bool peap_phase2_sufficient(struct eap_sm *sm, ++ struct eap_peap_data *data) ++{ ++ if ((data->phase2_auth == ALWAYS || ++ (data->phase2_auth == FOR_INITIAL && ++ !tls_connection_resumed(sm->ssl_ctx, data->ssl.conn) && ++ !data->ssl.client_cert_conf) || ++ data->phase2_eap_started) && ++ !data->phase2_eap_success) ++ return false; ++ return true; ++} ++ ++ + /** + * eap_tlv_process - Process a received EAP-TLV message and generate a response + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() +@@ -565,6 +594,11 @@ static int eap_tlv_process(struct eap_sm *sm, struct eap_peap_data *data, + " - force failed Phase 2"); + resp_status = EAP_TLV_RESULT_FAILURE; + ret->decision = DECISION_FAIL; ++ } else if (!peap_phase2_sufficient(sm, data)) { ++ wpa_printf(MSG_INFO, ++ "EAP-PEAP: Server indicated Phase 2 success, but sufficient Phase 2 authentication has not been completed"); ++ resp_status = EAP_TLV_RESULT_FAILURE; ++ ret->decision = DECISION_FAIL; + } else { + resp_status = EAP_TLV_RESULT_SUCCESS; + ret->decision = DECISION_UNCOND_SUCC; +@@ -864,8 +898,7 @@ continue_req: + /* EAP-Success within TLS tunnel is used to indicate + * shutdown of the TLS channel. The authentication has + * been completed. */ +- if (data->phase2_eap_started && +- !data->phase2_eap_success) { ++ if (!peap_phase2_sufficient(sm, data)) { + wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 " + "Success used to indicate success, " + "but Phase 2 EAP was not yet " +@@ -1156,8 +1189,9 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv, + static Boolean eap_peap_has_reauth_data(struct eap_sm *sm, void *priv) + { + struct eap_peap_data *data = priv; ++ + return tls_connection_established(sm->ssl_ctx, data->ssl.conn) && +- data->phase2_success; ++ data->phase2_success && data->phase2_auth != ALWAYS; + } + + +diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c +index 7dbd364..6c586ba 100644 +--- a/src/eap_peer/eap_tls_common.c ++++ b/src/eap_peer/eap_tls_common.c +@@ -220,6 +220,12 @@ static int eap_tls_params_from_conf(struct eap_sm *sm, + + sm->ext_cert_check = !!(params->flags & TLS_CONN_EXT_CERT_CHECK); + ++ if (!phase2) ++ data->client_cert_conf = params->client_cert || ++ params->client_cert_blob || ++ params->private_key || ++ params->private_key_blob; ++ + return 0; + } + +diff --git a/src/eap_peer/eap_tls_common.h b/src/eap_peer/eap_tls_common.h +index 306e6a9..e2cf829 100644 +--- a/src/eap_peer/eap_tls_common.h ++++ b/src/eap_peer/eap_tls_common.h +@@ -73,6 +73,11 @@ + * eap_type - EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST) + */ + u8 eap_type; ++ ++ /** ++ * client_cert_conf: Whether client certificate has been configured ++ */ ++ bool client_cert_conf; + }; + + +diff --git a/src/utils/includes.h b/src/utils/includes.h +index 75513fc..4166d0e 100644 +--- a/src/utils/includes.h ++++ b/src/utils/includes.h +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #ifndef _WIN32_WCE + #include +diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf +index 1bd43b2..4e4e2e0 100644 +--- a/wpa_supplicant/wpa_supplicant.conf ++++ b/wpa_supplicant/wpa_supplicant.conf +@@ -1205,6 +1205,13 @@ fast_reauth=1 + # * 0 = do not use cryptobinding (default) + # * 1 = use cryptobinding if server supports it + # * 2 = require cryptobinding ++# 'phase2_auth' option can be used to control Phase 2 (i.e., within TLS ++# tunnel) behavior for PEAP: ++# * 0 = do not require Phase 2 authentication ++# * 1 = require Phase 2 authentication when client certificate ++# (private_key/client_cert) is no used and TLS session resumption was ++# not used (default) ++# * 2 = require Phase 2 authentication in all cases + # EAP-WSC (WPS) uses following options: pin= or + # pbc=1. + # diff --git a/wpa_supplicant.spec b/wpa_supplicant.spec index b8eace2..c3adac5 100644 --- a/wpa_supplicant.spec +++ b/wpa_supplicant.spec @@ -1,7 +1,7 @@ Name: wpa_supplicant Epoch: 1 Version: 2.6 -Release: 30 +Release: 31 Summary: A WPA Supplicant with support for WPA and WPA2 (IEEE 802.11i / RSN) License: BSD or GPLv2 Url: https://w1.fi/wpa_supplicant/ @@ -106,6 +106,7 @@ Patch89: backport-0001-CVE-2022-23303-CVE-2022-23304.patch Patch90: backport-0002-CVE-2022-23303-CVE-2022-23304.patch Patch91: backport-0003-CVE-2022-23303-CVE-2022-23304.patch Patch92: backport-0004-CVE-2022-23303-CVE-2022-23304.patch +Patch93: CVE-2023-52160.patch BuildRequires: qt-devel >= 4.0 openssl-devel readline-devel dbus-devel libnl3-devel systemd-units docbook-utils Requires(post): systemd-sysv @@ -199,6 +200,12 @@ install -m644 %{name}/doc/docbook/*.5 %{buildroot}%{_mandir}/man5 %{_mandir}/man5/* %changelog +* Thu Apr 25 2024 dillon chen - 1:2.6-31 +- Type:cves +- ID:CVE-2023-52160 +- SUG:NA +- DESC:fix CVE-2023-52160 + * Wed Jan 26 2022 shixuantong - 1:2.6-30 - Type:cves - ID:CVE-2022-23303 CVE-2022-23304 -- Gitee