]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Add DPP_CONFIGURATOR_SIGN to generate own connector
authorJouni Malinen <jouni@qca.qualcomm.com>
Tue, 4 Jul 2017 14:48:44 +0000 (17:48 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 4 Jul 2017 14:48:44 +0000 (17:48 +0300)
The DPP Configurator can use this new command to generate its own signed
connector for the network that it manages.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/common/dpp.c
src/common/dpp.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/dpp_supplicant.c
wpa_supplicant/dpp_supplicant.h

index 528bdb4a2529a06cd8541dd68399ab09ac741fd3..026c81e5e71b0dae96d9ace00d6c5638c7fb3a9f 100644 (file)
@@ -4421,6 +4421,50 @@ fail:
 }
 
 
+int dpp_configurator_own_config(struct dpp_authentication *auth,
+                               const char *curve)
+{
+       struct wpabuf *conf_obj;
+       int ret = -1;
+
+       if (!auth->conf) {
+               wpa_printf(MSG_DEBUG, "DPP: No configurator specified");
+               return -1;
+       }
+
+       if (!curve) {
+               auth->curve = &dpp_curves[0];
+       } else {
+               auth->curve = dpp_get_curve_name(curve);
+               if (!auth->curve) {
+                       wpa_printf(MSG_INFO, "DPP: Unsupported curve: %s",
+                                  curve);
+                       return -1;
+               }
+       }
+       wpa_printf(MSG_DEBUG,
+                  "DPP: Building own configuration/connector with curve %s",
+                  auth->curve->name);
+
+       auth->own_protocol_key = dpp_gen_keypair(auth->curve);
+       if (!auth->own_protocol_key)
+               return -1;
+       dpp_copy_netaccesskey(auth);
+       auth->peer_protocol_key = auth->own_protocol_key;
+       dpp_copy_csign(auth, auth->conf->csign);
+
+       conf_obj = dpp_build_conf_obj(auth, 0);
+       if (!conf_obj)
+               goto fail;
+       ret = dpp_parse_conf_obj(auth, wpabuf_head(conf_obj),
+                                wpabuf_len(conf_obj));
+fail:
+       wpabuf_free(conf_obj);
+       auth->peer_protocol_key = NULL;
+       return ret;
+}
+
+
 static int dpp_compatible_netrole(const char *role1, const char *role2)
 {
        return (os_strcmp(role1, "sta") == 0 && os_strcmp(role2, "ap") == 0) ||
index 8aa78c51c77bb2d7e48b70043ad3e20de461342d..4a53c5d7654b225911b021386ae80d570722aa1f 100644 (file)
@@ -254,6 +254,8 @@ void dpp_configurator_free(struct dpp_configurator *conf);
 struct dpp_configurator *
 dpp_keygen_configurator(const char *curve, const u8 *privkey,
                        size_t privkey_len);
+int dpp_configurator_own_config(struct dpp_authentication *auth,
+                               const char *curve);
 int dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
                   const u8 *net_access_key, size_t net_access_key_len,
                   const u8 *csign_key, size_t csign_key_len,
index bb9f26e97c4945b2e8aa4b053f24d441aaa46672..710489db1c5ec3d32e1215f61c8c0c39e97f0e7a 100644 (file)
@@ -10256,6 +10256,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
        } else if (os_strncmp(buf, "DPP_CONFIGURATOR_REMOVE ", 24) == 0) {
                if (wpas_dpp_configurator_remove(wpa_s, buf + 24) < 0)
                        reply_len = -1;
+       } else if (os_strncmp(buf, "DPP_CONFIGURATOR_SIGN ", 22) == 0) {
+               if (wpas_dpp_configurator_sign(wpa_s, buf + 22) < 0)
+                       reply_len = -1;
        } else if (os_strncmp(buf, "DPP_PKEX_ADD ", 13) == 0) {
                int res;
 
index 6361b17dc9ffdb23a1187e3fb00f29212539ade0..7acb44fb22cc887b834ca739860e3f31c3944776 100644 (file)
@@ -980,48 +980,9 @@ static void wpas_dpp_process_config(struct wpa_supplicant *wpa_s,
 }
 
 
-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,
-                                const struct wpabuf *resp, u16 status_code)
+static void wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s,
+                                      struct dpp_authentication *auth)
 {
-       struct wpa_supplicant *wpa_s = ctx;
-       const u8 *pos;
-       struct dpp_authentication *auth = wpa_s->dpp_auth;
-
-       if (!auth || !auth->auth_success) {
-               wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
-               return;
-       }
-       if (!resp || status_code != WLAN_STATUS_SUCCESS) {
-               wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
-               goto fail;
-       }
-
-       wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
-                       adv_proto);
-       wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
-                       resp);
-
-       if (wpabuf_len(adv_proto) != 10 ||
-           !(pos = wpabuf_head(adv_proto)) ||
-           pos[0] != WLAN_EID_ADV_PROTO ||
-           pos[1] != 8 ||
-           pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
-           pos[4] != 5 ||
-           WPA_GET_BE24(&pos[5]) != OUI_WFA ||
-           pos[8] != 0x1a ||
-           pos[9] != 1) {
-               wpa_printf(MSG_DEBUG,
-                          "DPP: Not a DPP Advertisement Protocol ID");
-               goto fail;
-       }
-
-       if (dpp_conf_resp_rx(auth, resp) < 0) {
-               wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
-               goto fail;
-       }
-
        wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
        if (auth->ssid_len)
                wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
@@ -1079,7 +1040,52 @@ static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
        }
 
        wpas_dpp_process_config(wpa_s, auth);
+}
+
+
+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,
+                                const struct wpabuf *resp, u16 status_code)
+{
+       struct wpa_supplicant *wpa_s = ctx;
+       const u8 *pos;
+       struct dpp_authentication *auth = wpa_s->dpp_auth;
+
+       if (!auth || !auth->auth_success) {
+               wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
+               return;
+       }
+       if (!resp || status_code != WLAN_STATUS_SUCCESS) {
+               wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
+               goto fail;
+       }
+
+       wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
+                       adv_proto);
+       wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
+                       resp);
+
+       if (wpabuf_len(adv_proto) != 10 ||
+           !(pos = wpabuf_head(adv_proto)) ||
+           pos[0] != WLAN_EID_ADV_PROTO ||
+           pos[1] != 8 ||
+           pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
+           pos[4] != 5 ||
+           WPA_GET_BE24(&pos[5]) != OUI_WFA ||
+           pos[8] != 0x1a ||
+           pos[9] != 1) {
+               wpa_printf(MSG_DEBUG,
+                          "DPP: Not a DPP Advertisement Protocol ID");
+               goto fail;
+       }
 
+       if (dpp_conf_resp_rx(auth, resp) < 0) {
+               wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
+               goto fail;
+       }
+
+       wpas_dpp_handle_config_obj(wpa_s, auth);
        dpp_auth_deinit(wpa_s->dpp_auth);
        wpa_s->dpp_auth = NULL;
        return;
@@ -1785,6 +1791,31 @@ int wpas_dpp_configurator_remove(struct wpa_supplicant *wpa_s, const char *id)
 }
 
 
+int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd)
+{
+       struct dpp_authentication *auth;
+       int ret = -1;
+       char *curve = NULL;
+
+       auth = os_zalloc(sizeof(*auth));
+       if (!auth)
+               return -1;
+
+       curve = get_param(cmd, " curve=");
+       wpas_dpp_set_configurator(wpa_s, auth, cmd);
+
+       if (dpp_configurator_own_config(auth, curve) == 0) {
+               wpas_dpp_handle_config_obj(wpa_s, auth);
+               ret = 0;
+       }
+
+       dpp_auth_deinit(auth);
+       os_free(curve);
+
+       return ret;
+}
+
+
 static void
 wpas_dpp_tx_introduction_status(struct wpa_supplicant *wpa_s,
                                unsigned int freq, const u8 *dst,
index ced86c1b6f72fe8fd6f805250ea71d0a0a45d1e6..05a466d55f7c7a9115b1d2d3263a6629d69b6f14 100644 (file)
@@ -27,6 +27,7 @@ void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
                        const u8 *buf, size_t len, unsigned int freq);
 int wpas_dpp_configurator_add(struct wpa_supplicant *wpa_s, const char *cmd);
 int wpas_dpp_configurator_remove(struct wpa_supplicant *wpa_s, const char *id);
+int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd);
 int wpas_dpp_pkex_add(struct wpa_supplicant *wpa_s, const char *cmd);
 int wpas_dpp_pkex_remove(struct wpa_supplicant *wpa_s, const char *id);
 int wpas_dpp_init(struct wpa_supplicant *wpa_s);