mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2025-02-14 13:30:39 +01:00
handshake: Refactor ie setters
Calling handshake_state_setup_own_ciphers from within handshate_state_set_authenticator_ie was misleading. In all cases the supplicant chooses the AKM. This worked since our AP code only ever advertises a single AKM, but would not work in the general case. Similarly, the supplicant would choose which authentication type to use by either sending the WPA1 or WPA2 IE (or OSEN). Thus the setting of the related variables in handshake_state_set_authenticator_ie was also incorrect. In iwd, the supplicant_ie would be set after the authenticator_ie, so these settings would be overwritten in most cases. Refactor these two setters so that the supplicant's chosen rsn_info would be used to drive the handshake.
This commit is contained in:
parent
63ef918671
commit
5e631c8af8
@ -170,83 +170,73 @@ void handshake_state_set_8021x_config(struct handshake_state *s,
|
||||
s->settings_8021x = settings;
|
||||
}
|
||||
|
||||
static bool handshake_state_setup_own_ciphers(struct handshake_state *s,
|
||||
const struct ie_rsn_info *info)
|
||||
{
|
||||
if (__builtin_popcount(info->akm_suites) != 1)
|
||||
return false;
|
||||
|
||||
s->akm_suite = info->akm_suites;
|
||||
s->group_cipher = info->group_cipher;
|
||||
s->group_management_cipher = info->group_management_cipher;
|
||||
|
||||
/*
|
||||
* Don't set MFP for OSEN otherwise EAPoL will attempt to negotiate a
|
||||
* iGTK which is not allowed for OSEN.
|
||||
*/
|
||||
if (!s->osen_ie)
|
||||
s->mfp = info->mfpc;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool handshake_state_set_authenticator_ie(struct handshake_state *s,
|
||||
const uint8_t *ie)
|
||||
{
|
||||
struct ie_rsn_info info;
|
||||
|
||||
if (!ie_parse_rsne_from_data(ie, ie[1] + 2, &info))
|
||||
goto valid_ie;
|
||||
|
||||
if (!ie_parse_wpa_from_data(ie, ie[1] + 2, &info))
|
||||
goto valid_ie;
|
||||
|
||||
if (ie_parse_osen_from_data(ie, ie[1] + 2, &info) < 0)
|
||||
return false;
|
||||
|
||||
valid_ie:
|
||||
l_free(s->authenticator_ie);
|
||||
s->authenticator_ie = l_memdup(ie, ie[1] + 2u);
|
||||
s->wpa_ie = is_ie_wpa_ie(ie + 2, ie[1]);
|
||||
s->osen_ie = is_ie_wfa_ie(ie + 2, ie[1], IE_WFA_OI_OSEN);
|
||||
|
||||
if (!s->authenticator)
|
||||
return true;
|
||||
|
||||
if (s->wpa_ie) {
|
||||
if (ie_parse_wpa_from_data(ie, ie[1] + 2, &info) < 0)
|
||||
return false;
|
||||
} else if (s->osen_ie) {
|
||||
if (ie_parse_osen_from_data(ie, ie[1] + 2, &info) < 0)
|
||||
return false;
|
||||
} else {
|
||||
if (ie_parse_rsne_from_data(ie, ie[1] + 2, &info) < 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return handshake_state_setup_own_ciphers(s, &info);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool handshake_state_set_supplicant_ie(struct handshake_state *s,
|
||||
const uint8_t *ie)
|
||||
{
|
||||
struct ie_rsn_info info;
|
||||
bool wpa_ie = false;
|
||||
bool osen_ie = false;
|
||||
|
||||
l_free(s->supplicant_ie);
|
||||
s->supplicant_ie = l_memdup(ie, ie[1] + 2u);
|
||||
s->wpa_ie = is_ie_wpa_ie(ie + 2, ie[1]);
|
||||
s->osen_ie = is_ie_wfa_ie(ie + 2, ie[1], IE_WFA_OI_OSEN);
|
||||
if (!ie_parse_rsne_from_data(ie, ie[1] + 2, &info))
|
||||
goto valid_ie;
|
||||
|
||||
if (s->wpa_ie) {
|
||||
if (ie_parse_wpa_from_data(ie, ie[1] + 2, &info) < 0)
|
||||
return false;
|
||||
} else if (s->osen_ie) {
|
||||
if (ie_parse_osen_from_data(ie, ie[1] + 2, &info) < 0)
|
||||
return false;
|
||||
} else {
|
||||
if (ie_parse_rsne_from_data(ie, ie[1] + 2, &info) < 0)
|
||||
return false;
|
||||
if (!ie_parse_wpa_from_data(ie, ie[1] + 2, &info)) {
|
||||
wpa_ie = true;
|
||||
goto valid_ie;
|
||||
}
|
||||
|
||||
if (ie_parse_osen_from_data(ie, ie[1] + 2, &info) < 0)
|
||||
return false;
|
||||
|
||||
osen_ie = true;
|
||||
|
||||
valid_ie:
|
||||
if (__builtin_popcount(info.pairwise_ciphers) != 1)
|
||||
return false;
|
||||
|
||||
if (__builtin_popcount(info.akm_suites) != 1)
|
||||
return false;
|
||||
|
||||
l_free(s->supplicant_ie);
|
||||
s->supplicant_ie = l_memdup(ie, ie[1] + 2u);
|
||||
|
||||
s->osen_ie = osen_ie;
|
||||
s->wpa_ie = wpa_ie;
|
||||
|
||||
s->pairwise_cipher = info.pairwise_ciphers;
|
||||
s->group_cipher = info.group_cipher;
|
||||
s->group_management_cipher = info.group_management_cipher;
|
||||
s->akm_suite = info.akm_suites;
|
||||
|
||||
if (s->authenticator)
|
||||
return true;
|
||||
/*
|
||||
* Don't set MFP for OSEN otherwise EAPoL will attempt to negotiate a
|
||||
* iGTK which is not allowed for OSEN.
|
||||
*/
|
||||
if (!s->osen_ie)
|
||||
s->mfp = info.mfpc;
|
||||
|
||||
return handshake_state_setup_own_ciphers(s, &info);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void replace_ie(uint8_t **old, const uint8_t *new)
|
||||
|
Loading…
x
Reference in New Issue
Block a user