TLS implementation continues...
This commit is contained in:
@@ -83,16 +83,59 @@ namespace eap
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter: A.4. Handshake Protocol](https://tools.ietf.org/html/rfc5246#appendix-A.4)
|
||||
///
|
||||
enum handshake_type_t {
|
||||
hello_request = 0,
|
||||
client_hello = 1,
|
||||
server_hello = 2,
|
||||
certificate = 11,
|
||||
server_key_exchange = 12,
|
||||
certificate_request = 13,
|
||||
server_hello_done = 14,
|
||||
certificate_verify = 15,
|
||||
client_key_exchange = 16,
|
||||
finished = 20
|
||||
handshake_type_hello_request = 0,
|
||||
handshake_type_client_hello = 1,
|
||||
handshake_type_server_hello = 2,
|
||||
handshake_type_certificate = 11,
|
||||
handshake_type_server_key_exchange = 12,
|
||||
handshake_type_certificate_request = 13,
|
||||
handshake_type_server_hello_done = 14,
|
||||
handshake_type_certificate_verify = 15,
|
||||
handshake_type_client_key_exchange = 16,
|
||||
handshake_type_finished = 20
|
||||
};
|
||||
|
||||
///
|
||||
/// TLS alert level
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter: 7.2. Alert Protocol)](https://tools.ietf.org/html/rfc5246#section-7.2)
|
||||
///
|
||||
enum alert_level_t {
|
||||
alert_level_warning = 1,
|
||||
alert_level_fatal = 2,
|
||||
};
|
||||
|
||||
///
|
||||
/// TLS alert description
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter: 7.2. Alert Protocol)](https://tools.ietf.org/html/rfc5246#section-7.2)
|
||||
///
|
||||
enum alert_desc_t {
|
||||
alert_desc_close_notify = 0,
|
||||
alert_desc_unexpected_message = 10,
|
||||
alert_desc_bad_record_mac = 20,
|
||||
alert_desc_decryption_failed = 21, // reserved
|
||||
alert_desc_record_overflow = 22,
|
||||
alert_desc_decompression_failure = 30,
|
||||
alert_desc_handshake_failure = 40,
|
||||
alert_desc_no_certificate = 41, // reserved
|
||||
alert_desc_bad_certificate = 42,
|
||||
alert_desc_unsupported_certificate = 43,
|
||||
alert_desc_certificate_revoked = 44,
|
||||
alert_desc_certificate_expired = 45,
|
||||
alert_desc_certificate_unknown = 46,
|
||||
alert_desc_illegal_parameter = 47,
|
||||
alert_desc_unknown_ca = 48,
|
||||
alert_desc_access_denied = 49,
|
||||
alert_desc_decode_error = 50,
|
||||
alert_desc_decrypt_error = 51,
|
||||
alert_desc_export_restriction = 60, // reserved
|
||||
alert_desc_protocol_version = 70,
|
||||
alert_desc_insufficient_security = 71,
|
||||
alert_desc_internal_error = 80,
|
||||
alert_desc_user_canceled = 90,
|
||||
alert_desc_no_renegotiation = 100,
|
||||
alert_desc_unsupported_extension = 110,
|
||||
};
|
||||
|
||||
///
|
||||
@@ -210,6 +253,58 @@ namespace eap
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
///
|
||||
/// Master secret
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (8.1. Computing the Master Secret)](https://tools.ietf.org/html/rfc5246#section-8.1)
|
||||
///
|
||||
struct master_secret {
|
||||
unsigned char data[48];
|
||||
|
||||
///
|
||||
/// Constructs a all-zero master secret
|
||||
///
|
||||
master_secret();
|
||||
|
||||
///
|
||||
/// Constructs a pre-master secret
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 7.4.7.1. RSA-Encrypted Premaster Secret Message)](https://tools.ietf.org/html/rfc5246#section-7.4.7.1)
|
||||
///
|
||||
/// \param[in] cp Handle of the cryptographics provider
|
||||
///
|
||||
master_secret(_In_ HCRYPTPROV cp);
|
||||
|
||||
///
|
||||
/// Copies a master secret
|
||||
///
|
||||
/// \param[in] other Random to copy from
|
||||
///
|
||||
master_secret(_In_ const master_secret &other);
|
||||
|
||||
///
|
||||
/// Destructor
|
||||
///
|
||||
~master_secret();
|
||||
|
||||
///
|
||||
/// Copies a master secret
|
||||
///
|
||||
/// \param[in] other Random to copy from
|
||||
///
|
||||
/// \returns Reference to this object
|
||||
///
|
||||
master_secret& operator=(_In_ const master_secret &other);
|
||||
|
||||
///
|
||||
/// Empty the master secret
|
||||
///
|
||||
void clear();
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
public:
|
||||
///
|
||||
/// Constructs an EAP method
|
||||
@@ -301,21 +396,93 @@ namespace eap
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 7.4.1.2. Client Hello)](https://tools.ietf.org/html/rfc5246#section-7.4.1.2)
|
||||
///
|
||||
/// \returns Client Hello message
|
||||
/// \returns Client hello message
|
||||
///
|
||||
sanitizing_blob make_client_hello() const;
|
||||
|
||||
///
|
||||
/// Makes a TLS client certificate message
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 7.4.6. Client Certificate)](https://tools.ietf.org/html/rfc5246#section-7.4.6)
|
||||
///
|
||||
/// \returns Client certificate message
|
||||
///
|
||||
sanitizing_blob make_client_cert() const;
|
||||
|
||||
///
|
||||
/// Makes a TLS client key exchange message
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 7.4.7. Client Key Exchange Message )](https://tools.ietf.org/html/rfc5246#section-7.4.7)
|
||||
///
|
||||
/// \param[in] pms_enc Encoded pre master secret
|
||||
///
|
||||
/// \returns Client key exchange message
|
||||
///
|
||||
sanitizing_blob make_client_key_exchange(_In_ const sanitizing_blob &pms_enc) const;
|
||||
|
||||
///
|
||||
/// Makes a TLS change cipher spec message
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter A.1. Record Layer)](https://tools.ietf.org/html/rfc5246#appendix-A.1)
|
||||
///
|
||||
/// \returns Change cipher spec
|
||||
///
|
||||
static eap::sanitizing_blob make_change_chiper_spec();
|
||||
|
||||
///
|
||||
/// Makes a TLS finished message
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter A.1. Record Layer)](https://tools.ietf.org/html/rfc5246#appendix-A.1)
|
||||
///
|
||||
/// \returns Change cipher spec
|
||||
///
|
||||
eap::sanitizing_blob make_finished();
|
||||
|
||||
///
|
||||
/// Makes a TLS handshake
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter A.1. Record Layer)](https://tools.ietf.org/html/rfc5246#appendix-A.1)
|
||||
///
|
||||
/// \param[in] msg Handshake data contents
|
||||
/// \param[in] msg Handshake data contents
|
||||
///
|
||||
/// \returns TLS handshake message
|
||||
///
|
||||
static eap::sanitizing_blob make_handshake(_In_ const sanitizing_blob &msg);
|
||||
|
||||
///
|
||||
/// Makes a TLS handshake
|
||||
///
|
||||
/// \param[in] msg Handshake data contents
|
||||
/// \param[in] encrypt Should the message be encrypted?
|
||||
///
|
||||
/// \returns TLS handshake message
|
||||
///
|
||||
inline eap::sanitizing_blob make_handshake(_In_ const sanitizing_blob &msg, _In_ bool encrypted)
|
||||
{
|
||||
if (encrypted) {
|
||||
// Make unencrypted handshake, encrypt it, then make a new handshake message.
|
||||
sanitizing_blob msg_enc(std::move(make_handshake(msg)));
|
||||
encrypt_message(msg_enc);
|
||||
return make_handshake(msg_enc);
|
||||
} else
|
||||
return make_handshake(msg);
|
||||
}
|
||||
|
||||
///
|
||||
/// Generates keys required by current connection state
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 6.3. Key Calculation)](https://tools.ietf.org/html/rfc5246#section-6.3)
|
||||
///
|
||||
void derive_keys();
|
||||
|
||||
///
|
||||
/// Processes messages in a TLS packet
|
||||
///
|
||||
/// \param[in] pck Packet data
|
||||
/// \param[in] size_pck \p pck size in bytes
|
||||
///
|
||||
void process_packet(_In_bytecount_(size_pck) const void *pck, _In_ size_t size_pck);
|
||||
|
||||
///
|
||||
/// Processes a TLS handshake
|
||||
///
|
||||
@@ -326,6 +493,21 @@ namespace eap
|
||||
///
|
||||
void process_handshake(_In_bytecount_(msg_size) const void *msg, _In_ size_t msg_size);
|
||||
|
||||
///
|
||||
/// Processes a TLS handshake
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 7.2. Alert Protocol)](https://tools.ietf.org/html/rfc5246#section-7.2)
|
||||
///
|
||||
/// \param[in] msg TLS alert message data
|
||||
/// \param[in] msg_size TLS alert message data size
|
||||
///
|
||||
void process_alert(_In_bytecount_(msg_size) const void *msg, _In_ size_t msg_size);
|
||||
|
||||
///
|
||||
/// Verifies server's certificate if trusted by configuration
|
||||
///
|
||||
void verify_server_trust();
|
||||
|
||||
///
|
||||
/// Encrypt TLS message
|
||||
///
|
||||
@@ -343,14 +525,34 @@ namespace eap
|
||||
///
|
||||
/// Calculates pseudo-random P_hash data defined in RFC 5246
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter: 5. HMAC and the Pseudorandom Function)](https://tools.ietf.org/html/rfc5246#section-5)
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.1 (Chapter 5: HMAC and the Pseudorandom Function)](https://tools.ietf.org/html/rfc4346#section-5)
|
||||
///
|
||||
/// \param[in] alg Hashing algorithm to use (CALG_MD5 or CALG_SHA1)
|
||||
/// \param[in] secret Hashing secret key
|
||||
/// \param[in] size_secret \p secret size
|
||||
/// \param[in] seed Hashing seed
|
||||
/// \param[in] size_seed \p seed size
|
||||
/// \param[in] size Minimum number of bytes of pseudo-random data required
|
||||
/// \param[in] secret Hashing secret key
|
||||
/// \param[in] size_secret \p secret size
|
||||
/// \param[in] lblseed Concatenated label and seed
|
||||
/// \param[in] size_lblseed \p lblseed size
|
||||
/// \param[in] size Number of bytes of pseudo-random data required
|
||||
///
|
||||
/// \returns Generated pseudo-random data (\p size bytes)
|
||||
///
|
||||
std::vector<unsigned char> prf(
|
||||
_In_bytecount_(size_secret ) const void *secret,
|
||||
_In_ size_t size_secret,
|
||||
_In_bytecount_(size_lblseed) const void *lblseed,
|
||||
_In_ size_t size_lblseed,
|
||||
_In_ size_t size);
|
||||
|
||||
///
|
||||
/// Calculates pseudo-random P_hash data defined in RFC 5246
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 5: HMAC and the Pseudorandom Function)](https://tools.ietf.org/html/rfc5246#section-5)
|
||||
///
|
||||
/// \param[in] alg Hashing algorithm to use (CALG_MD5 or CALG_SHA1)
|
||||
/// \param[in] secret Hashing secret key
|
||||
/// \param[in] size_secret \p secret size
|
||||
/// \param[in] seed Hashing seed
|
||||
/// \param[in] size_seed \p seed size
|
||||
/// \param[in] size Minimum number of bytes of pseudo-random data required
|
||||
///
|
||||
/// \returns Generated pseudo-random data (\p size or longer)
|
||||
///
|
||||
@@ -382,7 +584,8 @@ namespace eap
|
||||
if (!CryptHashData(hash, (const BYTE*)secret, (DWORD)size_secret, 0))
|
||||
throw winstd::win_runtime_error(__FUNCTION__ " Error hashing secret.");
|
||||
winstd::crypt_key key;
|
||||
key.derive(m_cp, CALG_RC4, hash, 0);
|
||||
if (!key.derive(m_cp, CALG_RC4, hash, 0))
|
||||
throw winstd::win_runtime_error(__FUNCTION__ " Error deriving key.");
|
||||
return key.detach();
|
||||
}
|
||||
|
||||
@@ -407,10 +610,14 @@ namespace eap
|
||||
}
|
||||
|
||||
public:
|
||||
config_method_tls &m_cfg; ///< EAP-TLS method configuration
|
||||
credentials_tls &m_cred; ///< EAP-TLS user credentials
|
||||
|
||||
enum phase_t {
|
||||
phase_unknown = -1,
|
||||
phase_client_hello = 0,
|
||||
phase_server_hello = 1,
|
||||
phase_server_hello,
|
||||
phase_resume_session,
|
||||
} m_phase; ///< Session phase
|
||||
|
||||
packet m_packet_req; ///< Request packet
|
||||
@@ -418,7 +625,6 @@ namespace eap
|
||||
|
||||
winstd::crypt_prov m_cp; ///< Cryptography provider
|
||||
winstd::crypt_key m_key_hmac; ///< Symmetric key for HMAC calculation
|
||||
|
||||
winstd::crypt_key m_key_encrypt; ///< Key for encrypting messages
|
||||
winstd::crypt_key m_key_decrypt; ///< Key for decrypting messages
|
||||
|
||||
@@ -429,11 +635,16 @@ namespace eap
|
||||
|
||||
std::list<winstd::cert_context> m_server_cert_chain; ///< Server certificate chain
|
||||
|
||||
bool m_send_client_cert; ///< Did server request client certificate?
|
||||
|
||||
winstd::crypt_hash m_hash_handshake_msgs_md5; ///< Running MD5 hash of handshake messages sent
|
||||
winstd::crypt_hash m_hash_handshake_msgs_sha1; ///< Running SHA-1 hash of handshake messages sent
|
||||
|
||||
master_secret m_master_secret; ///< TLS master secret
|
||||
|
||||
bool m_send_client_cert; ///< Did server request client certificate?
|
||||
//bool m_server_hello_done; ///< Is server hello done?
|
||||
bool m_server_finished; ///< Did server send a valid finish message?
|
||||
bool m_cipher_spec; ///< Did server specify cipher?
|
||||
|
||||
protected:
|
||||
unsigned __int64 m_seq_num; ///< Sequence number for encryption
|
||||
};
|
||||
|
Reference in New Issue
Block a user