EAP-FAST: Divided eap_fast_process() into number of helper functions

This commit is contained in:
Jouni Malinen 2008-02-27 17:57:49 -08:00
parent 7f4c1d4300
commit cdd1bc9288

View File

@ -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: