diff --git a/lib/TLS/include/Method.h b/lib/TLS/include/Method.h index 51617dd..a5cf536 100644 --- a/lib/TLS/include/Method.h +++ b/lib/TLS/include/Method.h @@ -433,6 +433,7 @@ namespace eap tls_random m_key_mppe_server; ///< MS-MPPE-Send-Key sanitizing_blob m_session_id; ///< TLS session ID + bool m_session_resumed; ///< Did TLS session resume? std::list m_server_cert_chain; ///< Server certificate chain diff --git a/lib/TLS/src/Method.cpp b/lib/TLS/src/Method.cpp index e147ae6..fe41c41 100644 --- a/lib/TLS/src/Method.cpp +++ b/lib/TLS/src/Method.cpp @@ -65,6 +65,7 @@ eap::method_tls::method_tls(_In_ module &module, _In_ config_method_tls &cfg, _I m_cred(cred), m_user_ctx(NULL), #if EAP_TLS < EAP_TLS_SCHANNEL + m_session_resumed(false), m_phase(phase_unknown), m_seq_num_client(0), m_seq_num_server(0), @@ -106,6 +107,7 @@ eap::method_tls::method_tls(_Inout_ method_tls &&other) : m_key_mppe_client (std::move(other.m_key_mppe_client )), m_key_mppe_server (std::move(other.m_key_mppe_server )), m_session_id (std::move(other.m_session_id )), + m_session_resumed (std::move(other.m_session_resumed )), m_server_cert_chain (std::move(other.m_server_cert_chain )), m_hash_handshake_msgs_md5 (std::move(other.m_hash_handshake_msgs_md5 )), m_hash_handshake_msgs_sha1 (std::move(other.m_hash_handshake_msgs_sha1 )), @@ -157,6 +159,7 @@ eap::method_tls& eap::method_tls::operator=(_Inout_ method_tls &&other) m_key_mppe_client = std::move(other.m_key_mppe_client ); m_key_mppe_server = std::move(other.m_key_mppe_server ); m_session_id = std::move(other.m_session_id ); + m_session_resumed = std::move(other.m_session_resumed ); m_server_cert_chain = std::move(other.m_server_cert_chain ); m_hash_handshake_msgs_md5 = std::move(other.m_hash_handshake_msgs_md5 ); m_hash_handshake_msgs_sha1 = std::move(other.m_hash_handshake_msgs_sha1 ); @@ -301,7 +304,7 @@ void eap::method_tls::process_request_packet( user_impersonator impersonating(m_user_ctx); #if EAP_TLS < EAP_TLS_SCHANNEL - if (pReceivedPacket->Code == EapCodeRequest && (m_packet_req.m_flags & flags_req_start)) { + if (pReceivedPacket->Code == EapCodeRequest && (m_packet_req.m_flags & packet_tls::flags_req_start)) { // This is the EAP-TLS start message: (re)initialize method. m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank); m_phase = phase_client_hello; @@ -435,8 +438,10 @@ void eap::method_tls::process_request_packet( if (m_handshake[tls_handshake_type_finished]) { // Go to application data phase. And allow piggybacking of the first data message. m_phase = phase_application_data; + m_session_resumed = true; process_application_data(NULL, 0); } else { + m_session_resumed = false; m_phase = phase_change_cipher_spec; } break; diff --git a/lib/TTLS/src/Method.cpp b/lib/TTLS/src/Method.cpp index 2c90e22..5fd55e6 100644 --- a/lib/TTLS/src/Method.cpp +++ b/lib/TTLS/src/Method.cpp @@ -199,11 +199,24 @@ void eap::method_ttls::process_application_data(_In_bytecount_(size_msg) const v // Prepare inner authentication. #if EAP_TLS < EAP_TLS_SCHANNEL if (!m_state_client.m_alg_encrypt) + throw runtime_error(__FUNCTION__ " Refusing to continue with inner authentication unencrypted."); + + if (m_session_resumed) { + // On reconnect we do not need to do inner re-authentication. + return; + } #else if (!(m_sc_ctx.m_attrib & ISC_RET_CONFIDENTIALITY)) -#endif throw runtime_error(__FUNCTION__ " Refusing to continue with inner authentication unencrypted."); + SecPkgContext_SessionInfo session_info; + if (SUCCEEDED(QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_SESSION_INFO, &session_info)) && (session_info.dwFlags & SSL_SESSION_RECONNECT)) { + // On reconnect we do not need to do inner re-authentication. + // According to MSDN QueryContextAttributes(SECPKG_ATTR_SESSION_INFO) works from Windows 7 on. Therefore behaviour might vary. + return; + } +#endif + EapPeerMethodOutput eap_output = {}; eap_type_t eap_type = m_cfg.m_inner->get_method_id(); if (eap_type_noneap_start <= eap_type && eap_type < eap_type_noneap_end) {