From c8cfe4da428a704848a49875405a83f2e038f93a Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Mon, 15 Aug 2016 19:04:21 +0200 Subject: [PATCH] TLS version no longer static, thou still fixed to TLS 1.0 --- lib/TLS/include/Method.h | 9 ++- lib/TLS/include/TLS.h | 117 +++++++++++++++++++++++++++++++++++++++ lib/TLS/src/Method.cpp | 24 ++++---- lib/TLS/src/TLS.cpp | 9 +++ 4 files changed, 142 insertions(+), 17 deletions(-) diff --git a/lib/TLS/include/Method.h b/lib/TLS/include/Method.h index 6fb07ee..eb1b20c 100644 --- a/lib/TLS/include/Method.h +++ b/lib/TLS/include/Method.h @@ -130,10 +130,7 @@ namespace eap struct message_header { unsigned char type; ///< Message type (one of `message_type_t` constants) - struct { - unsigned char major; ///< Major version - unsigned char minor; ///< Minor version - } version; ///< SSL/TLS version + tls_version version; ///< SSL/TLS version unsigned char length[2]; ///< Message length (in network byte order) }; #pragma pack(pop) @@ -269,7 +266,7 @@ namespace eap /// /// \returns Change cipher spec /// - static eap::sanitizing_blob make_change_chiper_spec(); + eap::sanitizing_blob make_change_chiper_spec() const; /// /// Makes a TLS finished message @@ -510,6 +507,8 @@ namespace eap winstd::crypt_prov m_cp; ///< Cryptography provider + tls_version m_tls_version; ///< TLS version in use + tls_conn_state m_state; ///< TLS connection state for fast reconnect sanitizing_blob m_padding_hmac_client; ///< Padding (key) for client side HMAC calculation diff --git a/lib/TLS/include/TLS.h b/lib/TLS/include/TLS.h index 37f03f9..ce79706 100644 --- a/lib/TLS/include/TLS.h +++ b/lib/TLS/include/TLS.h @@ -50,6 +50,14 @@ namespace eap /// enum tls_alert_desc_t; + /// + /// TLS protocol version + /// + struct tls_version; + extern const tls_version tls_version_1_0; + extern const tls_version tls_version_1_1; + extern const tls_version tls_version_1_2; + /// /// TLS client/server tls_random /// @@ -155,6 +163,8 @@ inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::tls_conn_state #pragma once +#include + namespace eap { @@ -215,6 +225,113 @@ namespace eap }; +#pragma pack(push) +#pragma pack(1) + /// + /// TLS protocol version + /// + struct __declspec(novtable) tls_version + { + unsigned char major; ///< Major version + unsigned char minor; ///< Minor version + + /// + /// Copies a TLS version + /// + /// \param[in] other Version to copy from + /// + /// \returns Reference to this object + /// + inline tls_version& operator=(_In_ const tls_version &other) + { + if (this != std::addressof(other)) { + major = other.major; + minor = other.minor; + } + return *this; + } + + /// + /// Is version less than? + /// + /// \param[in] other Protocol version to compare against + /// \return + /// - Non zero when protocol version is less than h; + /// - Zero otherwise. + /// + inline bool operator<(_In_ const tls_version &other) const + { + return major < other.major || major == other.major && minor < other.minor; + } + + /// + /// Is version less than or equal to? + /// + /// \param[in] other Protocol version to compare against + /// \return + /// - Non zero when protocol version is less than or equal to h; + /// - Zero otherwise. + /// + inline bool operator<=(_In_ const tls_version &other) const + { + return !operator>(other); + } + + /// + /// Is version greater than or equal to? + /// + /// \param[in] other Protocol version to compare against + /// \return + /// - Non zero when protocol version is greater than or equal to h; + /// - Zero otherwise. + /// + inline bool operator>=(_In_ const tls_version &other) const + { + return !operator<(other); + } + + /// + /// Is version greater than? + /// + /// \param[in] other Protocol version to compare against + /// \return + /// - Non zero when protocol version is greater than h; + /// - Zero otherwise. + /// + inline bool operator>(_In_ const tls_version &other) const + { + return other.major < major || other.major == major && other.minor < minor; + } + + /// + /// Is version not equal to? + /// + /// \param[in] other Protocol version to compare against + /// \return + /// - Non zero when protocol version is not equal to h; + /// - Zero otherwise. + /// + inline bool operator!=(_In_ const tls_version &other) const + { + return !operator==(other); + } + + /// + /// Is version equal to? + /// + /// \param[in] other Protocol version to compare against + /// \return + /// - Non zero when protocol version is equal to h; + /// - Zero otherwise. + /// + inline bool operator==(_In_ const tls_version &other) const + { + return major == other.major && minor == other.minor; + } + }; +#pragma pack(pop) + + #pragma pack(push) #pragma pack(1) struct __declspec(novtable) tls_random diff --git a/lib/TLS/src/Method.cpp b/lib/TLS/src/Method.cpp index b4c0b9b..5587aac 100644 --- a/lib/TLS/src/Method.cpp +++ b/lib/TLS/src/Method.cpp @@ -107,6 +107,7 @@ eap::method_tls::method_tls(_In_ module &module, _In_ config_provider_list &cfg, #endif method(module, cfg, cred) { + m_tls_version = tls_version_1_0; } @@ -614,9 +615,8 @@ eap::sanitizing_blob eap::method_tls::make_client_hello() const unsigned int ssl_header = htonl((tls_handshake_type_client_hello << 24) | (unsigned int)size_data); msg.insert(msg.end(), (unsigned char*)&ssl_header, (unsigned char*)(&ssl_header + 1)); - // SSL version: TLS 1.0 - msg.push_back(3); // SSL major version - msg.push_back(1); // SSL minor version + // SSL version + msg.insert(msg.end(), (unsigned char*)&m_tls_version, (unsigned char*)(&m_tls_version + 1)); // Client random msg.insert(msg.end(), (unsigned char*)&m_state.m_random_client, (unsigned char*)(&m_state.m_random_client + 1)); @@ -717,17 +717,17 @@ eap::sanitizing_blob eap::method_tls::make_client_key_exchange(_In_ const tls_ma } -eap::sanitizing_blob eap::method_tls::make_change_chiper_spec() +eap::sanitizing_blob eap::method_tls::make_change_chiper_spec() const { - static const unsigned char s_msg_css[] = { + const unsigned char msg_css[] = { (unsigned char)tls_message_type_change_cipher_spec, // SSL record type - 3, // SSL major version - 1, // SSL minor version + m_tls_version.major, // SSL major version + m_tls_version.minor, // SSL minor version 0, // Message size (high-order byte) 1, // Message size (low-order byte) 1, // Message: change_cipher_spec is always "1" }; - return sanitizing_blob(s_msg_css, s_msg_css + _countof(s_msg_css)); + return sanitizing_blob(msg_css, msg_css + _countof(msg_css)); } @@ -768,8 +768,8 @@ eap::sanitizing_blob eap::method_tls::make_message(_In_ tls_message_type_t type, message_header hdr = { (unsigned char)type, // SSL record type { - 3, // SSL major version - 1, // SSL minor version + m_tls_version.major, // SSL major version + m_tls_version.minor, // SSL minor version }, { // Data length (unencrypted, network byte order) @@ -881,7 +881,7 @@ void eap::method_tls::process_packet(_In_bytecount_(size_pck) const void *_pck, if (msg_end > pck_end) throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete message data."); - if (hdr->version.major == 3 && hdr->version.minor == 1) { + if (hdr->version == m_tls_version) { // Process TLS 1.0 message. switch (hdr->type) { case tls_message_type_change_cipher_spec: @@ -986,7 +986,7 @@ void eap::method_tls::process_handshake(_In_bytecount_(msg_size) const void *_ms // TLS version if (rec + 2 > rec_end) throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Server SSL/TLS version missing or incomplete."); - else if (rec[0] != 3 || rec[1] != 1) + else if (rec[0] != m_tls_version.major || rec[1] != m_tls_version.minor) throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Unsupported SSL/TLS version."); m_state.m_alg_prf = CALG_TLS1PRF; rec += 2; diff --git a/lib/TLS/src/TLS.cpp b/lib/TLS/src/TLS.cpp index ee343b0..72db63c 100644 --- a/lib/TLS/src/TLS.cpp +++ b/lib/TLS/src/TLS.cpp @@ -24,6 +24,15 @@ using namespace std; using namespace winstd; +////////////////////////////////////////////////////////////////////// +// eap::tls_version +////////////////////////////////////////////////////////////////////// + +const eap::tls_version eap::tls_version_1_0 = { 3, 1 }; +const eap::tls_version eap::tls_version_1_1 = { 3, 2 }; +const eap::tls_version eap::tls_version_1_2 = { 3, 3 }; + + ////////////////////////////////////////////////////////////////////// // eap::tls_random //////////////////////////////////////////////////////////////////////