From cdd1bc9288706d6c7dc93bec1f0390a7028f0636 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 27 Feb 2008 17:57:49 -0800 Subject: [PATCH] EAP-FAST: Divided eap_fast_process() into number of helper functions --- src/eap_server/eap_fast.c | 205 ++++++++++++++++++++++---------------- 1 file changed, 121 insertions(+), 84 deletions(-) diff --git a/src/eap_server/eap_fast.c b/src/eap_server/eap_fast.c index c877bba6f..d7665af20 100644 --- a/src/eap_server/eap_fast.c +++ b/src/eap_server/eap_fast.c @@ -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: