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,50 +1323,46 @@ static void eap_fast_process_phase2(struct eap_sm *sm,
} }
static void eap_fast_process(struct eap_sm *sm, void *priv, static int eap_fast_process_version(struct eap_fast_data *data,
struct wpabuf *respData) int peer_version)
{ {
struct eap_fast_data *data = priv; data->peer_version = peer_version;
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);
if (pos == NULL || left < 1)
return;
flags = *pos++;
left--;
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) { if (data->force_version >= 0 && peer_version != data->force_version) {
wpa_printf(MSG_INFO, "EAP-FAST: peer did not select the forced" wpa_printf(MSG_INFO, "EAP-FAST: peer did not select the forced"
" version (forced=%d peer=%d) - reject", " version (forced=%d peer=%d) - reject",
data->force_version, peer_version); data->force_version, peer_version);
eap_fast_state(data, FAILURE); eap_fast_state(data, FAILURE);
return; return -1;
} }
if (peer_version < data->fast_version) { if (peer_version < data->fast_version) {
wpa_printf(MSG_DEBUG, "EAP-FAST: peer ver=%d, own ver=%d; " wpa_printf(MSG_DEBUG, "EAP-FAST: peer ver=%d, own ver=%d; "
"use version %d", "use version %d",
peer_version, data->fast_version, peer_version); peer_version, data->fast_version, peer_version);
data->fast_version = peer_version; data->fast_version = peer_version;
} }
if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
if (left < 4) { 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 " wpa_printf(MSG_INFO, "EAP-FAST: Short frame with TLS "
"length"); "length");
eap_fast_state(data, FAILURE); eap_fast_state(data, FAILURE);
return; return -1;
} }
tls_msg_len = WPA_GET_BE32(pos);
tls_msg_len = WPA_GET_BE32(*pos);
wpa_printf(MSG_DEBUG, "EAP-FAST: TLS Message Length: %d", wpa_printf(MSG_DEBUG, "EAP-FAST: TLS Message Length: %d",
tls_msg_len); tls_msg_len);
if (data->ssl.tls_in_left == 0) { if (data->ssl.tls_in_left == 0) {
data->ssl.tls_in_total = tls_msg_len; data->ssl.tls_in_total = tls_msg_len;
data->ssl.tls_in_left = tls_msg_len; data->ssl.tls_in_left = tls_msg_len;
@ -1374,53 +1370,58 @@ static void eap_fast_process(struct eap_sm *sm, void *priv,
data->ssl.tls_in = NULL; data->ssl.tls_in = NULL;
data->ssl.tls_in_len = 0; data->ssl.tls_in_len = 0;
} }
pos += 4;
left -= 4;
}
switch (data->state) { *pos += 4;
case PHASE1: *left -= 4;
if (eap_server_tls_process_helper(sm, &data->ssl, pos, left) <
0) { return 0;
wpa_printf(MSG_INFO, "EAP-FAST: TLS processing " }
"failed");
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); eap_fast_state(data, FAILURE);
return -1;
} }
if (!tls_connection_established(sm->ssl_ctx, data->ssl.conn) || if (!tls_connection_established(sm->ssl_ctx, data->ssl.conn) ||
data->ssl.tls_out_len > 0) data->ssl.tls_out_len > 0)
break; return 1;
/* /*
* Phase 1 was completed with the received message (e.g., when * Phase 1 was completed with the received message (e.g., when using
* using abbreviated handshake), so Phase 2 can be started * abbreviated handshake), so Phase 2 can be started immediately
* immediately without having to send through an empty message * without having to send through an empty message to the peer.
* to the peer.
*/ */
if (eap_fast_phase1_done(sm, data) < 0) return eap_fast_phase1_done(sm, data);
break; }
static void eap_fast_process_phase2_start(struct eap_sm *sm,
struct eap_fast_data *data)
{
u8 next_type;
/* fall through to PHASE2_START */
case PHASE2_START:
if (data->identity) { if (data->identity) {
os_free(sm->identity); os_free(sm->identity);
sm->identity = data->identity; sm->identity = data->identity;
data->identity = NULL; data->identity = NULL;
sm->identity_len = data->identity_len; sm->identity_len = data->identity_len;
data->identity_len = 0; data->identity_len = 0;
if (eap_user_get(sm, sm->identity, sm->identity_len, 1) if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
!= 0) {
wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: " wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: "
"Phase2 Identity not found " "Phase2 Identity not found "
"in the user database", "in the user database",
sm->identity, sm->identity, sm->identity_len);
sm->identity_len);
next_type = eap_fast_req_failure(sm, data); next_type = eap_fast_req_failure(sm, data);
} else { } else {
wpa_printf(MSG_DEBUG, "EAP-FAST: Identity " wpa_printf(MSG_DEBUG, "EAP-FAST: Identity already "
"already known - skip Phase 2 " "known - skip Phase 2 Identity Request");
"Identity Request");
next_type = sm->user->methods[0].method; next_type = sm->user->methods[0].method;
sm->user_eap_method_index = 1; sm->user_eap_method_index = 1;
} }
@ -1432,6 +1433,42 @@ static void eap_fast_process(struct eap_sm *sm, void *priv,
} }
eap_fast_phase2_init(sm, data, next_type); eap_fast_phase2_init(sm, data, next_type);
}
static void eap_fast_process(struct eap_sm *sm, void *priv,
struct wpabuf *respData)
{
struct eap_fast_data *data = priv;
const u8 *pos;
u8 flags;
size_t left;
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_FAST, respData,
&left);
if (pos == NULL || left < 1)
return;
flags = *pos++;
left--;
wpa_printf(MSG_DEBUG, "EAP-FAST: Received packet(len=%lu) - "
"Flags 0x%02x", (unsigned long) wpabuf_len(respData),
flags);
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;
switch (data->state) {
case PHASE1:
if (eap_fast_process_phase1(sm, data, pos, left))
break;
/* fall through to PHASE2_START */
case PHASE2_START:
eap_fast_process_phase2_start(sm, data);
break; break;
case PHASE2_ID: case PHASE2_ID:
case PHASE2_METHOD: case PHASE2_METHOD: