From a8c306953a052634d6103621b1317dcd5352d83d Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Thu, 11 Aug 2016 15:13:50 +0200 Subject: [PATCH] TLS work continues... --- lib/Events/res/EventsETW.man | Bin 34460 -> 48164 bytes lib/TLS/include/Method.h | 34 ++++-- lib/TLS/src/Method.cpp | 193 ++++++++++++++++++++++------------- lib/TTLS/src/Method.cpp | 2 +- 4 files changed, 152 insertions(+), 77 deletions(-) diff --git a/lib/Events/res/EventsETW.man b/lib/Events/res/EventsETW.man index f545bb3efdc7a85dbb36f6755816729c1c4a3875..47e4f20da12007d34012e8b4ca25ef112e7ed9ef 100644 GIT binary patch literal 48164 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 literal 34460 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 + 2)); m_packet_req.m_data.reserve(size_tot); - m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_FIRST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)size_tot), event_data::blank); + m_module.log_event(&EAPMETHOD_TLS_PACKET_RECV_FRAG_FIRST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)size_tot), event_data::blank); } else { // The Length field was not included. Odd. Nevermind, no pre-allocation then. - m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_FIRST1, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data::blank); + m_module.log_event(&EAPMETHOD_TLS_PACKET_RECV_FRAG_FIRST1, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data::blank); } } else { // Mid fragment received. - m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_MID, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)m_packet_req.m_data.size()), event_data::blank); + m_module.log_event(&EAPMETHOD_TLS_PACKET_RECV_FRAG_MID, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)m_packet_req.m_data.size()), event_data::blank); } m_packet_req.m_data.insert(m_packet_req.m_data.end(), packet_data_ptr, packet_data_ptr + packet_data_size); @@ -497,40 +497,11 @@ void eap::method_tls::process_request_packet( } else if (!m_packet_req.m_data.empty()) { // Last fragment received. Append data. m_packet_req.m_data.insert(m_packet_req.m_data.end(), packet_data_ptr, packet_data_ptr + packet_data_size); - m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_LAST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)m_packet_req.m_data.size()), event_data::blank); + m_module.log_event(&EAPMETHOD_TLS_PACKET_RECV_FRAG_LAST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)m_packet_req.m_data.size()), event_data::blank); } else { // This is a complete non-fragmented packet. m_packet_req.m_data.assign(packet_data_ptr, packet_data_ptr + packet_data_size); - m_module.log_event(&EAPMETHOD_PACKET_RECV, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data::blank); - } - - if (pReceivedPacket->Code == EapCodeRequest && pReceivedPacket->Data[1] & flags_req_start) { - // This is the TLS start message: initialize method. - m_phase = phase_client_hello; - m_packet_res.clear(); - m_padding_hmac_client.clear(); - //m_padding_hmac_server.clear(); - m_key_client.free(); - m_key_server.free(); - - // Generate client randomness. - m_state.m_random_client.reset(m_cp); - m_server_cert_chain.clear(); - m_session_id.clear(); - - // Create MD5 hash object. - if (!m_hash_handshake_msgs_md5.create(m_cp, CALG_MD5)) - throw win_runtime_error(__FUNCTION__ " Error creating MD5 hashing object."); - - // Create SHA-1 hash object. - if (!m_hash_handshake_msgs_sha1.create(m_cp, CALG_SHA1)) - throw win_runtime_error(__FUNCTION__ " Error creating SHA-1 hashing object."); - - m_send_client_cert = false; - //m_server_hello_done = false; - m_server_finished = false; - m_cipher_spec = false; - m_seq_num = 0; + m_module.log_event(&EAPMETHOD_TLS_PACKET_RECV, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data::blank); } m_packet_req.m_code = (EapCode)pReceivedPacket->Code; @@ -553,10 +524,39 @@ void eap::method_tls::process_request_packet( throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, string_printf(__FUNCTION__ " ACK expected, received %u-%u-%x.", m_packet_req.m_code, m_packet_req.m_id, m_packet_req.m_flags)); } + if (pReceivedPacket->Code == EapCodeRequest && m_packet_req.m_flags & flags_req_start) { + // This is the TLS start message: initialize method. + m_module.log_event(&EAPMETHOD_TLS_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank); + + m_phase = phase_client_hello; + m_packet_res.clear(); + m_padding_hmac_client.clear(); + //m_padding_hmac_server.clear(); + m_key_client.free(); + m_key_server.free(); + + // Generate client randomness. + m_state.m_random_client.reset(m_cp); + m_server_cert_chain.clear(); + m_session_id.clear(); + + // Create MD5 hash object. + if (!m_hash_handshake_msgs_md5.create(m_cp, CALG_MD5)) + throw win_runtime_error(__FUNCTION__ " Error creating MD5 hashing object."); + + // Create SHA-1 hash object. + if (!m_hash_handshake_msgs_sha1.create(m_cp, CALG_SHA1)) + throw win_runtime_error(__FUNCTION__ " Error creating SHA-1 hashing object."); + + m_send_client_cert = false; + m_server_hello_done = false; + m_server_finished = false; + m_cipher_spec = false; + m_seq_num = 0; + } + switch (m_phase) { case phase_client_hello: { - m_module.log_event(&EAPMETHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank); - // Build response packet. m_packet_res.m_code = EapCodeResponse; m_packet_res.m_id = m_packet_req.m_id; @@ -577,6 +577,17 @@ void eap::method_tls::process_request_packet( case phase_server_hello: { process_packet(m_packet_req.m_data.data(), m_packet_req.m_data.size()); + if (!m_server_hello_done) { + // Reply with ACK packet and wait for the next packet. + m_packet_res.m_code = EapCodeResponse; + m_packet_res.m_id = pReceivedPacket->Id; + m_packet_res.m_flags = 0; + m_packet_res.m_data.clear(); + pEapOutput->fAllowNotifications = FALSE; + pEapOutput->action = EapPeerMethodResponseActionSend; + break; + } + // Do we trust this server? if (m_server_cert_chain.empty()) throw win_runtime_error(ERROR_ENCRYPTION_FAILED, __FUNCTION__ " Can not continue without server's certificate."); @@ -623,6 +634,10 @@ void eap::method_tls::process_request_packet( m_packet_res.m_data.insert(m_packet_res.m_data.end(), handshake.begin(), handshake.end()); CryptHashData(m_hash_handshake_msgs_md5 , client_key_exchange.data(), (DWORD)client_key_exchange.size(), 0); CryptHashData(m_hash_handshake_msgs_sha1, client_key_exchange.data(), (DWORD)client_key_exchange.size(), 0); + + if (m_send_client_cert) { + // TODO: Create and append certificate_verify message! + } } // Append change cipher spec to packet. @@ -637,6 +652,7 @@ void eap::method_tls::process_request_packet( } else m_phase = phase_finished; + // Create finished message, and append to packet. sanitizing_blob finished(make_finished()); sanitizing_blob handshake(make_handshake(finished, m_cipher_spec)); m_packet_res.m_data.insert(m_packet_res.m_data.end(), handshake.begin(), handshake.end()); @@ -694,7 +710,7 @@ void eap::method_tls::get_response_packet( // No need to fragment the packet. m_packet_res.m_flags &= ~flags_res_length_incl; // No need to explicitly include the Length field either. data_dst = pSendPacket->Data + 2; - m_module.log_event(&EAPMETHOD_PACKET_SEND, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data::blank); + m_module.log_event(&EAPMETHOD_TLS_PACKET_SEND, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data::blank); } else { // But it should be fragmented. m_packet_res.m_flags |= flags_res_length_incl | flags_res_more_frag; @@ -702,7 +718,7 @@ void eap::method_tls::get_response_packet( data_dst = pSendPacket->Data + 6; size_data = size_packet_limit - 10; size_packet = size_packet_limit; - m_module.log_event(&EAPMETHOD_PACKET_SEND_FRAG_FIRST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank); + m_module.log_event(&EAPMETHOD_TLS_PACKET_SEND_FRAG_FIRST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank); } } else { // Continuing the fragmented packet... @@ -711,11 +727,11 @@ void eap::method_tls::get_response_packet( m_packet_res.m_flags &= ~flags_res_length_incl; size_data = size_packet_limit - 6; size_packet = size_packet_limit; - m_module.log_event(&EAPMETHOD_PACKET_SEND_FRAG_MID, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank); + m_module.log_event(&EAPMETHOD_TLS_PACKET_SEND_FRAG_MID, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank); } else { // This is the last fragment. m_packet_res.m_flags &= ~(flags_res_length_incl | flags_res_more_frag); - m_module.log_event(&EAPMETHOD_PACKET_SEND_FRAG_LAST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank); + m_module.log_event(&EAPMETHOD_TLS_PACKET_SEND_FRAG_LAST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank); } data_dst = pSendPacket->Data + 2; } @@ -992,16 +1008,7 @@ void eap::method_tls::process_packet(_In_bytecount_(size_pck) const void *_pck, // Process TLS 1.0 message. switch (hdr->type) { case message_type_change_cipher_spec: - if (msg + 1 > msg_end) - throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete change cipher spec message."); - else if (msg[0] != 1) - throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, string_printf(__FUNCTION__ " Invalid change cipher spec message (expected 1, received %u).", msg[0])); - - if (!m_cipher_spec) { - // Resuming previous session. - derive_keys(); - m_cipher_spec = true; - } + process_change_cipher_spec(msg, msg_end - msg); break; case message_type_alert: @@ -1021,6 +1028,15 @@ void eap::method_tls::process_packet(_In_bytecount_(size_pck) const void *_pck, } else process_handshake(msg, msg_end - msg); break; + + case message_type_application_data: + if (!m_cipher_spec) + throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Application data should be encrypted."); + + sanitizing_blob msg_dec(msg, msg_end); + decrypt_message(msg_dec); + process_application_data(msg_dec.data(), msg_dec.size()); + break; } } @@ -1029,6 +1045,41 @@ void eap::method_tls::process_packet(_In_bytecount_(size_pck) const void *_pck, } +void eap::method_tls::process_change_cipher_spec(_In_bytecount_(msg_size) const void *_msg, _In_ size_t msg_size) +{ + if (msg_size < 1) + throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete change cipher spec."); + + const unsigned char *msg = (const unsigned char*)_msg; + if (msg[0] != 1) + throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, string_printf(__FUNCTION__ " Invalid change cipher spec message (expected 1, received %u).", msg[0])); + + m_module.log_event(&EAPMETHOD_TLS_CHANGE_CIPHER_SPEC, event_data((unsigned int)eap_type_tls), event_data::blank); + + if (!m_cipher_spec) { + // Resuming previous session. + derive_keys(); + m_cipher_spec = true; + } +} + + +void eap::method_tls::process_alert(_In_bytecount_(msg_size) const void *_msg, _In_ size_t msg_size) +{ + if (msg_size < 2) + throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete alert."); + + const unsigned char *msg = (const unsigned char*)_msg; + + m_module.log_event(&EAPMETHOD_TLS_ALERT, event_data((unsigned int)eap_type_tls), event_data((unsigned char)msg[0]), event_data((unsigned char)msg[1]), event_data::blank); + + //if (msg[0] == alert_level_fatal) { + // // Clear session ID to avoid reconnection attempts. + // m_session_id.clear(); + //} +} + + void eap::method_tls::process_handshake(_In_bytecount_(msg_size) const void *_msg, _In_ size_t msg_size) { for (const unsigned char *msg = (const unsigned char*)_msg, *msg_end = msg + msg_size; msg < msg_end; ) { @@ -1043,7 +1094,8 @@ void eap::method_tls::process_handshake(_In_bytecount_(msg_size) const void *_ms throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete record data."); // Process record. - switch (hdr >> 24) { + unsigned char type = hdr >> 24; + switch (type) { case handshake_type_server_hello: // TLS version if (rec + 2 > rec_end) @@ -1071,6 +1123,7 @@ void eap::method_tls::process_handshake(_In_bytecount_(msg_size) const void *_ms if (rec[0] != 0x00 || rec[1] != 0x0a) throw win_runtime_error(ERROR_NOT_SUPPORTED, string_printf(__FUNCTION__ " Other than requested cipher selected (expected 0x000a, received 0x%02x%02x).", rec[0], rec[1])); + m_module.log_event(&EAPMETHOD_TLS_SERVER_HELLO, event_data((unsigned int)eap_type_tls), event_data((unsigned int)m_session_id.size()), event_data(m_session_id.data(), (ULONG)m_session_id.size()), event_data::blank); break; case handshake_type_certificate: { @@ -1103,15 +1156,20 @@ void eap::method_tls::process_handshake(_In_bytecount_(msg_size) const void *_ms list = cert_end; } + wstring cert_name(!m_server_cert_chain.empty() ? get_cert_title(m_server_cert_chain.front()) : L""); + m_module.log_event(&EAPMETHOD_TLS_CERTIFICATE, event_data((unsigned int)eap_type_tls), event_data(cert_name), event_data::blank); break; } case handshake_type_certificate_request: m_send_client_cert = true; + m_module.log_event(&EAPMETHOD_TLS_CERTIFICATE_REQUEST, event_data((unsigned int)eap_type_tls), event_data::blank); break; - //case handshake_type_server_hello_done: - // m_server_hello_done = true; + case handshake_type_server_hello_done: + m_server_hello_done = true; + m_module.log_event(&EAPMETHOD_TLS_SERVER_HELLO_DONE, event_data((unsigned int)eap_type_tls), event_data::blank); + break; case handshake_type_finished: { // According to https://tools.ietf.org/html/rfc5246#section-7.4.9 all verify_data is 12B. @@ -1133,8 +1191,12 @@ void eap::method_tls::process_handshake(_In_bytecount_(msg_size) const void *_ms throw win_runtime_error(ERROR_ENCRYPTION_FAILED, __FUNCTION__ " Integrity check failed."); m_server_finished = true; + m_module.log_event(&EAPMETHOD_TLS_FINISHED, event_data((unsigned int)eap_type_tls), event_data::blank); break; } + + default: + m_module.log_event(&EAPMETHOD_TLS_HANDSHAKE_IGNORE, event_data((unsigned int)eap_type_tls), event_data(type), event_data::blank); } msg = rec_end; @@ -1142,17 +1204,10 @@ void eap::method_tls::process_handshake(_In_bytecount_(msg_size) const void *_ms } -void eap::method_tls::process_alert(_In_bytecount_(msg_size) const void *msg, _In_ size_t msg_size) +void eap::method_tls::process_application_data(_In_bytecount_(msg_size) const void *msg, _In_ size_t msg_size) { UNREFERENCED_PARAMETER(msg); - - if (msg_size < 2) - throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete alert."); - - //if (msg[0] == alert_level_fatal) { - // // Clear session ID to avoid reconnection attempts. - // m_session_id.clear(); - //} + UNREFERENCED_PARAMETER(msg_size); } @@ -1180,7 +1235,7 @@ void eap::method_tls::verify_server_trust() if (_stricmp(a, b) == 0 || // Direct match a[0] == '*' && len_b + 1 >= len_a && _stricmp(a + 1, b + len_b - (len_a - 1)) == 0) // "*..." wildchar match { - m_module.log_event(&EAPMETHOD_SERVER_NAME_TRUSTED, event_data(subj), event_data::blank); + m_module.log_event(&EAPMETHOD_TLS_SERVER_NAME_TRUSTED, event_data(subj), event_data::blank); break; } } else @@ -1247,7 +1302,7 @@ void eap::method_tls::verify_server_trust() } } - m_module.log_event(&EAPMETHOD_SERVER_CERT_TRUSTED, event_data::blank); + m_module.log_event(&EAPMETHOD_TLS_SERVER_CERT_TRUSTED, event_data::blank); } diff --git a/lib/TTLS/src/Method.cpp b/lib/TTLS/src/Method.cpp index 4eea8a0..7e23fd8 100644 --- a/lib/TTLS/src/Method.cpp +++ b/lib/TTLS/src/Method.cpp @@ -98,7 +98,7 @@ void eap::method_ttls::process_request_packet( // Determine minimum EAP-TTLS version supported by server and us. version_t ver_remote = (version_t)(pReceivedPacket->Data[1] & flags_ver_mask); m_version = std::min(ver_remote, version_0); - m_module.log_event(&EAPMETHOD_HANDSHAKE_START1, event_data((unsigned int)eap_type_ttls), event_data((unsigned char)m_version), event_data((unsigned char)ver_remote), event_data::blank); + m_module.log_event(&EAPMETHOD_TTLS_HANDSHAKE_START, event_data((unsigned int)eap_type_ttls), event_data((unsigned char)m_version), event_data((unsigned char)ver_remote), event_data::blank); } m_outer.process_request_packet(pReceivedPacket, dwReceivedPacketSize, pEapOutput);