supplicant: add support for SAE key management

When SAE key managmenet is used, the supplicant can still use the "psk"
property. Only when the pass phrase doesn't conform to WPA-PSK
limitations, the sae_password must be used.
This commit is contained in:
Lubomir Rintel
2019-01-22 09:46:10 +01:00
parent 2d3e42b5a7
commit 6640fb4b36
3 changed files with 90 additions and 11 deletions

View File

@@ -807,7 +807,22 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
if (psk) {
size_t psk_len = strlen (psk);
if (psk_len == 64) {
if (psk_len >= 8 && psk_len <= 63) {
/* Use TYPE_STRING here so that it gets pushed to the
* supplicant as a string, and therefore gets quoted,
* and therefore the supplicant will interpret it as a
* passphrase and not a hex key.
*/
if (!nm_supplicant_config_add_option_with_type (self, "psk", psk, -1, TYPE_STRING, "<hidden>", error))
return FALSE;
} else if (nm_streq (key_mgmt, "sae")) {
/* If the SAE password doesn't comply with WPA-PSK limitation,
* we need to call it "sae_password" instead of "psk".
*/
if (!nm_supplicant_config_add_option_with_type (self, "sae_password", psk, -1, TYPE_STRING, "<hidden>", error))
return FALSE;
} else if (psk_len == 64) {
guint8 buffer[32];
/* Hex PSK */
@@ -827,14 +842,6 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
"<hidden>",
error))
return FALSE;
} else if (psk_len >= 8 && psk_len <= 63) {
/* Use TYPE_STRING here so that it gets pushed to the
* supplicant as a string, and therefore gets quoted,
* and therefore the supplicant will interpret it as a
* passphrase and not a hex key.
*/
if (!nm_supplicant_config_add_option_with_type (self, "psk", psk, -1, TYPE_STRING, "<hidden>", error))
return FALSE;
} else {
g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
"Cannot add psk to supplicant config due to invalid PSK length %u (not between 8 and 63 characters)",
@@ -861,7 +868,8 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
/* Only WPA-specific things when using WPA */
if ( !strcmp (key_mgmt, "wpa-none")
|| !strcmp (key_mgmt, "wpa-psk")
|| !strcmp (key_mgmt, "wpa-eap")) {
|| !strcmp (key_mgmt, "wpa-eap")
|| !strcmp (key_mgmt, "sae")) {
if (!ADD_STRING_LIST_VAL (self, setting, wireless_security, proto, protos, "proto", ' ', TRUE, NULL, error))
return FALSE;
if (!ADD_STRING_LIST_VAL (self, setting, wireless_security, pairwise, pairwise, "pairwise", ' ', TRUE, NULL, error))

View File

@@ -72,7 +72,7 @@ const char * proto_allowed[] = { "WPA", "RSN", NULL };
const char * key_mgmt_allowed[] = { "WPA-PSK", "WPA-PSK-SHA256",
"WPA-EAP", "WPA-EAP-SHA256",
"FILS-SHA256", "FILS-SHA384",
"IEEE8021X", "WPA-NONE",
"IEEE8021X", "WPA-NONE", "SAE",
"NONE", NULL };
const char * auth_alg_allowed[] = { "OPEN", "SHARED", "LEAP", NULL };
const char * eap_allowed[] = { "LEAP", "MD5", "TLS", "PEAP", "TTLS", "SIM",

View File

@@ -388,6 +388,76 @@ test_wifi_wpa_psk (const char *detail,
g_assert_not_reached ();
}
static void
test_wifi_sae_psk (const char *psk)
{
gs_unref_object NMConnection *connection = NULL;
gs_unref_variant GVariant *config_dict = NULL;
NMSettingWirelessSecurity *s_wsec;
gboolean success;
GError *error = NULL;
const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 };
gs_unref_bytes GBytes *ssid = g_bytes_new (ssid_data, sizeof (ssid_data));
const char *bssid_str = "11:22:33:44:55:66";
int short_psk = strlen (psk) < 8;
connection = new_basic_connection ("Test Wifi SAE", ssid, bssid_str);
/* Wifi Security setting */
s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wsec));
g_object_set (s_wsec,
NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae",
NM_SETTING_WIRELESS_SECURITY_PSK, psk,
NULL);
nm_setting_wireless_security_add_proto (s_wsec, "rsn");
nm_setting_wireless_security_add_pairwise (s_wsec, "tkip");
nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp");
nm_setting_wireless_security_add_group (s_wsec, "tkip");
nm_setting_wireless_security_add_group (s_wsec, "ccmp");
success = nm_connection_verify (connection, &error);
g_assert_no_error (error);
g_assert (success);
NMTST_EXPECT_NM_INFO ("Config: added 'ssid' value 'Test SSID'*");
NMTST_EXPECT_NM_INFO ("Config: added 'scan_ssid' value '1'*");
NMTST_EXPECT_NM_INFO ("Config: added 'bssid' value '11:22:33:44:55:66'*");
NMTST_EXPECT_NM_INFO ("Config: added 'freq_list' value *");
NMTST_EXPECT_NM_INFO ("Config: added 'key_mgmt' value 'SAE'");
if (short_psk)
NMTST_EXPECT_NM_INFO ("Config: added 'sae_password' value *");
else
NMTST_EXPECT_NM_INFO ("Config: added 'psk' value *");
NMTST_EXPECT_NM_INFO ("Config: added 'proto' value 'RSN'");
NMTST_EXPECT_NM_INFO ("Config: added 'pairwise' value 'TKIP CCMP'");
NMTST_EXPECT_NM_INFO ("Config: added 'group' value 'TKIP CCMP'");
NMTST_EXPECT_NM_INFO ("Config: added 'ieee80211w' value '0'");
config_dict = build_supplicant_config (connection, 1500, 0, TRUE, TRUE);
g_test_assert_expected_messages ();
g_assert (config_dict);
validate_opt ("wifi-sae", config_dict, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1));
validate_opt ("wifi-sae", config_dict, "ssid", TYPE_BYTES, ssid);
validate_opt ("wifi-sae", config_dict, "bssid", TYPE_KEYWORD, bssid_str);
validate_opt ("wifi-sae", config_dict, "key_mgmt", TYPE_KEYWORD, "SAE");
validate_opt ("wifi-sae", config_dict, "proto", TYPE_KEYWORD, "RSN");
validate_opt ("wifi-sae", config_dict, "pairwise", TYPE_KEYWORD, "TKIP CCMP");
validate_opt ("wifi-sae", config_dict, "group", TYPE_KEYWORD, "TKIP CCMP");
if (short_psk)
validate_opt ("wifi-sae", config_dict, "sae_password", TYPE_KEYWORD, psk);
else
validate_opt ("wifi-sae", config_dict, "psk", TYPE_KEYWORD, psk);
}
static void
test_wifi_sae (void)
{
test_wifi_sae_psk ("Moo");
test_wifi_sae_psk ("Hello World!");
}
static void
test_wifi_wpa_psk_types (void)
{
@@ -580,6 +650,7 @@ int main (int argc, char **argv)
g_test_add_func ("/supplicant-config/wifi-eap/locked-bssid", test_wifi_eap_locked_bssid);
g_test_add_func ("/supplicant-config/wifi-eap/unlocked-bssid", test_wifi_eap_unlocked_bssid);
g_test_add_func ("/supplicant-config/wifi-eap/fils-disabled", test_wifi_eap_fils_disabled);
g_test_add_func ("/supplicant-config/wifi-sae", test_wifi_sae);
return g_test_run ();
}