]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Recognize own PKEX Exchange Request if it ends up being received
authorJouni Malinen <quic_jouni@quicinc.com>
Thu, 21 Jul 2022 17:30:07 +0000 (20:30 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 21 Jul 2022 17:30:07 +0000 (20:30 +0300)
It is possible for a Controller to receive a copy of its own PKEX
Exchange Request in the case where the Controller is initiating a PKEX
exchange through a Relay. The Configurator role in the device would have
a matching PKEX code in that case and the device might reply as a PKEX
responder which would result in going through the exchange with the
Controller device itself. That is clearly not desired, so recognize this
special case by checking whether the Encrypted Key attribute value
matches a pending locally generated one when processing a received PKEX
Exchange Request.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
src/ap/dpp_hostapd.c
src/common/dpp.h
src/common/dpp_pkex.c
src/common/dpp_tcp.c
wpa_supplicant/dpp_supplicant.c

index d85a38df8cb1e5474c91d3445c5c344a8c36f922..ed4625dde64099eb4306bbf6e6f40a909973307c 100644 (file)
@@ -2132,6 +2132,15 @@ hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
                goto try_relay;
        }
 
+#ifdef CONFIG_DPP2
+       if (dpp_controller_is_own_pkex_req(hapd->iface->interfaces->dpp,
+                                          buf, len)) {
+               wpa_printf(MSG_DEBUG,
+                          "DPP: PKEX Exchange Request is from local Controller - ignore request");
+               return;
+       }
+#endif /* CONFIG_DPP2 */
+
        if (hapd->dpp_pkex) {
                /* TODO: Support parallel operations */
                wpa_printf(MSG_DEBUG,
index da9a33b5eb05633b4fea187adf2d4e178dcbe6fd..08febd94f2d7bc52cbb60896ce6b45d124d42aa2 100644 (file)
@@ -222,6 +222,7 @@ struct dpp_pkex {
        unsigned int exch_req_tries;
        unsigned int freq;
        u8 peer_version;
+       struct wpabuf *enc_key;
 };
 
 enum dpp_akm {
@@ -605,6 +606,8 @@ int dpp_notify_new_qr_code(struct dpp_authentication *auth,
 void dpp_controller_pkex_add(struct dpp_global *dpp,
                             struct dpp_bootstrap_info *bi,
                             const char *code, const char *identifier);
+bool dpp_controller_is_own_pkex_req(struct dpp_global *dpp,
+                                   const u8 *buf, size_t len);
 struct dpp_configuration * dpp_configuration_alloc(const char *type);
 int dpp_akm_psk(enum dpp_akm akm);
 int dpp_akm_sae(enum dpp_akm akm);
index c4713a4fec74339c25d4550d0f0bde0f57544dff..ff650cf0efd7e7b1ecdc1ebad844f6c793175394 100644 (file)
@@ -145,6 +145,8 @@ skip_finite_cyclic_group:
        My = wpabuf_put(msg, curve->prime_len);
        if (crypto_ec_point_to_bin(ec, M, Mx, My))
                goto fail;
+       wpabuf_free(pkex->enc_key);
+       pkex->enc_key = wpabuf_alloc_copy(Mx, 2 * curve->prime_len);
 
        os_memcpy(pkex->Mx, Mx, curve->prime_len);
 
@@ -1379,5 +1381,6 @@ void dpp_pkex_free(struct dpp_pkex *pkex)
        crypto_ec_key_deinit(pkex->peer_bootstrap_key);
        wpabuf_free(pkex->exchange_req);
        wpabuf_free(pkex->exchange_resp);
+       wpabuf_free(pkex->enc_key);
        os_free(pkex);
 }
index 5cd732907e3552f8a610ec29e9b45d8235353afb..fc5dfb97369c4ad01ed6a49251894358181a379b 100644 (file)
@@ -2264,6 +2264,35 @@ void dpp_controller_pkex_add(struct dpp_global *dpp,
 }
 
 
+bool dpp_controller_is_own_pkex_req(struct dpp_global *dpp,
+                                   const u8 *buf, size_t len)
+{
+       struct dpp_connection *conn;
+       const u8 *attr_key = NULL;
+       u16 attr_key_len = 0;
+
+       dl_list_for_each(conn, &dpp->tcp_init, struct dpp_connection, list) {
+               if (!conn->pkex || !conn->pkex->enc_key)
+                       continue;
+
+               if (!attr_key) {
+                       attr_key = dpp_get_attr(buf, len,
+                                               DPP_ATTR_ENCRYPTED_KEY,
+                                               &attr_key_len);
+                       if (!attr_key)
+                               return false;
+               }
+
+               if (attr_key_len == wpabuf_len(conn->pkex->enc_key) &&
+                   os_memcmp(attr_key, wpabuf_head(conn->pkex->enc_key),
+                             attr_key_len) == 0)
+                       return true;
+       }
+
+       return false;
+}
+
+
 void dpp_tcp_init_flush(struct dpp_global *dpp)
 {
        struct dpp_connection *conn, *tmp;
index 4b2e91a3a7bff10c95fa4f4b42845a0a0a12c2c1..64eb5ea631b687be06efbff7a47ca880890c71e4 100644 (file)
@@ -2976,6 +2976,14 @@ wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant *wpa_s, const u8 *src,
                return;
        }
 
+#ifdef CONFIG_DPP2
+       if (dpp_controller_is_own_pkex_req(wpa_s->dpp, buf, len)) {
+               wpa_printf(MSG_DEBUG,
+                          "DPP: PKEX Exchange Request is from local Controller - ignore request");
+               return;
+       }
+#endif /* CONFIG_DPP2 */
+
        if (wpa_s->dpp_pkex) {
                /* TODO: Support parallel operations */
                wpa_printf(MSG_DEBUG,