]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Add akm=sae and akm=psk+sae support in Enrollee role
authorJouni Malinen <jouni@qca.qualcomm.com>
Wed, 22 Nov 2017 19:04:41 +0000 (21:04 +0200)
committerJouni Malinen <j@w1.fi>
Wed, 22 Nov 2017 19:23:51 +0000 (21:23 +0200)
This allows DPP to be used for enrolling credentials for SAE networks in
addition to the legacy PSK (WPA-PSK) case. In addition, enable FT-PSK
and FT-SAE cases automatically.

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

index 821b5f3b587691b6ca73e860f95ea49682c2943e..222a53630781e85dadb7c115ea290f6d9ff120cf 100644 (file)
@@ -711,6 +711,8 @@ static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
        }
 
        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)
                wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
                        wpa_ssid_txt(auth->ssid, auth->ssid_len));
index dc975a5dead78de8afc2dc45e40042a07e6287af..e82d115e691104a96db3f6ba4086db7d1a979fed 100644 (file)
@@ -4517,6 +4517,11 @@ static int dpp_parse_cred_legacy(struct dpp_authentication *auth,
                os_strlcpy(auth->passphrase, pass->string,
                           sizeof(auth->passphrase));
        } else if (psk_hex && psk_hex->type == JSON_STRING) {
+               if (auth->akm == DPP_AKM_SAE) {
+                       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) {
                        wpa_printf(MSG_DEBUG, "DPP: Invalid psk_hex encoding");
@@ -4530,6 +4535,12 @@ static int dpp_parse_cred_legacy(struct dpp_authentication *auth,
                return -1;
        }
 
+       if ((auth->akm == DPP_AKM_SAE || auth->akm == DPP_AKM_PSK_SAE) &&
+           !auth->passphrase[0]) {
+               wpa_printf(MSG_DEBUG, "DPP: No pass for sae found");
+               return -1;
+       }
+
        return 0;
 }
 
@@ -5092,6 +5103,37 @@ fail:
 }
 
 
+const char * dpp_akm_str(enum dpp_akm akm)
+{
+       switch (akm) {
+       case DPP_AKM_DPP:
+               return "dpp";
+       case DPP_AKM_PSK:
+               return "psk";
+       case DPP_AKM_SAE:
+               return "sae";
+       case DPP_AKM_PSK_SAE:
+               return "psk+sae";
+       default:
+               return "??";
+       }
+}
+
+
+static enum dpp_akm dpp_akm_from_str(const char *akm)
+{
+       if (os_strcmp(akm, "psk") == 0)
+               return DPP_AKM_PSK;
+       if (os_strcmp(akm, "sae") == 0)
+               return DPP_AKM_SAE;
+       if (os_strcmp(akm, "psk+sae") == 0)
+               return DPP_AKM_PSK_SAE;
+       if (os_strcmp(akm, "dpp") == 0)
+               return DPP_AKM_DPP;
+       return DPP_AKM_UNKNOWN;
+}
+
+
 static int dpp_parse_conf_obj(struct dpp_authentication *auth,
                              const u8 *conf_obj, u16 conf_obj_len)
 {
@@ -5149,10 +5191,13 @@ static int dpp_parse_conf_obj(struct dpp_authentication *auth,
                dpp_auth_fail(auth, "No cred::akm string value found");
                goto fail;
        }
-       if (os_strcmp(token->string, "psk") == 0) {
+       auth->akm = dpp_akm_from_str(token->string);
+
+       if (auth->akm == DPP_AKM_PSK || auth->akm == DPP_AKM_SAE ||
+           auth->akm == DPP_AKM_PSK_SAE) {
                if (dpp_parse_cred_legacy(auth, cred) < 0)
                        goto fail;
-       } else if (os_strcmp(token->string, "dpp") == 0) {
+       } else if (auth->akm == DPP_AKM_DPP) {
                if (dpp_parse_cred_dpp(auth, cred) < 0)
                        goto fail;
        } else {
index 235e8ffb441a35aef21af15302758c3ff843d29e..b972126853b59ec5679ee548cc023a16f667197f 100644 (file)
@@ -136,6 +136,14 @@ struct dpp_pkex {
        unsigned int freq;
 };
 
+enum dpp_akm {
+       DPP_AKM_UNKNOWN,
+       DPP_AKM_DPP,
+       DPP_AKM_PSK,
+       DPP_AKM_SAE,
+       DPP_AKM_PSK_SAE
+};
+
 struct dpp_configuration {
        u8 ssid[32];
        size_t ssid_len;
@@ -201,6 +209,7 @@ struct dpp_authentication {
        char passphrase[64];
        u8 psk[PMK_LEN];
        int psk_set;
+       enum dpp_akm akm;
        struct wpabuf *net_access_key;
        os_time_t net_access_key_expiry;
        struct wpabuf *c_sign_key;
@@ -361,6 +370,7 @@ struct wpabuf * dpp_alloc_msg(enum dpp_public_action_frame_type type,
 const u8 * dpp_get_attr(const u8 *buf, size_t len, u16 req_id, u16 *ret_len);
 int dpp_check_attrs(const u8 *buf, size_t len);
 int dpp_key_expired(const char *timestamp, os_time_t *expiry);
+const char * dpp_akm_str(enum dpp_akm akm);
 void dpp_configurator_free(struct dpp_configurator *conf);
 struct dpp_configurator *
 dpp_keygen_configurator(const char *curve, const u8 *privkey,
index f2a3c4bf93afccebce3568d90db437bb4e2cbc34..25cf1014cdd967b0331362b1a0ab7d63b2fa4f0f 100644 (file)
@@ -160,6 +160,7 @@ extern "C" {
 #define DPP_EVENT_CONF_RECEIVED "DPP-CONF-RECEIVED "
 #define DPP_EVENT_CONF_SENT "DPP-CONF-SENT "
 #define DPP_EVENT_CONF_FAILED "DPP-CONF-FAILED "
+#define DPP_EVENT_CONFOBJ_AKM "DPP-CONFOBJ-AKM "
 #define DPP_EVENT_CONFOBJ_SSID "DPP-CONFOBJ-SSID "
 #define DPP_EVENT_CONFOBJ_PASS "DPP-CONFOBJ-PASS "
 #define DPP_EVENT_CONFOBJ_PSK "DPP-CONFOBJ-PSK "
index 7a7a8214fc0f2c4dfd2907c2a420591c28ea2d62..c20891c79b394865a8d77dfd0e36b500e656be56 100644 (file)
@@ -1108,7 +1108,13 @@ static struct wpa_ssid * wpas_dpp_add_network(struct wpa_supplicant *wpa_s,
        }
 
        if (!auth->connector) {
-               ssid->key_mgmt = WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_PSK_SHA256;
+               ssid->key_mgmt = 0;
+               if (auth->akm == DPP_AKM_PSK || auth->akm == DPP_AKM_PSK_SAE)
+                       ssid->key_mgmt |= WPA_KEY_MGMT_PSK |
+                               WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_FT_PSK;
+               if (auth->akm == DPP_AKM_SAE || auth->akm == DPP_AKM_PSK_SAE)
+                       ssid->key_mgmt |= WPA_KEY_MGMT_SAE |
+                               WPA_KEY_MGMT_FT_SAE;
                ssid->ieee80211w = 1;
                if (auth->passphrase[0]) {
                        if (wpa_config_set_quoted(ssid, "psk",