From 15af83cf1846870873a011ed4d714732f01cd2e4 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <quic_jouni@quicinc.com>
Date: Tue, 19 Jul 2022 21:23:04 +0300
Subject: [PATCH] DPP: Delete PKEX code and identifier on success completion of
 PKEX

We are not supposed to reuse these without being explicitly requested to
perform PKEX again. There is not a strong use case for being able to
provision an Enrollee multiple times with PKEX, so this should have no
issues on the Enrollee. For a Configurator, there might be some use
cases that would benefit from being able to use the same code with
multiple Enrollee devices, e.g., for guess access with a laptop and a
smart phone. That case will now require a new DPP_PKEX_ADD command on
the Configurator after each completion of the provisioning exchange.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>

CVE: CVE-2022-37660

Upstream-Status: Backport [https://git.w1.fi/cgit/hostap/commit/?id=15af83cf1846870873a011ed4d714732f01cd2e4]

Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
---
 src/ap/dpp_hostapd.c            | 22 +++++++++++++++++++++-
 wpa_supplicant/dpp_supplicant.c | 21 ++++++++++++++++++++-
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c
index d956be9..73b09ba 100644
--- a/src/ap/dpp_hostapd.c
+++ b/src/ap/dpp_hostapd.c
@@ -276,6 +276,22 @@ static int hostapd_dpp_pkex_next_channel(struct hostapd_data *hapd,
 }
 
 
+static void hostapd_dpp_pkex_clear_code(struct hostapd_data *hapd)
+{
+	if (!hapd->dpp_pkex_code && !hapd->dpp_pkex_identifier)
+		return;
+
+	/* Delete PKEX code and identifier on successful completion of
+	 * PKEX. We are not supposed to reuse these without being
+	 * explicitly requested to perform PKEX again. */
+	wpa_printf(MSG_DEBUG, "DPP: Delete PKEX code/identifier");
+	os_free(hapd->dpp_pkex_code);
+	hapd->dpp_pkex_code = NULL;
+	os_free(hapd->dpp_pkex_identifier);
+	hapd->dpp_pkex_identifier = NULL;
+}
+
+
 #ifdef CONFIG_DPP2
 static int hostapd_dpp_pkex_done(void *ctx, void *conn,
 				 struct dpp_bootstrap_info *peer_bi)
@@ -287,6 +303,8 @@ static int hostapd_dpp_pkex_done(void *ctx, void *conn,
 	struct dpp_bootstrap_info *own_bi = NULL;
 	struct dpp_authentication *auth;
 
+	hostapd_dpp_pkex_clear_code(hapd);
+
 	if (!cmd)
 		cmd = "";
 	wpa_printf(MSG_DEBUG, "DPP: Start authentication after PKEX (cmd: %s)",
@@ -2114,6 +2132,7 @@ hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
 				wpabuf_head(msg), wpabuf_len(msg));
 	wpabuf_free(msg);
 
+	hostapd_dpp_pkex_clear_code(hapd);
 	bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
 	if (!bi)
 		return;
@@ -2145,6 +2164,7 @@ hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
 		return;
 	}
 
+	hostapd_dpp_pkex_clear_code(hapd);
 	bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
 	if (!bi)
 		return;
@@ -2518,7 +2538,7 @@ int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
 			return -1;
 	}
 
-	if ((id_val != 0 && id_val != 1) || !hapd->dpp_pkex_code)
+	if ((id_val != 0 && id_val != 1))
 		return -1;
 
 	/* TODO: Support multiple PKEX entries */
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
index aab94cb..015ae66 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -2557,6 +2557,22 @@ static int wpas_dpp_pkex_next_channel(struct wpa_supplicant *wpa_s,
 }
 
 
+static void wpas_dpp_pkex_clear_code(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s->dpp_pkex_code && !wpa_s->dpp_pkex_identifier)
+		return;
+
+	/* Delete PKEX code and identifier on successful completion of
+	 * PKEX. We are not supposed to reuse these without being
+	 * explicitly requested to perform PKEX again. */
+	os_free(wpa_s->dpp_pkex_code);
+	wpa_s->dpp_pkex_code = NULL;
+	os_free(wpa_s->dpp_pkex_identifier);
+	wpa_s->dpp_pkex_identifier = NULL;
+
+}
+
+
 #ifdef CONFIG_DPP2
 static int wpas_dpp_pkex_done(void *ctx, void *conn,
 			      struct dpp_bootstrap_info *peer_bi)
@@ -2568,6 +2584,8 @@ static int wpas_dpp_pkex_done(void *ctx, void *conn,
 	struct dpp_bootstrap_info *own_bi = NULL;
 	struct dpp_authentication *auth;
 
+	wpas_dpp_pkex_clear_code(wpa_s);
+
 	if (!cmd)
 		cmd = "";
 	wpa_printf(MSG_DEBUG, "DPP: Start authentication after PKEX (cmd: %s)",
@@ -2872,6 +2890,7 @@ wpas_dpp_pkex_finish(struct wpa_supplicant *wpa_s, const u8 *peer,
 {
 	struct dpp_bootstrap_info *bi;
 
+	wpas_dpp_pkex_clear_code(wpa_s);
 	bi = dpp_pkex_finish(wpa_s->dpp, wpa_s->dpp_pkex, peer, freq);
 	if (!bi)
 		return NULL;
@@ -3521,7 +3540,7 @@ int wpas_dpp_pkex_remove(struct wpa_supplicant *wpa_s, const char *id)
 			return -1;
 	}
 
-	if ((id_val != 0 && id_val != 1) || !wpa_s->dpp_pkex_code)
+	if ((id_val != 0 && id_val != 1))
 		return -1;
 
 	/* TODO: Support multiple PKEX entries */
-- 
2.40.0

