mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-11-28 18:28:23 -05:00
EAP-FAST: Divided eap_fast_process() into number of helper functions
This commit is contained in:
parent
7f4c1d4300
commit
cdd1bc9288
@ -1323,6 +1323,119 @@ static void eap_fast_process_phase2(struct eap_sm *sm,
|
||||
}
|
||||
|
||||
|
||||
static int eap_fast_process_version(struct eap_fast_data *data,
|
||||
int peer_version)
|
||||
{
|
||||
data->peer_version = peer_version;
|
||||
|
||||
if (data->force_version >= 0 && peer_version != data->force_version) {
|
||||
wpa_printf(MSG_INFO, "EAP-FAST: peer did not select the forced"
|
||||
" version (forced=%d peer=%d) - reject",
|
||||
data->force_version, peer_version);
|
||||
eap_fast_state(data, FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (peer_version < data->fast_version) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-FAST: peer ver=%d, own ver=%d; "
|
||||
"use version %d",
|
||||
peer_version, data->fast_version, peer_version);
|
||||
data->fast_version = peer_version;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int eap_fast_process_length(struct eap_fast_data *data,
|
||||
const u8 **pos, size_t *left)
|
||||
{
|
||||
u32 tls_msg_len;
|
||||
|
||||
if (*left < 4) {
|
||||
wpa_printf(MSG_INFO, "EAP-FAST: Short frame with TLS "
|
||||
"length");
|
||||
eap_fast_state(data, FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tls_msg_len = WPA_GET_BE32(*pos);
|
||||
wpa_printf(MSG_DEBUG, "EAP-FAST: TLS Message Length: %d",
|
||||
tls_msg_len);
|
||||
|
||||
if (data->ssl.tls_in_left == 0) {
|
||||
data->ssl.tls_in_total = tls_msg_len;
|
||||
data->ssl.tls_in_left = tls_msg_len;
|
||||
os_free(data->ssl.tls_in);
|
||||
data->ssl.tls_in = NULL;
|
||||
data->ssl.tls_in_len = 0;
|
||||
}
|
||||
|
||||
*pos += 4;
|
||||
*left -= 4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int eap_fast_process_phase1(struct eap_sm *sm,
|
||||
struct eap_fast_data *data,
|
||||
const u8 *pos, size_t left)
|
||||
{
|
||||
if (eap_server_tls_process_helper(sm, &data->ssl, pos, left) < 0) {
|
||||
wpa_printf(MSG_INFO, "EAP-FAST: TLS processing failed");
|
||||
eap_fast_state(data, FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!tls_connection_established(sm->ssl_ctx, data->ssl.conn) ||
|
||||
data->ssl.tls_out_len > 0)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Phase 1 was completed with the received message (e.g., when using
|
||||
* abbreviated handshake), so Phase 2 can be started immediately
|
||||
* without having to send through an empty message to the peer.
|
||||
*/
|
||||
|
||||
return eap_fast_phase1_done(sm, data);
|
||||
}
|
||||
|
||||
|
||||
static void eap_fast_process_phase2_start(struct eap_sm *sm,
|
||||
struct eap_fast_data *data)
|
||||
{
|
||||
u8 next_type;
|
||||
|
||||
if (data->identity) {
|
||||
os_free(sm->identity);
|
||||
sm->identity = data->identity;
|
||||
data->identity = NULL;
|
||||
sm->identity_len = data->identity_len;
|
||||
data->identity_len = 0;
|
||||
if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: "
|
||||
"Phase2 Identity not found "
|
||||
"in the user database",
|
||||
sm->identity, sm->identity_len);
|
||||
next_type = eap_fast_req_failure(sm, data);
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG, "EAP-FAST: Identity already "
|
||||
"known - skip Phase 2 Identity Request");
|
||||
next_type = sm->user->methods[0].method;
|
||||
sm->user_eap_method_index = 1;
|
||||
}
|
||||
|
||||
eap_fast_state(data, PHASE2_METHOD);
|
||||
} else {
|
||||
eap_fast_state(data, PHASE2_ID);
|
||||
next_type = EAP_TYPE_IDENTITY;
|
||||
}
|
||||
|
||||
eap_fast_phase2_init(sm, data, next_type);
|
||||
}
|
||||
|
||||
|
||||
static void eap_fast_process(struct eap_sm *sm, void *priv,
|
||||
struct wpabuf *respData)
|
||||
{
|
||||
@ -1330,9 +1443,6 @@ static void eap_fast_process(struct eap_sm *sm, void *priv,
|
||||
const u8 *pos;
|
||||
u8 flags;
|
||||
size_t left;
|
||||
unsigned int tls_msg_len;
|
||||
int peer_version;
|
||||
u8 next_type;
|
||||
|
||||
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_FAST, respData,
|
||||
&left);
|
||||
@ -1343,95 +1453,22 @@ static void eap_fast_process(struct eap_sm *sm, void *priv,
|
||||
wpa_printf(MSG_DEBUG, "EAP-FAST: Received packet(len=%lu) - "
|
||||
"Flags 0x%02x", (unsigned long) wpabuf_len(respData),
|
||||
flags);
|
||||
data->peer_version = peer_version = flags & EAP_PEAP_VERSION_MASK;
|
||||
if (data->force_version >= 0 && peer_version != data->force_version) {
|
||||
wpa_printf(MSG_INFO, "EAP-FAST: peer did not select the forced"
|
||||
" version (forced=%d peer=%d) - reject",
|
||||
data->force_version, peer_version);
|
||||
eap_fast_state(data, FAILURE);
|
||||
|
||||
if (eap_fast_process_version(data, flags & EAP_PEAP_VERSION_MASK))
|
||||
return;
|
||||
|
||||
if ((flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) &&
|
||||
eap_fast_process_length(data, &pos, &left))
|
||||
return;
|
||||
}
|
||||
if (peer_version < data->fast_version) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-FAST: peer ver=%d, own ver=%d; "
|
||||
"use version %d",
|
||||
peer_version, data->fast_version, peer_version);
|
||||
data->fast_version = peer_version;
|
||||
}
|
||||
if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
|
||||
if (left < 4) {
|
||||
wpa_printf(MSG_INFO, "EAP-FAST: Short frame with TLS "
|
||||
"length");
|
||||
eap_fast_state(data, FAILURE);
|
||||
return;
|
||||
}
|
||||
tls_msg_len = WPA_GET_BE32(pos);
|
||||
wpa_printf(MSG_DEBUG, "EAP-FAST: TLS Message Length: %d",
|
||||
tls_msg_len);
|
||||
if (data->ssl.tls_in_left == 0) {
|
||||
data->ssl.tls_in_total = tls_msg_len;
|
||||
data->ssl.tls_in_left = tls_msg_len;
|
||||
os_free(data->ssl.tls_in);
|
||||
data->ssl.tls_in = NULL;
|
||||
data->ssl.tls_in_len = 0;
|
||||
}
|
||||
pos += 4;
|
||||
left -= 4;
|
||||
}
|
||||
|
||||
switch (data->state) {
|
||||
case PHASE1:
|
||||
if (eap_server_tls_process_helper(sm, &data->ssl, pos, left) <
|
||||
0) {
|
||||
wpa_printf(MSG_INFO, "EAP-FAST: TLS processing "
|
||||
"failed");
|
||||
eap_fast_state(data, FAILURE);
|
||||
}
|
||||
|
||||
if (!tls_connection_established(sm->ssl_ctx, data->ssl.conn) ||
|
||||
data->ssl.tls_out_len > 0)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Phase 1 was completed with the received message (e.g., when
|
||||
* using abbreviated handshake), so Phase 2 can be started
|
||||
* immediately without having to send through an empty message
|
||||
* to the peer.
|
||||
*/
|
||||
|
||||
if (eap_fast_phase1_done(sm, data) < 0)
|
||||
if (eap_fast_process_phase1(sm, data, pos, left))
|
||||
break;
|
||||
|
||||
/* fall through to PHASE2_START */
|
||||
case PHASE2_START:
|
||||
if (data->identity) {
|
||||
os_free(sm->identity);
|
||||
sm->identity = data->identity;
|
||||
data->identity = NULL;
|
||||
sm->identity_len = data->identity_len;
|
||||
data->identity_len = 0;
|
||||
if (eap_user_get(sm, sm->identity, sm->identity_len, 1)
|
||||
!= 0) {
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: "
|
||||
"Phase2 Identity not found "
|
||||
"in the user database",
|
||||
sm->identity,
|
||||
sm->identity_len);
|
||||
next_type = eap_fast_req_failure(sm, data);
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG, "EAP-FAST: Identity "
|
||||
"already known - skip Phase 2 "
|
||||
"Identity Request");
|
||||
next_type = sm->user->methods[0].method;
|
||||
sm->user_eap_method_index = 1;
|
||||
}
|
||||
|
||||
eap_fast_state(data, PHASE2_METHOD);
|
||||
} else {
|
||||
eap_fast_state(data, PHASE2_ID);
|
||||
next_type = EAP_TYPE_IDENTITY;
|
||||
}
|
||||
|
||||
eap_fast_phase2_init(sm, data, next_type);
|
||||
eap_fast_process_phase2_start(sm, data);
|
||||
break;
|
||||
case PHASE2_ID:
|
||||
case PHASE2_METHOD:
|
||||
|
Loading…
Reference in New Issue
Block a user