DPP2: Reconfig Authentication Request processing and Response generation
Extend Enrollee functionality to process Reconfig Authentication Request message, derive the needed keys, and generate Reconfig Authentication Response message. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
3774b6bd03
commit
65e94351dc
6 changed files with 435 additions and 3 deletions
|
@ -108,7 +108,7 @@ struct dpp_controller {
|
|||
};
|
||||
|
||||
|
||||
static void dpp_auth_fail(struct dpp_authentication *auth, const char *txt)
|
||||
void dpp_auth_fail(struct dpp_authentication *auth, const char *txt)
|
||||
{
|
||||
wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_FAIL "%s", txt);
|
||||
}
|
||||
|
@ -1002,6 +1002,7 @@ int dpp_prepare_channel_list(struct dpp_authentication *auth,
|
|||
return -1;
|
||||
auth->num_freq = 1;
|
||||
auth->freq[0] = neg_freq;
|
||||
auth->curr_freq = neg_freq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3255,10 +3256,12 @@ void dpp_auth_deinit(struct dpp_authentication *auth)
|
|||
dpp_configuration_free(auth->conf2_sta);
|
||||
EVP_PKEY_free(auth->own_protocol_key);
|
||||
EVP_PKEY_free(auth->peer_protocol_key);
|
||||
EVP_PKEY_free(auth->reconfig_old_protocol_key);
|
||||
wpabuf_free(auth->req_msg);
|
||||
wpabuf_free(auth->resp_msg);
|
||||
wpabuf_free(auth->conf_req);
|
||||
wpabuf_free(auth->reconfig_req_msg);
|
||||
wpabuf_free(auth->reconfig_resp_msg);
|
||||
for (i = 0; i < auth->num_conf_obj; i++) {
|
||||
struct dpp_config_obj *conf = &auth->conf_obj[i];
|
||||
|
||||
|
@ -4477,8 +4480,8 @@ static int dpp_parse_cred_legacy(struct dpp_config_obj *conf,
|
|||
}
|
||||
|
||||
|
||||
static EVP_PKEY * dpp_parse_jwk(struct json_token *jwk,
|
||||
const struct dpp_curve_params **key_curve)
|
||||
EVP_PKEY * dpp_parse_jwk(struct json_token *jwk,
|
||||
const struct dpp_curve_params **key_curve)
|
||||
{
|
||||
struct json_token *token;
|
||||
const struct dpp_curve_params *curve;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
struct crypto_ecdh;
|
||||
struct hostapd_ip_addr;
|
||||
struct dpp_global;
|
||||
struct json_token;
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
#define DPP_VERSION (dpp_version_override)
|
||||
|
@ -246,9 +247,11 @@ struct dpp_authentication {
|
|||
u8 r_capab;
|
||||
EVP_PKEY *own_protocol_key;
|
||||
EVP_PKEY *peer_protocol_key;
|
||||
EVP_PKEY *reconfig_old_protocol_key;
|
||||
struct wpabuf *req_msg;
|
||||
struct wpabuf *resp_msg;
|
||||
struct wpabuf *reconfig_req_msg;
|
||||
struct wpabuf *reconfig_resp_msg;
|
||||
/* Intersection of possible frequencies for initiating DPP
|
||||
* Authentication exchange */
|
||||
unsigned int freq[DPP_BOOTSTRAP_MAX_FREQ];
|
||||
|
@ -641,6 +644,13 @@ struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key,
|
|||
struct dpp_authentication *
|
||||
dpp_reconfig_init(struct dpp_global *dpp, void *msg_ctx,
|
||||
struct dpp_configurator *conf, unsigned int freq);
|
||||
struct dpp_authentication *
|
||||
dpp_reconfig_auth_req_rx(struct dpp_global *dpp, void *msg_ctx,
|
||||
const char *own_connector,
|
||||
const u8 *net_access_key, size_t net_access_key_len,
|
||||
const u8 *csign_key, size_t csign_key_len,
|
||||
unsigned int freq, const u8 *hdr,
|
||||
const u8 *attr_start, size_t attr_len);
|
||||
|
||||
#endif /* CONFIG_DPP */
|
||||
#endif /* DPP_H */
|
||||
|
|
|
@ -2236,6 +2236,114 @@ int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp,
|
|||
}
|
||||
|
||||
|
||||
int dpp_reconfig_derive_ke_responder(struct dpp_authentication *auth,
|
||||
const u8 *net_access_key,
|
||||
size_t net_access_key_len,
|
||||
struct json_token *peer_net_access_key)
|
||||
{
|
||||
BN_CTX *bnctx = NULL;
|
||||
EVP_PKEY *own_key = NULL, *peer_key = NULL;
|
||||
BIGNUM *sum = NULL, *q = NULL, *mx = NULL;
|
||||
EC_POINT *m = NULL;
|
||||
const EC_KEY *cR, *pR;
|
||||
const EC_GROUP *group;
|
||||
const BIGNUM *cR_bn, *pR_bn;
|
||||
const EC_POINT *CI_point;
|
||||
const EC_KEY *CI;
|
||||
u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
|
||||
u8 prk[DPP_MAX_HASH_LEN];
|
||||
const struct dpp_curve_params *curve;
|
||||
int res = -1;
|
||||
|
||||
own_key = dpp_set_keypair(&auth->curve, net_access_key,
|
||||
net_access_key_len);
|
||||
if (!own_key) {
|
||||
dpp_auth_fail(auth, "Failed to parse own netAccessKey");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
peer_key = dpp_parse_jwk(peer_net_access_key, &curve);
|
||||
if (!peer_key)
|
||||
goto fail;
|
||||
dpp_debug_print_key("DPP: Received netAccessKey", peer_key);
|
||||
|
||||
if (auth->curve != curve) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"DPP: Mismatching netAccessKey curves (%s != %s)",
|
||||
auth->curve->name, curve->name);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
auth->own_protocol_key = dpp_gen_keypair(curve);
|
||||
if (!auth->own_protocol_key)
|
||||
goto fail;
|
||||
|
||||
/* M = { cR + pR } * CI */
|
||||
cR = EVP_PKEY_get0_EC_KEY(own_key);
|
||||
pR = EVP_PKEY_get0_EC_KEY(auth->own_protocol_key);
|
||||
group = EC_KEY_get0_group(pR);
|
||||
bnctx = BN_CTX_new();
|
||||
sum = BN_new();
|
||||
mx = BN_new();
|
||||
q = BN_new();
|
||||
m = EC_POINT_new(group);
|
||||
if (!cR || !pR || !bnctx || !sum || !mx || !q || !m)
|
||||
goto fail;
|
||||
cR_bn = EC_KEY_get0_private_key(cR);
|
||||
pR_bn = EC_KEY_get0_private_key(pR);
|
||||
if (!cR_bn || !pR_bn)
|
||||
goto fail;
|
||||
CI = EVP_PKEY_get0_EC_KEY(peer_key);
|
||||
CI_point = EC_KEY_get0_public_key(CI);
|
||||
if (EC_GROUP_get_order(group, q, bnctx) != 1 ||
|
||||
BN_mod_add(sum, cR_bn, pR_bn, q, bnctx) != 1 ||
|
||||
EC_POINT_mul(group, m, NULL, CI_point, sum, bnctx) != 1 ||
|
||||
EC_POINT_get_affine_coordinates_GFp(group, m, mx, NULL,
|
||||
bnctx) != 1) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"OpenSSL: failed: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (dpp_bn2bin_pad(mx, Mx, curve->prime_len) < 0)
|
||||
goto fail;
|
||||
wpa_hexdump_key(MSG_DEBUG, "DPP: M.x", Mx, curve->prime_len);
|
||||
|
||||
/* ke = HKDF(I-nonce, "dpp reconfig key", M.x) */
|
||||
|
||||
/* HKDF-Extract(I-nonce, M.x) */
|
||||
if (dpp_hmac(curve->hash_len, auth->i_nonce, curve->nonce_len,
|
||||
Mx, curve->prime_len, prk) < 0)
|
||||
goto fail;
|
||||
wpa_hexdump_key(MSG_DEBUG, "DPP: PRK", prk, curve->hash_len);
|
||||
|
||||
/* HKDF-Expand(PRK, "dpp reconfig key", L) */
|
||||
if (dpp_hkdf_expand(curve->hash_len, prk, curve->hash_len,
|
||||
"dpp reconfig key", auth->ke, curve->hash_len) < 0)
|
||||
goto fail;
|
||||
wpa_hexdump_key(MSG_DEBUG,
|
||||
"DPP: ke = HKDF(I-nonce, \"dpp reconfig key\", M.x)",
|
||||
auth->ke, curve->hash_len);
|
||||
|
||||
res = 0;
|
||||
EVP_PKEY_free(auth->reconfig_old_protocol_key);
|
||||
auth->reconfig_old_protocol_key = own_key;
|
||||
own_key = NULL;
|
||||
fail:
|
||||
forced_memzero(prk, sizeof(prk));
|
||||
forced_memzero(Mx, sizeof(Mx));
|
||||
EC_POINT_clear_free(m);
|
||||
BN_free(q);
|
||||
BN_clear_free(mx);
|
||||
BN_clear_free(sum);
|
||||
EVP_PKEY_free(own_key);
|
||||
EVP_PKEY_free(peer_key);
|
||||
BN_CTX_free(bnctx);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
dpp_build_jws_prot_hdr(struct dpp_configurator *conf, size_t *signed1_len)
|
||||
{
|
||||
|
|
|
@ -38,9 +38,12 @@ int dpp_connector_match_groups(struct json_token *own_root,
|
|||
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);
|
||||
EVP_PKEY * dpp_parse_jwk(struct json_token *jwk,
|
||||
const struct dpp_curve_params **key_curve);
|
||||
int dpp_prepare_channel_list(struct dpp_authentication *auth,
|
||||
unsigned int neg_freq,
|
||||
struct hostapd_hw_modes *own_modes, u16 num_modes);
|
||||
void dpp_auth_fail(struct dpp_authentication *auth, const char *txt);
|
||||
|
||||
/* dpp_crypto.c */
|
||||
|
||||
|
@ -116,6 +119,10 @@ int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp,
|
|||
const char *code,
|
||||
const u8 *Kx, size_t Kx_len,
|
||||
u8 *z, unsigned int hash_len);
|
||||
int dpp_reconfig_derive_ke_responder(struct dpp_authentication *auth,
|
||||
const u8 *net_access_key,
|
||||
size_t net_access_key_len,
|
||||
struct json_token *peer_net_access_key);
|
||||
char * dpp_sign_connector(struct dpp_configurator *conf,
|
||||
const struct wpabuf *dppcon);
|
||||
int dpp_test_gen_invalid_key(struct wpabuf *msg,
|
||||
|
|
|
@ -7,11 +7,15 @@
|
|||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/json.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/random.h"
|
||||
#include "crypto/aes.h"
|
||||
#include "crypto/aes_siv.h"
|
||||
#include "dpp.h"
|
||||
#include "dpp_i.h"
|
||||
|
||||
|
@ -207,4 +211,254 @@ fail:
|
|||
goto out;
|
||||
}
|
||||
|
||||
|
||||
static int dpp_reconfig_build_resp(struct dpp_authentication *auth,
|
||||
const char *own_connector,
|
||||
struct wpabuf *conn_status)
|
||||
{
|
||||
struct wpabuf *msg = NULL, *clear, *pr = NULL;
|
||||
u8 *attr_start, *attr_end;
|
||||
size_t clear_len, attr_len, len[2];
|
||||
const u8 *addr[2];
|
||||
u8 *wrapped;
|
||||
int res = -1;
|
||||
|
||||
/* Build DPP Reconfig Authentication Response frame attributes */
|
||||
clear_len = 2 * (4 + auth->curve->nonce_len) +
|
||||
4 + wpabuf_len(conn_status);
|
||||
clear = wpabuf_alloc(clear_len);
|
||||
if (!clear)
|
||||
goto fail;
|
||||
|
||||
/* I-nonce (wrapped) */
|
||||
wpabuf_put_le16(clear, DPP_ATTR_I_NONCE);
|
||||
wpabuf_put_le16(clear, auth->curve->nonce_len);
|
||||
wpabuf_put_data(clear, auth->i_nonce, auth->curve->nonce_len);
|
||||
|
||||
/* R-nonce (wrapped) */
|
||||
wpabuf_put_le16(clear, DPP_ATTR_R_NONCE);
|
||||
wpabuf_put_le16(clear, auth->curve->nonce_len);
|
||||
wpabuf_put_data(clear, auth->r_nonce, auth->curve->nonce_len);
|
||||
|
||||
/* Connection Status (wrapped) */
|
||||
wpabuf_put_le16(clear, DPP_ATTR_CONN_STATUS);
|
||||
wpabuf_put_le16(clear, wpabuf_len(conn_status));
|
||||
wpabuf_put_buf(clear, conn_status);
|
||||
|
||||
pr = dpp_get_pubkey_point(auth->own_protocol_key, 0);
|
||||
if (!pr)
|
||||
goto fail;
|
||||
|
||||
attr_len = 4 + 1 + 4 + 1 +
|
||||
4 + os_strlen(own_connector) +
|
||||
4 + wpabuf_len(pr) +
|
||||
4 + wpabuf_len(clear) + AES_BLOCK_SIZE;
|
||||
msg = dpp_alloc_msg(DPP_PA_RECONFIG_AUTH_RESP, attr_len);
|
||||
if (!msg)
|
||||
goto fail;
|
||||
|
||||
attr_start = wpabuf_put(msg, 0);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* R-Connector */
|
||||
wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
|
||||
wpabuf_put_le16(msg, os_strlen(own_connector));
|
||||
wpabuf_put_str(msg, own_connector);
|
||||
|
||||
/* Responder Protocol Key (Pr) */
|
||||
wpabuf_put_le16(msg, DPP_ATTR_R_PROTOCOL_KEY);
|
||||
wpabuf_put_le16(msg, wpabuf_len(pr));
|
||||
wpabuf_put_buf(msg, pr);
|
||||
|
||||
attr_end = wpabuf_put(msg, 0);
|
||||
|
||||
/* OUI, OUI type, Crypto Suite, DPP frame type */
|
||||
addr[0] = wpabuf_head_u8(msg) + 2;
|
||||
len[0] = 3 + 1 + 1 + 1;
|
||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
|
||||
|
||||
/* Attributes before Wrapped Data */
|
||||
addr[1] = attr_start;
|
||||
len[1] = attr_end - attr_start;
|
||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
|
||||
|
||||
/* Wrapped Data: {I-nonce, R-nonce, Connection Status}ke */
|
||||
wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
|
||||
wpabuf_put_le16(msg, wpabuf_len(clear) + AES_BLOCK_SIZE);
|
||||
wrapped = wpabuf_put(msg, wpabuf_len(clear) + AES_BLOCK_SIZE);
|
||||
|
||||
wpa_hexdump_buf(MSG_DEBUG, "DPP: AES-SIV cleartext", clear);
|
||||
if (aes_siv_encrypt(auth->ke, auth->curve->hash_len,
|
||||
wpabuf_head(clear), wpabuf_len(clear),
|
||||
2, addr, len, wrapped) < 0)
|
||||
goto fail;
|
||||
|
||||
wpa_hexdump_buf(MSG_DEBUG,
|
||||
"DPP: Reconfig Authentication Response frame attributes",
|
||||
msg);
|
||||
|
||||
wpabuf_free(auth->reconfig_resp_msg);
|
||||
auth->reconfig_resp_msg = msg;
|
||||
|
||||
res = 0;
|
||||
out:
|
||||
wpabuf_free(clear);
|
||||
wpabuf_free(pr);
|
||||
return res;
|
||||
fail:
|
||||
wpabuf_free(msg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
struct dpp_authentication *
|
||||
dpp_reconfig_auth_req_rx(struct dpp_global *dpp, void *msg_ctx,
|
||||
const char *own_connector,
|
||||
const u8 *net_access_key, size_t net_access_key_len,
|
||||
const u8 *csign_key, size_t csign_key_len,
|
||||
unsigned int freq, const u8 *hdr,
|
||||
const u8 *attr_start, size_t attr_len)
|
||||
{
|
||||
struct dpp_authentication *auth = NULL;
|
||||
const u8 *trans_id, *version, *i_connector, *i_nonce;
|
||||
u16 trans_id_len, version_len, i_connector_len, i_nonce_len;
|
||||
struct dpp_signed_connector_info info;
|
||||
enum dpp_status_error res;
|
||||
struct json_token *root = NULL, *own_root = NULL, *token;
|
||||
unsigned char *own_conn = NULL;
|
||||
struct wpabuf *conn_status = NULL;
|
||||
|
||||
os_memset(&info, 0, sizeof(info));
|
||||
|
||||
trans_id = dpp_get_attr(attr_start, attr_len, DPP_ATTR_TRANSACTION_ID,
|
||||
&trans_id_len);
|
||||
if (!trans_id || trans_id_len != 1) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"DPP: Peer did not include Transaction ID");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
version = dpp_get_attr(attr_start, attr_len, DPP_ATTR_PROTOCOL_VERSION,
|
||||
&version_len);
|
||||
if (!version || version_len < 1 || version[0] < 2) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"DPP: Missing or invalid Protocol Version attribute");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
i_connector = dpp_get_attr(attr_start, attr_len, DPP_ATTR_CONNECTOR,
|
||||
&i_connector_len);
|
||||
if (!i_connector) {
|
||||
wpa_printf(MSG_DEBUG, "DPP: Missing I-Connector attribute");
|
||||
goto fail;
|
||||
}
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "DPP: I-Connector",
|
||||
i_connector, i_connector_len);
|
||||
|
||||
i_nonce = dpp_get_attr(attr_start, attr_len, DPP_ATTR_I_NONCE,
|
||||
&i_nonce_len);
|
||||
if (!i_nonce || i_nonce_len > DPP_MAX_NONCE_LEN) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"DPP: Missing or invalid I-Nonce attribute");
|
||||
goto fail;
|
||||
}
|
||||
wpa_hexdump(MSG_DEBUG, "DPP: I-Nonce", i_nonce, i_nonce_len);
|
||||
|
||||
res = dpp_check_signed_connector(&info, csign_key, csign_key_len,
|
||||
i_connector, i_connector_len);
|
||||
if (res != DPP_STATUS_OK) {
|
||||
wpa_printf(MSG_DEBUG, "DPP: Invalid I-Connector");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
root = json_parse((const char *) info.payload, info.payload_len);
|
||||
own_root = dpp_parse_own_connector(own_connector);
|
||||
if (!root || !own_root ||
|
||||
!dpp_connector_match_groups(own_root, root, true)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"DPP: I-Connector does not include compatible group netrole with own connector");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
token = json_get_member(root, "expiry");
|
||||
if (token && token->type == JSON_STRING &&
|
||||
dpp_key_expired(token->string, NULL)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"DPP: I-Connector (netAccessKey) has expired");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
token = json_get_member(root, "netAccessKey");
|
||||
if (!token || token->type != JSON_OBJECT) {
|
||||
wpa_printf(MSG_DEBUG, "DPP: No netAccessKey object found");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
auth = dpp_alloc_auth(dpp, msg_ctx);
|
||||
if (!auth)
|
||||
return NULL;
|
||||
|
||||
auth->reconfig = 1;
|
||||
auth->allowed_roles = DPP_CAPAB_ENROLLEE;
|
||||
if (dpp_prepare_channel_list(auth, freq, NULL, 0) < 0)
|
||||
goto fail;
|
||||
|
||||
auth->transaction_id = trans_id[0];
|
||||
|
||||
auth->peer_version = version[0];
|
||||
wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u",
|
||||
auth->peer_version);
|
||||
|
||||
os_memcpy(auth->i_nonce, i_nonce, i_nonce_len);
|
||||
|
||||
if (dpp_reconfig_derive_ke_responder(auth, net_access_key,
|
||||
net_access_key_len, token) < 0)
|
||||
goto fail;
|
||||
|
||||
if (i_nonce_len != auth->curve->nonce_len) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"DPP: Unexpected I-nonce length %u (curve nonce len %zu)",
|
||||
i_nonce_len, auth->curve->nonce_len);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (random_get_bytes(auth->r_nonce, auth->curve->nonce_len)) {
|
||||
wpa_printf(MSG_ERROR, "DPP: Failed to generate R-nonce");
|
||||
goto fail;
|
||||
}
|
||||
wpa_hexdump_key(MSG_DEBUG, "DPP: R-nonce",
|
||||
auth->r_nonce, auth->curve->nonce_len);
|
||||
|
||||
/* Build Connection Status object */
|
||||
/* TODO: Get appropriate result value */
|
||||
/* TODO: ssid64 and channelList */
|
||||
conn_status = dpp_build_conn_status(DPP_STATUS_NO_AP, NULL, 0, NULL);
|
||||
if (!conn_status)
|
||||
goto fail;
|
||||
|
||||
if (dpp_reconfig_build_resp(auth, own_connector, conn_status) < 0)
|
||||
goto fail;
|
||||
|
||||
out:
|
||||
os_free(info.payload);
|
||||
os_free(own_conn);
|
||||
json_free(root);
|
||||
json_free(own_root);
|
||||
wpabuf_free(conn_status);
|
||||
return auth;
|
||||
fail:
|
||||
dpp_auth_deinit(auth);
|
||||
auth = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DPP2 */
|
||||
|
|
|
@ -1915,6 +1915,53 @@ wpas_dpp_rx_reconfig_announcement(struct wpa_supplicant *wpa_s, const u8 *src,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wpas_dpp_rx_reconfig_auth_req(struct wpa_supplicant *wpa_s, const u8 *src,
|
||||
const u8 *hdr, const u8 *buf, size_t len,
|
||||
unsigned int freq)
|
||||
{
|
||||
struct wpa_ssid *ssid;
|
||||
struct dpp_authentication *auth;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DPP: Reconfig Authentication Request from "
|
||||
MACSTR, MAC2STR(src));
|
||||
|
||||
if (!wpa_s->dpp || wpa_s->dpp_auth ||
|
||||
!wpa_s->dpp_reconfig_announcement || !wpa_s->dpp_reconfig_ssid)
|
||||
return;
|
||||
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
|
||||
if (ssid == wpa_s->dpp_reconfig_ssid &&
|
||||
ssid->id == wpa_s->dpp_reconfig_ssid_id)
|
||||
break;
|
||||
}
|
||||
if (!ssid || !ssid->dpp_connector || !ssid->dpp_netaccesskey ||
|
||||
!ssid->dpp_csign)
|
||||
return;
|
||||
|
||||
auth = dpp_reconfig_auth_req_rx(wpa_s->dpp, wpa_s, ssid->dpp_connector,
|
||||
ssid->dpp_netaccesskey,
|
||||
ssid->dpp_netaccesskey_len,
|
||||
ssid->dpp_csign, ssid->dpp_csign_len,
|
||||
freq, hdr, buf, len);
|
||||
if (!auth)
|
||||
return;
|
||||
os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
|
||||
wpa_s->dpp_auth = auth;
|
||||
|
||||
wpas_dpp_chirp_stop(wpa_s);
|
||||
|
||||
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
|
||||
MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_RESP);
|
||||
if (offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr, broadcast,
|
||||
wpabuf_head(auth->reconfig_resp_msg),
|
||||
wpabuf_len(auth->reconfig_resp_msg),
|
||||
500, wpas_dpp_tx_status, 0) < 0) {
|
||||
dpp_auth_deinit(wpa_s->dpp_auth);
|
||||
wpa_s->dpp_auth = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DPP2 */
|
||||
|
||||
|
||||
|
@ -2480,6 +2527,9 @@ void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
|
|||
wpas_dpp_rx_reconfig_announcement(wpa_s, src, hdr, buf, len,
|
||||
freq);
|
||||
break;
|
||||
case DPP_PA_RECONFIG_AUTH_REQ:
|
||||
wpas_dpp_rx_reconfig_auth_req(wpa_s, src, hdr, buf, len, freq);
|
||||
break;
|
||||
#endif /* CONFIG_DPP2 */
|
||||
default:
|
||||
wpa_printf(MSG_DEBUG,
|
||||
|
|
Loading…
Reference in a new issue