From: Jouni Malinen Date: Sun, 23 Aug 2015 19:06:55 +0000 (+0300) Subject: EAP-PEAP server: Add support for session resumption X-Git-Tag: hostap_2_5~117 X-Git-Url: http://www.project-moonshot.org/gitweb/?a=commitdiff_plain;h=8bb5b875d1b570a6e51f2b25e151973b0f70eb6a;p=mech_eap.git EAP-PEAP server: Add support for session resumption This allows TLS session resumption to be used to enable abbreviated handshake and skipping of Phase 2. Signed-off-by: Jouni Malinen --- diff --git a/src/eap_server/eap_server_peap.c b/src/eap_server/eap_server_peap.c index ff3401b..51062b0 100644 --- a/src/eap_server/eap_server_peap.c +++ b/src/eap_server/eap_server_peap.c @@ -95,6 +95,37 @@ static void eap_peap_state(struct eap_peap_data *data, int state) eap_peap_state_txt(data->state), eap_peap_state_txt(state)); data->state = state; + if (state == FAILURE || state == FAILURE_REQ) + tls_connection_remove_session(data->ssl.conn); +} + + +static void eap_peap_valid_session(struct eap_sm *sm, + struct eap_peap_data *data) +{ + struct wpabuf *buf; + + if (!sm->tls_session_lifetime || + tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) + return; + + buf = wpabuf_alloc(1 + 1 + sm->identity_len); + if (!buf) + return; + wpabuf_put_u8(buf, EAP_TYPE_PEAP); + if (sm->identity) { + u8 id_len; + + if (sm->identity_len <= 255) + id_len = sm->identity_len; + else + id_len = 255; + wpabuf_put_u8(buf, id_len); + wpabuf_put_data(buf, sm->identity, id_len); + } else { + wpabuf_put_u8(buf, 0); + } + tls_connection_set_success_data(data->ssl.conn, buf); } @@ -708,10 +739,12 @@ static void eap_peap_process_phase2_tlv(struct eap_sm *sm, if (status == EAP_TLV_RESULT_SUCCESS) { wpa_printf(MSG_INFO, "EAP-PEAP: TLV Result - Success " "- requested %s", requested); - if (data->tlv_request == TLV_REQ_SUCCESS) + if (data->tlv_request == TLV_REQ_SUCCESS) { eap_peap_state(data, SUCCESS); - else + eap_peap_valid_session(sm, data); + } else { eap_peap_state(data, FAILURE); + } } else if (status == EAP_TLV_RESULT_FAILURE) { wpa_printf(MSG_INFO, "EAP-PEAP: TLV Result - Failure " @@ -1094,6 +1127,7 @@ static void eap_peap_process_phase2(struct eap_sm *sm, wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 Success"); if (data->state == SUCCESS_REQ) { eap_peap_state(data, SUCCESS); + eap_peap_valid_session(sm, data); } break; case EAP_CODE_FAILURE: @@ -1159,6 +1193,7 @@ static void eap_peap_process_msg(struct eap_sm *sm, void *priv, break; case SUCCESS_REQ: eap_peap_state(data, SUCCESS); + eap_peap_valid_session(sm, data); break; case FAILURE_REQ: eap_peap_state(data, FAILURE); @@ -1175,10 +1210,65 @@ static void eap_peap_process(struct eap_sm *sm, void *priv, struct wpabuf *respData) { struct eap_peap_data *data = priv; + const struct wpabuf *buf; + const u8 *pos; + u8 id_len; + if (eap_server_tls_process(sm, &data->ssl, respData, data, EAP_TYPE_PEAP, eap_peap_process_version, - eap_peap_process_msg) < 0) + eap_peap_process_msg) < 0) { eap_peap_state(data, FAILURE); + return; + } + + if (data->state == SUCCESS || + !tls_connection_established(sm->ssl_ctx, data->ssl.conn) || + !tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) + return; + + buf = tls_connection_get_success_data(data->ssl.conn); + if (!buf || wpabuf_len(buf) < 2) { + wpa_printf(MSG_DEBUG, + "EAP-PEAP: No success data in resumed session - reject attempt"); + eap_peap_state(data, FAILURE); + return; + } + + pos = wpabuf_head(buf); + if (*pos != EAP_TYPE_PEAP) { + wpa_printf(MSG_DEBUG, + "EAP-PEAP: Resumed session for another EAP type (%u) - reject attempt", + *pos); + eap_peap_state(data, FAILURE); + return; + } + + pos++; + id_len = *pos++; + wpa_hexdump_ascii(MSG_DEBUG, "EAP-PEAP: Identity from cached session", + pos, id_len); + os_free(sm->identity); + sm->identity = os_malloc(id_len ? id_len : 1); + if (!sm->identity) { + sm->identity_len = 0; + eap_peap_state(data, FAILURE); + return; + } + + os_memcpy(sm->identity, pos, id_len); + sm->identity_len = id_len; + + if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) { + wpa_hexdump_ascii(MSG_DEBUG, "EAP-PEAP: Phase2 Identity not found in the user database", + sm->identity, sm->identity_len); + eap_peap_state(data, FAILURE); + return; + } + + wpa_printf(MSG_DEBUG, + "EAP-PEAP: Resuming previous session - skip Phase2"); + eap_peap_state(data, SUCCESS_REQ); + tls_connection_set_success_data_resumed(data->ssl.conn); }