diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 3bba3aee3..0c372b965 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -3171,6 +3171,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, } 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_CONFIGURATOR_GET_KEY ", 25) == 0) { + reply_len = hostapd_dpp_configurator_get_key(hapd, + atoi(buf + 25), + reply, reply_size); } else if (os_strncmp(buf, "DPP_PKEX_ADD ", 13) == 0) { res = hostapd_dpp_pkex_add(hapd, buf + 12); if (res < 0) { diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c index 66835823a..e937d9c94 100644 --- a/hostapd/hostapd_cli.c +++ b/hostapd/hostapd_cli.c @@ -1436,6 +1436,13 @@ static int hostapd_cli_cmd_dpp_configurator_remove(struct wpa_ctrl *ctrl, } +static int hostapd_cli_cmd_dpp_configurator_get_key(struct wpa_ctrl *ctrl, + int argc, char *argv[]) +{ + return hostapd_cli_cmd(ctrl, "DPP_CONFIGURATOR_GET_KEY", 1, argc, argv); +} + + static int hostapd_cli_cmd_dpp_pkex_add(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -1623,6 +1630,9 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = { { "dpp_configurator_remove", hostapd_cli_cmd_dpp_configurator_remove, NULL, "*| = remove DPP configurator" }, + { "dpp_configurator_remove", hostapd_cli_cmd_dpp_configurator_get_key, + NULL, + " = Get DPP configurator's private key" }, { "dpp_pkex_add", hostapd_cli_cmd_dpp_pkex_add, NULL, "add PKEX code" }, { "dpp_pkex_remove", hostapd_cli_cmd_dpp_pkex_remove, NULL, diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index 0bebe5936..4d2b71ad8 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -1881,6 +1881,19 @@ int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd) } +int hostapd_dpp_configurator_get_key(struct hostapd_data *hapd, unsigned int id, + char *buf, size_t buflen) +{ + struct dpp_configurator *conf; + + conf = hostapd_dpp_configurator_get_id(hapd, id); + if (!conf) + return -1; + + return dpp_configurator_get_key(conf, buf, buflen); +} + + 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 c2c6200a0..3ef7c1456 100644 --- a/src/ap/dpp_hostapd.h +++ b/src/ap/dpp_hostapd.h @@ -30,6 +30,8 @@ void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok); 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_configurator_get_key(struct hostapd_data *hapd, unsigned int id, + char *buf, size_t buflen); 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 4e0bf3697..805507c63 100644 --- a/src/common/dpp.c +++ b/src/common/dpp.c @@ -5510,6 +5510,30 @@ void dpp_configurator_free(struct dpp_configurator *conf) } +int dpp_configurator_get_key(const struct dpp_configurator *conf, char *buf, + size_t buflen) +{ + EC_KEY *eckey; + int key_len, ret = -1; + unsigned char *key = NULL; + + if (!conf->csign) + return -1; + + eckey = EVP_PKEY_get1_EC_KEY(conf->csign); + if (!eckey) + return -1; + + key_len = i2d_ECPrivateKey(eckey, &key); + if (key_len > 0) + ret = wpa_snprintf_hex(buf, buflen, key, key_len); + + EC_KEY_free(eckey); + OPENSSL_free(key); + return ret; +} + + struct dpp_configurator * dpp_keygen_configurator(const char *curve, const u8 *privkey, size_t privkey_len) diff --git a/src/common/dpp.h b/src/common/dpp.h index b89b22cab..185a31c03 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -394,6 +394,8 @@ const u8 * dpp_get_attr(const u8 *buf, size_t len, u16 req_id, u16 *ret_len); int dpp_check_attrs(const u8 *buf, size_t len); int dpp_key_expired(const char *timestamp, os_time_t *expiry); const char * dpp_akm_str(enum dpp_akm akm); +int dpp_configurator_get_key(const struct dpp_configurator *conf, char *buf, + size_t buflen); void dpp_configurator_free(struct dpp_configurator *conf); struct dpp_configurator * dpp_keygen_configurator(const char *curve, const u8 *privkey, diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index a3aa3b634..23681dcbf 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -10576,6 +10576,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } 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_CONFIGURATOR_GET_KEY ", 25) == 0) { + reply_len = wpas_dpp_configurator_get_key(wpa_s, atoi(buf + 25), + reply, reply_size); } 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 57ba7bcbf..d14203ff9 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -2275,6 +2275,19 @@ int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd) } +int wpas_dpp_configurator_get_key(struct wpa_supplicant *wpa_s, unsigned int id, + char *buf, size_t buflen) +{ + struct dpp_configurator *conf; + + conf = dpp_configurator_get_id(wpa_s, id); + if (!conf) + return -1; + + return dpp_configurator_get_key(conf, buf, buflen); +} + + 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 0760b3648..9b539df79 100644 --- a/wpa_supplicant/dpp_supplicant.h +++ b/wpa_supplicant/dpp_supplicant.h @@ -28,6 +28,8 @@ void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src, 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_configurator_get_key(struct wpa_supplicant *wpa_s, unsigned int id, + char *buf, size_t buflen); 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); void wpas_dpp_stop(struct wpa_supplicant *wpa_s); diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 4f60890b3..de3367136 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -2948,6 +2948,13 @@ static int wpa_cli_cmd_dpp_configurator_remove(struct wpa_ctrl *ctrl, int argc, } +static int wpa_cli_cmd_dpp_configurator_get_key(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "DPP_CONFIGURATOR_GET_KEY", 1, argc, argv); +} + + static int wpa_cli_cmd_dpp_pkex_add(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -3604,6 +3611,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { { "dpp_configurator_remove", wpa_cli_cmd_dpp_configurator_remove, NULL, cli_cmd_flag_none, "*| = remove DPP configurator" }, + { "dpp_configurator_get_key", wpa_cli_cmd_dpp_configurator_get_key, + NULL, cli_cmd_flag_none, + " = Get DPP configurator's private key" }, { "dpp_pkex_add", wpa_cli_cmd_dpp_pkex_add, NULL, cli_cmd_flag_sensitive, "add PKEX code" },