Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wpa-supplicant: Update to recipe from Kirkstone #3614

Merged
merged 1 commit into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
From f6f7cead3661ceeef54b21f7e799c0afc98537ec Mon Sep 17 00:00:00 2001
From: Jouni Malinen <[email protected]>
Date: Sat, 8 Jul 2023 19:55:32 +0300
Subject: [PATCH] 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 <[email protected]>

CVE: CVE-2023-52160
Upstream-Status: Backport [https://w1.fi/cgit/hostap/commit/?id=8e6485a1bcb0baffdea9e55255a81270b768439c]

Signed-off-by: Claus Stovgaard <[email protected]>
Signed-off-by: Peter Marko <[email protected]>
---
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 ++++
wpa_supplicant/wpa_supplicant.conf | 7 ++++++
5 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h
index 3238f74..047eec2 100644
--- a/src/eap_peer/eap_config.h
+++ b/src/eap_peer/eap_config.h
@@ -469,6 +469,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 12e30df..6080697 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);
@@ -454,6 +469,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()
@@ -568,6 +597,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;
@@ -887,8 +921,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 "
@@ -1199,8 +1232,9 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
static bool 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 c1837db..a53eeb1 100644
--- a/src/eap_peer/eap_tls_common.c
+++ b/src/eap_peer/eap_tls_common.c
@@ -239,6 +239,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 9ac0012..3348634 100644
--- a/src/eap_peer/eap_tls_common.h
+++ b/src/eap_peer/eap_tls_common.h
@@ -79,6 +79,11 @@ struct eap_ssl_data {
* tls_v13 - Whether TLS v1.3 or newer is used
*/
int tls_v13;
+
+ /**
+ * client_cert_conf: Whether client certificate has been configured
+ */
+ bool client_cert_conf;
};


diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 6619d6b..d63f73c 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -1321,6 +1321,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=<Device Password> or
# pbc=1.
#
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
From 364c2da8741f0979dae497551e70b94c0e6c8636 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <[email protected]>
Date: Sun, 7 Jul 2024 11:46:49 +0300
Subject: [PATCH 1/3] SAE: Check for invalid Rejected Groups element length
explicitly

Instead of practically ignoring an odd octet at the end of the element,
check for such invalid case explicitly. This is needed to avoid a
potential group downgrade attack.

Signed-off-by: Jouni Malinen <[email protected]>

CVE: CVE-2024-3596
Upstream-Status: Backport [https://w1.fi/cgit/hostap/commit/?id=364c2da8741f0979dae497551e70b94c0e6c8636]
Signed-off-by: Peter Marko <[email protected]>
---
src/ap/ieee802_11.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index db4104928..1a62e30cc 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1258,7 +1258,7 @@ static int check_sae_rejected_groups(struct hostapd_data *hapd,
struct sae_data *sae)
{
const struct wpabuf *groups;
- size_t i, count;
+ size_t i, count, len;
const u8 *pos;

if (!sae->tmp)
@@ -1268,7 +1268,15 @@ static int check_sae_rejected_groups(struct hostapd_data *hapd,
return 0;

pos = wpabuf_head(groups);
- count = wpabuf_len(groups) / 2;
+ len = wpabuf_len(groups);
+ if (len & 1) {
+ wpa_printf(MSG_DEBUG,
+ "SAE: Invalid length of the Rejected Groups element payload: %zu",
+ len);
+ return 1;
+ }
+
+ count = len / 2;
for (i = 0; i < count; i++) {
int enabled;
u16 group;
--
2.30.2

This file was deleted.

Loading
Loading