From 7d9e3200544c96f0e976dfa4800ee2af086a5281 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 30 Jan 2020 23:56:31 +0200 Subject: [PATCH] DPP: Received Configurator backup processing Add local Configurator instance for each received Configurator backup. Signed-off-by: Jouni Malinen --- src/ap/dpp_hostapd.c | 30 ++++++++++ src/common/dpp.c | 99 ++++++++++++++++++++++++--------- src/common/dpp.h | 2 + src/common/wpa_ctrl.h | 1 + wpa_supplicant/dpp_supplicant.c | 28 ++++++++++ 5 files changed, 135 insertions(+), 25 deletions(-) diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index 48922516f..8e22c8ba6 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -762,6 +762,33 @@ static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd, } +static int hostapd_dpp_handle_key_pkg(struct hostapd_data *hapd, + struct dpp_asymmetric_key *key) +{ +#ifdef CONFIG_DPP2 + int res; + + if (!key) + return 0; + + wpa_printf(MSG_DEBUG, "DPP: Received Configurator backup"); + wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED); + + while (key) { + res = dpp_configurator_from_backup( + hapd->iface->interfaces->dpp, key); + if (res < 0) + return -1; + wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFIGURATOR_ID "%d", + res); + key = key->next; + } +#endif /* CONFIG_DPP2 */ + + return 0; +} + + static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token, enum gas_query_ap_result result, const struct wpabuf *adv_proto, @@ -806,6 +833,9 @@ static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token, } hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]); + if (hostapd_dpp_handle_key_pkg(hapd, auth->conf_key_pkg) < 0) + goto fail; + status = DPP_STATUS_OK; #ifdef CONFIG_TESTING_OPTIONS if (dpp_test == DPP_TEST_REJECT_CONFIG) { diff --git a/src/common/dpp.c b/src/common/dpp.c index 814adf0b0..abcd6bf28 100644 --- a/src/common/dpp.c +++ b/src/common/dpp.c @@ -7590,15 +7590,41 @@ int dpp_configurator_get_key(const struct dpp_configurator *conf, char *buf, } -struct dpp_configurator * -dpp_keygen_configurator(const char *curve, const u8 *privkey, - size_t privkey_len) +static int dpp_configurator_gen_kid(struct dpp_configurator *conf) { - 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; + + csign_pub = dpp_get_pubkey_point(conf->csign, 1); + if (!csign_pub) { + wpa_printf(MSG_INFO, "DPP: Failed to extract C-sign-key"); + return -1; + } + + /* 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); + wpabuf_free(csign_pub); + if (res < 0) { + wpa_printf(MSG_DEBUG, + "DPP: Failed to derive kid for C-sign-key"); + return -1; + } + + conf->kid = base64_url_encode(kid_hash, sizeof(kid_hash), NULL); + return conf->kid ? 0 : -1; +} + + +struct dpp_configurator * +dpp_keygen_configurator(const char *curve, const u8 *privkey, + size_t privkey_len) +{ + struct dpp_configurator *conf; conf = os_zalloc(sizeof(*conf)); if (!conf) @@ -7624,31 +7650,12 @@ dpp_keygen_configurator(const char *curve, const u8 *privkey, goto fail; conf->own = 1; - csign_pub = dpp_get_pubkey_point(conf->csign, 1); - if (!csign_pub) { - wpa_printf(MSG_INFO, "DPP: Failed to extract C-sign-key"); - goto fail; - } - - /* kid = SHA256(ANSI X9.63 uncompressed C-sign-key) */ - addr[0] = wpabuf_head(csign_pub); - len[0] = wpabuf_len(csign_pub); - if (sha256_vector(1, addr, len, kid_hash) < 0) { - wpa_printf(MSG_DEBUG, - "DPP: Failed to derive kid for C-sign-key"); - goto fail; - } - - conf->kid = base64_url_encode(kid_hash, sizeof(kid_hash), NULL); - if (!conf->kid) + if (dpp_configurator_gen_kid(conf) < 0) goto fail; -out: - wpabuf_free(csign_pub); return conf; fail: dpp_configurator_free(conf); - conf = NULL; - goto out; + return NULL; } @@ -10206,6 +10213,48 @@ int dpp_configurator_get_key_id(struct dpp_global *dpp, unsigned int id, #ifdef CONFIG_DPP2 +int dpp_configurator_from_backup(struct dpp_global *dpp, + struct dpp_asymmetric_key *key) +{ + struct dpp_configurator *conf; + const EC_KEY *eckey; + const EC_GROUP *group; + int nid; + const struct dpp_curve_params *curve; + + if (!key->csign) + return -1; + eckey = EVP_PKEY_get0_EC_KEY(key->csign); + if (!eckey) + return -1; + group = EC_KEY_get0_group(eckey); + if (!group) + return -1; + nid = EC_GROUP_get_curve_name(group); + curve = dpp_get_curve_nid(nid); + if (!curve) { + wpa_printf(MSG_INFO, "DPP: Unsupported group in c-sign-key"); + return -1; + } + + conf = os_zalloc(sizeof(*conf)); + if (!conf) + return -1; + conf->curve = curve; + conf->csign = key->csign; + key->csign = NULL; + conf->own = 1; + if (dpp_configurator_gen_kid(conf) < 0) { + dpp_configurator_free(conf); + return -1; + } + + conf->id = dpp_next_configurator_id(dpp); + dl_list_add(&dpp->configurator, &conf->list); + return conf->id; +} + + static void dpp_controller_conn_status_result_wait_timeout(void *eloop_ctx, void *timeout_ctx); diff --git a/src/common/dpp.h b/src/common/dpp.h index c8db9ab6a..c47a9b87c 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -566,6 +566,8 @@ 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, char *buf, size_t buflen); +int dpp_configurator_from_backup(struct dpp_global *dpp, + struct dpp_asymmetric_key *key); 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/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h index f03c698f1..48002be6c 100644 --- a/src/common/wpa_ctrl.h +++ b/src/common/wpa_ctrl.h @@ -179,6 +179,7 @@ extern "C" { #define DPP_EVENT_NET_ACCESS_KEY "DPP-NET-ACCESS-KEY " #define DPP_EVENT_MISSING_CONNECTOR "DPP-MISSING-CONNECTOR " #define DPP_EVENT_NETWORK_ID "DPP-NETWORK-ID " +#define DPP_EVENT_CONFIGURATOR_ID "DPP-CONFIGURATOR-ID " #define DPP_EVENT_RX "DPP-RX " #define DPP_EVENT_TX "DPP-TX " #define DPP_EVENT_TX_STATUS "DPP-TX-STATUS " diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index f147afd9d..0811ab300 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -1262,6 +1262,32 @@ static int wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s, } +static int wpas_dpp_handle_key_pkg(struct wpa_supplicant *wpa_s, + struct dpp_asymmetric_key *key) +{ +#ifdef CONFIG_DPP2 + int res; + + if (!key) + return 0; + + wpa_printf(MSG_DEBUG, "DPP: Received Configurator backup"); + wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED); + + while (key) { + res = dpp_configurator_from_backup(wpa_s->dpp, key); + if (res < 0) + return -1; + wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFIGURATOR_ID "%d", + res); + key = key->next; + } +#endif /* CONFIG_DPP2 */ + + return 0; +} + + static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token, enum gas_query_result result, const struct wpabuf *adv_proto, @@ -1318,6 +1344,8 @@ static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token, } if (auth->num_conf_obj) wpas_dpp_post_process_config(wpa_s, auth); + if (wpas_dpp_handle_key_pkg(wpa_s, auth->conf_key_pkg) < 0) + goto fail; status = DPP_STATUS_OK; #ifdef CONFIG_TESTING_OPTIONS -- 2.39.2