]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP2: Support multiple Config Objects in Enrollee
authorJouni Malinen <jouni@codeaurora.org>
Thu, 26 Sep 2019 22:08:56 +0000 (01:08 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 1 Oct 2019 11:21:51 +0000 (14:21 +0300)
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 <jouni@codeaurora.org>
src/ap/dpp_hostapd.c
src/common/dpp.c
src/common/dpp.h
wpa_supplicant/dpp_supplicant.c

index effcc7ab1d3a80b87bcb90260bf04ae3d6e0d0b7..085d42325b8a2348c1910ad08a663cbb5d415a4e 100644 (file)
@@ -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;
        }
 
index bdf5c0db8b82d63a025786d2d60f0a83ea58e966..fbad03eeb0810ea7d65b9a9c63ac9bc0c1c1a48c 100644 (file)
@@ -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)
index dfc06f1a458f2e989e594a1759471c3243274ada..5c1c83c3ed36fc9d8a2f82815deb92e4f1df2fe9 100644 (file)
@@ -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
index b4341f1870905d2f200eb9941824969fde7b4b26..425eff97207e7099ca1e0c8c47389abab8d0541f 100644 (file)
@@ -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;
+
+       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 wpas_dpp_handle_config_obj(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);