static int dpp_prepare_channel_list(struct dpp_authentication *auth,
+ unsigned int neg_freq,
struct hostapd_hw_modes *own_modes,
u16 num_modes)
{
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
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
}
#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)
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,
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,
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 */
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,