mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-11-25 00:38:24 -05:00
DPP2: Reconfig Authentication Request generation and transmission
Extend Configurator functionality to sign a special Connector for reconfiguration and reply with Reconfig Authentication Request frame when Reconfig Announcement frame is received with a matching C-sign key hash value. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
66ac616cdb
commit
3774b6bd03
@ -26,6 +26,10 @@ static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
|
|||||||
static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
|
static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
|
||||||
static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
|
static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
|
||||||
static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
|
static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
|
||||||
|
#ifdef CONFIG_DPP2
|
||||||
|
static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
|
||||||
|
void *timeout_ctx);
|
||||||
|
#endif /* CONFIG_DPP2 */
|
||||||
|
|
||||||
static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||||
|
|
||||||
@ -237,6 +241,10 @@ void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
|
|||||||
hapd, NULL);
|
hapd, NULL);
|
||||||
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
|
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
|
||||||
NULL);
|
NULL);
|
||||||
|
#ifdef CONFIG_DPP2
|
||||||
|
eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
|
||||||
|
hapd, NULL);
|
||||||
|
#endif /* CONFIG_DPP2 */
|
||||||
hostapd_drv_send_action_cancel_wait(hapd);
|
hostapd_drv_send_action_cancel_wait(hapd);
|
||||||
dpp_auth_deinit(hapd->dpp_auth);
|
dpp_auth_deinit(hapd->dpp_auth);
|
||||||
hapd->dpp_auth = NULL;
|
hapd->dpp_auth = NULL;
|
||||||
@ -539,6 +547,10 @@ int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
|
|||||||
hapd, NULL);
|
hapd, NULL);
|
||||||
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
|
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
|
||||||
NULL);
|
NULL);
|
||||||
|
#ifdef CONFIG_DPP2
|
||||||
|
eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
|
||||||
|
hapd, NULL);
|
||||||
|
#endif /* CONFIG_DPP2 */
|
||||||
hostapd_drv_send_action_cancel_wait(hapd);
|
hostapd_drv_send_action_cancel_wait(hapd);
|
||||||
dpp_auth_deinit(hapd->dpp_auth);
|
dpp_auth_deinit(hapd->dpp_auth);
|
||||||
}
|
}
|
||||||
@ -1198,6 +1210,22 @@ hostapd_dpp_rx_presence_announcement(struct hostapd_data *hapd, const u8 *src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
|
||||||
|
void *timeout_ctx)
|
||||||
|
{
|
||||||
|
struct hostapd_data *hapd = eloop_ctx;
|
||||||
|
struct dpp_authentication *auth = hapd->dpp_auth;
|
||||||
|
|
||||||
|
if (!auth)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "DPP: Reconfig Reply wait timeout");
|
||||||
|
hostapd_dpp_listen_stop(hapd);
|
||||||
|
dpp_auth_deinit(auth);
|
||||||
|
hapd->dpp_auth = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src,
|
hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src,
|
||||||
const u8 *hdr, const u8 *buf, size_t len,
|
const u8 *hdr, const u8 *buf, size_t len,
|
||||||
@ -1206,6 +1234,8 @@ hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src,
|
|||||||
const u8 *csign_hash;
|
const u8 *csign_hash;
|
||||||
u16 csign_hash_len;
|
u16 csign_hash_len;
|
||||||
struct dpp_configurator *conf;
|
struct dpp_configurator *conf;
|
||||||
|
struct dpp_authentication *auth;
|
||||||
|
unsigned int wait_time, max_wait_time;
|
||||||
|
|
||||||
if (hapd->dpp_auth) {
|
if (hapd->dpp_auth) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
@ -1233,7 +1263,41 @@ hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Initiate Reconfig Authentication */
|
auth = dpp_reconfig_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
|
||||||
|
conf, freq);
|
||||||
|
if (!auth)
|
||||||
|
return;
|
||||||
|
hostapd_dpp_set_testing_options(hapd, auth);
|
||||||
|
if (dpp_set_configurator(auth, hapd->dpp_configurator_params) < 0) {
|
||||||
|
dpp_auth_deinit(auth);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
|
||||||
|
hapd->dpp_auth = auth;
|
||||||
|
|
||||||
|
hapd->dpp_in_response_listen = 0;
|
||||||
|
hapd->dpp_auth_ok_on_ack = 0;
|
||||||
|
wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
|
||||||
|
max_wait_time = hapd->dpp_resp_wait_time ?
|
||||||
|
hapd->dpp_resp_wait_time : 2000;
|
||||||
|
if (wait_time > max_wait_time)
|
||||||
|
wait_time = max_wait_time;
|
||||||
|
wait_time += 10; /* give the driver some extra time to complete */
|
||||||
|
eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
|
||||||
|
hostapd_dpp_reconfig_reply_wait_timeout,
|
||||||
|
hapd, NULL);
|
||||||
|
wait_time -= 10;
|
||||||
|
|
||||||
|
wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
|
||||||
|
" freq=%u type=%d",
|
||||||
|
MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_REQ);
|
||||||
|
if (hostapd_drv_send_action(hapd, freq, wait_time, src,
|
||||||
|
wpabuf_head(auth->reconfig_req_msg),
|
||||||
|
wpabuf_len(auth->reconfig_req_msg)) < 0) {
|
||||||
|
dpp_auth_deinit(hapd->dpp_auth);
|
||||||
|
hapd->dpp_auth = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_DPP2 */
|
#endif /* CONFIG_DPP2 */
|
||||||
@ -1771,6 +1835,8 @@ void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
|
|||||||
eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
|
eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
|
||||||
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
|
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
|
||||||
#ifdef CONFIG_DPP2
|
#ifdef CONFIG_DPP2
|
||||||
|
eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
|
||||||
|
hapd, NULL);
|
||||||
if (ok && auth->peer_version >= 2 &&
|
if (ok && auth->peer_version >= 2 &&
|
||||||
auth->conf_resp_status == DPP_STATUS_OK) {
|
auth->conf_resp_status == DPP_STATUS_OK) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
|
wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
|
||||||
@ -2015,6 +2081,8 @@ void hostapd_dpp_deinit(struct hostapd_data *hapd)
|
|||||||
eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
|
eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
|
||||||
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
|
eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
|
||||||
#ifdef CONFIG_DPP2
|
#ifdef CONFIG_DPP2
|
||||||
|
eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
|
||||||
|
hapd, NULL);
|
||||||
eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
|
eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
|
||||||
NULL);
|
NULL);
|
||||||
eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
|
eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
|
||||||
|
@ -989,10 +989,9 @@ static int dpp_channel_local_list(struct dpp_authentication *auth,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int dpp_prepare_channel_list(struct dpp_authentication *auth,
|
int dpp_prepare_channel_list(struct dpp_authentication *auth,
|
||||||
unsigned int neg_freq,
|
unsigned int neg_freq,
|
||||||
struct hostapd_hw_modes *own_modes,
|
struct hostapd_hw_modes *own_modes, u16 num_modes)
|
||||||
u16 num_modes)
|
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
char freqs[DPP_BOOTSTRAP_MAX_FREQ * 6 + 10], *pos, *end;
|
char freqs[DPP_BOOTSTRAP_MAX_FREQ * 6 + 10], *pos, *end;
|
||||||
@ -2339,7 +2338,7 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
if (!auth->initiator || !auth->peer_bi) {
|
if (!auth->initiator || !auth->peer_bi || auth->reconfig) {
|
||||||
dpp_auth_fail(auth, "Unexpected Authentication Response");
|
dpp_auth_fail(auth, "Unexpected Authentication Response");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -2741,7 +2740,8 @@ int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr,
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
if (auth->initiator || !auth->own_bi || !auth->waiting_auth_conf) {
|
if (auth->initiator || !auth->own_bi || !auth->waiting_auth_conf ||
|
||||||
|
auth->reconfig) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"DPP: initiator=%d own_bi=%d waiting_auth_conf=%d",
|
"DPP: initiator=%d own_bi=%d waiting_auth_conf=%d",
|
||||||
auth->initiator, !!auth->own_bi,
|
auth->initiator, !!auth->own_bi,
|
||||||
@ -3195,7 +3195,7 @@ int dpp_set_configurator(struct dpp_authentication *auth, const char *cmd)
|
|||||||
wpa_printf(MSG_DEBUG, "DPP: Set configurator parameters: %s", cmd);
|
wpa_printf(MSG_DEBUG, "DPP: Set configurator parameters: %s", cmd);
|
||||||
|
|
||||||
pos = os_strstr(cmd, " configurator=");
|
pos = os_strstr(cmd, " configurator=");
|
||||||
if (pos) {
|
if (!auth->conf && pos) {
|
||||||
pos += 14;
|
pos += 14;
|
||||||
auth->conf = dpp_configurator_get_id(auth->global, atoi(pos));
|
auth->conf = dpp_configurator_get_id(auth->global, atoi(pos));
|
||||||
if (!auth->conf) {
|
if (!auth->conf) {
|
||||||
@ -3258,6 +3258,7 @@ void dpp_auth_deinit(struct dpp_authentication *auth)
|
|||||||
wpabuf_free(auth->req_msg);
|
wpabuf_free(auth->req_msg);
|
||||||
wpabuf_free(auth->resp_msg);
|
wpabuf_free(auth->resp_msg);
|
||||||
wpabuf_free(auth->conf_req);
|
wpabuf_free(auth->conf_req);
|
||||||
|
wpabuf_free(auth->reconfig_req_msg);
|
||||||
for (i = 0; i < auth->num_conf_obj; i++) {
|
for (i = 0; i < auth->num_conf_obj; i++) {
|
||||||
struct dpp_config_obj *conf = &auth->conf_obj[i];
|
struct dpp_config_obj *conf = &auth->conf_obj[i];
|
||||||
|
|
||||||
@ -3324,7 +3325,7 @@ dpp_build_conf_start(struct dpp_authentication *auth,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int dpp_build_jwk(struct wpabuf *buf, const char *name, EVP_PKEY *key,
|
int dpp_build_jwk(struct wpabuf *buf, const char *name, EVP_PKEY *key,
|
||||||
const char *kid, const struct dpp_curve_params *curve)
|
const char *kid, const struct dpp_curve_params *curve)
|
||||||
{
|
{
|
||||||
struct wpabuf *pub;
|
struct wpabuf *pub;
|
||||||
@ -6270,6 +6271,8 @@ void dpp_configurator_free(struct dpp_configurator *conf)
|
|||||||
return;
|
return;
|
||||||
EVP_PKEY_free(conf->csign);
|
EVP_PKEY_free(conf->csign);
|
||||||
os_free(conf->kid);
|
os_free(conf->kid);
|
||||||
|
os_free(conf->connector);
|
||||||
|
EVP_PKEY_free(conf->connector_key);
|
||||||
os_free(conf);
|
os_free(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +235,7 @@ struct dpp_authentication {
|
|||||||
struct dpp_bootstrap_info *tmp_own_bi;
|
struct dpp_bootstrap_info *tmp_own_bi;
|
||||||
u8 waiting_pubkey_hash[SHA256_MAC_LEN];
|
u8 waiting_pubkey_hash[SHA256_MAC_LEN];
|
||||||
int response_pending;
|
int response_pending;
|
||||||
|
int reconfig;
|
||||||
enum dpp_status_error auth_resp_status;
|
enum dpp_status_error auth_resp_status;
|
||||||
enum dpp_status_error conf_resp_status;
|
enum dpp_status_error conf_resp_status;
|
||||||
u8 peer_mac_addr[ETH_ALEN];
|
u8 peer_mac_addr[ETH_ALEN];
|
||||||
@ -247,6 +248,7 @@ struct dpp_authentication {
|
|||||||
EVP_PKEY *peer_protocol_key;
|
EVP_PKEY *peer_protocol_key;
|
||||||
struct wpabuf *req_msg;
|
struct wpabuf *req_msg;
|
||||||
struct wpabuf *resp_msg;
|
struct wpabuf *resp_msg;
|
||||||
|
struct wpabuf *reconfig_req_msg;
|
||||||
/* Intersection of possible frequencies for initiating DPP
|
/* Intersection of possible frequencies for initiating DPP
|
||||||
* Authentication exchange */
|
* Authentication exchange */
|
||||||
unsigned int freq[DPP_BOOTSTRAP_MAX_FREQ];
|
unsigned int freq[DPP_BOOTSTRAP_MAX_FREQ];
|
||||||
@ -304,6 +306,7 @@ struct dpp_authentication {
|
|||||||
int conn_status_requested;
|
int conn_status_requested;
|
||||||
int akm_use_selector;
|
int akm_use_selector;
|
||||||
int configurator_set;
|
int configurator_set;
|
||||||
|
u8 transaction_id;
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
char *config_obj_override;
|
char *config_obj_override;
|
||||||
char *discovery_override;
|
char *discovery_override;
|
||||||
@ -320,6 +323,8 @@ struct dpp_configurator {
|
|||||||
u8 kid_hash[SHA256_MAC_LEN];
|
u8 kid_hash[SHA256_MAC_LEN];
|
||||||
char *kid;
|
char *kid;
|
||||||
const struct dpp_curve_params *curve;
|
const struct dpp_curve_params *curve;
|
||||||
|
char *connector; /* own Connector for reconfiguration */
|
||||||
|
EVP_PKEY *connector_key;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dpp_introduction {
|
struct dpp_introduction {
|
||||||
@ -633,6 +638,9 @@ void dpp_global_deinit(struct dpp_global *dpp);
|
|||||||
|
|
||||||
struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key,
|
struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key,
|
||||||
size_t csign_key_len);
|
size_t csign_key_len);
|
||||||
|
struct dpp_authentication *
|
||||||
|
dpp_reconfig_init(struct dpp_global *dpp, void *msg_ctx,
|
||||||
|
struct dpp_configurator *conf, unsigned int freq);
|
||||||
|
|
||||||
#endif /* CONFIG_DPP */
|
#endif /* CONFIG_DPP */
|
||||||
#endif /* DPP_H */
|
#endif /* DPP_H */
|
||||||
|
@ -36,6 +36,11 @@ struct wpabuf * dpp_build_conn_status(enum dpp_status_error result,
|
|||||||
struct json_token * dpp_parse_own_connector(const char *own_connector);
|
struct json_token * dpp_parse_own_connector(const char *own_connector);
|
||||||
int dpp_connector_match_groups(struct json_token *own_root,
|
int dpp_connector_match_groups(struct json_token *own_root,
|
||||||
struct json_token *peer_root, bool reconfig);
|
struct json_token *peer_root, bool reconfig);
|
||||||
|
int dpp_build_jwk(struct wpabuf *buf, const char *name, EVP_PKEY *key,
|
||||||
|
const char *kid, const struct dpp_curve_params *curve);
|
||||||
|
int dpp_prepare_channel_list(struct dpp_authentication *auth,
|
||||||
|
unsigned int neg_freq,
|
||||||
|
struct hostapd_hw_modes *own_modes, u16 num_modes);
|
||||||
|
|
||||||
/* dpp_crypto.c */
|
/* dpp_crypto.c */
|
||||||
|
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
#include "utils/includes.h"
|
#include "utils/includes.h"
|
||||||
|
|
||||||
#include "utils/common.h"
|
#include "utils/common.h"
|
||||||
|
#include "utils/json.h"
|
||||||
#include "crypto/crypto.h"
|
#include "crypto/crypto.h"
|
||||||
|
#include "crypto/random.h"
|
||||||
#include "dpp.h"
|
#include "dpp.h"
|
||||||
#include "dpp_i.h"
|
#include "dpp_i.h"
|
||||||
|
|
||||||
@ -73,4 +75,136 @@ struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key,
|
|||||||
"DPP: Reconfig Announcement frame attributes", msg);
|
"DPP: Reconfig Announcement frame attributes", msg);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct wpabuf * dpp_reconfig_build_req(struct dpp_authentication *auth)
|
||||||
|
{
|
||||||
|
struct wpabuf *msg;
|
||||||
|
size_t attr_len;
|
||||||
|
|
||||||
|
/* Build DPP Reconfig Authentication Request frame attributes */
|
||||||
|
attr_len = 4 + 1 + 4 + 1 + 4 + os_strlen(auth->conf->connector) +
|
||||||
|
4 + auth->curve->nonce_len;
|
||||||
|
msg = dpp_alloc_msg(DPP_PA_RECONFIG_AUTH_REQ, attr_len);
|
||||||
|
if (!msg)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Transaction ID */
|
||||||
|
wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
|
||||||
|
wpabuf_put_le16(msg, 1);
|
||||||
|
wpabuf_put_u8(msg, auth->transaction_id);
|
||||||
|
|
||||||
|
/* Protocol Version */
|
||||||
|
wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
|
||||||
|
wpabuf_put_le16(msg, 1);
|
||||||
|
wpabuf_put_u8(msg, DPP_VERSION);
|
||||||
|
|
||||||
|
/* DPP Connector */
|
||||||
|
wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
|
||||||
|
wpabuf_put_le16(msg, os_strlen(auth->conf->connector));
|
||||||
|
wpabuf_put_str(msg, auth->conf->connector);
|
||||||
|
|
||||||
|
/* I-nonce */
|
||||||
|
wpabuf_put_le16(msg, DPP_ATTR_I_NONCE);
|
||||||
|
wpabuf_put_le16(msg, auth->curve->nonce_len);
|
||||||
|
wpabuf_put_data(msg, auth->i_nonce, auth->curve->nonce_len);
|
||||||
|
|
||||||
|
wpa_hexdump_buf(MSG_DEBUG,
|
||||||
|
"DPP: Reconfig Authentication Request frame attributes",
|
||||||
|
msg);
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int dpp_configurator_build_own_connector(struct dpp_configurator *conf)
|
||||||
|
{
|
||||||
|
struct wpabuf *dppcon = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (conf->connector)
|
||||||
|
return 0; /* already generated */
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"DPP: Sign own Configurator Connector for reconfiguration with curve %s",
|
||||||
|
conf->curve->name);
|
||||||
|
conf->connector_key = dpp_gen_keypair(conf->curve);
|
||||||
|
if (!conf->connector_key)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* Connector (JSON dppCon object) */
|
||||||
|
dppcon = wpabuf_alloc(1000 + 2 * conf->curve->prime_len * 4 / 3);
|
||||||
|
if (!dppcon)
|
||||||
|
goto fail;
|
||||||
|
json_start_object(dppcon, NULL);
|
||||||
|
json_start_array(dppcon, "groups");
|
||||||
|
json_start_object(dppcon, NULL);
|
||||||
|
json_add_string(dppcon, "groupId", "*");
|
||||||
|
json_value_sep(dppcon);
|
||||||
|
json_add_string(dppcon, "netRole", "configurator");
|
||||||
|
json_end_object(dppcon);
|
||||||
|
json_end_array(dppcon);
|
||||||
|
json_value_sep(dppcon);
|
||||||
|
if (dpp_build_jwk(dppcon, "netAccessKey", conf->connector_key, NULL,
|
||||||
|
conf->curve) < 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "DPP: Failed to build netAccessKey JWK");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
json_end_object(dppcon);
|
||||||
|
wpa_printf(MSG_DEBUG, "DPP: dppCon: %s",
|
||||||
|
(const char *) wpabuf_head(dppcon));
|
||||||
|
|
||||||
|
conf->connector = dpp_sign_connector(conf, dppcon);
|
||||||
|
if (!conf->connector)
|
||||||
|
goto fail;
|
||||||
|
wpa_printf(MSG_DEBUG, "DPP: signedConnector: %s", conf->connector);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
fail:
|
||||||
|
wpabuf_free(dppcon);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct dpp_authentication *
|
||||||
|
dpp_reconfig_init(struct dpp_global *dpp, void *msg_ctx,
|
||||||
|
struct dpp_configurator *conf, unsigned int freq)
|
||||||
|
{
|
||||||
|
struct dpp_authentication *auth;
|
||||||
|
|
||||||
|
auth = dpp_alloc_auth(dpp, msg_ctx);
|
||||||
|
if (!auth)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
auth->conf = conf;
|
||||||
|
auth->reconfig = 1;
|
||||||
|
auth->initiator = 1;
|
||||||
|
auth->waiting_auth_resp = 1;
|
||||||
|
auth->allowed_roles = DPP_CAPAB_CONFIGURATOR;
|
||||||
|
auth->configurator = 1;
|
||||||
|
auth->curve = conf->curve;
|
||||||
|
auth->transaction_id = 1;
|
||||||
|
if (dpp_prepare_channel_list(auth, freq, NULL, 0) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (dpp_configurator_build_own_connector(conf) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (random_get_bytes(auth->i_nonce, auth->curve->nonce_len)) {
|
||||||
|
wpa_printf(MSG_ERROR, "DPP: Failed to generate I-nonce");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
auth->reconfig_req_msg = dpp_reconfig_build_req(auth);
|
||||||
|
if (!auth->reconfig_req_msg)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
out:
|
||||||
|
return auth;
|
||||||
|
fail:
|
||||||
|
dpp_auth_deinit(auth);
|
||||||
|
auth = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_DPP2 */
|
#endif /* CONFIG_DPP2 */
|
||||||
|
@ -45,6 +45,10 @@ wpas_dpp_tx_pkex_status(struct wpa_supplicant *wpa_s,
|
|||||||
const u8 *src, const u8 *bssid,
|
const u8 *src, const u8 *bssid,
|
||||||
const u8 *data, size_t data_len,
|
const u8 *data, size_t data_len,
|
||||||
enum offchannel_send_action_result result);
|
enum offchannel_send_action_result result);
|
||||||
|
#ifdef CONFIG_DPP2
|
||||||
|
static void wpas_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
|
||||||
|
void *timeout_ctx);
|
||||||
|
#endif /* CONFIG_DPP2 */
|
||||||
|
|
||||||
static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||||
|
|
||||||
@ -246,6 +250,35 @@ static void wpas_dpp_try_to_connect(struct wpa_supplicant *wpa_s)
|
|||||||
|
|
||||||
#ifdef CONFIG_DPP2
|
#ifdef CONFIG_DPP2
|
||||||
|
|
||||||
|
static void wpas_dpp_stop_listen_for_tx(struct wpa_supplicant *wpa_s,
|
||||||
|
unsigned int freq,
|
||||||
|
unsigned int wait_time)
|
||||||
|
{
|
||||||
|
struct os_reltime now, res;
|
||||||
|
unsigned int remaining;
|
||||||
|
|
||||||
|
if (!wpa_s->dpp_listen_freq)
|
||||||
|
return;
|
||||||
|
|
||||||
|
os_get_reltime(&now);
|
||||||
|
if (os_reltime_before(&now, &wpa_s->dpp_listen_end)) {
|
||||||
|
os_reltime_sub(&wpa_s->dpp_listen_end, &now, &res);
|
||||||
|
remaining = res.sec * 1000 + res.usec / 1000;
|
||||||
|
} else {
|
||||||
|
remaining = 0;
|
||||||
|
}
|
||||||
|
if (wpa_s->dpp_listen_freq == freq && remaining > wait_time)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"DPP: Stop listen on %u MHz ending in %u ms to allow immediate TX on %u MHz for %u ms",
|
||||||
|
wpa_s->dpp_listen_freq, remaining, freq, wait_time);
|
||||||
|
wpas_dpp_listen_stop(wpa_s);
|
||||||
|
|
||||||
|
/* TODO: Restart listen in some cases after TX? */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void wpas_dpp_conn_status_result_timeout(void *eloop_ctx,
|
static void wpas_dpp_conn_status_result_timeout(void *eloop_ctx,
|
||||||
void *timeout_ctx)
|
void *timeout_ctx)
|
||||||
{
|
{
|
||||||
@ -434,6 +467,10 @@ static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
|
|||||||
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
|
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
|
||||||
eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s,
|
eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s,
|
||||||
NULL);
|
NULL);
|
||||||
|
#ifdef CONFIG_DPP2
|
||||||
|
eloop_cancel_timeout(wpas_dpp_reconfig_reply_wait_timeout,
|
||||||
|
wpa_s, NULL);
|
||||||
|
#endif /* CONFIG_DPP2 */
|
||||||
offchannel_send_action_done(wpa_s);
|
offchannel_send_action_done(wpa_s);
|
||||||
dpp_auth_deinit(wpa_s->dpp_auth);
|
dpp_auth_deinit(wpa_s->dpp_auth);
|
||||||
wpa_s->dpp_auth = NULL;
|
wpa_s->dpp_auth = NULL;
|
||||||
@ -766,6 +803,10 @@ int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd)
|
|||||||
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
|
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
|
||||||
eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s,
|
eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s,
|
||||||
NULL);
|
NULL);
|
||||||
|
#ifdef CONFIG_DPP2
|
||||||
|
eloop_cancel_timeout(wpas_dpp_reconfig_reply_wait_timeout,
|
||||||
|
wpa_s, NULL);
|
||||||
|
#endif /* CONFIG_DPP2 */
|
||||||
offchannel_send_action_done(wpa_s);
|
offchannel_send_action_done(wpa_s);
|
||||||
dpp_auth_deinit(wpa_s->dpp_auth);
|
dpp_auth_deinit(wpa_s->dpp_auth);
|
||||||
wpa_s->dpp_auth = NULL;
|
wpa_s->dpp_auth = NULL;
|
||||||
@ -1780,6 +1821,23 @@ wpas_dpp_rx_presence_announcement(struct wpa_supplicant *wpa_s, const u8 *src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wpas_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
|
||||||
|
void *timeout_ctx)
|
||||||
|
{
|
||||||
|
struct wpa_supplicant *wpa_s = eloop_ctx;
|
||||||
|
struct dpp_authentication *auth = wpa_s->dpp_auth;
|
||||||
|
|
||||||
|
if (!auth)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "DPP: Reconfig Reply wait timeout");
|
||||||
|
offchannel_send_action_done(wpa_s);
|
||||||
|
wpas_dpp_listen_stop(wpa_s);
|
||||||
|
dpp_auth_deinit(auth);
|
||||||
|
wpa_s->dpp_auth = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wpas_dpp_rx_reconfig_announcement(struct wpa_supplicant *wpa_s, const u8 *src,
|
wpas_dpp_rx_reconfig_announcement(struct wpa_supplicant *wpa_s, const u8 *src,
|
||||||
const u8 *hdr, const u8 *buf, size_t len,
|
const u8 *hdr, const u8 *buf, size_t len,
|
||||||
@ -1788,6 +1846,8 @@ wpas_dpp_rx_reconfig_announcement(struct wpa_supplicant *wpa_s, const u8 *src,
|
|||||||
const u8 *csign_hash;
|
const u8 *csign_hash;
|
||||||
u16 csign_hash_len;
|
u16 csign_hash_len;
|
||||||
struct dpp_configurator *conf;
|
struct dpp_configurator *conf;
|
||||||
|
struct dpp_authentication *auth;
|
||||||
|
unsigned int wait_time, max_wait_time;
|
||||||
|
|
||||||
if (!wpa_s->dpp)
|
if (!wpa_s->dpp)
|
||||||
return;
|
return;
|
||||||
@ -1817,7 +1877,42 @@ wpas_dpp_rx_reconfig_announcement(struct wpa_supplicant *wpa_s, const u8 *src,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Initiate Reconfig Authentication */
|
auth = dpp_reconfig_init(wpa_s->dpp, wpa_s, conf, freq);
|
||||||
|
if (!auth)
|
||||||
|
return;
|
||||||
|
wpas_dpp_set_testing_options(wpa_s, auth);
|
||||||
|
if (dpp_set_configurator(auth, wpa_s->dpp_configurator_params) < 0) {
|
||||||
|
dpp_auth_deinit(auth);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
|
||||||
|
wpa_s->dpp_auth = auth;
|
||||||
|
|
||||||
|
wpa_s->dpp_in_response_listen = 0;
|
||||||
|
wpa_s->dpp_auth_ok_on_ack = 0;
|
||||||
|
wait_time = wpa_s->max_remain_on_chan;
|
||||||
|
max_wait_time = wpa_s->dpp_resp_wait_time ?
|
||||||
|
wpa_s->dpp_resp_wait_time : 2000;
|
||||||
|
if (wait_time > max_wait_time)
|
||||||
|
wait_time = max_wait_time;
|
||||||
|
wait_time += 10; /* give the driver some extra time to complete */
|
||||||
|
eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
|
||||||
|
wpas_dpp_reconfig_reply_wait_timeout,
|
||||||
|
wpa_s, NULL);
|
||||||
|
wait_time -= 10;
|
||||||
|
|
||||||
|
wpas_dpp_stop_listen_for_tx(wpa_s, freq, wait_time);
|
||||||
|
|
||||||
|
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
|
||||||
|
MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_REQ);
|
||||||
|
if (offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr, broadcast,
|
||||||
|
wpabuf_head(auth->reconfig_req_msg),
|
||||||
|
wpabuf_len(auth->reconfig_req_msg),
|
||||||
|
wait_time, wpas_dpp_tx_status, 0) < 0) {
|
||||||
|
dpp_auth_deinit(wpa_s->dpp_auth);
|
||||||
|
wpa_s->dpp_auth = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_DPP2 */
|
#endif /* CONFIG_DPP2 */
|
||||||
@ -2853,6 +2948,8 @@ void wpas_dpp_deinit(struct wpa_supplicant *wpa_s)
|
|||||||
eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout,
|
eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout,
|
||||||
wpa_s, NULL);
|
wpa_s, NULL);
|
||||||
eloop_cancel_timeout(wpas_dpp_conn_status_result_timeout, wpa_s, NULL);
|
eloop_cancel_timeout(wpas_dpp_conn_status_result_timeout, wpa_s, NULL);
|
||||||
|
eloop_cancel_timeout(wpas_dpp_reconfig_reply_wait_timeout,
|
||||||
|
wpa_s, NULL);
|
||||||
dpp_pfs_free(wpa_s->dpp_pfs);
|
dpp_pfs_free(wpa_s->dpp_pfs);
|
||||||
wpa_s->dpp_pfs = NULL;
|
wpa_s->dpp_pfs = NULL;
|
||||||
wpas_dpp_chirp_stop(wpa_s);
|
wpas_dpp_chirp_stop(wpa_s);
|
||||||
|
Loading…
Reference in New Issue
Block a user