DPP: Add DPP Status attribute into Peer Discovery Response

This was added in DPP tech spec v0.2.7 to allow result of network
introduction to be reported.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2017-10-29 11:43:41 +02:00 committed by Jouni Malinen
parent ba0840c9f8
commit e85b660129
5 changed files with 146 additions and 61 deletions

View file

@ -890,6 +890,46 @@ static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
} }
static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd,
const u8 *src, unsigned int freq,
u8 trans_id,
enum dpp_status_error status)
{
struct wpabuf *msg;
msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP,
5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector));
if (!msg)
return;
/* Transaction ID */
wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
wpabuf_put_le16(msg, 1);
wpabuf_put_u8(msg, trans_id);
/* DPP Status */
wpabuf_put_le16(msg, DPP_ATTR_STATUS);
wpabuf_put_le16(msg, 1);
wpabuf_put_u8(msg, status);
/* DPP Connector */
if (status == DPP_STATUS_OK) {
wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
wpabuf_put_str(msg, hapd->conf->dpp_connector);
}
wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR
" status=%d", MAC2STR(src), status);
wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
" freq=%u type=%d status=%d", MAC2STR(src), freq,
DPP_PA_PEER_DISCOVERY_RESP, status);
hostapd_drv_send_action(hapd, freq, 0, src,
wpabuf_head(msg), wpabuf_len(msg));
wpabuf_free(msg);
}
static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd, static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
const u8 *src, const u8 *src,
const u8 *buf, size_t len, const u8 *buf, size_t len,
@ -901,7 +941,7 @@ static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
struct dpp_introduction intro; struct dpp_introduction intro;
os_time_t expire; os_time_t expire;
int expiration; int expiration;
struct wpabuf *msg; enum dpp_status_error res;
wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR, wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR,
MAC2STR(src)); MAC2STR(src));
@ -941,14 +981,24 @@ static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
return; return;
} }
if (dpp_peer_intro(&intro, hapd->conf->dpp_connector, res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
wpabuf_head(hapd->conf->dpp_netaccesskey), wpabuf_head(hapd->conf->dpp_netaccesskey),
wpabuf_len(hapd->conf->dpp_netaccesskey), wpabuf_len(hapd->conf->dpp_netaccesskey),
wpabuf_head(hapd->conf->dpp_csign), wpabuf_head(hapd->conf->dpp_csign),
wpabuf_len(hapd->conf->dpp_csign), wpabuf_len(hapd->conf->dpp_csign),
connector, connector_len, &expire) < 0) { connector, connector_len, &expire);
if (res == 255) {
wpa_printf(MSG_INFO, wpa_printf(MSG_INFO,
"DPP: Network Introduction protocol resulted in failure"); "DPP: Network Introduction protocol resulted in internal failure (peer "
MACSTR ")", MAC2STR(src));
return;
}
if (res != DPP_STATUS_OK) {
wpa_printf(MSG_INFO,
"DPP: Network Introduction protocol resulted in failure (peer "
MACSTR " status %d)", MAC2STR(src), res);
hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
res);
return; return;
} }
@ -966,29 +1016,8 @@ static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
return; return;
} }
msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP, hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
5 + 4 + os_strlen(hapd->conf->dpp_connector)); DPP_STATUS_OK);
if (!msg)
return;
/* Transaction ID */
wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
wpabuf_put_le16(msg, 1);
wpabuf_put_u8(msg, trans_id[0]);
/* DPP Connector */
wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
wpabuf_put_str(msg, hapd->conf->dpp_connector);
wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR,
MAC2STR(src));
wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
" freq=%u type=%d", MAC2STR(src), freq,
DPP_PA_PEER_DISCOVERY_RESP);
hostapd_drv_send_action(hapd, freq, 0, src,
wpabuf_head(msg), wpabuf_len(msg));
wpabuf_free(msg);
} }

View file

@ -4356,11 +4356,11 @@ struct dpp_signed_connector_info {
size_t payload_len; size_t payload_len;
}; };
static int static enum dpp_status_error
dpp_process_signed_connector(struct dpp_signed_connector_info *info, dpp_process_signed_connector(struct dpp_signed_connector_info *info,
EVP_PKEY *csign_pub, const char *connector) EVP_PKEY *csign_pub, const char *connector)
{ {
int ret = -1; enum dpp_status_error ret = 255;
const char *pos, *end, *signed_start, *signed_end; const char *pos, *end, *signed_start, *signed_end;
struct wpabuf *kid = NULL; struct wpabuf *kid = NULL;
unsigned char *prot_hdr = NULL, *signature = NULL; unsigned char *prot_hdr = NULL, *signature = NULL;
@ -4394,6 +4394,7 @@ dpp_process_signed_connector(struct dpp_signed_connector_info *info,
end = os_strchr(pos, '.'); end = os_strchr(pos, '.');
if (!end) { if (!end) {
wpa_printf(MSG_DEBUG, "DPP: Missing dot(1) in signedConnector"); wpa_printf(MSG_DEBUG, "DPP: Missing dot(1) in signedConnector");
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail; goto fail;
} }
prot_hdr = base64_url_decode((const unsigned char *) pos, prot_hdr = base64_url_decode((const unsigned char *) pos,
@ -4401,18 +4402,22 @@ dpp_process_signed_connector(struct dpp_signed_connector_info *info,
if (!prot_hdr) { if (!prot_hdr) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: Failed to base64url decode signedConnector JWS Protected Header"); "DPP: Failed to base64url decode signedConnector JWS Protected Header");
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail; goto fail;
} }
wpa_hexdump_ascii(MSG_DEBUG, wpa_hexdump_ascii(MSG_DEBUG,
"DPP: signedConnector - JWS Protected Header", "DPP: signedConnector - JWS Protected Header",
prot_hdr, prot_hdr_len); prot_hdr, prot_hdr_len);
kid = dpp_parse_jws_prot_hdr(curve, prot_hdr, prot_hdr_len, &sign_md); kid = dpp_parse_jws_prot_hdr(curve, prot_hdr, prot_hdr_len, &sign_md);
if (!kid) if (!kid) {
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail; goto fail;
}
if (wpabuf_len(kid) != SHA256_MAC_LEN) { if (wpabuf_len(kid) != SHA256_MAC_LEN) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: Unexpected signedConnector JWS Protected Header kid length: %u (expected %u)", "DPP: Unexpected signedConnector JWS Protected Header kid length: %u (expected %u)",
(unsigned int) wpabuf_len(kid), SHA256_MAC_LEN); (unsigned int) wpabuf_len(kid), SHA256_MAC_LEN);
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail; goto fail;
} }
@ -4421,6 +4426,7 @@ dpp_process_signed_connector(struct dpp_signed_connector_info *info,
if (!end) { if (!end) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: Missing dot(2) in signedConnector"); "DPP: Missing dot(2) in signedConnector");
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail; goto fail;
} }
signed_end = end - 1; signed_end = end - 1;
@ -4429,6 +4435,7 @@ dpp_process_signed_connector(struct dpp_signed_connector_info *info,
if (!info->payload) { if (!info->payload) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: Failed to base64url decode signedConnector JWS Payload"); "DPP: Failed to base64url decode signedConnector JWS Payload");
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail; goto fail;
} }
wpa_hexdump_ascii(MSG_DEBUG, wpa_hexdump_ascii(MSG_DEBUG,
@ -4440,18 +4447,22 @@ dpp_process_signed_connector(struct dpp_signed_connector_info *info,
if (!signature) { if (!signature) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: Failed to base64url decode signedConnector signature"); "DPP: Failed to base64url decode signedConnector signature");
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail; goto fail;
} }
wpa_hexdump(MSG_DEBUG, "DPP: signedConnector - signature", wpa_hexdump(MSG_DEBUG, "DPP: signedConnector - signature",
signature, signature_len); signature, signature_len);
if (dpp_check_pubkey_match(csign_pub, kid) < 0) if (dpp_check_pubkey_match(csign_pub, kid) < 0) {
ret = DPP_STATUS_NO_MATCH;
goto fail; goto fail;
}
if (signature_len & 0x01) { if (signature_len & 0x01) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: Unexpected signedConnector signature length (%d)", "DPP: Unexpected signedConnector signature length (%d)",
(int) signature_len); (int) signature_len);
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail; goto fail;
} }
@ -4492,10 +4503,11 @@ dpp_process_signed_connector(struct dpp_signed_connector_info *info,
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: EVP_DigestVerifyFinal failed (res=%d): %s", "DPP: EVP_DigestVerifyFinal failed (res=%d): %s",
res, ERR_error_string(ERR_get_error(), NULL)); res, ERR_error_string(ERR_get_error(), NULL));
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail; goto fail;
} }
ret = 0; ret = DPP_STATUS_OK;
fail: fail:
EC_KEY_free(eckey); EC_KEY_free(eckey);
EVP_MD_CTX_destroy(md_ctx); EVP_MD_CTX_destroy(md_ctx);
@ -4554,7 +4566,7 @@ static int dpp_parse_cred_dpp(struct dpp_authentication *auth,
} }
if (dpp_process_signed_connector(&info, csign_pub, if (dpp_process_signed_connector(&info, csign_pub,
signed_connector) < 0) signed_connector) != DPP_STATUS_OK)
goto fail; goto fail;
if (dpp_parse_connector(auth, info.payload, info.payload_len) < 0) { if (dpp_parse_connector(auth, info.payload, info.payload_len) < 0) {
@ -5021,15 +5033,16 @@ fail:
} }
int dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector, enum dpp_status_error
const u8 *net_access_key, size_t net_access_key_len, dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
const u8 *csign_key, size_t csign_key_len, const u8 *net_access_key, size_t net_access_key_len,
const u8 *peer_connector, size_t peer_connector_len, const u8 *csign_key, size_t csign_key_len,
os_time_t *expiry) const u8 *peer_connector, size_t peer_connector_len,
os_time_t *expiry)
{ {
struct json_token *root = NULL, *netkey, *token; struct json_token *root = NULL, *netkey, *token;
struct json_token *own_root = NULL; struct json_token *own_root = NULL;
int ret = -1; enum dpp_status_error ret = 255, res;
EVP_PKEY *own_key = NULL, *peer_key = NULL; EVP_PKEY *own_key = NULL, *peer_key = NULL;
struct wpabuf *own_key_pub = NULL; struct wpabuf *own_key_pub = NULL;
const struct dpp_curve_params *curve, *own_curve; const struct dpp_curve_params *curve, *own_curve;
@ -5097,18 +5110,23 @@ int dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
os_memcpy(signed_connector, peer_connector, peer_connector_len); os_memcpy(signed_connector, peer_connector, peer_connector_len);
signed_connector[peer_connector_len] = '\0'; signed_connector[peer_connector_len] = '\0';
if (dpp_process_signed_connector(&info, csign, signed_connector) < 0) res = dpp_process_signed_connector(&info, csign, signed_connector);
if (res != DPP_STATUS_OK) {
ret = res;
goto fail; goto fail;
}
root = json_parse((const char *) info.payload, info.payload_len); root = json_parse((const char *) info.payload, info.payload_len);
if (!root) { if (!root) {
wpa_printf(MSG_DEBUG, "DPP: JSON parsing of connector failed"); wpa_printf(MSG_DEBUG, "DPP: JSON parsing of connector failed");
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail; goto fail;
} }
if (!dpp_connector_match_groups(own_root, root)) { if (!dpp_connector_match_groups(own_root, root)) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: Peer connector does not include compatible group netrole with own connector"); "DPP: Peer connector does not include compatible group netrole with own connector");
ret = DPP_STATUS_NO_MATCH;
goto fail; goto fail;
} }
@ -5121,6 +5139,7 @@ int dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
if (dpp_key_expired(token->string, expiry)) { if (dpp_key_expired(token->string, expiry)) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: Connector (netAccessKey) has expired"); "DPP: Connector (netAccessKey) has expired");
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail; goto fail;
} }
} }
@ -5128,18 +5147,22 @@ int dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
netkey = json_get_member(root, "netAccessKey"); netkey = json_get_member(root, "netAccessKey");
if (!netkey || netkey->type != JSON_OBJECT) { if (!netkey || netkey->type != JSON_OBJECT) {
wpa_printf(MSG_DEBUG, "DPP: No netAccessKey object found"); wpa_printf(MSG_DEBUG, "DPP: No netAccessKey object found");
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail; goto fail;
} }
peer_key = dpp_parse_jwk(netkey, &curve); peer_key = dpp_parse_jwk(netkey, &curve);
if (!peer_key) if (!peer_key) {
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail; goto fail;
}
dpp_debug_print_key("DPP: Received netAccessKey", peer_key); dpp_debug_print_key("DPP: Received netAccessKey", peer_key);
if (own_curve != curve) { if (own_curve != curve) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: Mismatching netAccessKey curves (%s != %s)", "DPP: Mismatching netAccessKey curves (%s != %s)",
own_curve->name, curve->name); own_curve->name, curve->name);
ret = DPP_STATUS_INVALID_CONNECTOR;
goto fail; goto fail;
} }
@ -5173,9 +5196,9 @@ int dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
goto fail; goto fail;
} }
ret = 0; ret = DPP_STATUS_OK;
fail: fail:
if (ret < 0) if (ret != DPP_STATUS_OK)
os_memset(intro, 0, sizeof(*intro)); os_memset(intro, 0, sizeof(*intro));
os_memset(Nx, 0, sizeof(Nx)); os_memset(Nx, 0, sizeof(Nx));
EVP_PKEY_CTX_free(ctx); EVP_PKEY_CTX_free(ctx);

View file

@ -63,6 +63,8 @@ enum dpp_status_error {
DPP_STATUS_BAD_GROUP = 4, DPP_STATUS_BAD_GROUP = 4,
DPP_STATUS_CONFIGURE_FAILURE = 5, DPP_STATUS_CONFIGURE_FAILURE = 5,
DPP_STATUS_RESPONSE_PENDING = 6, DPP_STATUS_RESPONSE_PENDING = 6,
DPP_STATUS_INVALID_CONNECTOR = 7,
DPP_STATUS_NO_MATCH = 8,
}; };
#define DPP_CAPAB_ENROLLEE BIT(0) #define DPP_CAPAB_ENROLLEE BIT(0)
@ -292,11 +294,12 @@ 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 dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector, enum dpp_status_error
const u8 *net_access_key, size_t net_access_key_len, dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
const u8 *csign_key, size_t csign_key_len, const u8 *net_access_key, size_t net_access_key_len,
const u8 *peer_connector, size_t peer_connector_len, const u8 *csign_key, size_t csign_key_len,
os_time_t *expiry); const u8 *peer_connector, size_t peer_connector_len,
os_time_t *expiry);
struct dpp_pkex * dpp_pkex_init(struct dpp_bootstrap_info *bi, struct dpp_pkex * dpp_pkex_init(struct dpp_bootstrap_info *bi,
const u8 *own_mac, const u8 *own_mac,
const char *identifier, const char *identifier,

View file

@ -171,6 +171,7 @@ extern "C" {
#define DPP_EVENT_TX "DPP-TX " #define DPP_EVENT_TX "DPP-TX "
#define DPP_EVENT_TX_STATUS "DPP-TX-STATUS " #define DPP_EVENT_TX_STATUS "DPP-TX-STATUS "
#define DPP_EVENT_FAIL "DPP-FAIL " #define DPP_EVENT_FAIL "DPP-FAIL "
#define DPP_EVENT_INTRO "DPP-INTRO "
/* MESH events */ /* MESH events */
#define MESH_GROUP_STARTED "MESH-GROUP-STARTED " #define MESH_GROUP_STARTED "MESH-GROUP-STARTED "

View file

@ -1243,14 +1243,15 @@ static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s,
const u8 *buf, size_t len) const u8 *buf, size_t len)
{ {
struct wpa_ssid *ssid; struct wpa_ssid *ssid;
const u8 *connector, *trans_id; const u8 *connector, *trans_id, *status;
u16 connector_len, trans_id_len; u16 connector_len, trans_id_len, status_len;
struct dpp_introduction intro; struct dpp_introduction intro;
struct rsn_pmksa_cache_entry *entry; struct rsn_pmksa_cache_entry *entry;
struct os_time now; struct os_time now;
struct os_reltime rnow; struct os_reltime rnow;
os_time_t expiry; os_time_t expiry;
unsigned int seconds; unsigned int seconds;
enum dpp_status_error res;
wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Response from " MACSTR, wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Response from " MACSTR,
MAC2STR(src)); MAC2STR(src));
@ -1278,12 +1279,32 @@ static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s,
if (!trans_id || trans_id_len != 1) { if (!trans_id || trans_id_len != 1) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: Peer did not include Transaction ID"); "DPP: Peer did not include Transaction ID");
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
" fail=missing_transaction_id", MAC2STR(src));
goto fail; goto fail;
} }
if (trans_id[0] != TRANSACTION_ID) { if (trans_id[0] != TRANSACTION_ID) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: Ignore frame with unexpected Transaction ID %u", "DPP: Ignore frame with unexpected Transaction ID %u",
trans_id[0]); trans_id[0]);
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
" fail=transaction_id_mismatch", MAC2STR(src));
goto fail;
}
status = dpp_get_attr(buf, len, DPP_ATTR_STATUS, &status_len);
if (!status || status_len != 1) {
wpa_printf(MSG_DEBUG, "DPP: Peer did not include Status");
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
" fail=missing_status", MAC2STR(src));
goto fail;
}
if (status[0] != DPP_STATUS_OK) {
wpa_printf(MSG_DEBUG,
"DPP: Peer rejected network introduction: Status %u",
status[0]);
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
" status=%u", MAC2STR(src), status[0]);
goto fail; goto fail;
} }
@ -1291,17 +1312,22 @@ static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s,
if (!connector) { if (!connector) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: Peer did not include its Connector"); "DPP: Peer did not include its Connector");
return; wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
" fail=missing_connector", MAC2STR(src));
goto fail;
} }
if (dpp_peer_intro(&intro, ssid->dpp_connector, res = dpp_peer_intro(&intro, ssid->dpp_connector,
ssid->dpp_netaccesskey, ssid->dpp_netaccesskey,
ssid->dpp_netaccesskey_len, ssid->dpp_netaccesskey_len,
ssid->dpp_csign, ssid->dpp_csign,
ssid->dpp_csign_len, ssid->dpp_csign_len,
connector, connector_len, &expiry) < 0) { connector, connector_len, &expiry);
if (res != DPP_STATUS_OK) {
wpa_printf(MSG_INFO, wpa_printf(MSG_INFO,
"DPP: Network Introduction protocol resulted in failure"); "DPP: Network Introduction protocol resulted in failure");
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
" fail=peer_connector_validation_failed", MAC2STR(src));
goto fail; goto fail;
} }
@ -1325,6 +1351,9 @@ static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s,
entry->network_ctx = ssid; entry->network_ctx = ssid;
wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, entry); wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, entry);
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_INTRO "peer=" MACSTR
" status=%u", MAC2STR(src), status[0]);
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: Try connection again after successful network introduction"); "DPP: Try connection again after successful network introduction");
if (wpa_supplicant_fast_associate(wpa_s) != 1) { if (wpa_supplicant_fast_associate(wpa_s) != 1) {