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 <jouni@qca.qualcomm.com>
This commit is contained in:
parent
7eb6bfb45d
commit
a2588be82c
6 changed files with 81 additions and 45 deletions
|
@ -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) {
|
} else if (os_strncmp(buf, "DPP_CONFIGURATOR_REMOVE ", 24) == 0) {
|
||||||
if (hostapd_dpp_configurator_remove(hapd, buf + 24) < 0)
|
if (hostapd_dpp_configurator_remove(hapd, buf + 24) < 0)
|
||||||
reply_len = -1;
|
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) {
|
} else if (os_strncmp(buf, "DPP_PKEX_ADD ", 13) == 0) {
|
||||||
res = hostapd_dpp_pkex_add(hapd, buf + 12);
|
res = hostapd_dpp_pkex_add(hapd, buf + 12);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
|
|
@ -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,
|
static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
|
||||||
enum gas_query_ap_result result,
|
struct dpp_authentication *auth)
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
|
wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
|
||||||
wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
|
wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
|
||||||
dpp_akm_str(auth->akm));
|
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);
|
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);
|
dpp_auth_deinit(hapd->dpp_auth);
|
||||||
hapd->dpp_auth = NULL;
|
hapd->dpp_auth = NULL;
|
||||||
return;
|
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)
|
int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
|
||||||
{
|
{
|
||||||
struct dpp_bootstrap_info *own_bi;
|
struct dpp_bootstrap_info *own_bi;
|
||||||
|
|
|
@ -28,6 +28,7 @@ hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
|
||||||
const u8 *query, size_t query_len);
|
const u8 *query, size_t query_len);
|
||||||
int hostapd_dpp_configurator_add(struct hostapd_data *hapd, const char *cmd);
|
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_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_add(struct hostapd_data *hapd, const char *cmd);
|
||||||
int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id);
|
int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id);
|
||||||
void hostapd_dpp_stop(struct hostapd_data *hapd);
|
void hostapd_dpp_stop(struct hostapd_data *hapd);
|
||||||
|
|
|
@ -5469,7 +5469,7 @@ fail:
|
||||||
|
|
||||||
|
|
||||||
int dpp_configurator_own_config(struct dpp_authentication *auth,
|
int dpp_configurator_own_config(struct dpp_authentication *auth,
|
||||||
const char *curve)
|
const char *curve, int ap)
|
||||||
{
|
{
|
||||||
struct wpabuf *conf_obj;
|
struct wpabuf *conf_obj;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
@ -5500,7 +5500,7 @@ int dpp_configurator_own_config(struct dpp_authentication *auth,
|
||||||
auth->peer_protocol_key = auth->own_protocol_key;
|
auth->peer_protocol_key = auth->own_protocol_key;
|
||||||
dpp_copy_csign(auth, auth->conf->csign);
|
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)
|
if (!conf_obj)
|
||||||
goto fail;
|
goto fail;
|
||||||
ret = dpp_parse_conf_obj(auth, wpabuf_head(conf_obj),
|
ret = dpp_parse_conf_obj(auth, wpabuf_head(conf_obj),
|
||||||
|
|
|
@ -382,7 +382,7 @@ struct dpp_configurator *
|
||||||
dpp_keygen_configurator(const char *curve, const u8 *privkey,
|
dpp_keygen_configurator(const char *curve, const u8 *privkey,
|
||||||
size_t privkey_len);
|
size_t privkey_len);
|
||||||
int dpp_configurator_own_config(struct dpp_authentication *auth,
|
int dpp_configurator_own_config(struct dpp_authentication *auth,
|
||||||
const char *curve);
|
const char *curve, int ap);
|
||||||
enum dpp_status_error
|
enum dpp_status_error
|
||||||
dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
|
dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
|
||||||
const u8 *net_access_key, size_t net_access_key_len,
|
const u8 *net_access_key, size_t net_access_key_len,
|
||||||
|
|
|
@ -2176,7 +2176,7 @@ int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd)
|
||||||
curve = get_param(cmd, " curve=");
|
curve = get_param(cmd, " curve=");
|
||||||
wpas_dpp_set_configurator(wpa_s, auth, cmd);
|
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);
|
wpas_dpp_handle_config_obj(wpa_s, auth);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue