]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP2: Presence Announcement processing at Configurator
authorJouni Malinen <jouni@codeaurora.org>
Fri, 27 Mar 2020 13:34:09 +0000 (15:34 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 27 Mar 2020 18:05:25 +0000 (20:05 +0200)
Process received Presence Announcement frames and initiate
Authentication exchange if matching information is available on the
Configurator.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/common/dpp.c
src/common/dpp.h
wpa_supplicant/dpp_supplicant.c

index 56abe507f2377e0ca07473440377ee0c62270ae4..c71a6424f223c970cf611c6ce4efb00b905ebf14 100644 (file)
@@ -2246,6 +2246,7 @@ static int dpp_channel_local_list(struct dpp_authentication *auth,
 
 
 static int dpp_prepare_channel_list(struct dpp_authentication *auth,
+                                   unsigned int neg_freq,
                                    struct hostapd_hw_modes *own_modes,
                                    u16 num_modes)
 {
@@ -2253,6 +2254,14 @@ static int dpp_prepare_channel_list(struct dpp_authentication *auth,
        char freqs[DPP_BOOTSTRAP_MAX_FREQ * 6 + 10], *pos, *end;
        unsigned int i;
 
+       if (!own_modes) {
+               if (!neg_freq)
+                       return -1;
+               auth->num_freq = 1;
+               auth->freq[0] = neg_freq;
+               return 0;
+       }
+
        if (auth->peer_bi->num_freq > 0)
                res = dpp_channel_intersect(auth, own_modes, num_modes);
        else
@@ -2392,7 +2401,7 @@ struct dpp_authentication * dpp_auth_init(struct dpp_global *dpp, void *msg_ctx,
        auth->curve = peer_bi->curve;
 
        if (dpp_autogen_bootstrap_key(auth) < 0 ||
-           dpp_prepare_channel_list(auth, own_modes, num_modes) < 0)
+           dpp_prepare_channel_list(auth, neg_freq, own_modes, num_modes) < 0)
                goto fail;
 
 #ifdef CONFIG_TESTING_OPTIONS
@@ -2488,6 +2497,8 @@ struct dpp_authentication * dpp_auth_init(struct dpp_global *dpp, void *msg_ctx,
        }
 #endif /* CONFIG_TESTING_OPTIONS */
 
+       if (neg_freq && auth->num_freq == 1 && auth->freq[0] == neg_freq)
+               neg_freq = 0;
        auth->req_msg = dpp_auth_build_req(auth, pi, nonce_len, r_pubkey_hash,
                                           i_pubkey_hash, neg_freq);
        if (!auth->req_msg)
@@ -10597,8 +10608,27 @@ void dpp_bootstrap_find_pair(struct dpp_global *dpp, const u8 *i_bootstrap,
                if (*own_bi && *peer_bi)
                        break;
        }
+}
+
+
+#ifdef CONFIG_DPP2
+struct dpp_bootstrap_info * dpp_bootstrap_find_chirp(struct dpp_global *dpp,
+                                                    const u8 *hash)
+{
+       struct dpp_bootstrap_info *bi;
 
+       if (!dpp)
+               return NULL;
+
+       dl_list_for_each(bi, &dpp->bootstrap, struct dpp_bootstrap_info, list) {
+               if (!bi->own && os_memcmp(bi->pubkey_hash_chirp, hash,
+                                         SHA256_MAC_LEN) == 0)
+                       return bi;
+       }
+
+       return NULL;
 }
+#endif /* CONFIG_DPP2 */
 
 
 static int dpp_nfc_update_bi_channel(struct dpp_bootstrap_info *own_bi,
index 513918bb5696beadca01f5fb5206721e28dd054c..61be2184b71935faa1730a3c891a1c708861dfc2 100644 (file)
@@ -578,6 +578,8 @@ void dpp_bootstrap_find_pair(struct dpp_global *dpp, const u8 *i_bootstrap,
                             const u8 *r_bootstrap,
                             struct dpp_bootstrap_info **own_bi,
                             struct dpp_bootstrap_info **peer_bi);
+struct dpp_bootstrap_info * dpp_bootstrap_find_chirp(struct dpp_global *dpp,
+                                                    const u8 *hash);
 int dpp_configurator_add(struct dpp_global *dpp, const char *cmd);
 int dpp_configurator_remove(struct dpp_global *dpp, const char *id);
 int dpp_configurator_get_key_id(struct dpp_global *dpp, unsigned int id,
index c6d555662bb6b5fbf1fc71abbcddef47da673a1b..45fd3a744495c192212b0c4a174f7c1d69669bb2 100644 (file)
@@ -1694,6 +1694,67 @@ static void wpas_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi)
                wpas_dpp_chirp_stop(wpa_s);
 }
 
+
+static void
+wpas_dpp_rx_presence_announcement(struct wpa_supplicant *wpa_s, const u8 *src,
+                                 const u8 *hdr, const u8 *buf, size_t len,
+                                 unsigned int freq)
+{
+       const u8 *r_bootstrap;
+       u16 r_bootstrap_len;
+       struct dpp_bootstrap_info *peer_bi;
+       struct dpp_authentication *auth;
+
+       if (!wpa_s->dpp)
+               return;
+
+       if (wpa_s->dpp_auth) {
+               wpa_printf(MSG_DEBUG,
+                          "DPP: Ignore Presence Announcement during ongoing Authentication");
+               return;
+       }
+
+       wpa_printf(MSG_DEBUG, "DPP: Presence Announcement from " MACSTR,
+                  MAC2STR(src));
+
+       r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
+                                  &r_bootstrap_len);
+       if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
+               wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL
+                       "Missing or invalid required Responder Bootstrapping Key Hash attribute");
+               return;
+       }
+       wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
+                   r_bootstrap, r_bootstrap_len);
+       peer_bi = dpp_bootstrap_find_chirp(wpa_s->dpp, r_bootstrap);
+       if (!peer_bi) {
+               wpa_printf(MSG_DEBUG,
+                          "DPP: No matching bootstrapping information found");
+               return;
+       }
+
+       auth = dpp_auth_init(wpa_s->dpp, wpa_s, peer_bi, NULL,
+                            DPP_CAPAB_CONFIGURATOR, freq, NULL, 0);
+       if (!auth)
+               return;
+       wpas_dpp_set_testing_options(wpa_s, auth);
+       if (dpp_set_configurator(auth, wpa_s->dpp_configurator_params) < 0) {
+               dpp_auth_deinit(auth);
+               return;
+       }
+
+       auth->neg_freq = freq;
+
+       if (!is_zero_ether_addr(peer_bi->mac_addr))
+               os_memcpy(auth->peer_mac_addr, peer_bi->mac_addr, ETH_ALEN);
+
+       wpa_s->dpp_auth = auth;
+       if (wpas_dpp_auth_init_next(wpa_s) < 0) {
+               dpp_auth_deinit(wpa_s->dpp_auth);
+               wpa_s->dpp_auth = NULL;
+       }
+}
+
 #endif /* CONFIG_DPP2 */
 
 
@@ -2239,6 +2300,10 @@ void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
        case DPP_PA_CONNECTION_STATUS_RESULT:
                wpas_dpp_rx_conn_status_result(wpa_s, src, hdr, buf, len);
                break;
+       case DPP_PA_PRESENCE_ANNOUNCEMENT:
+               wpas_dpp_rx_presence_announcement(wpa_s, src, hdr, buf, len,
+                                                 freq);
+               break;
 #endif /* CONFIG_DPP2 */
        default:
                wpa_printf(MSG_DEBUG,