diff --git a/src/common/dpp.c b/src/common/dpp.c index 528bdb4a2..026c81e5e 100644 --- a/src/common/dpp.c +++ b/src/common/dpp.c @@ -4421,6 +4421,50 @@ fail: } +int dpp_configurator_own_config(struct dpp_authentication *auth, + const char *curve) +{ + struct wpabuf *conf_obj; + int ret = -1; + + if (!auth->conf) { + wpa_printf(MSG_DEBUG, "DPP: No configurator specified"); + return -1; + } + + if (!curve) { + auth->curve = &dpp_curves[0]; + } else { + auth->curve = dpp_get_curve_name(curve); + if (!auth->curve) { + wpa_printf(MSG_INFO, "DPP: Unsupported curve: %s", + curve); + return -1; + } + } + wpa_printf(MSG_DEBUG, + "DPP: Building own configuration/connector with curve %s", + auth->curve->name); + + auth->own_protocol_key = dpp_gen_keypair(auth->curve); + if (!auth->own_protocol_key) + return -1; + dpp_copy_netaccesskey(auth); + auth->peer_protocol_key = auth->own_protocol_key; + dpp_copy_csign(auth, auth->conf->csign); + + conf_obj = dpp_build_conf_obj(auth, 0); + if (!conf_obj) + goto fail; + ret = dpp_parse_conf_obj(auth, wpabuf_head(conf_obj), + wpabuf_len(conf_obj)); +fail: + wpabuf_free(conf_obj); + auth->peer_protocol_key = NULL; + return ret; +} + + static int dpp_compatible_netrole(const char *role1, const char *role2) { return (os_strcmp(role1, "sta") == 0 && os_strcmp(role2, "ap") == 0) || diff --git a/src/common/dpp.h b/src/common/dpp.h index 8aa78c51c..4a53c5d76 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -254,6 +254,8 @@ void dpp_configurator_free(struct dpp_configurator *conf); 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); int dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector, const u8 *net_access_key, size_t net_access_key_len, const u8 *csign_key, size_t csign_key_len, diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index bb9f26e97..710489db1 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -10256,6 +10256,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "DPP_CONFIGURATOR_REMOVE ", 24) == 0) { if (wpas_dpp_configurator_remove(wpa_s, buf + 24) < 0) reply_len = -1; + } else if (os_strncmp(buf, "DPP_CONFIGURATOR_SIGN ", 22) == 0) { + if (wpas_dpp_configurator_sign(wpa_s, buf + 22) < 0) + reply_len = -1; } else if (os_strncmp(buf, "DPP_PKEX_ADD ", 13) == 0) { int res; diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index 6361b17dc..7acb44fb2 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -980,48 +980,9 @@ static void wpas_dpp_process_config(struct wpa_supplicant *wpa_s, } -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, - const struct wpabuf *resp, u16 status_code) +static void wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s, + struct dpp_authentication *auth) { - struct wpa_supplicant *wpa_s = ctx; - const u8 *pos; - struct dpp_authentication *auth = wpa_s->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(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED); if (auth->ssid_len) wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s", @@ -1079,7 +1040,52 @@ static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token, } wpas_dpp_process_config(wpa_s, auth); +} + +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, + const struct wpabuf *resp, u16 status_code) +{ + struct wpa_supplicant *wpa_s = ctx; + const u8 *pos; + struct dpp_authentication *auth = wpa_s->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; + } + + wpas_dpp_handle_config_obj(wpa_s, auth); dpp_auth_deinit(wpa_s->dpp_auth); wpa_s->dpp_auth = NULL; return; @@ -1785,6 +1791,31 @@ int wpas_dpp_configurator_remove(struct wpa_supplicant *wpa_s, const char *id) } +int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, 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="); + wpas_dpp_set_configurator(wpa_s, auth, cmd); + + if (dpp_configurator_own_config(auth, curve) == 0) { + wpas_dpp_handle_config_obj(wpa_s, auth); + ret = 0; + } + + dpp_auth_deinit(auth); + os_free(curve); + + return ret; +} + + static void wpas_dpp_tx_introduction_status(struct wpa_supplicant *wpa_s, unsigned int freq, const u8 *dst, diff --git a/wpa_supplicant/dpp_supplicant.h b/wpa_supplicant/dpp_supplicant.h index ced86c1b6..05a466d55 100644 --- a/wpa_supplicant/dpp_supplicant.h +++ b/wpa_supplicant/dpp_supplicant.h @@ -27,6 +27,7 @@ void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src, const u8 *buf, size_t len, unsigned int freq); int wpas_dpp_configurator_add(struct wpa_supplicant *wpa_s, const char *cmd); int wpas_dpp_configurator_remove(struct wpa_supplicant *wpa_s, const char *id); +int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd); int wpas_dpp_pkex_add(struct wpa_supplicant *wpa_s, const char *cmd); int wpas_dpp_pkex_remove(struct wpa_supplicant *wpa_s, const char *id); int wpas_dpp_init(struct wpa_supplicant *wpa_s);