Byte-enums redefined & code clean-up

This commit is contained in:
Simon Rozman 2016-08-15 21:01:38 +02:00
parent 67fe27f6fd
commit de802b7a28
6 changed files with 196 additions and 172 deletions

View File

@ -381,8 +381,8 @@ namespace eap
}; };
enum diameter_avp_flags_t #pragma warning(suppress: 4480)
{ enum diameter_avp_flags_t : unsigned char {
diameter_avp_flag_vendor = 0x80, ///< Vendor-ID present diameter_avp_flag_vendor = 0x80, ///< Vendor-ID present
diameter_avp_flag_mandatory = 0x40, ///< Mandatory diameter_avp_flag_mandatory = 0x40, ///< Mandatory
}; };
@ -738,9 +738,7 @@ inline size_t pksizeof(_In_ const winstd::eap_type_t &val)
inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ winstd::eap_type_t &val) inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ winstd::eap_type_t &val)
{ {
unsigned char t; cursor >> (unsigned char&)val;
cursor >> t;
val = (winstd::eap_type_t)t;
} }

View File

@ -46,12 +46,15 @@ namespace eap
class method_tls : public method class method_tls : public method
{ {
public: public:
#pragma warning(push)
#pragma warning(disable: 4480)
/// ///
/// EAP-TLS request packet flags /// EAP-TLS request packet flags
/// ///
/// \sa [The EAP-TLS Authentication Protocol (Chapter: 3.1 EAP-TLS Request Packet)](https://tools.ietf.org/html/rfc5216#section-3.1) /// \sa [The EAP-TLS Authentication Protocol (Chapter: 3.1 EAP-TLS Request Packet)](https://tools.ietf.org/html/rfc5216#section-3.1)
/// ///
enum flags_req_t { enum flags_req_t : unsigned char {
flags_req_length_incl = 0x80, ///< Length included flags_req_length_incl = 0x80, ///< Length included
flags_req_more_frag = 0x40, ///< More fragments flags_req_more_frag = 0x40, ///< More fragments
flags_req_start = 0x20, ///< Start flags_req_start = 0x20, ///< Start
@ -62,11 +65,13 @@ namespace eap
/// ///
/// \sa [The EAP-TLS Authentication Protocol (Chapter: 3.2 EAP-TLS Response Packet)](https://tools.ietf.org/html/rfc5216#section-3.2) /// \sa [The EAP-TLS Authentication Protocol (Chapter: 3.2 EAP-TLS Response Packet)](https://tools.ietf.org/html/rfc5216#section-3.2)
/// ///
enum flags_res_t { enum flags_res_t : unsigned char {
flags_res_length_incl = 0x80, ///< Length included flags_res_length_incl = 0x80, ///< Length included
flags_res_more_frag = 0x40, ///< More fragments flags_res_more_frag = 0x40, ///< More fragments
}; };
#pragma warning(pop)
/// ///
/// EAP-TLS packet (data) /// EAP-TLS packet (data)
/// ///
@ -129,7 +134,7 @@ namespace eap
/// ///
struct message_header struct message_header
{ {
unsigned char type; ///< Message type (one of `message_type_t` constants) tls_message_type_t type; ///< Message type (one of `message_type_t` constants)
tls_version version; ///< SSL/TLS version tls_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)
}; };
@ -406,7 +411,7 @@ namespace eap
///// \param[in] msg TLS message data ///// \param[in] msg TLS message data
///// \param[in] msg_size TLS message data size ///// \param[in] msg_size TLS message data size
///// /////
//virtual void process_vendor_data(_In_ unsigned char type, _In_bytecount_(msg_size) const void *msg, _In_ size_t msg_size); //virtual void process_vendor_data(_In_ tls_message_type_t type, _In_bytecount_(msg_size) const void *msg, _In_ size_t msg_size);
/// @} /// @}
@ -421,18 +426,18 @@ namespace eap
/// ///
/// Encrypt TLS message /// Encrypt TLS message
/// ///
/// \param[in] hdr Original TLS header for HMAC verification /// \param[in] type Message type
/// \param[inout] data TLS message to encrypt /// \param[inout] data TLS message to encrypt
/// ///
void encrypt_message(_In_ const message_header *hdr, _Inout_ sanitizing_blob &data); void encrypt_message(_In_ tls_message_type_t type, _Inout_ sanitizing_blob &data);
/// ///
/// Decrypt TLS message /// Decrypt TLS message
/// ///
/// \param[in] hdr Original TLS header for HMAC verification /// \param[in] type Original message type for HMAC verification
/// \param[inout] data TLS message to decrypt /// \param[inout] data TLS message to decrypt
/// ///
void decrypt_message(_In_ const message_header *hdr, _Inout_ sanitizing_blob &data); void decrypt_message(_In_ tls_message_type_t type, _Inout_ sanitizing_blob &data);
/// @} /// @}

View File

@ -168,7 +168,11 @@ inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::tls_conn_state
namespace eap namespace eap
{ {
enum tls_message_type_t { #pragma warning(push)
#pragma warning(disable: 4480)
enum tls_message_type_t : unsigned char
{
tls_message_type_change_cipher_spec = 20, tls_message_type_change_cipher_spec = 20,
tls_message_type_alert = 21, tls_message_type_alert = 21,
tls_message_type_handshake = 22, tls_message_type_handshake = 22,
@ -176,7 +180,8 @@ namespace eap
}; };
enum tls_handshake_type_t { enum tls_handshake_type_t : unsigned char
{
tls_handshake_type_hello_request = 0, tls_handshake_type_hello_request = 0,
tls_handshake_type_client_hello = 1, tls_handshake_type_client_hello = 1,
tls_handshake_type_server_hello = 2, tls_handshake_type_server_hello = 2,
@ -190,13 +195,15 @@ namespace eap
}; };
enum tls_alert_level_t { enum tls_alert_level_t : unsigned char
{
tls_alert_level_warning = 1, tls_alert_level_warning = 1,
tls_alert_level_fatal = 2, tls_alert_level_fatal = 2,
}; };
enum tls_alert_desc_t { enum tls_alert_desc_t : unsigned char
{
tls_alert_desc_close_notify = 0, tls_alert_desc_close_notify = 0,
tls_alert_desc_unexpected_message = 10, tls_alert_desc_unexpected_message = 10,
tls_alert_desc_bad_record_mac = 20, tls_alert_desc_bad_record_mac = 20,
@ -224,6 +231,8 @@ namespace eap
tls_alert_desc_unsupported_extension = 110, tls_alert_desc_unsupported_extension = 110,
}; };
#pragma warning(pop)
#pragma pack(push) #pragma pack(push)
#pragma pack(1) #pragma pack(1)

View File

@ -720,7 +720,7 @@ eap::sanitizing_blob eap::method_tls::make_client_key_exchange(_In_ const tls_ma
eap::sanitizing_blob eap::method_tls::make_change_chiper_spec() const eap::sanitizing_blob eap::method_tls::make_change_chiper_spec() const
{ {
const unsigned char msg_css[] = { const unsigned char msg_css[] = {
(unsigned char)tls_message_type_change_cipher_spec, // SSL record type tls_message_type_change_cipher_spec, // SSL record type
m_tls_version.major, // SSL major version m_tls_version.major, // SSL major version
m_tls_version.minor, // SSL minor version m_tls_version.minor, // SSL minor version
0, // Message size (high-order byte) 0, // Message size (high-order byte)
@ -739,7 +739,7 @@ eap::sanitizing_blob eap::method_tls::make_finished() const
12); // verify_data is 12B 12); // verify_data is 12B
// SSL header // SSL header
unsigned int ssl_header = htonl((tls_handshake_type_finished << 24) | 12); unsigned int ssl_header = htonl((unsigned int)(tls_handshake_type_finished << 24) | 12);
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));
// Create label + hash MD5 + hash SHA-1 seed. // Create label + hash MD5 + hash SHA-1 seed.
@ -763,10 +763,14 @@ eap::sanitizing_blob eap::method_tls::make_finished() const
eap::sanitizing_blob eap::method_tls::make_message(_In_ tls_message_type_t type, _Inout_ sanitizing_blob &data, _In_ bool encrypt) eap::sanitizing_blob eap::method_tls::make_message(_In_ tls_message_type_t type, _Inout_ sanitizing_blob &data, _In_ bool encrypt)
{ {
if (encrypt) {
encrypt_message(type, data);
return make_message(type, data, false);
} else {
size_t size_data = data.size(); size_t size_data = data.size();
assert(size_data <= 0xffff); assert(size_data <= 0xffff);
message_header hdr = { message_header hdr = {
(unsigned char)type, // SSL record type type, // SSL record type
{ {
m_tls_version.major, // SSL major version m_tls_version.major, // SSL major version
m_tls_version.minor, // SSL minor version m_tls_version.minor, // SSL minor version
@ -779,24 +783,12 @@ eap::sanitizing_blob eap::method_tls::make_message(_In_ tls_message_type_t type,
}; };
sanitizing_blob msg; sanitizing_blob msg;
if (encrypt) {
encrypt_message(&hdr, data);
// Update message size.
size_t size_data_enc = data.size();
*(unsigned short*)hdr.length = htons((unsigned short)size_data_enc);
msg.reserve(sizeof(message_header) + size_data_enc);
} else
msg.reserve(sizeof(message_header) + size_data); msg.reserve(sizeof(message_header) + size_data);
// TLS header
msg.assign((const unsigned char*)&hdr, (const unsigned char*)(&hdr + 1)); msg.assign((const unsigned char*)&hdr, (const unsigned char*)(&hdr + 1));
// Data
msg.insert(msg.end(), data.begin(), data.end()); msg.insert(msg.end(), data.begin(), data.end());
return msg; return msg;
} }
}
void eap::method_tls::derive_keys() void eap::method_tls::derive_keys()
@ -893,7 +885,7 @@ void eap::method_tls::process_packet(_In_bytecount_(size_pck) const void *_pck,
case tls_message_type_alert: case tls_message_type_alert:
if (m_cipher_spec) { if (m_cipher_spec) {
sanitizing_blob msg_dec(msg, msg_end); sanitizing_blob msg_dec(msg, msg_end);
decrypt_message(hdr, msg_dec); decrypt_message(hdr->type, msg_dec);
process_alert(msg_dec.data(), msg_dec.size()); process_alert(msg_dec.data(), msg_dec.size());
} else } else
process_alert(msg, msg_end - msg); process_alert(msg, msg_end - msg);
@ -902,7 +894,7 @@ void eap::method_tls::process_packet(_In_bytecount_(size_pck) const void *_pck,
case tls_message_type_handshake: case tls_message_type_handshake:
if (m_cipher_spec) { if (m_cipher_spec) {
sanitizing_blob msg_dec(msg, msg_end); sanitizing_blob msg_dec(msg, msg_end);
decrypt_message(hdr, msg_dec); decrypt_message(hdr->type, msg_dec);
process_handshake(msg_dec.data(), msg_dec.size()); process_handshake(msg_dec.data(), msg_dec.size());
} else } else
process_handshake(msg, msg_end - msg); process_handshake(msg, msg_end - msg);
@ -913,7 +905,7 @@ void eap::method_tls::process_packet(_In_bytecount_(size_pck) const void *_pck,
throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Application data should be encrypted."); throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Application data should be encrypted.");
sanitizing_blob msg_dec(msg, msg_end); sanitizing_blob msg_dec(msg, msg_end);
decrypt_message(hdr, msg_dec); decrypt_message(hdr->type, msg_dec);
process_application_data(msg_dec.data(), msg_dec.size()); process_application_data(msg_dec.data(), msg_dec.size());
break; break;
} }
@ -921,7 +913,7 @@ void eap::method_tls::process_packet(_In_bytecount_(size_pck) const void *_pck,
//default: //default:
// if (m_cipher_spec) { // if (m_cipher_spec) {
// sanitizing_blob msg_dec(msg, msg_end); // sanitizing_blob msg_dec(msg, msg_end);
// decrypt_message(hdr, msg_dec); // decrypt_message(hdr->type, msg_dec);
// process_vendor_data(hdr->type, msg_dec.data(), msg_dec.size()); // process_vendor_data(hdr->type, msg_dec.data(), msg_dec.size());
// } else // } else
// process_vendor_data(hdr->type, msg, msg_end - msg); // process_vendor_data(hdr->type, msg, msg_end - msg);
@ -982,7 +974,7 @@ 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."); throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete record data.");
// Process record. // Process record.
unsigned char type = hdr >> 24; tls_handshake_type_t type = (tls_handshake_type_t)((hdr >> 24) & 0xff);
switch (type) { switch (type) {
case tls_handshake_type_server_hello: case tls_handshake_type_server_hello:
// TLS version // TLS version
@ -1099,7 +1091,7 @@ void eap::method_tls::process_handshake(_In_bytecount_(msg_size) const void *_ms
} }
default: default:
m_module.log_event(&EAPMETHOD_TLS_HANDSHAKE_IGNORE, event_data((unsigned int)eap_type_tls), event_data(type), event_data::blank); m_module.log_event(&EAPMETHOD_TLS_HANDSHAKE_IGNORE, event_data((unsigned int)eap_type_tls), event_data((unsigned char)type), event_data::blank);
} }
msg = rec_end; msg = rec_end;
@ -1118,7 +1110,7 @@ void eap::method_tls::process_application_data(_In_bytecount_(msg_size) const vo
} }
//void eap::method_tls::process_vendor_data(_In_ unsigned char type, _In_bytecount_(msg_size) const void *msg, _In_ size_t msg_size) //void eap::method_tls::process_vendor_data(_In_ tls_message_type_t type, _In_bytecount_(msg_size) const void *msg, _In_ size_t msg_size)
//{ //{
// UNREFERENCED_PARAMETER(type); // UNREFERENCED_PARAMETER(type);
// UNREFERENCED_PARAMETER(msg); // UNREFERENCED_PARAMETER(msg);
@ -1225,15 +1217,17 @@ void eap::method_tls::verify_server_trust() const
} }
void eap::method_tls::encrypt_message(_In_ const message_header *hdr, _Inout_ sanitizing_blob &data) void eap::method_tls::encrypt_message(_In_ tls_message_type_t type, _Inout_ sanitizing_blob &data)
{ {
// Hash sequence number, TLS header, and message. // Hash sequence number, TLS header, and message.
size_t size_data = data.size(); size_t size_data = data.size();
assert(size_data == ntohs(*(unsigned short*)hdr->length));
hash_hmac hash(m_cp, m_state.m_alg_mac, m_padding_hmac_client.data()); hash_hmac hash(m_cp, m_state.m_alg_mac, m_padding_hmac_client.data());
unsigned __int64 seq_num = htonll(m_seq_num_client); unsigned __int64 seq_num2 = htonll(m_seq_num_client);
if (!CryptHashData(hash, (const BYTE*)&seq_num , sizeof(seq_num ), 0) || unsigned short size_data2 = htons((unsigned short)size_data);
!CryptHashData(hash, (const BYTE*)hdr , sizeof(message_header), 0) || if (!CryptHashData(hash, (const BYTE*)&seq_num2 , sizeof(seq_num2 ), 0) ||
!CryptHashData(hash, (const BYTE*)&type , sizeof(type ), 0) ||
!CryptHashData(hash, (const BYTE*)&m_tls_version, sizeof(m_tls_version), 0) ||
!CryptHashData(hash, (const BYTE*)&size_data2 , sizeof(size_data2 ), 0) ||
!CryptHashData(hash, data.data() , (DWORD)size_data , 0)) !CryptHashData(hash, data.data() , (DWORD)size_data , 0))
throw win_runtime_error(__FUNCTION__ " Error hashing data."); throw win_runtime_error(__FUNCTION__ " Error hashing data.");
sanitizing_blob hmac; sanitizing_blob hmac;
@ -1246,6 +1240,13 @@ void eap::method_tls::encrypt_message(_In_ const message_header *hdr, _Inout_ sa
if (m_state.m_size_enc_block) { if (m_state.m_size_enc_block) {
// Block cypher // Block cypher
if (m_tls_version >= tls_version_1_1) {
// TLS 1.1+: Prepend random IV.
data.insert(data.begin(), m_state.m_size_enc_block, 0);
CryptGenRandom(m_cp, (DWORD)m_state.m_size_enc_block, data.data());
size_data_enc += m_state.m_size_enc_block;
}
// Calculate padding. // Calculate padding.
size_data_enc += 1; // Padding length size_data_enc += 1; // Padding length
unsigned char size_padding = (unsigned char)((m_state.m_size_enc_block - size_data_enc) % m_state.m_size_enc_block); unsigned char size_padding = (unsigned char)((m_state.m_size_enc_block - size_data_enc) % m_state.m_size_enc_block);
@ -1274,34 +1275,43 @@ void eap::method_tls::encrypt_message(_In_ const message_header *hdr, _Inout_ sa
} }
void eap::method_tls::decrypt_message(_In_ const message_header *hdr, _Inout_ sanitizing_blob &data) void eap::method_tls::decrypt_message(_In_ tls_message_type_t type, _Inout_ sanitizing_blob &data)
{ {
// Decrypt. // Decrypt.
if (!CryptDecrypt(m_key_server, NULL, FALSE, 0, data)) if (!CryptDecrypt(m_key_server, NULL, FALSE, 0, data))
throw win_runtime_error(__FUNCTION__ " Error decrypting message."); throw win_runtime_error(__FUNCTION__ " Error decrypting message.");
size_t size = data.size(); if (!data.empty()) {
if (size) { size_t size_data = data.size();
size_t size_data = size;
if (m_state.m_size_enc_block) { if (m_state.m_size_enc_block) {
// Check padding. // Check padding.
unsigned char padding = data.back(); unsigned char padding = data.back();
size_data -= padding + 1; size_data -= padding + 1;
for (size_t i = size_data, i_end = size - 1; i < i_end; i++) for (size_t i = size_data, i_end = data.size() - 1; i < i_end; i++)
if (data[i] != padding) if (data[i] != padding)
throw invalid_argument(__FUNCTION__ " Incorrect message padding."); throw invalid_argument(__FUNCTION__ " Incorrect message padding.");
// Remove padding.
data.resize(size_data);
if (m_tls_version >= tls_version_1_1) {
// TLS 1.1+: Remove random IV.
data.erase(data.begin(), data.begin() + m_state.m_size_enc_block);
size_data -= m_state.m_size_enc_block;
}
} }
size_data -= m_state.m_size_mac_hash; size_data -= m_state.m_size_mac_hash;
// Hash sequence number, TLS header (without length), original message length, and message. // Hash sequence number, TLS header (without length), original message length, and message.
hash_hmac hash(m_cp, m_state.m_alg_mac, m_padding_hmac_server.data()); hash_hmac hash(m_cp, m_state.m_alg_mac, m_padding_hmac_server.data());
unsigned __int64 seq_num = htonll(m_seq_num_server); unsigned __int64 seq_num2 = htonll(m_seq_num_server);
unsigned short size_data2 = htons((unsigned short)size_data); unsigned short size_data2 = htons((unsigned short)size_data);
if (!CryptHashData(hash, (const BYTE*)&seq_num , sizeof(seq_num), 0) || if (!CryptHashData(hash, (const BYTE*)&seq_num2 , sizeof(seq_num2 ), 0) ||
!CryptHashData(hash, (const BYTE*)hdr , 3, 0) || !CryptHashData(hash, (const BYTE*)&type , sizeof(type ), 0) ||
!CryptHashData(hash, (const BYTE*)&size_data2, 2, 0) || !CryptHashData(hash, (const BYTE*)&m_tls_version, sizeof(m_tls_version), 0) ||
!CryptHashData(hash, (const BYTE*)&size_data2 , sizeof(size_data2 ), 0) ||
!CryptHashData(hash, data.data() , (DWORD)size_data , 0)) !CryptHashData(hash, data.data() , (DWORD)size_data , 0))
throw win_runtime_error(__FUNCTION__ " Error hashing data."); throw win_runtime_error(__FUNCTION__ " Error hashing data.");
sanitizing_blob hmac; sanitizing_blob hmac;

View File

@ -45,7 +45,8 @@ namespace eap
/// ///
/// \sa [Extensible Authentication Protocol Tunneled Transport Layer Security Authenticated Protocol Version 0 (EAP-TTLSv0) (Chapter: 9.1 Packet Format)](https://tools.ietf.org/html/rfc5281#section-9.1) /// \sa [Extensible Authentication Protocol Tunneled Transport Layer Security Authenticated Protocol Version 0 (EAP-TTLSv0) (Chapter: 9.1 Packet Format)](https://tools.ietf.org/html/rfc5281#section-9.1)
/// ///
enum flags_t { #pragma warning(suppress: 4480)
enum flags_t : unsigned char {
flags_length_incl = method_tls::flags_req_length_incl, ///< Length included flags_length_incl = method_tls::flags_req_length_incl, ///< Length included
flags_more_frag = method_tls::flags_req_more_frag, ///< More fragments flags_more_frag = method_tls::flags_req_more_frag, ///< More fragments
flags_start = method_tls::flags_req_start, ///< Start flags_start = method_tls::flags_req_start, ///< Start
@ -147,7 +148,8 @@ namespace eap
public: public:
credentials_ttls &m_cred; ///< TTLS credentials credentials_ttls &m_cred; ///< TTLS credentials
enum version_t { #pragma warning(suppress: 4480)
enum version_t :unsigned char {
version_0 = 0, ///< EAP-TTLS v0 version_0 = 0, ///< EAP-TTLS v0
} m_version; ///< EAP-TTLS version } m_version; ///< EAP-TTLS version
}; };

@ -1 +1 @@
Subproject commit 37d768dabfc09557c316d2a64ccfecc336054ff4 Subproject commit dfbe66a826628d7cd3d7a0d6159987a4b9e68faa