From 5cc0148e7f46cd62f3f16b0a02f7ecdb0a1c8b3e Mon Sep 17 00:00:00 2001 From: James Prestwood Date: Mon, 22 Apr 2019 10:11:46 -0700 Subject: [PATCH] station: enable FILS support station will now check if ERP has cached keys for FILS when building the handshake, as well as get the ERP cache and set it into the handshake object. --- src/station.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/src/station.c b/src/station.c index 26ff22f5..40396fac 100644 --- a/src/station.c +++ b/src/station.c @@ -49,6 +49,7 @@ #include "src/station.h" #include "src/blacklist.h" #include "src/mpdu.h" +#include "src/erp.h" static struct l_queue *station_list; static uint32_t netdev_watch; @@ -488,6 +489,46 @@ static void station_handshake_event(struct handshake_state *hs, } } +static bool station_has_erp_identity(struct network *network) +{ + struct erp_cache_entry *cache; + struct l_settings *settings; + char *check_id; + const char *identity; + bool ret; + + settings = network_get_settings(network); + if (!settings) + return false; + + check_id = l_settings_get_string(settings, "Security", "EAP-Identity"); + if (!check_id) + return false; + + cache = erp_cache_get(network_get_ssid(network)); + if (!cache) { + l_free(check_id); + return false; + } + + identity = erp_cache_entry_get_identity(cache); + + ret = strcmp(check_id, identity) == 0; + + l_free(check_id); + erp_cache_put(cache); + + /* + * The settings file must have change out from under us. In this + * case we want to remove the ERP entry because it is no longer + * valid. + */ + if (!ret) + erp_cache_remove(identity); + + return ret; +} + static int station_build_handshake_rsn(struct handshake_state *hs, struct wiphy *wiphy, struct network *network, @@ -495,6 +536,7 @@ static int station_build_handshake_rsn(struct handshake_state *hs, { enum security security = network_get_security(network); bool add_mde = false; + bool fils_hint = false; const struct l_settings *settings = iwd_get_config(); struct ie_rsn_info bss_info; @@ -507,7 +549,18 @@ static int station_build_handshake_rsn(struct handshake_state *hs, memset(&bss_info, 0, sizeof(bss_info)); scan_bss_get_rsn_info(bss, &bss_info); - info.akm_suites = wiphy_select_akm(wiphy, bss, false); + if (bss_info.akm_suites & (IE_RSN_AKM_SUITE_FILS_SHA256 | + IE_RSN_AKM_SUITE_FILS_SHA384)) + hs->support_fils = true; + + /* + * If this network 8021x we might have a set of cached EAP keys. If so + * wiphy may select FILS if supported by the AP. + */ + if (security == SECURITY_8021X && hs->support_fils) + fils_hint = station_has_erp_identity(network); + + info.akm_suites = wiphy_select_akm(wiphy, bss, fils_hint); /* * Special case for OWE. With OWE we still need to build up the @@ -646,6 +699,15 @@ static struct handshake_state *station_handshake_setup(struct station *station, handshake_state_set_8021x_config(hs, network_get_settings(network)); + /* + * If FILS was chosen, the ERP cache has been verified to exist. We + * wait to get it until here because at this point so there are no + * failure paths before fils_sm_new + */ + if (hs->akm_suite == IE_RSN_AKM_SUITE_FILS_SHA256 || + hs->akm_suite == IE_RSN_AKM_SUITE_FILS_SHA384) + hs->erp_cache = erp_cache_get(network_get_ssid(network)); + return hs; no_psk: