EAP-AKA: Validate RES Length field in AT_RES
This change breaks interoperability with older wpa_supplicant versions (everything up to and including wpa_supplicant 0.5.10 and 0.6.5) which incorrectly used this field as number of bytes, not bits, in RES.
This commit is contained in:
parent
fa71a1d84a
commit
04a5bad682
3 changed files with 13 additions and 2 deletions
|
@ -517,6 +517,7 @@ int eap_sim_parse_attr(const u8 *start, const u8 *end,
|
||||||
break;
|
break;
|
||||||
case EAP_SIM_AT_RES:
|
case EAP_SIM_AT_RES:
|
||||||
wpa_printf(MSG_DEBUG, "EAP-SIM: AT_RES");
|
wpa_printf(MSG_DEBUG, "EAP-SIM: AT_RES");
|
||||||
|
attr->res_len_bits = WPA_GET_BE16(apos);
|
||||||
apos += 2;
|
apos += 2;
|
||||||
alen -= 2;
|
alen -= 2;
|
||||||
if (!aka || alen < EAP_AKA_MIN_RES_LEN ||
|
if (!aka || alen < EAP_AKA_MIN_RES_LEN ||
|
||||||
|
|
|
@ -137,6 +137,7 @@ struct eap_sim_attrs {
|
||||||
const u8 *checkcode;
|
const u8 *checkcode;
|
||||||
size_t num_chal, version_list_len, encr_data_len;
|
size_t num_chal, version_list_len, encr_data_len;
|
||||||
size_t next_pseudonym_len, next_reauth_id_len, identity_len, res_len;
|
size_t next_pseudonym_len, next_reauth_id_len, identity_len, res_len;
|
||||||
|
size_t res_len_bits;
|
||||||
size_t checkcode_len;
|
size_t checkcode_len;
|
||||||
enum eap_sim_id_req id_req;
|
enum eap_sim_id_req id_req;
|
||||||
int notification, counter, selected_version, client_error_code;
|
int notification, counter, selected_version, client_error_code;
|
||||||
|
|
|
@ -666,10 +666,19 @@ static void eap_aka_process_challenge(struct eap_sm *sm,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr->res == NULL || attr->res_len != data->res_len ||
|
/*
|
||||||
|
* AT_RES is padded, so verify that there is enough room for RES and
|
||||||
|
* that the RES length in bits matches with the expected RES.
|
||||||
|
*/
|
||||||
|
if (attr->res == NULL || attr->res_len < data->res_len ||
|
||||||
|
attr->res_len_bits != data->res_len * 8 ||
|
||||||
os_memcmp(attr->res, data->res, data->res_len) != 0) {
|
os_memcmp(attr->res, data->res, data->res_len) != 0) {
|
||||||
wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message did not "
|
wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message did not "
|
||||||
"include valid AT_RES");
|
"include valid AT_RES (attr len=%lu, res len=%lu "
|
||||||
|
"bits, expected %lu bits)",
|
||||||
|
(unsigned long) attr->res_len,
|
||||||
|
(unsigned long) attr->res_len_bits,
|
||||||
|
(unsigned long) data->res_len);
|
||||||
data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;
|
data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;
|
||||||
eap_aka_state(data, NOTIFICATION);
|
eap_aka_state(data, NOTIFICATION);
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in a new issue