]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Received Configurator backup processing
authorJouni Malinen <jouni@codeaurora.org>
Thu, 30 Jan 2020 21:56:31 +0000 (23:56 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 31 Jan 2020 21:16:05 +0000 (23:16 +0200)
Add local Configurator instance for each received Configurator backup.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/ap/dpp_hostapd.c
src/common/dpp.c
src/common/dpp.h
src/common/wpa_ctrl.h
wpa_supplicant/dpp_supplicant.c

index 48922516fa6ccd8e3dcbd8a4ebe42adf2f6ec56a..8e22c8ba60c323d3ded303e8c1ba799425c4d64a 100644 (file)
@@ -762,6 +762,33 @@ static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
 }
 
 
+static int hostapd_dpp_handle_key_pkg(struct hostapd_data *hapd,
+                                     struct dpp_asymmetric_key *key)
+{
+#ifdef CONFIG_DPP2
+       int res;
+
+       if (!key)
+               return 0;
+
+       wpa_printf(MSG_DEBUG, "DPP: Received Configurator backup");
+       wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
+
+       while (key) {
+               res = dpp_configurator_from_backup(
+                       hapd->iface->interfaces->dpp, key);
+               if (res < 0)
+                       return -1;
+               wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFIGURATOR_ID "%d",
+                       res);
+               key = key->next;
+       }
+#endif /* CONFIG_DPP2 */
+
+       return 0;
+}
+
+
 static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
                                    enum gas_query_ap_result result,
                                    const struct wpabuf *adv_proto,
@@ -806,6 +833,9 @@ static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
        }
 
        hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
+       if (hostapd_dpp_handle_key_pkg(hapd, auth->conf_key_pkg) < 0)
+               goto fail;
+
        status = DPP_STATUS_OK;
 #ifdef CONFIG_TESTING_OPTIONS
        if (dpp_test == DPP_TEST_REJECT_CONFIG) {
index 814adf0b0736ec0eaf058d3cd4f07368684725fd..abcd6bf289d30ab9b6ab0ff044279aa4afbb8801 100644 (file)
@@ -7590,15 +7590,41 @@ int dpp_configurator_get_key(const struct dpp_configurator *conf, char *buf,
 }
 
 
-struct dpp_configurator *
-dpp_keygen_configurator(const char *curve, const u8 *privkey,
-                       size_t privkey_len)
+static int dpp_configurator_gen_kid(struct dpp_configurator *conf)
 {
-       struct dpp_configurator *conf;
        struct wpabuf *csign_pub = NULL;
        u8 kid_hash[SHA256_MAC_LEN];
        const u8 *addr[1];
        size_t len[1];
+       int res;
+
+       csign_pub = dpp_get_pubkey_point(conf->csign, 1);
+       if (!csign_pub) {
+               wpa_printf(MSG_INFO, "DPP: Failed to extract C-sign-key");
+               return -1;
+       }
+
+       /* kid = SHA256(ANSI X9.63 uncompressed C-sign-key) */
+       addr[0] = wpabuf_head(csign_pub);
+       len[0] = wpabuf_len(csign_pub);
+       res = sha256_vector(1, addr, len, kid_hash);
+       wpabuf_free(csign_pub);
+       if (res < 0) {
+               wpa_printf(MSG_DEBUG,
+                          "DPP: Failed to derive kid for C-sign-key");
+               return -1;
+       }
+
+       conf->kid = base64_url_encode(kid_hash, sizeof(kid_hash), NULL);
+       return conf->kid ? 0 : -1;
+}
+
+
+struct dpp_configurator *
+dpp_keygen_configurator(const char *curve, const u8 *privkey,
+                       size_t privkey_len)
+{
+       struct dpp_configurator *conf;
 
        conf = os_zalloc(sizeof(*conf));
        if (!conf)
@@ -7624,31 +7650,12 @@ dpp_keygen_configurator(const char *curve, const u8 *privkey,
                goto fail;
        conf->own = 1;
 
-       csign_pub = dpp_get_pubkey_point(conf->csign, 1);
-       if (!csign_pub) {
-               wpa_printf(MSG_INFO, "DPP: Failed to extract C-sign-key");
-               goto fail;
-       }
-
-       /* kid = SHA256(ANSI X9.63 uncompressed C-sign-key) */
-       addr[0] = wpabuf_head(csign_pub);
-       len[0] = wpabuf_len(csign_pub);
-       if (sha256_vector(1, addr, len, kid_hash) < 0) {
-               wpa_printf(MSG_DEBUG,
-                          "DPP: Failed to derive kid for C-sign-key");
-               goto fail;
-       }
-
-       conf->kid = base64_url_encode(kid_hash, sizeof(kid_hash), NULL);
-       if (!conf->kid)
+       if (dpp_configurator_gen_kid(conf) < 0)
                goto fail;
-out:
-       wpabuf_free(csign_pub);
        return conf;
 fail:
        dpp_configurator_free(conf);
-       conf = NULL;
-       goto out;
+       return NULL;
 }
 
 
@@ -10206,6 +10213,48 @@ int dpp_configurator_get_key_id(struct dpp_global *dpp, unsigned int id,
 
 #ifdef CONFIG_DPP2
 
+int dpp_configurator_from_backup(struct dpp_global *dpp,
+                                struct dpp_asymmetric_key *key)
+{
+       struct dpp_configurator *conf;
+       const EC_KEY *eckey;
+       const EC_GROUP *group;
+       int nid;
+       const struct dpp_curve_params *curve;
+
+       if (!key->csign)
+               return -1;
+       eckey = EVP_PKEY_get0_EC_KEY(key->csign);
+       if (!eckey)
+               return -1;
+       group = EC_KEY_get0_group(eckey);
+       if (!group)
+               return -1;
+       nid = EC_GROUP_get_curve_name(group);
+       curve = dpp_get_curve_nid(nid);
+       if (!curve) {
+               wpa_printf(MSG_INFO, "DPP: Unsupported group in c-sign-key");
+               return -1;
+       }
+
+       conf = os_zalloc(sizeof(*conf));
+       if (!conf)
+               return -1;
+       conf->curve = curve;
+       conf->csign = key->csign;
+       key->csign = NULL;
+       conf->own = 1;
+       if (dpp_configurator_gen_kid(conf) < 0) {
+               dpp_configurator_free(conf);
+               return -1;
+       }
+
+       conf->id = dpp_next_configurator_id(dpp);
+       dl_list_add(&dpp->configurator, &conf->list);
+       return conf->id;
+}
+
+
 static void dpp_controller_conn_status_result_wait_timeout(void *eloop_ctx,
                                                           void *timeout_ctx);
 
index c8db9ab6a4b4ab44b111f1f1df388e9f526c9e8d..c47a9b87c7eb8a514140c8fc645e231d8f8c0bb8 100644 (file)
@@ -566,6 +566,8 @@ int dpp_configurator_add(struct dpp_global *dpp, const char *cmd);
 int dpp_configurator_remove(struct dpp_global *dpp, const char *id);
 int dpp_configurator_get_key_id(struct dpp_global *dpp, unsigned int id,
                                char *buf, size_t buflen);
+int dpp_configurator_from_backup(struct dpp_global *dpp,
+                                struct dpp_asymmetric_key *key);
 int dpp_relay_add_controller(struct dpp_global *dpp,
                             struct dpp_relay_config *config);
 int dpp_relay_rx_action(struct dpp_global *dpp, const u8 *src, const u8 *hdr,
index f03c698f1e156fc26c1ac1b5ad32cef1162a986f..48002be6ce975c2299d61ae8f568ac1e16cfff54 100644 (file)
@@ -179,6 +179,7 @@ extern "C" {
 #define DPP_EVENT_NET_ACCESS_KEY "DPP-NET-ACCESS-KEY "
 #define DPP_EVENT_MISSING_CONNECTOR "DPP-MISSING-CONNECTOR "
 #define DPP_EVENT_NETWORK_ID "DPP-NETWORK-ID "
+#define DPP_EVENT_CONFIGURATOR_ID "DPP-CONFIGURATOR-ID "
 #define DPP_EVENT_RX "DPP-RX "
 #define DPP_EVENT_TX "DPP-TX "
 #define DPP_EVENT_TX_STATUS "DPP-TX-STATUS "
index f147afd9d20a1c138e1f4679dbe9462d0a39bcc4..0811ab300215202a8c439b717d3a8327838d8873 100644 (file)
@@ -1262,6 +1262,32 @@ static int wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s,
 }
 
 
+static int wpas_dpp_handle_key_pkg(struct wpa_supplicant *wpa_s,
+                                  struct dpp_asymmetric_key *key)
+{
+#ifdef CONFIG_DPP2
+       int res;
+
+       if (!key)
+               return 0;
+
+       wpa_printf(MSG_DEBUG, "DPP: Received Configurator backup");
+       wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
+
+       while (key) {
+               res = dpp_configurator_from_backup(wpa_s->dpp, key);
+               if (res < 0)
+                       return -1;
+               wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFIGURATOR_ID "%d",
+                       res);
+               key = key->next;
+       }
+#endif /* CONFIG_DPP2 */
+
+       return 0;
+}
+
+
 static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
                                 enum gas_query_result result,
                                 const struct wpabuf *adv_proto,
@@ -1318,6 +1344,8 @@ static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
        }
        if (auth->num_conf_obj)
                wpas_dpp_post_process_config(wpa_s, auth);
+       if (wpas_dpp_handle_key_pkg(wpa_s, auth->conf_key_pkg) < 0)
+               goto fail;
 
        status = DPP_STATUS_OK;
 #ifdef CONFIG_TESTING_OPTIONS