From cafd786e1952de506218ec49deadfcfa8613f529 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Mon, 29 Aug 2016 20:40:37 +0200 Subject: [PATCH] Own TLS updated to keep it alive (now that the fuss around outer/inner methods settled) --- lib/TLS/include/Method.h | 2 +- lib/TLS/src/Method.cpp | 33 +++++++++++++++++++++------- lib/TTLS/include/Method.h | 4 +--- lib/TTLS/src/Method.cpp | 45 ++++++++++++++++++++------------------- 4 files changed, 50 insertions(+), 34 deletions(-) diff --git a/lib/TLS/include/Method.h b/lib/TLS/include/Method.h index e328473..b04f286 100644 --- a/lib/TLS/include/Method.h +++ b/lib/TLS/include/Method.h @@ -362,12 +362,12 @@ namespace eap /// Process handshake /// void process_handshake(); +#endif /// /// Process application data /// void process_application_data(); -#endif /// /// Processes a TLS application_data message diff --git a/lib/TLS/src/Method.cpp b/lib/TLS/src/Method.cpp index 2388805..6848a8b 100644 --- a/lib/TLS/src/Method.cpp +++ b/lib/TLS/src/Method.cpp @@ -544,14 +544,22 @@ void eap::method_tls::process_request_packet( sanitizing_blob msg_finished(make_message(tls_message_type_handshake, make_finished())); m_packet_res.m_data.insert(m_packet_res.m_data.end(), msg_finished.begin(), msg_finished.end()); - m_phase = m_handshake[tls_handshake_type_finished] ? phase_application_data : phase_change_cipher_spec; + 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; + process_application_data(NULL, 0); + } else { + m_phase = phase_change_cipher_spec; + } break; } case phase_change_cipher_spec: // Wait in this phase until server sends change cipher spec and finish. - if (m_state_server.m_alg_encrypt && m_handshake[tls_handshake_type_finished]) + if (m_state_server.m_alg_encrypt && m_handshake[tls_handshake_type_finished]) { m_phase = phase_application_data; + process_application_data(NULL, 0); + } break; case phase_application_data: @@ -702,20 +710,29 @@ void eap::method_tls::get_result( } case EapPeerMethodResultFailure: +#if EAP_TLS < EAP_TLS_SCHANNEL + m_module.log_event( + m_phase < phase_change_cipher_spec ? &EAPMETHOD_METHOD_FAILURE_INIT : + m_phase < phase_application_data ? &EAPMETHOD_METHOD_FAILURE_HANDSHAKE : &EAPMETHOD_METHOD_FAILURE, + event_data((unsigned int)eap_type_tls), event_data::blank); + + // Mark credentials as failed, so GUI can re-prompt user. + // But be careful: do so only if this happened after transition from handshake to application data phase. + m_cfg.m_auth_failed = m_phase >= phase_application_data; + + // Clear session resumption data. + m_cfg.m_session_id.clear(); + m_cfg.m_master_secret.clear(); +#else m_module.log_event( m_phase_prev < phase_handshake_cont ? &EAPMETHOD_METHOD_FAILURE_INIT : m_phase_prev < phase_application_data ? &EAPMETHOD_METHOD_FAILURE_HANDSHAKE : &EAPMETHOD_METHOD_FAILURE, event_data((unsigned int)eap_type_tls), event_data::blank); -#if EAP_TLS < EAP_TLS_SCHANNEL - // Clear session resumption data. - m_cfg.m_session_id.clear(); - m_cfg.m_master_secret.clear(); -#endif - // Mark credentials as failed, so GUI can re-prompt user. // But be careful: do so only if this happened after transition from handshake to application data phase. m_cfg.m_auth_failed = m_phase_prev < phase_application_data && m_phase >= phase_application_data; +#endif // Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt. // EapHost is well aware of the failed condition. diff --git a/lib/TTLS/include/Method.h b/lib/TTLS/include/Method.h index d4ec1f6..3ab96f2 100644 --- a/lib/TTLS/include/Method.h +++ b/lib/TTLS/include/Method.h @@ -140,7 +140,7 @@ namespace eap /// virtual void derive_msk(); -#else +#endif /// /// Processes an application message @@ -150,8 +150,6 @@ namespace eap /// virtual void process_application_data(_In_bytecount_(size_msg) const void *msg, _In_ size_t size_msg); -#endif - protected: config_method_ttls &m_cfg; ///< EAP-TTLS method configuration credentials_ttls &m_cred; ///< EAP-TTLS credentials diff --git a/lib/TTLS/src/Method.cpp b/lib/TTLS/src/Method.cpp index 0781b74..ced1d49 100644 --- a/lib/TTLS/src/Method.cpp +++ b/lib/TTLS/src/Method.cpp @@ -106,22 +106,6 @@ void eap::method_ttls::process_request_packet( // Do the TLS. method_tls::process_request_packet(pReceivedPacket, dwReceivedPacketSize, pEapOutput); - -#if EAP_TLS < EAP_TLS_SCHANNEL - if (m_phase == phase_application_data) { - // Send inner authentication. - if (!m_state_client.m_alg_encrypt) - throw runtime_error(__FUNCTION__ " Refusing to continue with inner authentication unencrypted."); - - m_module.log_event(&EAPMETHOD_TTLS_INNER_CRED, event_data((unsigned int)eap_type_ttls), event_data(m_cred.m_inner->get_name()), event_data::blank); - - m_packet_res.m_code = EapCodeResponse; - m_packet_res.m_id = m_packet_req.m_id; - m_packet_res.m_flags = 0; - sanitizing_blob msg_application(make_message(tls_message_type_application_data, make_pap_client())); - m_packet_res.m_data.insert(m_packet_res.m_data.end(), msg_application.begin(), msg_application.end()); - } -#endif } @@ -208,12 +192,16 @@ void eap::method_ttls::derive_msk() _key_block += sizeof(tls_random); } -#else +#endif void eap::method_ttls::process_application_data(_In_bytecount_(size_msg) const void *msg, _In_ size_t size_msg) { // Prepare inner authentication. +#if EAP_TLS < EAP_TLS_SCHANNEL + if (!m_state_client.m_alg_encrypt) +#else if (!(m_sc_ctx.m_attrib & ISC_RET_CONFIDENTIALITY)) +#endif throw runtime_error(__FUNCTION__ " Refusing to continue with inner authentication unencrypted."); EapPeerMethodOutput eap_output = {}; @@ -239,17 +227,26 @@ void eap::method_ttls::process_application_data(_In_bytecount_(size_msg) const v switch (eap_output.action) { case EapPeerMethodResponseActionSend: { // Retrieve inner packet and send it. - SECURITY_STATUS status; - // Get maximum message sizes. + // Get maximum message size and allocate memory for response packet. +#if EAP_TLS < EAP_TLS_SCHANNEL + m_packet_res.m_code = EapCodeResponse; + m_packet_res.m_id = m_packet_req.m_id; + m_packet_res.m_flags = 0; + + DWORD size_data = m_size_inner_packet_max; + sanitizing_blob data(size_data, 0); + unsigned char *ptr_data = data.data(); +#else SecPkgContext_StreamSizes sizes; - status = QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_STREAM_SIZES, &sizes); + SECURITY_STATUS status = QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_STREAM_SIZES, &sizes); if (FAILED(status)) throw sec_runtime_error(status, __FUNCTION__ " Error getting Schannel required encryption sizes."); sanitizing_blob data(sizes.cbHeader + m_size_inner_packet_max + sizes.cbTrailer, 0); DWORD size_data = m_size_inner_packet_max; unsigned char *ptr_data = data.data() + sizes.cbHeader; +#endif m_inner->get_response_packet((EapPacket*)ptr_data, &size_data); if (eap_type_noneap_start <= eap_type && eap_type < eap_type_noneap_end) { @@ -257,6 +254,11 @@ void eap::method_ttls::process_application_data(_In_bytecount_(size_msg) const v memmove(ptr_data, ptr_data + 4, size_data -= 4); } +#if EAP_TLS < EAP_TLS_SCHANNEL + data.resize(size_data); + sanitizing_blob msg_application(make_message(tls_message_type_application_data, std::move(data))); + m_packet_res.m_data.insert(m_packet_res.m_data.end(), msg_application.begin(), msg_application.end()); +#else // Prepare input/output buffer(s). SecBuffer buf[] = { { sizes.cbHeader, SECBUFFER_STREAM_HEADER , data.data() }, @@ -275,6 +277,7 @@ void eap::method_ttls::process_application_data(_In_bytecount_(size_msg) const v if (FAILED(status)) throw sec_runtime_error(status, __FUNCTION__ " Error encrypting message."); m_packet_res.m_data.insert(m_packet_res.m_data.end(), (const unsigned char*)buf[0].pvBuffer, (const unsigned char*)buf[0].pvBuffer + buf[0].cbBuffer + buf[1].cbBuffer + buf[2].cbBuffer); +#endif break; } @@ -283,5 +286,3 @@ void eap::method_ttls::process_application_data(_In_bytecount_(size_msg) const v throw invalid_argument(string_printf(__FUNCTION__ " Inner method returned an unsupported action (action %u).", eap_output.action).c_str()); } } - -#endif