From 66ac616cdb31c7ffd086a99aa6aab757cb181646 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 2 May 2020 00:16:05 +0300 Subject: [PATCH] DPP2: Process received Reconfig Announcement frame Check if there is a matching Configurator and be ready to initiate Reconfig Authentication (which itself is not included in this commit). Signed-off-by: Jouni Malinen --- src/ap/dpp_hostapd.c | 43 ++++++++++++++++++++++ src/common/dpp.c | 64 +++++++++++++++++++++++++++++++-- src/common/dpp.h | 3 ++ wpa_supplicant/dpp_supplicant.c | 45 +++++++++++++++++++++++ 4 files changed, 152 insertions(+), 3 deletions(-) diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index 0926a7659..a5e53cbd8 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -1197,6 +1197,45 @@ hostapd_dpp_rx_presence_announcement(struct hostapd_data *hapd, const u8 *src, } } + +static void +hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src, + const u8 *hdr, const u8 *buf, size_t len, + unsigned int freq) +{ + const u8 *csign_hash; + u16 csign_hash_len; + struct dpp_configurator *conf; + + if (hapd->dpp_auth) { + wpa_printf(MSG_DEBUG, + "DPP: Ignore Reconfig Announcement during ongoing Authentication"); + return; + } + + wpa_printf(MSG_DEBUG, "DPP: Reconfig Announcement from " MACSTR, + MAC2STR(src)); + + csign_hash = dpp_get_attr(buf, len, DPP_ATTR_C_SIGN_KEY_HASH, + &csign_hash_len); + if (!csign_hash || csign_hash_len != SHA256_MAC_LEN) { + wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL + "Missing or invalid required Configurator C-sign key Hash attribute"); + return; + } + wpa_hexdump(MSG_MSGDUMP, "DPP: Configurator C-sign key Hash (kid)", + csign_hash, csign_hash_len); + conf = dpp_configurator_find_kid(hapd->iface->interfaces->dpp, + csign_hash); + if (!conf) { + wpa_printf(MSG_DEBUG, + "DPP: No matching Configurator information found"); + return; + } + + /* TODO: Initiate Reconfig Authentication */ +} + #endif /* CONFIG_DPP2 */ @@ -1663,6 +1702,10 @@ void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src, hostapd_dpp_rx_presence_announcement(hapd, src, hdr, buf, len, freq); break; + case DPP_PA_RECONFIG_ANNOUNCEMENT: + hostapd_dpp_rx_reconfig_announcement(hapd, src, hdr, buf, len, + freq); + break; #endif /* CONFIG_DPP2 */ default: wpa_printf(MSG_DEBUG, diff --git a/src/common/dpp.c b/src/common/dpp.c index 938e96248..b9b5d53aa 100644 --- a/src/common/dpp.c +++ b/src/common/dpp.c @@ -6301,7 +6301,6 @@ int dpp_configurator_get_key(const struct dpp_configurator *conf, char *buf, static int dpp_configurator_gen_kid(struct dpp_configurator *conf) { struct wpabuf *csign_pub = NULL; - u8 kid_hash[SHA256_MAC_LEN]; const u8 *addr[1]; size_t len[1]; int res; @@ -6315,7 +6314,7 @@ static int dpp_configurator_gen_kid(struct dpp_configurator *conf) /* kid = SHA256(ANSI X9.63 uncompressed C-sign-key) */ addr[0] = wpabuf_head(csign_pub); len[0] = wpabuf_len(csign_pub); - res = sha256_vector(1, addr, len, kid_hash); + res = sha256_vector(1, addr, len, conf->kid_hash); wpabuf_free(csign_pub); if (res < 0) { wpa_printf(MSG_DEBUG, @@ -6323,7 +6322,8 @@ static int dpp_configurator_gen_kid(struct dpp_configurator *conf) return -1; } - conf->kid = base64_url_encode(kid_hash, sizeof(kid_hash), NULL); + conf->kid = base64_url_encode(conf->kid_hash, sizeof(conf->kid_hash), + NULL); return conf->kid ? 0 : -1; } @@ -7167,6 +7167,23 @@ int dpp_configurator_from_backup(struct dpp_global *dpp, } +struct dpp_configurator * dpp_configurator_find_kid(struct dpp_global *dpp, + const u8 *kid) +{ + struct dpp_configurator *conf; + + if (!dpp) + return NULL; + + dl_list_for_each(conf, &dpp->configurator, + struct dpp_configurator, list) { + if (os_memcmp(conf->kid_hash, kid, SHA256_MAC_LEN) == 0) + return conf; + } + return NULL; +} + + static void dpp_controller_conn_status_result_wait_timeout(void *eloop_ctx, void *timeout_ctx); @@ -8010,6 +8027,44 @@ static int dpp_controller_rx_presence_announcement(struct dpp_connection *conn, } +static int dpp_controller_rx_reconfig_announcement(struct dpp_connection *conn, + const u8 *hdr, const u8 *buf, + size_t len) +{ + const u8 *csign_hash; + u16 csign_hash_len; + struct dpp_configurator *conf; + struct dpp_global *dpp = conn->ctrl->global; + + if (conn->auth) { + wpa_printf(MSG_DEBUG, + "DPP: Ignore Reconfig Announcement during ongoing Authentication"); + return -1; + } + + wpa_printf(MSG_DEBUG, "DPP: Reconfig Announcement"); + + csign_hash = dpp_get_attr(buf, len, DPP_ATTR_C_SIGN_KEY_HASH, + &csign_hash_len); + if (!csign_hash || csign_hash_len != SHA256_MAC_LEN) { + wpa_msg(dpp->msg_ctx, MSG_INFO, DPP_EVENT_FAIL + "Missing or invalid required Configurator C-sign key Hash attribute"); + return -1; + } + wpa_hexdump(MSG_MSGDUMP, "DPP: Configurator C-sign key Hash (kid)", + csign_hash, csign_hash_len); + conf = dpp_configurator_find_kid(dpp, csign_hash); + if (!conf) { + wpa_printf(MSG_DEBUG, + "DPP: No matching Configurator information found"); + return -1; + } + + /* TODO: Initiate Reconfig Authentication */ + return -1; +} + + static int dpp_controller_rx_action(struct dpp_connection *conn, const u8 *msg, size_t len) { @@ -8063,6 +8118,9 @@ static int dpp_controller_rx_action(struct dpp_connection *conn, const u8 *msg, case DPP_PA_PRESENCE_ANNOUNCEMENT: return dpp_controller_rx_presence_announcement(conn, msg, pos, end - pos); + case DPP_PA_RECONFIG_ANNOUNCEMENT: + return dpp_controller_rx_reconfig_announcement(conn, msg, pos, + end - pos); default: /* TODO: missing messages types */ wpa_printf(MSG_DEBUG, diff --git a/src/common/dpp.h b/src/common/dpp.h index 988c6fc2c..f560b34ef 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -317,6 +317,7 @@ struct dpp_configurator { unsigned int id; int own; EVP_PKEY *csign; + u8 kid_hash[SHA256_MAC_LEN]; char *kid; const struct dpp_curve_params *curve; }; @@ -601,6 +602,8 @@ int dpp_configurator_get_key_id(struct dpp_global *dpp, unsigned int id, char *buf, size_t buflen); int dpp_configurator_from_backup(struct dpp_global *dpp, struct dpp_asymmetric_key *key); +struct dpp_configurator * dpp_configurator_find_kid(struct dpp_global *dpp, + const u8 *kid); int dpp_relay_add_controller(struct dpp_global *dpp, struct dpp_relay_config *config); int dpp_relay_rx_action(struct dpp_global *dpp, const u8 *src, const u8 *hdr, diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index f74f1d695..a0e47a8b7 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -1779,6 +1779,47 @@ wpas_dpp_rx_presence_announcement(struct wpa_supplicant *wpa_s, const u8 *src, } } + +static void +wpas_dpp_rx_reconfig_announcement(struct wpa_supplicant *wpa_s, const u8 *src, + const u8 *hdr, const u8 *buf, size_t len, + unsigned int freq) +{ + const u8 *csign_hash; + u16 csign_hash_len; + struct dpp_configurator *conf; + + if (!wpa_s->dpp) + return; + + if (wpa_s->dpp_auth) { + wpa_printf(MSG_DEBUG, + "DPP: Ignore Reconfig Announcement during ongoing Authentication"); + return; + } + + wpa_printf(MSG_DEBUG, "DPP: Reconfig Announcement from " MACSTR, + MAC2STR(src)); + + csign_hash = dpp_get_attr(buf, len, DPP_ATTR_C_SIGN_KEY_HASH, + &csign_hash_len); + if (!csign_hash || csign_hash_len != SHA256_MAC_LEN) { + wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL + "Missing or invalid required Configurator C-sign key Hash attribute"); + return; + } + wpa_hexdump(MSG_MSGDUMP, "DPP: Configurator C-sign key Hash (kid)", + csign_hash, csign_hash_len); + conf = dpp_configurator_find_kid(wpa_s->dpp, csign_hash); + if (!conf) { + wpa_printf(MSG_DEBUG, + "DPP: No matching Configurator information found"); + return; + } + + /* TODO: Initiate Reconfig Authentication */ +} + #endif /* CONFIG_DPP2 */ @@ -2340,6 +2381,10 @@ void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src, wpas_dpp_rx_presence_announcement(wpa_s, src, hdr, buf, len, freq); break; + case DPP_PA_RECONFIG_ANNOUNCEMENT: + wpas_dpp_rx_reconfig_announcement(wpa_s, src, hdr, buf, len, + freq); + break; #endif /* CONFIG_DPP2 */ default: wpa_printf(MSG_DEBUG,