]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Indicate if SSID has been verified in STATUS output
authorJouni Malinen <quic_jouni@quicinc.com>
Thu, 11 Jul 2024 19:44:46 +0000 (22:44 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 11 Jul 2024 19:58:12 +0000 (22:58 +0300)
Add a new "ssid_verified=1" entry into the control interface STATUS
command output if the SSID has been verified for the current
association. This verification may have been done implicitly (e.g., with
SAE H2E and FT protocol binding in the SSID into key derivation or with
FILS protecting the SSID element in the (Re)Association Request frame)
or explicitly with the recently added SSID protection mechanism during
the 4-way handshake.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
src/rsn_supp/wpa_i.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/events.c
wpa_supplicant/wpa_supplicant_i.h
wpa_supplicant/wpas_glue.c

index 21dfeb5fb61382f3b9540bdb5d399ce3800686db..323690a6651caa9028a34e60f582f44a31c8cfd6 100644 (file)
@@ -2560,8 +2560,7 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
                        goto failed;
                }
 
-               wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
-                       "RSN: SSID matched expected value");
+               wpa_sm_ssid_verified(sm);
        }
 
        if (mlo && !ie.valid_mlo_gtks) {
index c3ea689068fe4a6cc82a17c8259fafd7b0696a13..2bef093e3fa00e18f8f09cba6f62cbbb14b6c701 100644 (file)
@@ -104,6 +104,7 @@ struct wpa_sm_ctx {
 #endif /* CONFIG_PASN */
        void (*notify_pmksa_cache_entry)(void *ctx,
                                         struct rsn_pmksa_cache_entry *entry);
+       void (*ssid_verified)(void *ctx);
 };
 
 
index dc429b8b261e7c3213c7bbaa7b280a7d90337fb1..d7e780519cdb177d4f97a9f3420050bf9bbf45a6 100644 (file)
@@ -518,6 +518,12 @@ wpa_sm_notify_pmksa_cache_entry(struct wpa_sm *sm,
                sm->ctx->notify_pmksa_cache_entry(sm->ctx->ctx, entry);
 }
 
+static inline void wpa_sm_ssid_verified(struct wpa_sm *sm)
+{
+       if (sm->ctx->ssid_verified)
+               sm->ctx->ssid_verified(sm->ctx->ctx);
+}
+
 int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk,
                       int ver, const u8 *dest, u16 proto,
                       u8 *msg, size_t msg_len, u8 *key_mic);
index 74d61132e8a4dc433a9c657ad478730e51944729..acc6ab52400b3e1007ab56d860857eb94cb51bc1 100644 (file)
@@ -2568,6 +2568,13 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
        }
 #endif /* CONFIG_SME */
 
+       if (wpa_s->ssid_verified) {
+               ret = os_snprintf(pos, end - pos, "ssid_verified=1\n");
+               if (os_snprintf_error(end - pos, ret))
+                       return pos - buf;
+               pos += ret;
+       }
+
 #ifdef ANDROID
        /*
         * Allow using the STATUS command with default behavior, say for debug,
index d45e7925db5cfe7f42d7eed3aeecd21f1f8b1b96..e8b7eea1169e90448be863246aa521c70944c1e6 100644 (file)
@@ -432,6 +432,8 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
 #ifdef CONFIG_SME
        wpa_s->sme.bss_max_idle_period = 0;
 #endif /* CONFIG_SME */
+
+       wpa_s->ssid_verified = false;
 }
 
 
@@ -3368,6 +3370,15 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
        bool bssid_known;
 
        wpa_dbg(wpa_s, MSG_DEBUG, "Association info event");
+       wpa_s->ssid_verified = false;
+#ifdef CONFIG_SAE
+#ifdef CONFIG_SME
+       /* SAE H2E binds the SSID into PT and that verifies the SSID
+        * implicitly. */
+       if (wpa_s->sme.sae.state == SAE_ACCEPTED && wpa_s->sme.sae.h2e)
+               wpa_s->ssid_verified = true;
+#endif /* CONFIG_SME */
+#endif /* CONFIG_SAE */
        bssid_known = wpa_drv_get_bssid(wpa_s, bssid) == 0;
        if (data->assoc_info.req_ies)
                wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies,
@@ -3469,14 +3480,22 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
 
 #ifdef CONFIG_FILS
 #ifdef CONFIG_SME
-       if ((wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS ||
-            wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS_SK_PFS) &&
-           (!data->assoc_info.resp_frame ||
-            fils_process_assoc_resp(wpa_s->wpa,
-                                    data->assoc_info.resp_frame,
-                                    data->assoc_info.resp_frame_len) < 0)) {
-               wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_UNSPECIFIED);
-               return -1;
+       if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS ||
+           wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS_SK_PFS) {
+               if (!data->assoc_info.resp_frame ||
+                   fils_process_assoc_resp(wpa_s->wpa,
+                                           data->assoc_info.resp_frame,
+                                           data->assoc_info.resp_frame_len) <
+                   0) {
+                       wpa_supplicant_deauthenticate(wpa_s,
+                                                     WLAN_REASON_UNSPECIFIED);
+                       return -1;
+               }
+
+               /* FILS use of an AEAD cipher include the SSID element in
+                * (Re)Association Request frame in the AAD and since the AP
+                * accepted that, the SSID was verified. */
+               wpa_s->ssid_verified = true;
        }
 #endif /* CONFIG_SME */
 
@@ -3537,6 +3556,9 @@ no_pfs:
                                wpa_s, WLAN_REASON_INVALID_IE);
                        return -1;
                }
+               /* SSID is included in PMK-R0 derivation, so it is verified
+                * implicitly. */
+               wpa_s->ssid_verified = true;
        }
 
        p = data->assoc_info.resp_ies;
@@ -3598,6 +3620,9 @@ no_pfs:
                        return -1;
                }
                wpa_dbg(wpa_s, MSG_DEBUG, "FT: Reassociation Response done");
+               /* SSID is included in PMK-R0 derivation, so it is verified
+                * implicitly. */
+               wpa_s->ssid_verified = true;
        }
 
        wpa_sm_set_ft_params(wpa_s->wpa, data->assoc_info.resp_ies,
index 7a128622522149a81bc6928260bfcecf7765a200..13406881de7e1d7a7eebb73baa207b8d6e352e5a 100644 (file)
@@ -1609,6 +1609,8 @@ struct wpa_supplicant {
        struct wpa_radio_work *nan_usd_listen_work;
        struct wpa_radio_work *nan_usd_tx_work;
 #endif /* CONFIG_NAN_USD */
+
+       bool ssid_verified;
 };
 
 
index eea854899665f7d6c933bc2354aff757b00e54bc..9b68d07c6a6fa00641a17b41582aac27447f765b 100644 (file)
@@ -1409,6 +1409,15 @@ wpa_supplicant_notify_pmksa_cache_entry(void *_wpa_s,
 }
 
 
+static void wpa_supplicant_ssid_verified(void *_wpa_s)
+{
+       struct wpa_supplicant *wpa_s = _wpa_s;
+
+       wpa_s->ssid_verified = true;
+       wpa_msg(wpa_s, MSG_INFO, "RSN: SSID matched expected value");
+}
+
+
 int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
 {
 #ifndef CONFIG_NO_WPA
@@ -1475,6 +1484,7 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
        ctx->set_ltf_keyseed = wpa_supplicant_set_ltf_keyseed;
 #endif /* CONFIG_PASN */
        ctx->notify_pmksa_cache_entry = wpa_supplicant_notify_pmksa_cache_entry;
+       ctx->ssid_verified = wpa_supplicant_ssid_verified;
 
        wpa_s->wpa = wpa_sm_init(ctx);
        if (wpa_s->wpa == NULL) {