aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <jouni@codeaurora.org>2018-05-19 14:28:01 (GMT)
committerJouni Malinen <j@w1.fi>2018-05-19 14:30:29 (GMT)
commit9be19d0b9c4e4948e70fbfeb9076d30af9d0071f (patch)
tree21ed8486d3cf56ec80bf1877c023b621ec9008e2 /wpa_supplicant
parentd6a65a83fb61c855e9c776e3f89278ed8b214535 (diff)
downloadhostap-9be19d0b9c4e4948e70fbfeb9076d30af9d0071f.zip
hostap-9be19d0b9c4e4948e70fbfeb9076d30af9d0071f.tar.gz
hostap-9be19d0b9c4e4948e70fbfeb9076d30af9d0071f.tar.bz2
SAE: Add support for using the optional Password Identifier
This extends the SAE implementation in both infrastructure and mesh BSS cases to allow an optional Password Identifier to be used. This uses the mechanism added in P802.11REVmd/D1.0. The Password Identifier is configured in a wpa_supplicant network profile as a new string parameter sae_password_id. In hostapd configuration, the existing sae_password parameter has been extended to allow the password identifier (and also a peer MAC address) to be set. In addition, multiple sae_password entries can now be provided to hostapd to allow multiple per-peer and per-identifier passwords to be set. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/config.c2
-rw-r--r--wpa_supplicant/config_file.c1
-rw-r--r--wpa_supplicant/config_ssid.h8
-rw-r--r--wpa_supplicant/config_winreg.c1
-rw-r--r--wpa_supplicant/mesh_rsn.c6
-rw-r--r--wpa_supplicant/sme.c16
-rw-r--r--wpa_supplicant/wpa_supplicant.conf5
7 files changed, 38 insertions, 1 deletions
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index f65bbb0..8ec6062 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2134,6 +2134,7 @@ static const struct parse_data ssid_fields[] = {
{ FUNC_KEY(psk) },
{ INT(mem_only_psk) },
{ STR_KEY(sae_password) },
+ { STR(sae_password_id) },
{ FUNC(proto) },
{ FUNC(key_mgmt) },
{ INT(bg_scan_period) },
@@ -2474,6 +2475,7 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid)
str_clear_free(ssid->passphrase);
os_free(ssid->ext_psk);
str_clear_free(ssid->sae_password);
+ os_free(ssid->sae_password_id);
#ifdef IEEE8021X_EAPOL
eap_peer_config_free(&ssid->eap);
#endif /* IEEE8021X_EAPOL */
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index d186f78..aa73f9d 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -749,6 +749,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
write_psk(f, ssid);
INT(mem_only_psk);
STR(sae_password);
+ STR(sae_password_id);
write_proto(f, ssid);
write_key_mgmt(f, ssid);
INT_DEF(bg_scan_period, DEFAULT_BG_SCAN_PERIOD);
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 9fd56c3..5b872fa 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -194,6 +194,14 @@ struct wpa_ssid {
char *sae_password;
/**
+ * sae_password_id - SAE password identifier
+ *
+ * This parameter can be used to identify a specific SAE password. If
+ * not included, the default SAE password is used instead.
+ */
+ char *sae_password_id;
+
+ /**
* ext_psk - PSK/passphrase name in external storage
*
* If this is set, PSK/passphrase will be fetched from external storage
diff --git a/wpa_supplicant/config_winreg.c b/wpa_supplicant/config_winreg.c
index 8b8992b..0ce1830 100644
--- a/wpa_supplicant/config_winreg.c
+++ b/wpa_supplicant/config_winreg.c
@@ -873,6 +873,7 @@ static int wpa_config_write_network(HKEY hk, struct wpa_ssid *ssid, int id)
write_bssid(netw, ssid);
write_psk(netw, ssid);
STR(sae_password);
+ STR(sae_password_id);
write_proto(netw, ssid);
write_key_mgmt(netw, ssid);
write_pairwise(netw, ssid);
diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c
index 25dcde5..e74cb16 100644
--- a/wpa_supplicant/mesh_rsn.c
+++ b/wpa_supplicant/mesh_rsn.c
@@ -332,8 +332,14 @@ static int mesh_rsn_build_sae_commit(struct wpa_supplicant *wpa_s,
return -1;
}
+ if (sta->sae->tmp && !sta->sae->tmp->pw_id && ssid->sae_password_id) {
+ sta->sae->tmp->pw_id = os_strdup(ssid->sae_password_id);
+ if (!sta->sae->tmp->pw_id)
+ return -1;
+ }
return sae_prepare_commit(wpa_s->own_addr, sta->addr,
(u8 *) password, os_strlen(password),
+ ssid->sae_password_id,
sta->sae);
}
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 1348e1c..d57195f 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -117,12 +117,15 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
if (sae_prepare_commit(wpa_s->own_addr, bssid,
(u8 *) password, os_strlen(password),
+ ssid->sae_password_id,
&wpa_s->sme.sae) < 0) {
wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
return NULL;
}
len = wpa_s->sme.sae_token ? wpabuf_len(wpa_s->sme.sae_token) : 0;
+ if (ssid->sae_password_id)
+ len += 4 + os_strlen(ssid->sae_password_id);
buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + len);
if (buf == NULL)
return NULL;
@@ -130,7 +133,8 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
wpabuf_put_le16(buf, 1); /* Transaction seq# */
wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
}
- sae_write_commit(&wpa_s->sme.sae, buf, wpa_s->sme.sae_token);
+ sae_write_commit(&wpa_s->sme.sae, buf, wpa_s->sme.sae_token,
+ ssid->sae_password_id);
return buf;
}
@@ -1005,6 +1009,16 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
return 0;
}
+ if (auth_transaction == 1 &&
+ status_code == WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER) {
+ const u8 *bssid = sa ? sa : wpa_s->pending_bssid;
+
+ wpa_msg(wpa_s, MSG_INFO,
+ WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER MACSTR,
+ MAC2STR(bssid));
+ return -1;
+ }
+
if (status_code != WLAN_STATUS_SUCCESS)
return -1;
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 892e735..a235ea0 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -954,6 +954,11 @@ fast_reauth=1
# used, but psk follows the WPA-PSK constraints (8..63 characters) even though
# SAE passwords do not have such constraints.
#
+# sae_password_id: SAE password identifier
+# This parameter can be used to set an identifier for the SAE password. By
+# default, no such identifier is used. If set, the specified identifier value
+# is used by the other peer to select which password to use for authentication.
+#
# eapol_flags: IEEE 802.1X/EAPOL options (bit field)
# Dynamic WEP key required for non-WPA mode
# bit0 (1): require dynamically generated unicast WEP key