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 <j@w1.fi>
This commit is contained in:
parent
e23e35e39a
commit
8bb5b875d1
1 changed files with 93 additions and 3 deletions
|
@ -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(data->state),
|
||||||
eap_peap_state_txt(state));
|
eap_peap_state_txt(state));
|
||||||
data->state = 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) {
|
if (status == EAP_TLV_RESULT_SUCCESS) {
|
||||||
wpa_printf(MSG_INFO, "EAP-PEAP: TLV Result - Success "
|
wpa_printf(MSG_INFO, "EAP-PEAP: TLV Result - Success "
|
||||||
"- requested %s", requested);
|
"- requested %s", requested);
|
||||||
if (data->tlv_request == TLV_REQ_SUCCESS)
|
if (data->tlv_request == TLV_REQ_SUCCESS) {
|
||||||
eap_peap_state(data, SUCCESS);
|
eap_peap_state(data, SUCCESS);
|
||||||
else
|
eap_peap_valid_session(sm, data);
|
||||||
|
} else {
|
||||||
eap_peap_state(data, FAILURE);
|
eap_peap_state(data, FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (status == EAP_TLV_RESULT_FAILURE) {
|
} else if (status == EAP_TLV_RESULT_FAILURE) {
|
||||||
wpa_printf(MSG_INFO, "EAP-PEAP: 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");
|
wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 Success");
|
||||||
if (data->state == SUCCESS_REQ) {
|
if (data->state == SUCCESS_REQ) {
|
||||||
eap_peap_state(data, SUCCESS);
|
eap_peap_state(data, SUCCESS);
|
||||||
|
eap_peap_valid_session(sm, data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EAP_CODE_FAILURE:
|
case EAP_CODE_FAILURE:
|
||||||
|
@ -1159,6 +1193,7 @@ static void eap_peap_process_msg(struct eap_sm *sm, void *priv,
|
||||||
break;
|
break;
|
||||||
case SUCCESS_REQ:
|
case SUCCESS_REQ:
|
||||||
eap_peap_state(data, SUCCESS);
|
eap_peap_state(data, SUCCESS);
|
||||||
|
eap_peap_valid_session(sm, data);
|
||||||
break;
|
break;
|
||||||
case FAILURE_REQ:
|
case FAILURE_REQ:
|
||||||
eap_peap_state(data, FAILURE);
|
eap_peap_state(data, FAILURE);
|
||||||
|
@ -1175,10 +1210,65 @@ static void eap_peap_process(struct eap_sm *sm, void *priv,
|
||||||
struct wpabuf *respData)
|
struct wpabuf *respData)
|
||||||
{
|
{
|
||||||
struct eap_peap_data *data = priv;
|
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,
|
if (eap_server_tls_process(sm, &data->ssl, respData, data,
|
||||||
EAP_TYPE_PEAP, eap_peap_process_version,
|
EAP_TYPE_PEAP, eap_peap_process_version,
|
||||||
eap_peap_process_msg) < 0)
|
eap_peap_process_msg) < 0) {
|
||||||
eap_peap_state(data, FAILURE);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue