From a2588be82ce001cc79bf4906a1344c9dba317451 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 27 Nov 2017 12:43:40 +0200 Subject: [PATCH] DPP: Add DPP_CONFIGURATOR_SIGN support to hostapd Configurator signing its own Connector was previously supported only in wpa_supplicant. This commit extends that to hostapd to allow an AP acting as a Configurator to self-configure itself. Signed-off-by: Jouni Malinen --- hostapd/ctrl_iface.c | 3 + src/ap/dpp_hostapd.c | 114 ++++++++++++++++++++------------ src/ap/dpp_hostapd.h | 1 + src/common/dpp.c | 4 +- src/common/dpp.h | 2 +- wpa_supplicant/dpp_supplicant.c | 2 +- 6 files changed, 81 insertions(+), 45 deletions(-) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index a4d78b958..f24da81e8 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -3040,6 +3040,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, } else if (os_strncmp(buf, "DPP_CONFIGURATOR_REMOVE ", 24) == 0) { if (hostapd_dpp_configurator_remove(hapd, buf + 24) < 0) reply_len = -1; + } else if (os_strncmp(buf, "DPP_CONFIGURATOR_SIGN ", 22) == 0) { + if (hostapd_dpp_configurator_sign(hapd, buf + 22) < 0) + reply_len = -1; } else if (os_strncmp(buf, "DPP_PKEX_ADD ", 13) == 0) { res = hostapd_dpp_pkex_add(hapd, buf + 12); if (res < 0) { diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index 7e39a5244..8654ee9be 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -682,48 +682,9 @@ static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src, } -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, - const struct wpabuf *resp, u16 status_code) +static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd, + struct dpp_authentication *auth) { - struct hostapd_data *hapd = ctx; - const u8 *pos; - struct dpp_authentication *auth = hapd->dpp_auth; - - if (!auth || !auth->auth_success) { - wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress"); - return; - } - if (!resp || status_code != WLAN_STATUS_SUCCESS) { - wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed"); - goto fail; - } - - wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto", - adv_proto); - wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)", - resp); - - if (wpabuf_len(adv_proto) != 10 || - !(pos = wpabuf_head(adv_proto)) || - pos[0] != WLAN_EID_ADV_PROTO || - pos[1] != 8 || - pos[3] != WLAN_EID_VENDOR_SPECIFIC || - pos[4] != 5 || - WPA_GET_BE24(&pos[5]) != OUI_WFA || - pos[8] != 0x1a || - pos[9] != 1) { - wpa_printf(MSG_DEBUG, - "DPP: Not a DPP Advertisement Protocol ID"); - goto fail; - } - - if (dpp_conf_resp_rx(auth, resp) < 0) { - wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed"); - goto fail; - } - wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED); wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s", dpp_akm_str(auth->akm)); @@ -789,6 +750,52 @@ static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token, os_free(hex); } } +} + + +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, + const struct wpabuf *resp, u16 status_code) +{ + struct hostapd_data *hapd = ctx; + const u8 *pos; + struct dpp_authentication *auth = hapd->dpp_auth; + + if (!auth || !auth->auth_success) { + wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress"); + return; + } + if (!resp || status_code != WLAN_STATUS_SUCCESS) { + wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed"); + goto fail; + } + + wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto", + adv_proto); + wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)", + resp); + + if (wpabuf_len(adv_proto) != 10 || + !(pos = wpabuf_head(adv_proto)) || + pos[0] != WLAN_EID_ADV_PROTO || + pos[1] != 8 || + pos[3] != WLAN_EID_VENDOR_SPECIFIC || + pos[4] != 5 || + WPA_GET_BE24(&pos[5]) != OUI_WFA || + pos[8] != 0x1a || + pos[9] != 1) { + wpa_printf(MSG_DEBUG, + "DPP: Not a DPP Advertisement Protocol ID"); + goto fail; + } + + if (dpp_conf_resp_rx(auth, resp) < 0) { + wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed"); + goto fail; + } + + hostapd_dpp_handle_config_obj(hapd, auth); dpp_auth_deinit(hapd->dpp_auth); hapd->dpp_auth = NULL; return; @@ -1534,6 +1541,31 @@ int hostapd_dpp_configurator_remove(struct hostapd_data *hapd, const char *id) } +int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd) +{ + struct dpp_authentication *auth; + int ret = -1; + char *curve = NULL; + + auth = os_zalloc(sizeof(*auth)); + if (!auth) + return -1; + + curve = get_param(cmd, " curve="); + hostapd_dpp_set_configurator(hapd, auth, cmd); + + if (dpp_configurator_own_config(auth, curve, 1) == 0) { + hostapd_dpp_handle_config_obj(hapd, auth); + ret = 0; + } + + dpp_auth_deinit(auth); + os_free(curve); + + return ret; +} + + int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd) { struct dpp_bootstrap_info *own_bi; diff --git a/src/ap/dpp_hostapd.h b/src/ap/dpp_hostapd.h index bc710d49c..ecbdcf6f5 100644 --- a/src/ap/dpp_hostapd.h +++ b/src/ap/dpp_hostapd.h @@ -28,6 +28,7 @@ hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa, const u8 *query, size_t query_len); int hostapd_dpp_configurator_add(struct hostapd_data *hapd, const char *cmd); int hostapd_dpp_configurator_remove(struct hostapd_data *hapd, const char *id); +int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd); int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd); int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id); void hostapd_dpp_stop(struct hostapd_data *hapd); diff --git a/src/common/dpp.c b/src/common/dpp.c index a73c068e9..74cdddac7 100644 --- a/src/common/dpp.c +++ b/src/common/dpp.c @@ -5469,7 +5469,7 @@ fail: int dpp_configurator_own_config(struct dpp_authentication *auth, - const char *curve) + const char *curve, int ap) { struct wpabuf *conf_obj; int ret = -1; @@ -5500,7 +5500,7 @@ int dpp_configurator_own_config(struct dpp_authentication *auth, auth->peer_protocol_key = auth->own_protocol_key; dpp_copy_csign(auth, auth->conf->csign); - conf_obj = dpp_build_conf_obj(auth, 0); + conf_obj = dpp_build_conf_obj(auth, ap); if (!conf_obj) goto fail; ret = dpp_parse_conf_obj(auth, wpabuf_head(conf_obj), diff --git a/src/common/dpp.h b/src/common/dpp.h index 3c01728aa..c5806d96b 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -382,7 +382,7 @@ struct dpp_configurator * dpp_keygen_configurator(const char *curve, const u8 *privkey, size_t privkey_len); int dpp_configurator_own_config(struct dpp_authentication *auth, - const char *curve); + const char *curve, int ap); enum dpp_status_error dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector, const u8 *net_access_key, size_t net_access_key_len, diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index f54429446..13b5326d1 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -2176,7 +2176,7 @@ int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd) curve = get_param(cmd, " curve="); wpas_dpp_set_configurator(wpa_s, auth, cmd); - if (dpp_configurator_own_config(auth, curve) == 0) { + if (dpp_configurator_own_config(auth, curve, 0) == 0) { wpas_dpp_handle_config_obj(wpa_s, auth); ret = 0; }