From 52d469de11124d0fc7fbbd7e8a9ab8244428316a Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 27 Sep 2019 01:08:56 +0300 Subject: [PATCH] DPP2: Support multiple Config Objects in Enrollee Process all received DPP Configuration Object attributes from Configuration Result in Enrollee STA case. If wpa_supplicant is configured to add networks automatically, this results in one network being added for each included Configuration Object. Signed-off-by: Jouni Malinen --- src/ap/dpp_hostapd.c | 35 ++++----- src/common/dpp.c | 125 +++++++++++++++++++++++--------- src/common/dpp.h | 21 ++++-- wpa_supplicant/dpp_supplicant.c | 115 ++++++++++++++++++----------- 4 files changed, 192 insertions(+), 104 deletions(-) diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index effcc7ab1..085d42325 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -607,47 +607,48 @@ static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src, static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd, - struct dpp_authentication *auth) + struct dpp_authentication *auth, + struct dpp_config_obj *conf) { wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED); wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s", - dpp_akm_str(auth->akm)); - if (auth->ssid_len) + dpp_akm_str(conf->akm)); + if (conf->ssid_len) wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s", - wpa_ssid_txt(auth->ssid, auth->ssid_len)); - if (auth->connector) { + wpa_ssid_txt(conf->ssid, conf->ssid_len)); + if (conf->connector) { /* TODO: Save the Connector and consider using a command * to fetch the value instead of sending an event with * it. The Connector could end up being larger than what * most clients are ready to receive as an event * message. */ wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s", - auth->connector); - } else if (auth->passphrase[0]) { + conf->connector); + } else if (conf->passphrase[0]) { char hex[64 * 2 + 1]; wpa_snprintf_hex(hex, sizeof(hex), - (const u8 *) auth->passphrase, - os_strlen(auth->passphrase)); + (const u8 *) conf->passphrase, + os_strlen(conf->passphrase)); wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s", hex); - } else if (auth->psk_set) { + } else if (conf->psk_set) { char hex[PMK_LEN * 2 + 1]; - wpa_snprintf_hex(hex, sizeof(hex), auth->psk, PMK_LEN); + wpa_snprintf_hex(hex, sizeof(hex), conf->psk, PMK_LEN); wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s", hex); } - if (auth->c_sign_key) { + if (conf->c_sign_key) { char *hex; size_t hexlen; - hexlen = 2 * wpabuf_len(auth->c_sign_key) + 1; + hexlen = 2 * wpabuf_len(conf->c_sign_key) + 1; hex = os_malloc(hexlen); if (hex) { wpa_snprintf_hex(hex, hexlen, - wpabuf_head(auth->c_sign_key), - wpabuf_len(auth->c_sign_key)); + wpabuf_head(conf->c_sign_key), + wpabuf_len(conf->c_sign_key)); wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_C_SIGN_KEY "%s", hex); os_free(hex); @@ -720,7 +721,7 @@ static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token, goto fail; } - hostapd_dpp_handle_config_obj(hapd, auth); + hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]); status = DPP_STATUS_OK; #ifdef CONFIG_TESTING_OPTIONS if (dpp_test == DPP_TEST_REJECT_CONFIG) { @@ -1568,7 +1569,7 @@ int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd) if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx, auth, cmd) == 0 && dpp_configurator_own_config(auth, curve, 1) == 0) { - hostapd_dpp_handle_config_obj(hapd, auth); + hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]); ret = 0; } diff --git a/src/common/dpp.c b/src/common/dpp.c index bdf5c0db8..fbad03eeb 100644 --- a/src/common/dpp.c +++ b/src/common/dpp.c @@ -742,6 +742,34 @@ const u8 * dpp_get_attr(const u8 *buf, size_t len, u16 req_id, u16 *ret_len) } +static const u8 * dpp_get_attr_next(const u8 *prev, const u8 *buf, size_t len, + u16 req_id, u16 *ret_len) +{ + u16 id, alen; + const u8 *pos, *end = buf + len; + + if (!prev) + pos = buf; + else + pos = prev + WPA_GET_LE16(prev - 2); + while (end - pos >= 4) { + id = WPA_GET_LE16(pos); + pos += 2; + alen = WPA_GET_LE16(pos); + pos += 2; + if (alen > end - pos) + return NULL; + if (id == req_id) { + *ret_len = alen; + return pos; + } + pos += alen; + } + + return NULL; +} + + int dpp_check_attrs(const u8 *buf, size_t len) { const u8 *pos, *end; @@ -4568,6 +4596,8 @@ int dpp_set_configurator(struct dpp_global *dpp, void *msg_ctx, void dpp_auth_deinit(struct dpp_authentication *auth) { + unsigned int i; + if (!auth) return; dpp_configuration_free(auth->conf_ap); @@ -4579,9 +4609,13 @@ void dpp_auth_deinit(struct dpp_authentication *auth) wpabuf_free(auth->req_msg); wpabuf_free(auth->resp_msg); wpabuf_free(auth->conf_req); - os_free(auth->connector); + for (i = 0; i < auth->num_conf_obj; i++) { + struct dpp_config_obj *conf = &auth->conf_obj[i]; + + os_free(conf->connector); + wpabuf_free(conf->c_sign_key); + } wpabuf_free(auth->net_access_key); - wpabuf_free(auth->c_sign_key); dpp_bootstrap_info_free(auth->tmp_own_bi); #ifdef CONFIG_TESTING_OPTIONS os_free(auth->config_obj_override); @@ -5352,7 +5386,7 @@ fail: } -static int dpp_parse_cred_legacy(struct dpp_authentication *auth, +static int dpp_parse_cred_legacy(struct dpp_config_obj *conf, struct json_token *cred) { struct json_token *pass, *psk_hex; @@ -5369,28 +5403,28 @@ static int dpp_parse_cred_legacy(struct dpp_authentication *auth, pass->string, len); if (len < 8 || len > 63) return -1; - os_strlcpy(auth->passphrase, pass->string, - sizeof(auth->passphrase)); + os_strlcpy(conf->passphrase, pass->string, + sizeof(conf->passphrase)); } else if (psk_hex && psk_hex->type == JSON_STRING) { - if (dpp_akm_sae(auth->akm) && !dpp_akm_psk(auth->akm)) { + if (dpp_akm_sae(conf->akm) && !dpp_akm_psk(conf->akm)) { wpa_printf(MSG_DEBUG, "DPP: Unexpected psk_hex with akm=sae"); return -1; } if (os_strlen(psk_hex->string) != PMK_LEN * 2 || - hexstr2bin(psk_hex->string, auth->psk, PMK_LEN) < 0) { + hexstr2bin(psk_hex->string, conf->psk, PMK_LEN) < 0) { wpa_printf(MSG_DEBUG, "DPP: Invalid psk_hex encoding"); return -1; } wpa_hexdump_key(MSG_DEBUG, "DPP: Legacy PSK", - auth->psk, PMK_LEN); - auth->psk_set = 1; + conf->psk, PMK_LEN); + conf->psk_set = 1; } else { wpa_printf(MSG_DEBUG, "DPP: No pass or psk_hex strings found"); return -1; } - if (dpp_akm_sae(auth->akm) && !auth->passphrase[0]) { + if (dpp_akm_sae(conf->akm) && !conf->passphrase[0]) { wpa_printf(MSG_DEBUG, "DPP: No pass for sae found"); return -1; } @@ -5558,6 +5592,7 @@ int dpp_key_expired(const char *timestamp, os_time_t *expiry) static int dpp_parse_connector(struct dpp_authentication *auth, + struct dpp_config_obj *conf, const unsigned char *payload, u16 payload_len) { @@ -5685,7 +5720,7 @@ static int dpp_check_pubkey_match(EVP_PKEY *pub, struct wpabuf *r_hash) } -static void dpp_copy_csign(struct dpp_authentication *auth, EVP_PKEY *csign) +static void dpp_copy_csign(struct dpp_config_obj *conf, EVP_PKEY *csign) { unsigned char *der = NULL; int der_len; @@ -5693,13 +5728,14 @@ static void dpp_copy_csign(struct dpp_authentication *auth, EVP_PKEY *csign) der_len = i2d_PUBKEY(csign, &der); if (der_len <= 0) return; - wpabuf_free(auth->c_sign_key); - auth->c_sign_key = wpabuf_alloc_copy(der, der_len); + wpabuf_free(conf->c_sign_key); + conf->c_sign_key = wpabuf_alloc_copy(der, der_len); OPENSSL_free(der); } -static void dpp_copy_netaccesskey(struct dpp_authentication *auth) +static void dpp_copy_netaccesskey(struct dpp_authentication *auth, + struct dpp_config_obj *conf) { unsigned char *der = NULL; int der_len; @@ -5893,6 +5929,7 @@ fail: static int dpp_parse_cred_dpp(struct dpp_authentication *auth, + struct dpp_config_obj *conf, struct json_token *cred) { struct dpp_signed_connector_info info; @@ -5904,10 +5941,10 @@ static int dpp_parse_cred_dpp(struct dpp_authentication *auth, os_memset(&info, 0, sizeof(info)); - if (dpp_akm_psk(auth->akm) || dpp_akm_sae(auth->akm)) { + if (dpp_akm_psk(conf->akm) || dpp_akm_sae(conf->akm)) { wpa_printf(MSG_DEBUG, "DPP: Legacy credential included in Connector credential"); - if (dpp_parse_cred_legacy(auth, cred) < 0) + if (dpp_parse_cred_legacy(conf, cred) < 0) return -1; } @@ -5946,16 +5983,17 @@ static int dpp_parse_cred_dpp(struct dpp_authentication *auth, signed_connector) != DPP_STATUS_OK) goto fail; - if (dpp_parse_connector(auth, info.payload, info.payload_len) < 0) { + if (dpp_parse_connector(auth, conf, + info.payload, info.payload_len) < 0) { wpa_printf(MSG_DEBUG, "DPP: Failed to parse connector"); goto fail; } - os_free(auth->connector); - auth->connector = os_strdup(signed_connector); + os_free(conf->connector); + conf->connector = os_strdup(signed_connector); - dpp_copy_csign(auth, csign_pub); - dpp_copy_netaccesskey(auth); + dpp_copy_csign(conf, csign_pub); + dpp_copy_netaccesskey(auth, conf); ret = 0; fail: @@ -6009,6 +6047,7 @@ static int dpp_parse_conf_obj(struct dpp_authentication *auth, { int ret = -1; struct json_token *root, *token, *discovery, *cred; + struct dpp_config_obj *conf; root = json_parse((const char *) conf_obj, conf_obj_len); if (!root) @@ -6047,8 +6086,17 @@ static int dpp_parse_conf_obj(struct dpp_authentication *auth, dpp_auth_fail(auth, "Too long discovery::ssid string value"); goto fail; } - auth->ssid_len = os_strlen(token->string); - os_memcpy(auth->ssid, token->string, auth->ssid_len); + + if (auth->num_conf_obj == DPP_MAX_CONF_OBJ) { + wpa_printf(MSG_DEBUG, + "DPP: No room for this many Config Objects - ignore this one"); + json_free(root); + return 0; + } + conf = &auth->conf_obj[auth->num_conf_obj++]; + + conf->ssid_len = os_strlen(token->string); + os_memcpy(conf->ssid, token->string, conf->ssid_len); cred = json_get_member(root, "cred"); if (!cred || cred->type != JSON_OBJECT) { @@ -6061,13 +6109,13 @@ static int dpp_parse_conf_obj(struct dpp_authentication *auth, dpp_auth_fail(auth, "No cred::akm string value found"); goto fail; } - auth->akm = dpp_akm_from_str(token->string); + conf->akm = dpp_akm_from_str(token->string); - if (dpp_akm_legacy(auth->akm)) { - if (dpp_parse_cred_legacy(auth, cred) < 0) + if (dpp_akm_legacy(conf->akm)) { + if (dpp_parse_cred_legacy(conf, cred) < 0) goto fail; - } else if (dpp_akm_dpp(auth->akm)) { - if (dpp_parse_cred_dpp(auth, cred) < 0) + } else if (dpp_akm_dpp(conf->akm)) { + if (dpp_parse_cred_dpp(auth, conf, cred) < 0) goto fail; } else { wpa_printf(MSG_DEBUG, "DPP: Unsupported akm: %s", @@ -6164,17 +6212,22 @@ int dpp_conf_resp_rx(struct dpp_authentication *auth, goto fail; } - conf_obj = dpp_get_attr(unwrapped, unwrapped_len, - DPP_ATTR_CONFIG_OBJ, &conf_obj_len); + conf_obj = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_CONFIG_OBJ, + &conf_obj_len); if (!conf_obj) { dpp_auth_fail(auth, "Missing required Configuration Object attribute"); goto fail; } - wpa_hexdump_ascii(MSG_DEBUG, "DPP: configurationObject JSON", - conf_obj, conf_obj_len); - if (dpp_parse_conf_obj(auth, conf_obj, conf_obj_len) < 0) - goto fail; + while (conf_obj) { + wpa_hexdump_ascii(MSG_DEBUG, "DPP: configurationObject JSON", + conf_obj, conf_obj_len); + if (dpp_parse_conf_obj(auth, conf_obj, conf_obj_len) < 0) + goto fail; + conf_obj = dpp_get_attr_next(conf_obj, unwrapped, unwrapped_len, + DPP_ATTR_CONFIG_OBJ, + &conf_obj_len); + } #ifdef CONFIG_DPP2 status = dpp_get_attr(unwrapped, unwrapped_len, @@ -6672,9 +6725,9 @@ int dpp_configurator_own_config(struct dpp_authentication *auth, auth->own_protocol_key = dpp_gen_keypair(auth->curve); if (!auth->own_protocol_key) return -1; - dpp_copy_netaccesskey(auth); + dpp_copy_netaccesskey(auth, &auth->conf_obj[0]); auth->peer_protocol_key = auth->own_protocol_key; - dpp_copy_csign(auth, auth->conf->csign); + dpp_copy_csign(&auth->conf_obj[0], auth->conf->csign); conf_obj = dpp_build_conf_obj(auth, ap, 0); if (!conf_obj) diff --git a/src/common/dpp.h b/src/common/dpp.h index dfc06f1a4..5c1c83c3e 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -184,6 +184,8 @@ struct dpp_configuration { int psk_set; }; +#define DPP_MAX_CONF_OBJ 10 + struct dpp_authentication { void *msg_ctx; u8 peer_version; @@ -241,16 +243,19 @@ struct dpp_authentication { struct dpp_configuration *conf_sta; struct dpp_configuration *conf2_sta; struct dpp_configurator *conf; - char *connector; /* received signedConnector */ - u8 ssid[SSID_MAX_LEN]; - u8 ssid_len; - char passphrase[64]; - u8 psk[PMK_LEN]; - int psk_set; - enum dpp_akm akm; + struct dpp_config_obj { + char *connector; /* received signedConnector */ + u8 ssid[SSID_MAX_LEN]; + u8 ssid_len; + char passphrase[64]; + u8 psk[PMK_LEN]; + int psk_set; + enum dpp_akm akm; + struct wpabuf *c_sign_key; + } conf_obj[DPP_MAX_CONF_OBJ]; + unsigned int num_conf_obj; struct wpabuf *net_access_key; os_time_t net_access_key_expiry; - struct wpabuf *c_sign_key; int send_conn_status; int conn_status_requested; #ifdef CONFIG_TESTING_OPTIONS diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index b4341f187..425eff972 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -958,12 +958,13 @@ static void wpas_dpp_start_gas_server(struct wpa_supplicant *wpa_s) static struct wpa_ssid * wpas_dpp_add_network(struct wpa_supplicant *wpa_s, - struct dpp_authentication *auth) + struct dpp_authentication *auth, + struct dpp_config_obj *conf) { struct wpa_ssid *ssid; #ifdef CONFIG_DPP2 - if (auth->akm == DPP_AKM_SAE) { + if (conf->akm == DPP_AKM_SAE) { #ifdef CONFIG_SAE struct wpa_driver_capa capa; int res; @@ -990,27 +991,27 @@ static struct wpa_ssid * wpas_dpp_add_network(struct wpa_supplicant *wpa_s, wpa_config_set_network_defaults(ssid); ssid->disabled = 1; - ssid->ssid = os_malloc(auth->ssid_len); + ssid->ssid = os_malloc(conf->ssid_len); if (!ssid->ssid) goto fail; - os_memcpy(ssid->ssid, auth->ssid, auth->ssid_len); - ssid->ssid_len = auth->ssid_len; + os_memcpy(ssid->ssid, conf->ssid, conf->ssid_len); + ssid->ssid_len = conf->ssid_len; - if (auth->connector) { + if (conf->connector) { ssid->key_mgmt = WPA_KEY_MGMT_DPP; ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED; - ssid->dpp_connector = os_strdup(auth->connector); + ssid->dpp_connector = os_strdup(conf->connector); if (!ssid->dpp_connector) goto fail; } - if (auth->c_sign_key) { - ssid->dpp_csign = os_malloc(wpabuf_len(auth->c_sign_key)); + if (conf->c_sign_key) { + ssid->dpp_csign = os_malloc(wpabuf_len(conf->c_sign_key)); if (!ssid->dpp_csign) goto fail; - os_memcpy(ssid->dpp_csign, wpabuf_head(auth->c_sign_key), - wpabuf_len(auth->c_sign_key)); - ssid->dpp_csign_len = wpabuf_len(auth->c_sign_key); + os_memcpy(ssid->dpp_csign, wpabuf_head(conf->c_sign_key), + wpabuf_len(conf->c_sign_key)); + ssid->dpp_csign_len = wpabuf_len(conf->c_sign_key); } if (auth->net_access_key) { @@ -1025,31 +1026,31 @@ static struct wpa_ssid * wpas_dpp_add_network(struct wpa_supplicant *wpa_s, ssid->dpp_netaccesskey_expiry = auth->net_access_key_expiry; } - if (!auth->connector || dpp_akm_psk(auth->akm) || - dpp_akm_sae(auth->akm)) { - if (!auth->connector) + if (!conf->connector || dpp_akm_psk(conf->akm) || + dpp_akm_sae(conf->akm)) { + if (!conf->connector) ssid->key_mgmt = 0; - if (dpp_akm_psk(auth->akm)) + if (dpp_akm_psk(conf->akm)) ssid->key_mgmt |= WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_FT_PSK; - if (dpp_akm_sae(auth->akm)) + if (dpp_akm_sae(conf->akm)) ssid->key_mgmt |= WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE; ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL; - if (auth->passphrase[0]) { + if (conf->passphrase[0]) { if (wpa_config_set_quoted(ssid, "psk", - auth->passphrase) < 0) + conf->passphrase) < 0) goto fail; wpa_config_update_psk(ssid); ssid->export_keys = 1; } else { - ssid->psk_set = auth->psk_set; - os_memcpy(ssid->psk, auth->psk, PMK_LEN); + ssid->psk_set = conf->psk_set; + os_memcpy(ssid->psk, conf->psk, PMK_LEN); } } - os_memcpy(wpa_s->dpp_last_ssid, auth->ssid, auth->ssid_len); - wpa_s->dpp_last_ssid_len = auth->ssid_len; + os_memcpy(wpa_s->dpp_last_ssid, conf->ssid, conf->ssid_len); + wpa_s->dpp_last_ssid_len = conf->ssid_len; return ssid; fail: @@ -1060,14 +1061,15 @@ fail: static int wpas_dpp_process_config(struct wpa_supplicant *wpa_s, - struct dpp_authentication *auth) + struct dpp_authentication *auth, + struct dpp_config_obj *conf) { struct wpa_ssid *ssid; if (wpa_s->conf->dpp_config_processing < 1) return 0; - ssid = wpas_dpp_add_network(wpa_s, auth); + ssid = wpas_dpp_add_network(wpa_s, auth, conf); if (!ssid) return -1; @@ -1081,49 +1083,56 @@ static int wpas_dpp_process_config(struct wpa_supplicant *wpa_s, wpa_printf(MSG_DEBUG, "DPP: Failed to update configuration"); #endif /* CONFIG_NO_CONFIG_WRITE */ + return 0; +} + + +static void wpas_dpp_post_process_config(struct wpa_supplicant *wpa_s, + struct dpp_authentication *auth) +{ if (wpa_s->conf->dpp_config_processing < 2) - return 0; + return; #ifdef CONFIG_DPP2 if (auth->peer_version >= 2) { wpa_printf(MSG_DEBUG, "DPP: Postpone connection attempt to wait for completion of DPP Configuration Result"); auth->connect_on_tx_status = 1; - return 0; + return; } #endif /* CONFIG_DPP2 */ wpas_dpp_try_to_connect(wpa_s); - return 0; } static int wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s, - struct dpp_authentication *auth) + struct dpp_authentication *auth, + struct dpp_config_obj *conf) { wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED); - if (auth->ssid_len) + if (conf->ssid_len) wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s", - wpa_ssid_txt(auth->ssid, auth->ssid_len)); - if (auth->connector) { + wpa_ssid_txt(conf->ssid, conf->ssid_len)); + if (conf->connector) { /* TODO: Save the Connector and consider using a command * to fetch the value instead of sending an event with * it. The Connector could end up being larger than what * most clients are ready to receive as an event * message. */ wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONNECTOR "%s", - auth->connector); + conf->connector); } - if (auth->c_sign_key) { + if (conf->c_sign_key) { char *hex; size_t hexlen; - hexlen = 2 * wpabuf_len(auth->c_sign_key) + 1; + hexlen = 2 * wpabuf_len(conf->c_sign_key) + 1; hex = os_malloc(hexlen); if (hex) { wpa_snprintf_hex(hex, hexlen, - wpabuf_head(auth->c_sign_key), - wpabuf_len(auth->c_sign_key)); + wpabuf_head(conf->c_sign_key), + wpabuf_len(conf->c_sign_key)); wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_C_SIGN_KEY "%s", hex); os_free(hex); @@ -1151,7 +1160,7 @@ static int wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s, } } - return wpas_dpp_process_config(wpa_s, auth); + return wpas_dpp_process_config(wpa_s, auth, conf); } @@ -1165,6 +1174,7 @@ static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token, struct dpp_authentication *auth = wpa_s->dpp_auth; int res; enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED; + unsigned int i; wpa_s->dpp_gas_dialog_token = -1; @@ -1202,9 +1212,14 @@ static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token, goto fail; } - res = wpas_dpp_handle_config_obj(wpa_s, auth); - if (res < 0) - goto fail; + for (i = 0; i < auth->num_conf_obj; i++) { + res = wpas_dpp_handle_config_obj(wpa_s, auth, + &auth->conf_obj[i]); + if (res < 0) + goto fail; + } + if (auth->num_conf_obj) + wpas_dpp_post_process_config(wpa_s, auth); status = DPP_STATUS_OK; #ifdef CONFIG_TESTING_OPTIONS @@ -1522,8 +1537,19 @@ static int wpas_dpp_process_conf_obj(void *ctx, struct dpp_authentication *auth) { struct wpa_supplicant *wpa_s = ctx; + unsigned int i; + int res = -1; - return wpas_dpp_handle_config_obj(wpa_s, auth); + for (i = 0; i < auth->num_conf_obj; i++) { + res = wpas_dpp_handle_config_obj(wpa_s, auth, + &auth->conf_obj[i]); + if (res) + break; + } + if (!res) + wpas_dpp_post_process_config(wpa_s, auth); + + return res; } #endif /* CONFIG_DPP2 */ @@ -2193,7 +2219,10 @@ int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd) wpas_dpp_set_testing_options(wpa_s, auth); if (dpp_set_configurator(wpa_s->dpp, wpa_s, auth, cmd) == 0 && dpp_configurator_own_config(auth, curve, 0) == 0) - ret = wpas_dpp_handle_config_obj(wpa_s, auth); + ret = wpas_dpp_handle_config_obj(wpa_s, auth, + &auth->conf_obj[0]); + if (!ret) + wpas_dpp_post_process_config(wpa_s, auth); dpp_auth_deinit(auth); os_free(curve);