Schannel and ownTLS MSK derivation unified
This commit is contained in:
parent
00aee5bb78
commit
621669828b
@ -176,7 +176,7 @@ void eap::method_mschapv2::get_result(
|
|||||||
m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_legacy_mschapv2), event_data::blank);
|
m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_legacy_mschapv2), event_data::blank);
|
||||||
m_cfg.m_auth_failed = false;
|
m_cfg.m_auth_failed = false;
|
||||||
|
|
||||||
ppResult->fIsSuccess = TRUE;
|
ppResult->fIsSuccess = TRUE;
|
||||||
ppResult->dwFailureReasonCode = ERROR_SUCCESS;
|
ppResult->dwFailureReasonCode = ERROR_SUCCESS;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -189,11 +189,11 @@ void eap::method_mschapv2::get_result(
|
|||||||
|
|
||||||
// Mark credentials as failed, so GUI can re-prompt user.
|
// Mark credentials as failed, so GUI can re-prompt user.
|
||||||
// But be careful: do so only after credentials were actually tried.
|
// But be careful: do so only after credentials were actually tried.
|
||||||
m_cfg.m_auth_failed = m_phase == phase_finished;
|
m_cfg.m_auth_failed = m_phase_prev < phase_finished && m_phase >= phase_finished;
|
||||||
|
|
||||||
// Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt.
|
// Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt.
|
||||||
// EapHost is well aware of the failed condition.
|
// EapHost is well aware of the failed condition.
|
||||||
//ppResult->fIsSuccess = FALSE;
|
//ppResult->fIsSuccess = FALSE;
|
||||||
//ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED;
|
//ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -176,7 +176,7 @@ void eap::method_pap::get_result(
|
|||||||
m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_legacy_pap), event_data::blank);
|
m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_legacy_pap), event_data::blank);
|
||||||
m_cfg.m_auth_failed = false;
|
m_cfg.m_auth_failed = false;
|
||||||
|
|
||||||
ppResult->fIsSuccess = TRUE;
|
ppResult->fIsSuccess = TRUE;
|
||||||
ppResult->dwFailureReasonCode = ERROR_SUCCESS;
|
ppResult->dwFailureReasonCode = ERROR_SUCCESS;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -189,11 +189,11 @@ void eap::method_pap::get_result(
|
|||||||
|
|
||||||
// Mark credentials as failed, so GUI can re-prompt user.
|
// Mark credentials as failed, so GUI can re-prompt user.
|
||||||
// But be careful: do so only after credentials were actually tried.
|
// But be careful: do so only after credentials were actually tried.
|
||||||
m_cfg.m_auth_failed = m_phase == phase_finished;
|
m_cfg.m_auth_failed = m_phase_prev < phase_finished && m_phase >= phase_finished;
|
||||||
|
|
||||||
// Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt.
|
// Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt.
|
||||||
// EapHost is well aware of the failed condition.
|
// EapHost is well aware of the failed condition.
|
||||||
//ppResult->fIsSuccess = FALSE;
|
//ppResult->fIsSuccess = FALSE;
|
||||||
//ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED;
|
//ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -223,6 +223,8 @@ namespace eap
|
|||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \name Key derivation
|
/// \name Key derivation
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
@ -235,6 +237,8 @@ namespace eap
|
|||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
#if EAP_TLS < EAP_TLS_SCHANNEL
|
||||||
|
|
||||||
/// \name Server message processing
|
/// \name Server message processing
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
@ -420,6 +424,9 @@ namespace eap
|
|||||||
packet_tls m_packet_req; ///< Request packet
|
packet_tls m_packet_req; ///< Request packet
|
||||||
packet_tls m_packet_res; ///< Response packet
|
packet_tls m_packet_res; ///< Response packet
|
||||||
|
|
||||||
|
tls_random m_key_mppe_client; ///< MS-MPPE-Recv-Key
|
||||||
|
tls_random m_key_mppe_server; ///< MS-MPPE-Send-Key
|
||||||
|
|
||||||
#if EAP_TLS < EAP_TLS_SCHANNEL
|
#if EAP_TLS < EAP_TLS_SCHANNEL
|
||||||
winstd::crypt_prov m_cp; ///< Cryptography provider for general services
|
winstd::crypt_prov m_cp; ///< Cryptography provider for general services
|
||||||
winstd::crypt_prov m_cp_enc_client; ///< Cryptography provider for encryption
|
winstd::crypt_prov m_cp_enc_client; ///< Cryptography provider for encryption
|
||||||
@ -438,9 +445,6 @@ namespace eap
|
|||||||
tls_random m_random_client; ///< Client random
|
tls_random m_random_client; ///< Client random
|
||||||
tls_random m_random_server; ///< Server random
|
tls_random m_random_server; ///< Server random
|
||||||
|
|
||||||
tls_random m_key_mppe_client; ///< MS-MPPE-Recv-Key
|
|
||||||
tls_random m_key_mppe_server; ///< MS-MPPE-Send-Key
|
|
||||||
|
|
||||||
sanitizing_blob m_session_id; ///< TLS session ID
|
sanitizing_blob m_session_id; ///< TLS session ID
|
||||||
bool m_session_resumed; ///< Did TLS session resume?
|
bool m_session_resumed; ///< Did TLS session resume?
|
||||||
|
|
||||||
|
@ -90,6 +90,8 @@ eap::method_tls::method_tls(_Inout_ method_tls &&other) :
|
|||||||
m_user_ctx (std::move(other.m_user_ctx )),
|
m_user_ctx (std::move(other.m_user_ctx )),
|
||||||
m_packet_req (std::move(other.m_packet_req )),
|
m_packet_req (std::move(other.m_packet_req )),
|
||||||
m_packet_res (std::move(other.m_packet_res )),
|
m_packet_res (std::move(other.m_packet_res )),
|
||||||
|
m_key_mppe_client (std::move(other.m_key_mppe_client )),
|
||||||
|
m_key_mppe_server (std::move(other.m_key_mppe_server )),
|
||||||
#if EAP_TLS < EAP_TLS_SCHANNEL
|
#if EAP_TLS < EAP_TLS_SCHANNEL
|
||||||
m_cp (std::move(other.m_cp )),
|
m_cp (std::move(other.m_cp )),
|
||||||
m_cp_enc_client (std::move(other.m_cp_enc_client )),
|
m_cp_enc_client (std::move(other.m_cp_enc_client )),
|
||||||
@ -104,8 +106,6 @@ eap::method_tls::method_tls(_Inout_ method_tls &&other) :
|
|||||||
m_master_secret (std::move(other.m_master_secret )),
|
m_master_secret (std::move(other.m_master_secret )),
|
||||||
m_random_client (std::move(other.m_random_client )),
|
m_random_client (std::move(other.m_random_client )),
|
||||||
m_random_server (std::move(other.m_random_server )),
|
m_random_server (std::move(other.m_random_server )),
|
||||||
m_key_mppe_client (std::move(other.m_key_mppe_client )),
|
|
||||||
m_key_mppe_server (std::move(other.m_key_mppe_server )),
|
|
||||||
m_session_id (std::move(other.m_session_id )),
|
m_session_id (std::move(other.m_session_id )),
|
||||||
m_session_resumed (std::move(other.m_session_resumed )),
|
m_session_resumed (std::move(other.m_session_resumed )),
|
||||||
m_server_cert_chain (std::move(other.m_server_cert_chain )),
|
m_server_cert_chain (std::move(other.m_server_cert_chain )),
|
||||||
@ -142,6 +142,8 @@ eap::method_tls& eap::method_tls::operator=(_Inout_ method_tls &&other)
|
|||||||
m_user_ctx = std::move(other.m_user_ctx );
|
m_user_ctx = std::move(other.m_user_ctx );
|
||||||
m_packet_req = std::move(other.m_packet_req );
|
m_packet_req = std::move(other.m_packet_req );
|
||||||
m_packet_res = std::move(other.m_packet_res );
|
m_packet_res = std::move(other.m_packet_res );
|
||||||
|
m_key_mppe_client = std::move(other.m_key_mppe_client );
|
||||||
|
m_key_mppe_server = std::move(other.m_key_mppe_server );
|
||||||
#if EAP_TLS < EAP_TLS_SCHANNEL
|
#if EAP_TLS < EAP_TLS_SCHANNEL
|
||||||
m_cp = std::move(other.m_cp );
|
m_cp = std::move(other.m_cp );
|
||||||
m_cp_enc_client = std::move(other.m_cp_enc_client );
|
m_cp_enc_client = std::move(other.m_cp_enc_client );
|
||||||
@ -156,8 +158,6 @@ eap::method_tls& eap::method_tls::operator=(_Inout_ method_tls &&other)
|
|||||||
m_master_secret = std::move(other.m_master_secret );
|
m_master_secret = std::move(other.m_master_secret );
|
||||||
m_random_client = std::move(other.m_random_client );
|
m_random_client = std::move(other.m_random_client );
|
||||||
m_random_server = std::move(other.m_random_server );
|
m_random_server = std::move(other.m_random_server );
|
||||||
m_key_mppe_client = std::move(other.m_key_mppe_client );
|
|
||||||
m_key_mppe_server = std::move(other.m_key_mppe_server );
|
|
||||||
m_session_id = std::move(other.m_session_id );
|
m_session_id = std::move(other.m_session_id );
|
||||||
m_session_resumed = std::move(other.m_session_resumed );
|
m_session_resumed = std::move(other.m_session_resumed );
|
||||||
m_server_cert_chain = std::move(other.m_server_cert_chain );
|
m_server_cert_chain = std::move(other.m_server_cert_chain );
|
||||||
@ -308,6 +308,9 @@ void eap::method_tls::process_request_packet(
|
|||||||
// This is the EAP-TLS start message: (re)initialize method.
|
// This is the EAP-TLS start message: (re)initialize method.
|
||||||
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank);
|
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank);
|
||||||
m_phase = phase_client_hello;
|
m_phase = phase_client_hello;
|
||||||
|
|
||||||
|
m_key_mppe_client.clear();
|
||||||
|
m_key_mppe_server.clear();
|
||||||
} else {
|
} else {
|
||||||
// Process the packet.
|
// Process the packet.
|
||||||
memset(m_handshake, 0, sizeof(m_handshake));
|
memset(m_handshake, 0, sizeof(m_handshake));
|
||||||
@ -319,9 +322,6 @@ void eap::method_tls::process_request_packet(
|
|||||||
case phase_client_hello: {
|
case phase_client_hello: {
|
||||||
m_tls_version = tls_version_1_2;
|
m_tls_version = tls_version_1_2;
|
||||||
|
|
||||||
m_key_mppe_client.clear();
|
|
||||||
m_key_mppe_server.clear();
|
|
||||||
|
|
||||||
m_server_cert_chain.clear();
|
m_server_cert_chain.clear();
|
||||||
|
|
||||||
// Create handshake hashing objects.
|
// Create handshake hashing objects.
|
||||||
@ -464,6 +464,8 @@ void eap::method_tls::process_request_packet(
|
|||||||
// This is the EAP-TLS start message: (re)initialize method.
|
// This is the EAP-TLS start message: (re)initialize method.
|
||||||
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank);
|
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank);
|
||||||
m_phase = phase_handshake_init;
|
m_phase = phase_handshake_init;
|
||||||
|
m_key_mppe_client.clear();
|
||||||
|
m_key_mppe_server.clear();
|
||||||
m_sc_queue.assign(m_packet_req.m_data.begin(), m_packet_req.m_data.end());
|
m_sc_queue.assign(m_packet_req.m_data.begin(), m_packet_req.m_data.end());
|
||||||
} else
|
} else
|
||||||
m_sc_queue.insert(m_sc_queue.end(), m_packet_req.m_data.begin(), m_packet_req.m_data.end());
|
m_sc_queue.insert(m_sc_queue.end(), m_packet_req.m_data.begin(), m_packet_req.m_data.end());
|
||||||
@ -510,7 +512,6 @@ void eap::method_tls::get_result(
|
|||||||
case EapPeerMethodResultSuccess: {
|
case EapPeerMethodResultSuccess: {
|
||||||
m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_tls), event_data::blank);
|
m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_tls), event_data::blank);
|
||||||
|
|
||||||
#if EAP_TLS < EAP_TLS_SCHANNEL
|
|
||||||
// Derive MSK/EMSK for line encryption.
|
// Derive MSK/EMSK for line encryption.
|
||||||
derive_msk();
|
derive_msk();
|
||||||
|
|
||||||
@ -522,34 +523,15 @@ void eap::method_tls::get_result(
|
|||||||
a.create_ms_mppe_key(17, (LPCBYTE)&m_key_mppe_server, sizeof(tls_random));
|
a.create_ms_mppe_key(17, (LPCBYTE)&m_key_mppe_server, sizeof(tls_random));
|
||||||
m_eap_attr.push_back(std::move(a));
|
m_eap_attr.push_back(std::move(a));
|
||||||
m_eap_attr.push_back(eap_attr::blank);
|
m_eap_attr.push_back(eap_attr::blank);
|
||||||
#else
|
|
||||||
// Derive MSK/EMSK for line encryption.
|
|
||||||
SecPkgContext_EapKeyBlock key_block;
|
|
||||||
SECURITY_STATUS status = QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_EAP_KEY_BLOCK, &key_block);
|
|
||||||
if (FAILED(status))
|
|
||||||
throw sec_runtime_error(status, __FUNCTION__ "Error generating MSK in Schannel.");
|
|
||||||
const unsigned char *_key_block = key_block.rgbKeys;
|
|
||||||
|
|
||||||
// Fill array with RADIUS attributes.
|
|
||||||
eap_attr a;
|
|
||||||
m_eap_attr.reserve(m_eap_attr.size() + 3);
|
|
||||||
a.create_ms_mppe_key(16, _key_block, sizeof(tls_random));
|
|
||||||
m_eap_attr.push_back(std::move(a));
|
|
||||||
_key_block += sizeof(tls_random);
|
|
||||||
a.create_ms_mppe_key(17, _key_block, sizeof(tls_random));
|
|
||||||
m_eap_attr.push_back(std::move(a));
|
|
||||||
_key_block += sizeof(tls_random);
|
|
||||||
m_eap_attr.push_back(eap_attr::blank);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Clear credentials as failed.
|
// Clear credentials as failed.
|
||||||
m_cfg.m_auth_failed = false;
|
m_cfg.m_auth_failed = false;
|
||||||
|
|
||||||
ppResult->fIsSuccess = TRUE;
|
ppResult->fIsSuccess = TRUE;
|
||||||
ppResult->dwFailureReasonCode = ERROR_SUCCESS;
|
ppResult->dwFailureReasonCode = ERROR_SUCCESS;
|
||||||
|
|
||||||
#if EAP_TLS < EAP_TLS_SCHANNEL
|
#if EAP_TLS < EAP_TLS_SCHANNEL
|
||||||
// Update configuration with session resumption data and prepare BLOB.
|
// Update configuration with session resumption data.
|
||||||
m_cfg.m_session_id = m_session_id;
|
m_cfg.m_session_id = m_session_id;
|
||||||
m_cfg.m_master_secret = m_master_secret;
|
m_cfg.m_master_secret = m_master_secret;
|
||||||
#else
|
#else
|
||||||
@ -561,6 +543,7 @@ void eap::method_tls::get_result(
|
|||||||
SECBUFFER_TOKEN,
|
SECBUFFER_TOKEN,
|
||||||
&dwType };
|
&dwType };
|
||||||
SecBufferDesc token_desc = { SECBUFFER_VERSION, 1, &token };
|
SecBufferDesc token_desc = { SECBUFFER_VERSION, 1, &token };
|
||||||
|
SECURITY_STATUS status;
|
||||||
if (SUCCEEDED(status = ApplyControlToken(m_sc_ctx, &token_desc))) {
|
if (SUCCEEDED(status = ApplyControlToken(m_sc_ctx, &token_desc))) {
|
||||||
// Prepare output buffer(s).
|
// Prepare output buffer(s).
|
||||||
SecBuffer buf_out[] = { { 0, SECBUFFER_TOKEN, NULL }, };
|
SecBuffer buf_out[] = { { 0, SECBUFFER_TOKEN, NULL }, };
|
||||||
@ -591,7 +574,7 @@ void eap::method_tls::get_result(
|
|||||||
|
|
||||||
// Mark credentials as failed, so GUI can re-prompt user.
|
// Mark credentials as failed, so GUI can re-prompt user.
|
||||||
// But be careful: do so only if this happened after transition from handshake to application data phase.
|
// But be careful: do so only if this happened after transition from handshake to application data phase.
|
||||||
m_cfg.m_auth_failed = m_phase >= phase_application_data;
|
m_cfg.m_auth_failed = m_phase_prev < phase_application_data && m_phase >= phase_application_data;
|
||||||
|
|
||||||
// Clear session resumption data.
|
// Clear session resumption data.
|
||||||
m_cfg.m_session_id.clear();
|
m_cfg.m_session_id.clear();
|
||||||
@ -611,7 +594,7 @@ void eap::method_tls::get_result(
|
|||||||
|
|
||||||
// Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt.
|
// Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt.
|
||||||
// EapHost is well aware of the failed condition.
|
// EapHost is well aware of the failed condition.
|
||||||
//ppResult->fIsSuccess = FALSE;
|
//ppResult->fIsSuccess = FALSE;
|
||||||
//ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED;
|
//ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -817,15 +800,27 @@ eap::sanitizing_blob eap::method_tls::make_message(_In_ tls_message_type_t type,
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void eap::method_tls::derive_msk()
|
void eap::method_tls::derive_msk()
|
||||||
{
|
{
|
||||||
|
const unsigned char *_key_block;
|
||||||
|
|
||||||
|
#if EAP_TLS < EAP_TLS_SCHANNEL
|
||||||
static const unsigned char s_label[] = "client EAP encryption";
|
static const unsigned char s_label[] = "client EAP encryption";
|
||||||
sanitizing_blob seed(s_label, s_label + _countof(s_label) - 1);
|
sanitizing_blob seed(s_label, s_label + _countof(s_label) - 1);
|
||||||
seed.insert(seed.end(), (const unsigned char*)&m_random_client, (const unsigned char*)(&m_random_client + 1));
|
seed.insert(seed.end(), (const unsigned char*)&m_random_client, (const unsigned char*)(&m_random_client + 1));
|
||||||
seed.insert(seed.end(), (const unsigned char*)&m_random_server, (const unsigned char*)(&m_random_server + 1));
|
seed.insert(seed.end(), (const unsigned char*)&m_random_server, (const unsigned char*)(&m_random_server + 1));
|
||||||
sanitizing_blob key_block(prf(m_cp, m_alg_prf, m_master_secret, seed, 2*sizeof(tls_random)));
|
sanitizing_blob key_block(prf(m_cp, m_alg_prf, m_master_secret, seed, 2*sizeof(tls_random)));
|
||||||
const unsigned char *_key_block = key_block.data();
|
_key_block = key_block.data();
|
||||||
|
#else
|
||||||
|
// Derive MSK/EMSK for line encryption.
|
||||||
|
SecPkgContext_EapKeyBlock key_block;
|
||||||
|
SECURITY_STATUS status = QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_EAP_KEY_BLOCK, &key_block);
|
||||||
|
if (FAILED(status))
|
||||||
|
throw sec_runtime_error(status, __FUNCTION__ " Error generating MSK in Schannel.");
|
||||||
|
_key_block = key_block.rgbKeys;
|
||||||
|
#endif
|
||||||
|
|
||||||
// MS-MPPE-Recv-Key
|
// MS-MPPE-Recv-Key
|
||||||
memcpy(&m_key_mppe_client, _key_block, sizeof(tls_random));
|
memcpy(&m_key_mppe_client, _key_block, sizeof(tls_random));
|
||||||
@ -836,6 +831,7 @@ void eap::method_tls::derive_msk()
|
|||||||
_key_block += sizeof(tls_random);
|
_key_block += sizeof(tls_random);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if EAP_TLS < EAP_TLS_SCHANNEL
|
||||||
|
|
||||||
void eap::method_tls::process_packet(_In_bytecount_(size_pck) const void *_pck, _In_ size_t size_pck)
|
void eap::method_tls::process_packet(_In_bytecount_(size_pck) const void *_pck, _In_ size_t size_pck)
|
||||||
{
|
{
|
||||||
|
@ -118,8 +118,6 @@ namespace eap
|
|||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
#if EAP_TLS < EAP_TLS_SCHANNEL
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Generates master session key
|
/// Generates master session key
|
||||||
///
|
///
|
||||||
@ -127,8 +125,6 @@ namespace eap
|
|||||||
///
|
///
|
||||||
virtual void derive_msk();
|
virtual void derive_msk();
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Processes an application message
|
/// Processes an application message
|
||||||
///
|
///
|
||||||
|
@ -120,10 +120,11 @@ void eap::method_ttls::get_result(
|
|||||||
_In_ EapPeerMethodResultReason reason,
|
_In_ EapPeerMethodResultReason reason,
|
||||||
_Inout_ EapPeerMethodResult *ppResult)
|
_Inout_ EapPeerMethodResult *ppResult)
|
||||||
{
|
{
|
||||||
if (m_phase != phase_application_data) {
|
// Do the TLS.
|
||||||
// Do the TLS.
|
method_tls::get_result(reason, ppResult);
|
||||||
method_tls::get_result(reason, ppResult);
|
|
||||||
} else {
|
if (m_phase == phase_application_data) {
|
||||||
|
|
||||||
// Get inner method result.
|
// Get inner method result.
|
||||||
EapPeerMethodResult result = {};
|
EapPeerMethodResult result = {};
|
||||||
m_inner->get_result(reason, &result);
|
m_inner->get_result(reason, &result);
|
||||||
@ -131,16 +132,6 @@ void eap::method_ttls::get_result(
|
|||||||
if (result.fSaveConnectionData)
|
if (result.fSaveConnectionData)
|
||||||
ppResult->fSaveConnectionData = TRUE;
|
ppResult->fSaveConnectionData = TRUE;
|
||||||
|
|
||||||
#if EAP_TLS >= EAP_TLS_SCHANNEL
|
|
||||||
// EAP-TTLS uses different label in PRF for MSK derivation than EAP-TLS.
|
|
||||||
static const DWORD s_key_id = 0x01; // EAP-TTLSv0 Keying Material
|
|
||||||
static const SecPkgContext_EapPrfInfo s_prf_info = { 0, sizeof(s_key_id), (PBYTE)&s_key_id };
|
|
||||||
SECURITY_STATUS status = SetContextAttributes(m_sc_ctx, SECPKG_ATTR_EAP_PRF_INFO, (void*)&s_prf_info, sizeof(s_prf_info));
|
|
||||||
if (FAILED(status))
|
|
||||||
throw sec_runtime_error(status, __FUNCTION__ "Error setting EAP-TTLS PRF in Schannel.");
|
|
||||||
#endif
|
|
||||||
method_tls::get_result(EapPeerMethodResultSuccess, ppResult);
|
|
||||||
|
|
||||||
if (reason == EapPeerMethodResultFailure) {
|
if (reason == EapPeerMethodResultFailure) {
|
||||||
// Clear session resumption data.
|
// Clear session resumption data.
|
||||||
#if EAP_TLS < EAP_TLS_SCHANNEL
|
#if EAP_TLS < EAP_TLS_SCHANNEL
|
||||||
@ -154,10 +145,11 @@ void eap::method_ttls::get_result(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if EAP_TLS < EAP_TLS_SCHANNEL
|
|
||||||
|
|
||||||
void eap::method_ttls::derive_msk()
|
void eap::method_ttls::derive_msk()
|
||||||
{
|
{
|
||||||
|
const unsigned char *_key_block;
|
||||||
|
|
||||||
|
#if EAP_TLS < EAP_TLS_SCHANNEL
|
||||||
//
|
//
|
||||||
// TLS versions 1.0 [RFC2246] and 1.1 [RFC4346] define the same PRF
|
// TLS versions 1.0 [RFC2246] and 1.1 [RFC4346] define the same PRF
|
||||||
// function, and any EAP-TTLSv0 implementation based on these versions
|
// function, and any EAP-TTLSv0 implementation based on these versions
|
||||||
@ -178,7 +170,21 @@ void eap::method_ttls::derive_msk()
|
|||||||
seed.insert(seed.end(), (const unsigned char*)&m_random_client, (const unsigned char*)(&m_random_client + 1));
|
seed.insert(seed.end(), (const unsigned char*)&m_random_client, (const unsigned char*)(&m_random_client + 1));
|
||||||
seed.insert(seed.end(), (const unsigned char*)&m_random_server, (const unsigned char*)(&m_random_server + 1));
|
seed.insert(seed.end(), (const unsigned char*)&m_random_server, (const unsigned char*)(&m_random_server + 1));
|
||||||
sanitizing_blob key_block(prf(m_cp, CALG_TLS1PRF, m_master_secret, seed, 2*sizeof(tls_random)));
|
sanitizing_blob key_block(prf(m_cp, CALG_TLS1PRF, m_master_secret, seed, 2*sizeof(tls_random)));
|
||||||
const unsigned char *_key_block = key_block.data();
|
_key_block = key_block.data();
|
||||||
|
#else
|
||||||
|
// EAP-TTLS uses different label in PRF for MSK derivation than EAP-TLS.
|
||||||
|
static const DWORD s_key_id = 0x01; // EAP-TTLSv0 Keying Material
|
||||||
|
static const SecPkgContext_EapPrfInfo s_prf_info = { 0, sizeof(s_key_id), (PBYTE)&s_key_id };
|
||||||
|
SECURITY_STATUS status = SetContextAttributes(m_sc_ctx, SECPKG_ATTR_EAP_PRF_INFO, (void*)&s_prf_info, sizeof(s_prf_info));
|
||||||
|
if (FAILED(status))
|
||||||
|
throw sec_runtime_error(status, __FUNCTION__ " Error setting EAP-TTLS PRF in Schannel.");
|
||||||
|
|
||||||
|
SecPkgContext_EapKeyBlock key_block;
|
||||||
|
status = QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_EAP_KEY_BLOCK, &key_block);
|
||||||
|
if (FAILED(status))
|
||||||
|
throw sec_runtime_error(status, __FUNCTION__ " Error generating MSK in Schannel.");
|
||||||
|
_key_block = key_block.rgbKeys;
|
||||||
|
#endif
|
||||||
|
|
||||||
// MSK: MPPE-Recv-Key
|
// MSK: MPPE-Recv-Key
|
||||||
memcpy(&m_key_mppe_client, _key_block, sizeof(tls_random));
|
memcpy(&m_key_mppe_client, _key_block, sizeof(tls_random));
|
||||||
@ -189,7 +195,6 @@ void eap::method_ttls::derive_msk()
|
|||||||
_key_block += sizeof(tls_random);
|
_key_block += sizeof(tls_random);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void eap::method_ttls::process_application_data(_In_bytecount_(size_msg) const void *msg, _In_ size_t size_msg)
|
void eap::method_ttls::process_application_data(_In_bytecount_(size_msg) const void *msg, _In_ size_t size_msg)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user