DPP: Add DPP_CONFIGURATOR_SIGN to generate own connector
The DPP Configurator can use this new command to generate its own signed connector for the network that it manages. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
dc7fc09ccd
commit
f522bb2377
5 changed files with 122 additions and 41 deletions
|
@ -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)
|
static int dpp_compatible_netrole(const char *role1, const char *role2)
|
||||||
{
|
{
|
||||||
return (os_strcmp(role1, "sta") == 0 && os_strcmp(role2, "ap") == 0) ||
|
return (os_strcmp(role1, "sta") == 0 && os_strcmp(role2, "ap") == 0) ||
|
||||||
|
|
|
@ -254,6 +254,8 @@ void dpp_configurator_free(struct dpp_configurator *conf);
|
||||||
struct dpp_configurator *
|
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,
|
||||||
|
const char *curve);
|
||||||
int dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
|
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 *net_access_key, size_t net_access_key_len,
|
||||||
const u8 *csign_key, size_t csign_key_len,
|
const u8 *csign_key, size_t csign_key_len,
|
||||||
|
|
|
@ -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) {
|
} else if (os_strncmp(buf, "DPP_CONFIGURATOR_REMOVE ", 24) == 0) {
|
||||||
if (wpas_dpp_configurator_remove(wpa_s, buf + 24) < 0)
|
if (wpas_dpp_configurator_remove(wpa_s, buf + 24) < 0)
|
||||||
reply_len = -1;
|
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) {
|
} else if (os_strncmp(buf, "DPP_PKEX_ADD ", 13) == 0) {
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
|
|
@ -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,
|
static void wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s,
|
||||||
enum gas_query_result result,
|
struct dpp_authentication *auth)
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
|
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
|
||||||
if (auth->ssid_len)
|
if (auth->ssid_len)
|
||||||
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
|
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);
|
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);
|
dpp_auth_deinit(wpa_s->dpp_auth);
|
||||||
wpa_s->dpp_auth = NULL;
|
wpa_s->dpp_auth = NULL;
|
||||||
return;
|
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
|
static void
|
||||||
wpas_dpp_tx_introduction_status(struct wpa_supplicant *wpa_s,
|
wpas_dpp_tx_introduction_status(struct wpa_supplicant *wpa_s,
|
||||||
unsigned int freq, const u8 *dst,
|
unsigned int freq, const u8 *dst,
|
||||||
|
|
|
@ -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);
|
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_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_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_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_pkex_remove(struct wpa_supplicant *wpa_s, const char *id);
|
||||||
int wpas_dpp_init(struct wpa_supplicant *wpa_s);
|
int wpas_dpp_init(struct wpa_supplicant *wpa_s);
|
||||||
|
|
Loading…
Reference in a new issue