TLS version no longer static, thou still fixed to TLS 1.0

This commit is contained in:
Simon Rozman 2016-08-15 19:04:21 +02:00
parent 3267b7f53d
commit c8cfe4da42
4 changed files with 142 additions and 17 deletions

View File

@ -130,10 +130,7 @@ namespace eap
struct message_header struct message_header
{ {
unsigned char type; ///< Message type (one of `message_type_t` constants) unsigned char type; ///< Message type (one of `message_type_t` constants)
struct { tls_version version; ///< SSL/TLS version
unsigned char major; ///< Major version
unsigned char minor; ///< Minor version
} version; ///< SSL/TLS version
unsigned char length[2]; ///< Message length (in network byte order) unsigned char length[2]; ///< Message length (in network byte order)
}; };
#pragma pack(pop) #pragma pack(pop)
@ -269,7 +266,7 @@ namespace eap
/// ///
/// \returns Change cipher spec /// \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 /// Makes a TLS finished message
@ -510,6 +507,8 @@ namespace eap
winstd::crypt_prov m_cp; ///< Cryptography provider 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 tls_conn_state m_state; ///< TLS connection state for fast reconnect
sanitizing_blob m_padding_hmac_client; ///< Padding (key) for client side HMAC calculation sanitizing_blob m_padding_hmac_client; ///< Padding (key) for client side HMAC calculation

View File

@ -50,6 +50,14 @@ namespace eap
/// ///
enum tls_alert_desc_t; 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 /// TLS client/server tls_random
/// ///
@ -155,6 +163,8 @@ inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::tls_conn_state
#pragma once #pragma once
#include <memory>
namespace eap 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(push)
#pragma pack(1) #pragma pack(1)
struct __declspec(novtable) tls_random struct __declspec(novtable) tls_random

View File

@ -107,6 +107,7 @@ eap::method_tls::method_tls(_In_ module &module, _In_ config_provider_list &cfg,
#endif #endif
method(module, cfg, cred) 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); 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)); msg.insert(msg.end(), (unsigned char*)&ssl_header, (unsigned char*)(&ssl_header + 1));
// SSL version: TLS 1.0 // SSL version
msg.push_back(3); // SSL major version msg.insert(msg.end(), (unsigned char*)&m_tls_version, (unsigned char*)(&m_tls_version + 1));
msg.push_back(1); // SSL minor version
// Client random // Client random
msg.insert(msg.end(), (unsigned char*)&m_state.m_random_client, (unsigned char*)(&m_state.m_random_client + 1)); 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 (unsigned char)tls_message_type_change_cipher_spec, // SSL record type
3, // SSL major version m_tls_version.major, // SSL major version
1, // SSL minor version m_tls_version.minor, // SSL minor version
0, // Message size (high-order byte) 0, // Message size (high-order byte)
1, // Message size (low-order byte) 1, // Message size (low-order byte)
1, // Message: change_cipher_spec is always "1" 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 = { message_header hdr = {
(unsigned char)type, // SSL record type (unsigned char)type, // SSL record type
{ {
3, // SSL major version m_tls_version.major, // SSL major version
1, // SSL minor version m_tls_version.minor, // SSL minor version
}, },
{ {
// Data length (unencrypted, network byte order) // 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) if (msg_end > pck_end)
throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete message data."); 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. // Process TLS 1.0 message.
switch (hdr->type) { switch (hdr->type) {
case tls_message_type_change_cipher_spec: 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 // TLS version
if (rec + 2 > rec_end) if (rec + 2 > rec_end)
throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Server SSL/TLS version missing or incomplete."); 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."); throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Unsupported SSL/TLS version.");
m_state.m_alg_prf = CALG_TLS1PRF; m_state.m_alg_prf = CALG_TLS1PRF;
rec += 2; rec += 2;

View File

@ -24,6 +24,15 @@ using namespace std;
using namespace winstd; 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 // eap::tls_random
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////