Compare commits
14 Commits
1.0-alpha6
...
1.0-alpha8
Author | SHA1 | Date | |
---|---|---|---|
a04647b7b5 | |||
df1d431bd0 | |||
16527c8124 | |||
69e6b775f8 | |||
c69316071f | |||
a02d1e7094 | |||
078636eb14 | |||
cabae26e0b | |||
7376693838 | |||
a5b3914a09 | |||
8beb7bd27a | |||
00dd1277c5 | |||
e9839706b6 | |||
f5b03bc0bf |
@@ -29,7 +29,7 @@
|
||||
// Product version as a single DWORD
|
||||
// Note: Used for version comparison within C/C++ code.
|
||||
//
|
||||
#define PRODUCT_VERSION 0x00ff0600
|
||||
#define PRODUCT_VERSION 0x00ff0800
|
||||
|
||||
//
|
||||
// Product version by components
|
||||
@@ -39,26 +39,26 @@
|
||||
//
|
||||
#define PRODUCT_VERSION_MAJ 0
|
||||
#define PRODUCT_VERSION_MIN 255
|
||||
#define PRODUCT_VERSION_REV 6
|
||||
#define PRODUCT_VERSION_REV 8
|
||||
#define PRODUCT_VERSION_BUILD 0
|
||||
|
||||
//
|
||||
// Human readable product version and build year for UI
|
||||
//
|
||||
#define PRODUCT_VERSION_STR "1.0-alpha6"
|
||||
#define PRODUCT_VERSION_STR "1.0-alpha8"
|
||||
#define PRODUCT_BUILD_YEAR_STR "2016"
|
||||
|
||||
//
|
||||
// Numerical version presentation for ProductVersion propery in
|
||||
// MSI packages (syntax: N.N[.N[.N]])
|
||||
//
|
||||
#define PRODUCT_VERSION_INST "0.255.6"
|
||||
#define PRODUCT_VERSION_INST "0.255.8"
|
||||
|
||||
//
|
||||
// The product code for ProductCode property in MSI packages
|
||||
// Replace with new on every version change, regardless how minor it is.
|
||||
//
|
||||
#define PRODUCT_VERSION_GUID "{BC83D8A6-59FB-4DD9-87F7-CCA4822EE432}"
|
||||
#define PRODUCT_VERSION_GUID "{82B292B6-F561-4DE1-8963-262A20B4E085}"
|
||||
|
||||
//
|
||||
// Since the product name is not finally confirmed at the time of
|
||||
|
@@ -342,7 +342,7 @@ namespace eap
|
||||
bool m_allow_save; ///< Are credentials allowed to be saved to Windows Credential Manager?
|
||||
bool m_use_preshared; ///< Use pre-shared credentials
|
||||
std::unique_ptr<credentials> m_preshared; ///< Pre-shared credentials
|
||||
bool m_cred_failed; ///< Did credential fail last time?
|
||||
bool m_auth_failed; ///< Did credential fail last time?
|
||||
};
|
||||
|
||||
|
||||
|
@@ -54,6 +54,18 @@ namespace eap
|
||||
{
|
||||
class credentials : public config
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Credential source when combined
|
||||
///
|
||||
enum source_t {
|
||||
source_unknown = -1, ///< Unknown source
|
||||
source_cache = 0, ///< Credentials were obtained from EAPHost cache
|
||||
source_preshared, ///< Credentials were set by method configuration
|
||||
source_storage ///< Credentials were loaded from Windows Credential Manager
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
///
|
||||
/// Constructs credentials
|
||||
@@ -158,26 +170,6 @@ namespace eap
|
||||
/// Returns credential name (for GUI display).
|
||||
///
|
||||
virtual winstd::tstring get_name() const;
|
||||
|
||||
///
|
||||
/// Combine credentials in the following order:
|
||||
///
|
||||
/// 1. Cached credentials
|
||||
/// 2. Pre-configured credentials
|
||||
/// 3. Stored credentials
|
||||
///
|
||||
/// \param[in] cred_cached Cached credentials (optional, can be \c NULL)
|
||||
/// \param[in] cfg Method configuration
|
||||
/// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from (optional, can be \c NULL)
|
||||
///
|
||||
/// \returns
|
||||
/// - \c true if credentials were set;
|
||||
/// - \c false otherwise
|
||||
///
|
||||
virtual bool combine(
|
||||
_In_ const credentials *cred_cached,
|
||||
_In_ config_method_with_cred &cfg,
|
||||
_In_opt_z_ LPCTSTR pszTargetName);
|
||||
};
|
||||
|
||||
|
||||
|
@@ -57,6 +57,25 @@ namespace eap
|
||||
///
|
||||
typedef std::vector<unsigned char, winstd::sanitizing_allocator<unsigned char> > sanitizing_blob;
|
||||
|
||||
///
|
||||
/// Sanitizing BLOB of fixed size
|
||||
///
|
||||
template<size_t N> struct sanitizing_blob_f;
|
||||
|
||||
///
|
||||
/// Sanitizing BLOB of fixed size (zero initialized)
|
||||
///
|
||||
template<size_t N> struct sanitizing_blob_zf;
|
||||
|
||||
///
|
||||
/// Sanitizing BLOB of fixed size (zero initialized in _DEBUG version)
|
||||
///
|
||||
#ifdef _DEBUG
|
||||
#define sanitizing_blob_xf sanitizing_blob_zf
|
||||
#else
|
||||
#define sanitizing_blob_xf sanitizing_blob_f
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Diameter AVP flags
|
||||
///
|
||||
@@ -347,6 +366,31 @@ inline size_t pksizeof(const winstd::eap_type_t &val);
|
||||
///
|
||||
inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ winstd::eap_type_t &val);
|
||||
|
||||
///
|
||||
/// Packs a BLOB
|
||||
///
|
||||
/// \param[inout] cursor Memory cursor
|
||||
/// \param[in] val Variable with data to pack
|
||||
///
|
||||
template<size_t N> inline void operator<<(_Inout_ eap::cursor_out &cursor, _In_ const eap::sanitizing_blob_f<N> &val);
|
||||
|
||||
///
|
||||
/// Returns packed size of a BLOB
|
||||
///
|
||||
/// \param[in] val Data to pack
|
||||
///
|
||||
/// \returns Size of data when packed (in bytes)
|
||||
///
|
||||
template<size_t N> inline size_t pksizeof(_In_ const eap::sanitizing_blob_f<N> &val);
|
||||
|
||||
///
|
||||
/// Unpacks a BLOB
|
||||
///
|
||||
/// \param[inout] cursor Memory cursor
|
||||
/// \param[out] val Variable to receive unpacked value
|
||||
///
|
||||
template<size_t N> inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::sanitizing_blob_f<N> &val);
|
||||
|
||||
#ifndef htonll
|
||||
///
|
||||
/// Convert host converts an unsigned __int64 from host to TCP/IP network byte order.
|
||||
@@ -381,6 +425,167 @@ namespace eap
|
||||
};
|
||||
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
template<size_t N>
|
||||
struct __declspec(novtable) sanitizing_blob_f<N>
|
||||
{
|
||||
unsigned char data[N]; ///< BLOB data
|
||||
|
||||
///
|
||||
/// Constructor
|
||||
///
|
||||
inline sanitizing_blob_f()
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// Copies a BLOB
|
||||
///
|
||||
/// \param[in] other BLOB to copy from
|
||||
///
|
||||
inline sanitizing_blob_f(_In_ const sanitizing_blob_f<N> &other)
|
||||
{
|
||||
memcpy(data, other.data, N);
|
||||
}
|
||||
|
||||
///
|
||||
/// Moves the BLOB
|
||||
///
|
||||
/// \param[inout] other Zero-initialized BLOB to move from
|
||||
///
|
||||
inline sanitizing_blob_f(_Inout_ sanitizing_blob_zf<N> &&other)
|
||||
{
|
||||
memcpy(data, other.data, N);
|
||||
memset(other.data, 0, N);
|
||||
}
|
||||
|
||||
///
|
||||
/// Destructor
|
||||
///
|
||||
inline ~sanitizing_blob_f()
|
||||
{
|
||||
SecureZeroMemory(data, N);
|
||||
}
|
||||
|
||||
///
|
||||
/// Copies a BLOB
|
||||
///
|
||||
/// \param[in] other BLOB to copy from
|
||||
///
|
||||
/// \returns Reference to this object
|
||||
///
|
||||
inline sanitizing_blob_f& operator=(_In_ const sanitizing_blob_f<N> &other)
|
||||
{
|
||||
if (this != std::addressof(other))
|
||||
memcpy(data, other.data, N);
|
||||
return *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// Moves the BLOB
|
||||
///
|
||||
/// \param[inout] other Zero-initialized BLOB to copy from
|
||||
///
|
||||
/// \returns Reference to this object
|
||||
///
|
||||
inline sanitizing_blob_f& operator=(_Inout_ sanitizing_blob_zf<N> &&other)
|
||||
{
|
||||
if (this != std::addressof(other)) {
|
||||
memcpy(data, other.data, N);
|
||||
memset(other.data, 0, N);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// Is BLOB not equal to?
|
||||
///
|
||||
/// \param[in] other BLOB to compare against
|
||||
///
|
||||
/// \returns
|
||||
/// - \c true when BLOBs are not equal;
|
||||
/// - \c false otherwise
|
||||
///
|
||||
inline bool operator!=(_In_ const sanitizing_blob_f<N> &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
///
|
||||
/// Is BLOB equal to?
|
||||
///
|
||||
/// \param[in] other BLOB to compare against
|
||||
///
|
||||
/// \returns
|
||||
/// - \c true when BLOBs are equal;
|
||||
/// - \c false otherwise
|
||||
///
|
||||
inline bool operator==(_In_ const sanitizing_blob_f<N> &other) const
|
||||
{
|
||||
for (size_t i = 0; i < N; i++)
|
||||
if (data[i] != other.data[i]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
/// Is BLOB empty?
|
||||
///
|
||||
/// \returns
|
||||
/// - \c true when BLOB is all-zero;
|
||||
/// - \c false otherwise
|
||||
///
|
||||
inline bool empty() const
|
||||
{
|
||||
for (size_t i = 0; i < N; i++)
|
||||
if (data[i]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
/// Zero the BLOB
|
||||
///
|
||||
inline void clear()
|
||||
{
|
||||
memset(data, 0, N);
|
||||
}
|
||||
};
|
||||
|
||||
template<size_t N>
|
||||
struct __declspec(novtable) sanitizing_blob_zf<N> : sanitizing_blob_f<N>
|
||||
{
|
||||
///
|
||||
/// Constructor
|
||||
///
|
||||
inline sanitizing_blob_zf() : sanitizing_blob_f<N>()
|
||||
{
|
||||
memset(data, 0, N);
|
||||
}
|
||||
|
||||
///
|
||||
/// Copies a BLOB
|
||||
///
|
||||
/// \param[in] other BLOB to copy from
|
||||
///
|
||||
inline sanitizing_blob_zf(_In_ const sanitizing_blob_f<N> &other) :
|
||||
sanitizing_blob_f<N>(other)
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// Moves the BLOB
|
||||
///
|
||||
/// \param[inout] other Zero-initialized BLOB to move from
|
||||
///
|
||||
inline sanitizing_blob_zf(_Inout_ sanitizing_blob_zf<N> &&other) :
|
||||
sanitizing_blob_f<N>(std::move(other))
|
||||
{
|
||||
}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
#pragma warning(suppress: 4480)
|
||||
enum diameter_avp_flags_t : unsigned char {
|
||||
diameter_avp_flag_vendor = 0x80, ///< Vendor-ID present
|
||||
@@ -742,6 +947,34 @@ inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ winstd::eap_type_t
|
||||
}
|
||||
|
||||
|
||||
template<size_t N>
|
||||
inline void operator<<(_Inout_ eap::cursor_out &cursor, _In_ const eap::sanitizing_blob_f<N> &val)
|
||||
{
|
||||
eap::cursor_out::ptr_type ptr_end = cursor.ptr + sizeof(eap::sanitizing_blob_f<N>);
|
||||
assert(ptr_end <= cursor.ptr_end);
|
||||
memcpy(cursor.ptr, val.data, sizeof(eap::sanitizing_blob_f<N>));
|
||||
cursor.ptr = ptr_end;
|
||||
}
|
||||
|
||||
|
||||
template<size_t N>
|
||||
inline size_t pksizeof(_In_ const eap::sanitizing_blob_f<N> &val)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(val);
|
||||
return sizeof(eap::sanitizing_blob_f<N>);
|
||||
}
|
||||
|
||||
|
||||
template<size_t N>
|
||||
inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::sanitizing_blob_f<N> &val)
|
||||
{
|
||||
eap::cursor_in::ptr_type ptr_end = cursor.ptr + sizeof(eap::sanitizing_blob_f<N>);
|
||||
assert(ptr_end <= cursor.ptr_end);
|
||||
memcpy(val.data, cursor.ptr, sizeof(eap::sanitizing_blob_f<N>));
|
||||
cursor.ptr = ptr_end;
|
||||
}
|
||||
|
||||
|
||||
#ifndef htonll
|
||||
|
||||
inline unsigned __int64 htonll(unsigned __int64 val)
|
||||
|
@@ -56,12 +56,6 @@ namespace eap
|
||||
///
|
||||
method(_In_ module &module, _In_ config_provider_list &cfg, _In_ credentials &cred);
|
||||
|
||||
///
|
||||
/// Copies an EAP method
|
||||
///
|
||||
/// \param[in] other EAP method to copy from
|
||||
///
|
||||
method(_In_ const method &other);
|
||||
|
||||
///
|
||||
/// Moves an EAP method
|
||||
@@ -70,15 +64,6 @@ namespace eap
|
||||
///
|
||||
method(_Inout_ method &&other);
|
||||
|
||||
///
|
||||
/// Copies an EAP method
|
||||
///
|
||||
/// \param[in] other EAP method to copy from
|
||||
///
|
||||
/// \returns Reference to this object
|
||||
///
|
||||
method& operator=(_In_ const method &other);
|
||||
|
||||
///
|
||||
/// Moves an EAP method
|
||||
///
|
||||
@@ -139,6 +124,11 @@ namespace eap
|
||||
|
||||
/// @}
|
||||
|
||||
private:
|
||||
// This class is noncopyable.
|
||||
method(_In_ const method &other);
|
||||
method& operator=(_In_ const method &other);
|
||||
|
||||
public:
|
||||
module &m_module; ///< EAP module
|
||||
config_provider_list &m_cfg; ///< Providers configuration
|
||||
|
@@ -139,7 +139,7 @@ eap::config_method& eap::config_method::operator=(_Inout_ config_method &&other)
|
||||
eap::config_method_with_cred::config_method_with_cred(_In_ module &mod) :
|
||||
m_allow_save(true),
|
||||
m_use_preshared(false),
|
||||
m_cred_failed(false),
|
||||
m_auth_failed(false),
|
||||
config_method(mod)
|
||||
{
|
||||
}
|
||||
@@ -149,7 +149,7 @@ eap::config_method_with_cred::config_method_with_cred(_In_ const config_method_w
|
||||
m_allow_save(other.m_allow_save),
|
||||
m_use_preshared(other.m_use_preshared),
|
||||
m_preshared(other.m_preshared ? (credentials*)other.m_preshared->clone() : nullptr),
|
||||
m_cred_failed(other.m_cred_failed),
|
||||
m_auth_failed(other.m_auth_failed),
|
||||
config_method(other)
|
||||
{
|
||||
}
|
||||
@@ -159,7 +159,7 @@ eap::config_method_with_cred::config_method_with_cred(_Inout_ config_method_with
|
||||
m_allow_save(std::move(other.m_allow_save)),
|
||||
m_use_preshared(std::move(other.m_use_preshared)),
|
||||
m_preshared(std::move(other.m_preshared)),
|
||||
m_cred_failed(std::move(other.m_cred_failed)),
|
||||
m_auth_failed(std::move(other.m_auth_failed)),
|
||||
config_method(std::move(other))
|
||||
{
|
||||
}
|
||||
@@ -172,7 +172,7 @@ eap::config_method_with_cred& eap::config_method_with_cred::operator=(_In_ const
|
||||
m_allow_save = other.m_allow_save;
|
||||
m_use_preshared = other.m_use_preshared;
|
||||
m_preshared.reset(other.m_preshared ? (credentials*)other.m_preshared->clone() : nullptr);
|
||||
m_cred_failed = other.m_cred_failed;
|
||||
m_auth_failed = other.m_auth_failed;
|
||||
}
|
||||
|
||||
return *this;
|
||||
@@ -186,7 +186,7 @@ eap::config_method_with_cred& eap::config_method_with_cred::operator=(_Inout_ co
|
||||
m_allow_save = std::move(other.m_allow_save );
|
||||
m_use_preshared = std::move(other.m_use_preshared);
|
||||
m_preshared = std::move(other.m_preshared );
|
||||
m_cred_failed = std::move(other.m_cred_failed );
|
||||
m_auth_failed = std::move(other.m_auth_failed );
|
||||
}
|
||||
|
||||
return *this;
|
||||
@@ -248,7 +248,7 @@ void eap::config_method_with_cred::operator<<(_Inout_ cursor_out &cursor) const
|
||||
cursor << m_allow_save;
|
||||
cursor << m_use_preshared;
|
||||
cursor << *m_preshared;
|
||||
cursor << m_cred_failed;
|
||||
cursor << m_auth_failed;
|
||||
}
|
||||
|
||||
|
||||
@@ -259,7 +259,7 @@ size_t eap::config_method_with_cred::get_pk_size() const
|
||||
pksizeof(m_allow_save ) +
|
||||
pksizeof(m_use_preshared) +
|
||||
pksizeof(*m_preshared ) +
|
||||
pksizeof(m_cred_failed );
|
||||
pksizeof(m_auth_failed );
|
||||
}
|
||||
|
||||
|
||||
@@ -269,7 +269,7 @@ void eap::config_method_with_cred::operator>>(_Inout_ cursor_in &cursor)
|
||||
cursor >> m_allow_save;
|
||||
cursor >> m_use_preshared;
|
||||
cursor >> *m_preshared;
|
||||
cursor >> m_cred_failed;
|
||||
cursor >> m_auth_failed;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -83,19 +83,6 @@ tstring eap::credentials::get_name() const
|
||||
}
|
||||
|
||||
|
||||
bool eap::credentials::combine(
|
||||
_In_ const credentials *cred_cached,
|
||||
_In_ config_method_with_cred &cfg,
|
||||
_In_opt_z_ LPCTSTR pszTargetName)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(cred_cached);
|
||||
UNREFERENCED_PARAMETER(cfg);
|
||||
UNREFERENCED_PARAMETER(pszTargetName);
|
||||
|
||||
// When there's nothing to combine...
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// eap::credentials_pass
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@@ -36,14 +36,6 @@ eap::method::method(_In_ module &module, _In_ config_provider_list &cfg, _In_ cr
|
||||
}
|
||||
|
||||
|
||||
eap::method::method(_In_ const method &other) :
|
||||
m_module(other.m_module),
|
||||
m_cfg(other.m_cfg),
|
||||
m_cred(other.m_cred)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
eap::method::method(_Inout_ method &&other) :
|
||||
m_module(other.m_module),
|
||||
m_cfg(other.m_cfg),
|
||||
@@ -52,18 +44,6 @@ eap::method::method(_Inout_ method &&other) :
|
||||
}
|
||||
|
||||
|
||||
eap::method& eap::method::operator=(_In_ const method &other)
|
||||
{
|
||||
if (this != std::addressof(other)) {
|
||||
assert(std::addressof(m_module) == std::addressof(other.m_module)); // Copy method within same module only!
|
||||
assert(std::addressof(m_cfg ) == std::addressof(other.m_cfg )); // Copy method with same configuration only!
|
||||
assert(std::addressof(m_cred ) == std::addressof(other.m_cred )); // Copy method with same credentials only!
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
eap::method& eap::method::operator=(_Inout_ method &&other)
|
||||
{
|
||||
if (this != std::addressof(other)) {
|
||||
|
@@ -486,6 +486,11 @@ public:
|
||||
this->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(_Tthis::OnUpdateUI));
|
||||
}
|
||||
|
||||
inline void SetRememberValue(bool val)
|
||||
{
|
||||
return m_remember->SetValue(val);
|
||||
}
|
||||
|
||||
inline bool GetRememberValue() const
|
||||
{
|
||||
return m_remember->GetValue();
|
||||
|
@@ -182,7 +182,7 @@ wxEAPCredentialWarningPanel::wxEAPCredentialWarningPanel(const eap::config_provi
|
||||
if (m_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE))
|
||||
wxSetIconFromResource(m_note_icon, m_icon, m_shell32, MAKEINTRESOURCE(161));
|
||||
|
||||
m_note_label->SetLabel(_("Previous attempt to connect using provided credentials failed. Please, make sure your credentials are correct, or try again later."));
|
||||
m_note_label->SetLabel(_("Previous attempt to connect failed. Please, make sure your credentials are correct, or try again later."));
|
||||
m_note_label->Wrap(449);
|
||||
|
||||
CreateContactFields(prov);
|
||||
|
Binary file not shown.
@@ -113,7 +113,7 @@ namespace eap
|
||||
/// - \c true if credentials were set;
|
||||
/// - \c false otherwise
|
||||
///
|
||||
bool combine(
|
||||
source_t combine(
|
||||
_In_ const credentials_pap *cred_cached,
|
||||
_In_ const config_method_pap &cfg,
|
||||
_In_opt_z_ LPCTSTR pszTargetName);
|
||||
|
@@ -75,7 +75,7 @@ LPCTSTR eap::credentials_pap::target_suffix() const
|
||||
}
|
||||
|
||||
|
||||
bool eap::credentials_pap::combine(
|
||||
eap::credentials::source_t eap::credentials_pap::combine(
|
||||
_In_ const credentials_pap *cred_cached,
|
||||
_In_ const config_method_pap &cfg,
|
||||
_In_opt_z_ LPCTSTR pszTargetName)
|
||||
@@ -84,14 +84,14 @@ bool eap::credentials_pap::combine(
|
||||
// Using EAP service cached credentials.
|
||||
*this = *cred_cached;
|
||||
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED1, event_data((unsigned int)eap_type_pap), event_data(credentials_pap::get_name()), event_data::blank);
|
||||
return true;
|
||||
return source_cache;
|
||||
}
|
||||
|
||||
if (cfg.m_use_preshared) {
|
||||
// Using preshared credentials.
|
||||
*this = *(credentials_pap*)cfg.m_preshared.get();
|
||||
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_PRESHARED1, event_data((unsigned int)eap_type_pap), event_data(credentials_pap::get_name()), event_data::blank);
|
||||
return true;
|
||||
return source_preshared;
|
||||
}
|
||||
|
||||
if (pszTargetName) {
|
||||
@@ -102,11 +102,11 @@ bool eap::credentials_pap::combine(
|
||||
// Using stored credentials.
|
||||
*this = std::move(cred_loaded);
|
||||
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_STORED1, event_data((unsigned int)eap_type_pap), event_data(credentials_pap::get_name()), event_data::blank);
|
||||
return true;
|
||||
return source_storage;
|
||||
} catch (...) {
|
||||
// Not actually an error.
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return source_unknown;
|
||||
}
|
||||
|
@@ -200,7 +200,7 @@ namespace eap
|
||||
/// - \c true if credentials were set;
|
||||
/// - \c false otherwise
|
||||
///
|
||||
bool combine(
|
||||
source_t combine(
|
||||
_In_ const credentials_tls *cred_cached,
|
||||
_In_ const config_method_tls &cfg,
|
||||
_In_opt_z_ LPCTSTR pszTargetName);
|
||||
|
@@ -150,13 +150,6 @@ namespace eap
|
||||
///
|
||||
method_tls(_In_ module &module, _In_ config_provider_list &cfg, _In_ credentials_tls &cred);
|
||||
|
||||
///
|
||||
/// Copies an EAP method
|
||||
///
|
||||
/// \param[in] other EAP method to copy from
|
||||
///
|
||||
method_tls(_In_ const method_tls &other);
|
||||
|
||||
///
|
||||
/// Moves an EAP method
|
||||
///
|
||||
@@ -169,15 +162,6 @@ namespace eap
|
||||
///
|
||||
virtual ~method_tls();
|
||||
|
||||
///
|
||||
/// Copies an EAP method
|
||||
///
|
||||
/// \param[in] other EAP method to copy from
|
||||
///
|
||||
/// \returns Reference to this object
|
||||
///
|
||||
method_tls& operator=(_In_ const method_tls &other);
|
||||
|
||||
///
|
||||
/// Moves an EAP method
|
||||
///
|
||||
@@ -242,7 +226,7 @@ namespace eap
|
||||
///
|
||||
/// \returns Client hello message
|
||||
///
|
||||
sanitizing_blob make_client_hello() const;
|
||||
sanitizing_blob make_client_hello();
|
||||
|
||||
///
|
||||
/// Makes a TLS client certificate message
|
||||
@@ -264,15 +248,6 @@ namespace eap
|
||||
///
|
||||
sanitizing_blob make_client_key_exchange(_In_ const tls_master_secret &pms) 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
|
||||
///
|
||||
eap::sanitizing_blob make_change_chiper_spec() const;
|
||||
|
||||
///
|
||||
/// Makes a TLS finished message
|
||||
///
|
||||
@@ -324,25 +299,17 @@ namespace eap
|
||||
/// \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] type Message type
|
||||
/// \param[in] data Message data contents
|
||||
/// \param[in] encrypt Should \p data get encrypted?
|
||||
/// \param[inout] data Message data contents
|
||||
///
|
||||
/// \returns TLS message message
|
||||
///
|
||||
eap::sanitizing_blob make_message(_In_ tls_message_type_t type, _Inout_ sanitizing_blob &data, _In_ bool encrypt);
|
||||
eap::sanitizing_blob make_message(_In_ tls_message_type_t type, _Inout_ sanitizing_blob &&data);
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Key derivation
|
||||
/// @{
|
||||
|
||||
///
|
||||
/// 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();
|
||||
|
||||
///
|
||||
/// Generates master session key
|
||||
///
|
||||
@@ -468,28 +435,6 @@ namespace eap
|
||||
_In_ size_t size_seed,
|
||||
_In_ size_t size);
|
||||
|
||||
///
|
||||
/// Calculates pseudo-random P_hash data defined in RFC 5246
|
||||
///
|
||||
/// \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)
|
||||
/// \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] secret Hashing secret key
|
||||
/// \param[in] seed Random seed
|
||||
/// \param[in] size_seed \p seed size
|
||||
/// \param[in] size Number of bytes of pseudo-random data required
|
||||
///
|
||||
/// \returns Generated pseudo-random data (\p size bytes)
|
||||
///
|
||||
inline sanitizing_blob prf(
|
||||
_In_ const tls_master_secret &secret,
|
||||
_In_bytecount_(size_seed) const void *seed,
|
||||
_In_ size_t size_seed,
|
||||
_In_ size_t size) const
|
||||
{
|
||||
return prf(m_cp, m_state.m_alg_prf, secret, seed, size_seed, size);
|
||||
}
|
||||
|
||||
///
|
||||
/// Calculates pseudo-random P_hash data defined in RFC 5246
|
||||
///
|
||||
@@ -515,27 +460,6 @@ namespace eap
|
||||
return prf(cp, alg, secret, seed.data(), seed.size() * sizeof(_Ty), size);
|
||||
}
|
||||
|
||||
///
|
||||
/// Calculates pseudo-random P_hash data defined in RFC 5246
|
||||
///
|
||||
/// \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)
|
||||
/// \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] secret Hashing secret key
|
||||
/// \param[in] seed Random seed
|
||||
/// \param[in] size Number of bytes of pseudo-random data required
|
||||
///
|
||||
/// \returns Generated pseudo-random data (\p size bytes)
|
||||
///
|
||||
template<class _Ty, class _Ax>
|
||||
inline sanitizing_blob prf(
|
||||
_In_ const tls_master_secret &secret,
|
||||
_In_ const std::vector<_Ty, _Ax> &seed,
|
||||
_In_ size_t size) const
|
||||
{
|
||||
return prf(m_cp, m_state.m_alg_prf, secret, seed.data(), seed.size() * sizeof(_Ty), size);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
///
|
||||
@@ -543,6 +467,7 @@ namespace eap
|
||||
///
|
||||
/// \sa [How to export and import plain text session keys by using CryptoAPI](https://support.microsoft.com/en-us/kb/228786)
|
||||
///
|
||||
/// \param[in] cp Handle of the cryptographics provider
|
||||
/// \param[in] alg Key algorithm
|
||||
/// \param[in] key Key that decrypts \p secret
|
||||
/// \param[in] secret Key data
|
||||
@@ -551,6 +476,7 @@ namespace eap
|
||||
/// \returns Key
|
||||
///
|
||||
HCRYPTKEY create_key(
|
||||
_In_ HCRYPTPROV cp,
|
||||
_In_ ALG_ID alg,
|
||||
_In_ HCRYPTKEY key,
|
||||
_In_bytecount_(size_secret) const void *secret,
|
||||
@@ -562,16 +488,22 @@ namespace eap
|
||||
packet m_packet_req; ///< Request packet
|
||||
packet m_packet_res; ///< Response packet
|
||||
|
||||
winstd::crypt_prov m_cp; ///< Cryptography provider
|
||||
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_server; ///< Cryptography provider for encryption
|
||||
winstd::crypt_key m_key_exp1; ///< Key for importing derived keys
|
||||
|
||||
tls_version m_tls_version; ///< TLS version in use
|
||||
ALG_ID m_alg_prf; ///< Pseudo-random function algorithm in use
|
||||
|
||||
tls_conn_state m_state; ///< TLS connection state for fast reconnect
|
||||
tls_conn_state m_state_client; ///< Client TLS connection state
|
||||
tls_conn_state m_state_client_pending; ///< Client TLS connection state (pending)
|
||||
tls_conn_state m_state_server; ///< Server TLS connection state
|
||||
tls_conn_state m_state_server_pending; ///< Server TLS connection state (pending)
|
||||
|
||||
sanitizing_blob m_padding_hmac_client; ///< Padding (key) for client side HMAC calculation
|
||||
sanitizing_blob m_padding_hmac_server; ///< Padding (key) for server side HMAC calculation
|
||||
winstd::crypt_key m_key_client; ///< Key for encrypting messages
|
||||
winstd::crypt_key m_key_server; ///< Key for decrypting messages
|
||||
tls_master_secret m_master_secret; ///< TLS master secret
|
||||
tls_random m_random_client; ///< Client 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
|
||||
@@ -580,14 +512,19 @@ namespace eap
|
||||
|
||||
std::list<winstd::cert_context> m_server_cert_chain; ///< Server certificate chain
|
||||
|
||||
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
|
||||
winstd::crypt_hash m_hash_handshake_msgs_sha256; ///< Running SHA-256 hash of handshake messages sent
|
||||
winstd::crypt_hash m_hash_handshake_msgs_md5; ///< Running MD5 hash of handshake messages
|
||||
winstd::crypt_hash m_hash_handshake_msgs_sha1; ///< Running SHA-1 hash of handshake messages
|
||||
winstd::crypt_hash m_hash_handshake_msgs_sha256; ///< Running SHA-256 hash of handshake messages
|
||||
|
||||
bool m_certificate_req; ///< Did server request client certificate?
|
||||
bool m_server_hello_done; ///< Is server hello done?
|
||||
bool m_cipher_spec; ///< Did server specify cipher?
|
||||
bool m_server_finished; ///< Did server send a valid finish message?
|
||||
bool m_handshake[tls_handshake_type_max]; ///< Handshake flags (map od handshake messages received)
|
||||
|
||||
enum {
|
||||
phase_unknown = -1, ///< Unknown phase
|
||||
phase_client_hello = 0, ///< Send client hello
|
||||
phase_server_hello, ///< Wait for server hello
|
||||
phase_change_cipher_spec, ///< Wait for change cipher spec
|
||||
phase_application_data ///< Exchange application data
|
||||
} m_phase; ///< What phase is our communication at?
|
||||
|
||||
unsigned __int64 m_seq_num_client; ///< Sequence number for encrypting
|
||||
unsigned __int64 m_seq_num_server; ///< Sequence number for decrypting
|
||||
|
@@ -59,7 +59,7 @@ namespace eap
|
||||
extern const tls_version tls_version_1_2;
|
||||
|
||||
///
|
||||
/// TLS client/server tls_random
|
||||
/// TLS client/server random
|
||||
///
|
||||
struct tls_random;
|
||||
|
||||
@@ -71,11 +71,11 @@ namespace eap
|
||||
struct tls_master_secret;
|
||||
|
||||
///
|
||||
/// TLS client connection state
|
||||
/// HMAC padding
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 6.1. Connection States)](https://tools.ietf.org/html/rfc5246#section-6.1)
|
||||
/// \sa [HMAC: Keyed-Hashing for Message Authentication](https://tools.ietf.org/html/rfc2104)
|
||||
///
|
||||
class tls_conn_state;
|
||||
struct hmac_padding;
|
||||
|
||||
///
|
||||
/// Our own implementation of HMAC hashing
|
||||
@@ -83,83 +83,40 @@ namespace eap
|
||||
///
|
||||
/// \sa [HMAC: Keyed-Hashing for Message Authentication](https://tools.ietf.org/html/rfc2104)
|
||||
///
|
||||
class hash_hmac;
|
||||
class hmac_hash;
|
||||
|
||||
///
|
||||
/// TLS client connection state
|
||||
///
|
||||
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 6.1. Connection States)](https://tools.ietf.org/html/rfc5246#section-6.1)
|
||||
///
|
||||
class tls_conn_state;
|
||||
}
|
||||
|
||||
///
|
||||
/// Packs a TLS tls_random
|
||||
///
|
||||
/// \param[inout] cursor Memory cursor
|
||||
/// \param[in] val Variable with data to pack
|
||||
///
|
||||
inline void operator<<(_Inout_ eap::cursor_out &cursor, _In_ const eap::tls_random &val);
|
||||
|
||||
///
|
||||
/// Returns packed size of TLS tls_random
|
||||
///
|
||||
/// \param[in] val Data to pack
|
||||
///
|
||||
/// \returns Size of data when packed (in bytes)
|
||||
///
|
||||
inline size_t pksizeof(_In_ const eap::tls_random &val);
|
||||
|
||||
///
|
||||
/// Unpacks a TLS tls_random
|
||||
///
|
||||
/// \param[inout] cursor Memory cursor
|
||||
/// \param[out] val Variable to receive unpacked value
|
||||
///
|
||||
inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::tls_random &val);
|
||||
|
||||
///
|
||||
/// Packs a TLS master secret
|
||||
///
|
||||
/// \param[inout] cursor Memory cursor
|
||||
/// \param[in] val Variable with data to pack
|
||||
///
|
||||
inline void operator<<(_Inout_ eap::cursor_out &cursor, _In_ const eap::tls_master_secret &val);
|
||||
|
||||
///
|
||||
/// Returns packed size of TLS master secret
|
||||
///
|
||||
/// \param[in] val Data to pack
|
||||
///
|
||||
/// \returns Size of data when packed (in bytes)
|
||||
///
|
||||
inline size_t pksizeof(_In_ const eap::tls_master_secret &val);
|
||||
|
||||
///
|
||||
/// Unpacks a TLS master secret
|
||||
///
|
||||
/// \param[inout] cursor Memory cursor
|
||||
/// \param[out] val Variable to receive unpacked value
|
||||
///
|
||||
inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::tls_master_secret &val);
|
||||
|
||||
///
|
||||
/// Packs a TLS connection state
|
||||
///
|
||||
/// \param[inout] cursor Memory cursor
|
||||
/// \param[in] val Variable with data to pack
|
||||
///
|
||||
inline void operator<<(_Inout_ eap::cursor_out &cursor, _In_ const eap::tls_conn_state &val);
|
||||
|
||||
///
|
||||
/// Returns packed size of TLS connection state
|
||||
///
|
||||
/// \param[in] val Data to pack
|
||||
///
|
||||
/// \returns Size of data when packed (in bytes)
|
||||
///
|
||||
inline size_t pksizeof(_In_ const eap::tls_conn_state &val);
|
||||
|
||||
///
|
||||
/// Unpacks a TLS connection state
|
||||
///
|
||||
/// \param[inout] cursor Memory cursor
|
||||
/// \param[out] val Variable to receive unpacked value
|
||||
///
|
||||
inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::tls_conn_state &val);
|
||||
/////
|
||||
///// Packs a TLS connection state
|
||||
/////
|
||||
///// \param[inout] cursor Memory cursor
|
||||
///// \param[in] val Variable with data to pack
|
||||
/////
|
||||
//inline void operator<<(_Inout_ eap::cursor_out &cursor, _In_ const eap::tls_conn_state &val);
|
||||
//
|
||||
/////
|
||||
///// Returns packed size of TLS connection state
|
||||
/////
|
||||
///// \param[in] val Data to pack
|
||||
/////
|
||||
///// \returns Size of data when packed (in bytes)
|
||||
/////
|
||||
//inline size_t pksizeof(_In_ const eap::tls_conn_state &val);
|
||||
//
|
||||
/////
|
||||
///// Unpacks a TLS connection state
|
||||
/////
|
||||
///// \param[inout] cursor Memory cursor
|
||||
///// \param[out] val Variable to receive unpacked value
|
||||
/////
|
||||
//inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::tls_conn_state &val);
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -191,7 +148,10 @@ namespace eap
|
||||
tls_handshake_type_server_hello_done = 14,
|
||||
tls_handshake_type_certificate_verify = 15,
|
||||
tls_handshake_type_client_key_exchange = 16,
|
||||
tls_handshake_type_finished = 20
|
||||
tls_handshake_type_finished = 20,
|
||||
|
||||
tls_handshake_type_min = 0, ///< First existing handshake message
|
||||
tls_handshake_type_max = 21 ///< First non-existing (officially) handshake message
|
||||
};
|
||||
|
||||
|
||||
@@ -343,59 +303,24 @@ namespace eap
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct __declspec(novtable) tls_random
|
||||
struct __declspec(novtable) tls_random : public sanitizing_blob_xf<32>
|
||||
{
|
||||
unsigned char data[32]; ///< Randomness
|
||||
|
||||
///
|
||||
/// Constructs a all-zero tls_random
|
||||
///
|
||||
tls_random();
|
||||
|
||||
///
|
||||
/// Copies a tls_random
|
||||
///
|
||||
/// \param[in] other Random to copy from
|
||||
///
|
||||
tls_random(_In_ const tls_random &other);
|
||||
|
||||
///
|
||||
/// Destructor
|
||||
///
|
||||
~tls_random();
|
||||
|
||||
///
|
||||
/// Copies a tls_random
|
||||
///
|
||||
/// \param[in] other Random to copy from
|
||||
///
|
||||
/// \returns Reference to this object
|
||||
///
|
||||
tls_random& operator=(_In_ const tls_random &other);
|
||||
|
||||
///
|
||||
/// Empty the tls_random
|
||||
///
|
||||
void clear();
|
||||
|
||||
///
|
||||
/// Generate tls_random
|
||||
/// Generate TLS random
|
||||
///
|
||||
/// \param[in] cp Handle of the cryptographics provider
|
||||
///
|
||||
void reset(_In_ HCRYPTPROV cp);
|
||||
void randomize(_In_ HCRYPTPROV cp);
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct __declspec(novtable) tls_master_secret
|
||||
struct __declspec(novtable) tls_master_secret : public sanitizing_blob_xf<48>
|
||||
{
|
||||
unsigned char data[48];
|
||||
|
||||
///
|
||||
/// Constructs a all-zero master secret
|
||||
/// Constructor
|
||||
///
|
||||
tls_master_secret();
|
||||
|
||||
@@ -412,92 +337,68 @@ namespace eap
|
||||
///
|
||||
/// Copies a master secret
|
||||
///
|
||||
/// \param[in] other Random to copy from
|
||||
/// \param[in] other Master secret to copy from
|
||||
///
|
||||
tls_master_secret(_In_ const tls_master_secret &other);
|
||||
tls_master_secret(_In_ const sanitizing_blob_f<48> &other);
|
||||
|
||||
#ifdef _DEBUG
|
||||
///
|
||||
/// Destructor
|
||||
/// Moves the master secret
|
||||
///
|
||||
~tls_master_secret();
|
||||
|
||||
/// \param[inout] other Master secret to move from
|
||||
///
|
||||
/// Copies a master secret
|
||||
///
|
||||
/// \param[in] other Random to copy from
|
||||
///
|
||||
/// \returns Reference to this object
|
||||
///
|
||||
tls_master_secret& operator=(_In_ const tls_master_secret &other);
|
||||
|
||||
///
|
||||
/// Empty the master secret
|
||||
///
|
||||
void clear();
|
||||
tls_master_secret(_Inout_ sanitizing_blob_zf<48> &&other);
|
||||
#endif
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
class tls_conn_state
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct __declspec(novtable) hmac_padding : public sanitizing_blob_xf<64>
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs a connection state
|
||||
/// Constructor
|
||||
///
|
||||
tls_conn_state();
|
||||
hmac_padding();
|
||||
|
||||
///
|
||||
/// Copies a connection state
|
||||
/// Derive padding from secret
|
||||
///
|
||||
/// \param[in] other Connection state to copy from
|
||||
/// \param[in] cp Handle of the cryptographics provider
|
||||
/// \param[in] alg Hashing algorithm
|
||||
/// \param[in] secret HMAC secret
|
||||
/// \param[in] size_secret \p secret size
|
||||
/// \param[in] pad Padding value to XOR with (0x36=inner, 0x5c=outer...)
|
||||
///
|
||||
tls_conn_state(_In_ const tls_conn_state &other);
|
||||
hmac_padding(
|
||||
_In_ HCRYPTPROV cp,
|
||||
_In_ ALG_ID alg,
|
||||
_In_bytecount_(size_secret ) const void *secret,
|
||||
_In_ size_t size_secret,
|
||||
_In_opt_ unsigned char pad = 0x36);
|
||||
|
||||
///
|
||||
/// Moves a connection state
|
||||
/// Copies a padding
|
||||
///
|
||||
/// \param[in] other Connection state to move from
|
||||
/// \param[in] other Master secret to copy from
|
||||
///
|
||||
tls_conn_state(_Inout_ tls_conn_state &&other);
|
||||
hmac_padding(_In_ const sanitizing_blob_f<64> &other);
|
||||
|
||||
#ifdef _DEBUG
|
||||
///
|
||||
/// Copies a connection state
|
||||
/// Moves the padding
|
||||
///
|
||||
/// \param[in] other Connection state to copy from
|
||||
/// \param[inout] other Padding to move from
|
||||
///
|
||||
/// \returns Reference to this object
|
||||
///
|
||||
tls_conn_state& operator=(_In_ const tls_conn_state &other);
|
||||
|
||||
///
|
||||
/// Moves a connection state
|
||||
///
|
||||
/// \param[in] other Connection state to move from
|
||||
///
|
||||
/// \returns Reference to this object
|
||||
///
|
||||
tls_conn_state& operator=(_Inout_ tls_conn_state &&other);
|
||||
|
||||
public:
|
||||
ALG_ID m_alg_prf; ///> Pseudo-tls_random function algorithm
|
||||
ALG_ID m_alg_encrypt; ///> Bulk encryption algorithm
|
||||
size_t m_size_enc_key; ///> Encryption key size in bytes (has to comply with `m_alg_encrypt`)
|
||||
size_t m_size_enc_iv; ///> Encryption initialization vector size in bytes (has to comply with `m_alg_encrypt`)
|
||||
size_t m_size_enc_block; ///> Encryption block size in bytes (has to comply with `m_alg_encrypt`)
|
||||
ALG_ID m_alg_mac; ///> Message authenticy check algorithm
|
||||
size_t m_size_mac_key; ///> Message authenticy check algorithm key size (has to comply with `m_alg_mac`)
|
||||
size_t m_size_mac_hash; ///> Message authenticy check algorithm result size (has to comply with `m_alg_mac`)
|
||||
tls_master_secret m_master_secret; ///< TLS master secret
|
||||
tls_random m_random_client; ///< Client tls_random
|
||||
tls_random m_random_server; ///< Server tls_random
|
||||
hmac_padding(_Inout_ sanitizing_blob_zf<64> &&other);
|
||||
#endif
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
class hash_hmac
|
||||
class hmac_hash
|
||||
{
|
||||
public:
|
||||
typedef unsigned char padding_t[64];
|
||||
|
||||
public:
|
||||
///
|
||||
/// Construct new HMAC hashing object
|
||||
@@ -507,7 +408,7 @@ namespace eap
|
||||
/// \param[in] secret HMAC secret
|
||||
/// \param[in] size_secret \p secret size
|
||||
///
|
||||
hash_hmac(
|
||||
hmac_hash(
|
||||
_In_ HCRYPTPROV cp,
|
||||
_In_ ALG_ID alg,
|
||||
_In_bytecount_(size_secret ) const void *secret,
|
||||
@@ -520,10 +421,10 @@ namespace eap
|
||||
/// \param[in] alg Hashing algorithm
|
||||
/// \param[in] padding HMAC secret XOR inner padding
|
||||
///
|
||||
hash_hmac(
|
||||
hmac_hash(
|
||||
_In_ HCRYPTPROV cp,
|
||||
_In_ ALG_ID alg,
|
||||
_In_ const padding_t padding);
|
||||
_In_ const hmac_padding &padding);
|
||||
|
||||
///
|
||||
/// Provides access to inner hash object to hash data at will.
|
||||
@@ -556,99 +457,61 @@ namespace eap
|
||||
throw win_runtime_error(__FUNCTION__ " Error calculating outer hash.");
|
||||
}
|
||||
|
||||
///
|
||||
/// Helper method to pre-derive inner padding for frequent reuse
|
||||
///
|
||||
/// \param[in] cp Handle of the cryptographics provider
|
||||
/// \param[in] alg Hashing algorithm
|
||||
/// \param[in] secret HMAC secret
|
||||
/// \param[in] size_secret \p secret size
|
||||
/// \param[out] padding HMAC secret XOR inner padding
|
||||
///
|
||||
static void inner_padding(
|
||||
_In_ HCRYPTPROV cp,
|
||||
_In_ ALG_ID alg,
|
||||
_In_bytecount_(size_secret ) const void *secret,
|
||||
_In_ size_t size_secret,
|
||||
_Out_ padding_t padding);
|
||||
|
||||
protected:
|
||||
winstd::crypt_hash m_hash_inner; ///< Inner hashing object
|
||||
winstd::crypt_hash m_hash_outer; ///< Outer hashing object
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
inline void operator<<(_Inout_ eap::cursor_out &cursor, _In_ const eap::tls_random &val)
|
||||
{
|
||||
eap::cursor_out::ptr_type ptr_end = cursor.ptr + sizeof(eap::tls_random);
|
||||
assert(ptr_end <= cursor.ptr_end);
|
||||
memcpy(cursor.ptr, val.data, sizeof(eap::tls_random));
|
||||
cursor.ptr = ptr_end;
|
||||
}
|
||||
|
||||
|
||||
inline size_t pksizeof(_In_ const eap::tls_random &val)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(val);
|
||||
return sizeof(eap::tls_random);
|
||||
}
|
||||
|
||||
|
||||
inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::tls_random &val)
|
||||
{
|
||||
eap::cursor_in::ptr_type ptr_end = cursor.ptr + sizeof(eap::tls_random);
|
||||
assert(ptr_end <= cursor.ptr_end);
|
||||
memcpy(val.data, cursor.ptr, sizeof(eap::tls_random));
|
||||
cursor.ptr = ptr_end;
|
||||
}
|
||||
|
||||
|
||||
inline void operator<<(_Inout_ eap::cursor_out &cursor, _In_ const eap::tls_master_secret &val)
|
||||
{
|
||||
eap::cursor_out::ptr_type ptr_end = cursor.ptr + sizeof(eap::tls_master_secret);
|
||||
assert(ptr_end <= cursor.ptr_end);
|
||||
memcpy(cursor.ptr, val.data, sizeof(eap::tls_master_secret));
|
||||
cursor.ptr = ptr_end;
|
||||
}
|
||||
|
||||
|
||||
inline size_t pksizeof(_In_ const eap::tls_master_secret &val)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(val);
|
||||
return sizeof(eap::tls_master_secret);
|
||||
}
|
||||
|
||||
|
||||
inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::tls_master_secret &val)
|
||||
{
|
||||
eap::cursor_in::ptr_type ptr_end = cursor.ptr + sizeof(eap::tls_master_secret);
|
||||
assert(ptr_end <= cursor.ptr_end);
|
||||
memcpy(val.data, cursor.ptr, sizeof(eap::tls_master_secret));
|
||||
cursor.ptr = ptr_end;
|
||||
}
|
||||
|
||||
|
||||
inline void operator<<(_Inout_ eap::cursor_out &cursor, _In_ const eap::tls_conn_state &val)
|
||||
{
|
||||
cursor << val.m_master_secret;
|
||||
cursor << val.m_random_client;
|
||||
cursor << val.m_random_server;
|
||||
}
|
||||
|
||||
|
||||
inline size_t pksizeof(_In_ const eap::tls_conn_state &val)
|
||||
{
|
||||
return
|
||||
pksizeof(val.m_master_secret) +
|
||||
pksizeof(val.m_random_client) +
|
||||
pksizeof(val.m_random_server);
|
||||
}
|
||||
|
||||
|
||||
inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::tls_conn_state &val)
|
||||
{
|
||||
cursor >> val.m_master_secret;
|
||||
cursor >> val.m_random_client;
|
||||
cursor >> val.m_random_server;
|
||||
|
||||
|
||||
class tls_conn_state
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs a connection state
|
||||
///
|
||||
tls_conn_state();
|
||||
|
||||
///
|
||||
/// Copy a connection state
|
||||
///
|
||||
/// \param[in] other Connection state to copy from
|
||||
///
|
||||
tls_conn_state(_In_ const tls_conn_state &other);
|
||||
|
||||
///
|
||||
/// Moves a connection state
|
||||
///
|
||||
/// \param[inout] other Connection state to move from
|
||||
///
|
||||
tls_conn_state(_Inout_ tls_conn_state &&other);
|
||||
|
||||
///
|
||||
/// Copy a connection state
|
||||
///
|
||||
/// \param[inout] other Connection state to copy from
|
||||
///
|
||||
/// \returns Reference to this object
|
||||
///
|
||||
tls_conn_state& operator=(_In_ const tls_conn_state &other);
|
||||
|
||||
///
|
||||
/// Moves a connection state
|
||||
///
|
||||
/// \param[in] other Connection state to move from
|
||||
///
|
||||
/// \returns Reference to this object
|
||||
///
|
||||
tls_conn_state& operator=(_Inout_ tls_conn_state &&other);
|
||||
|
||||
public:
|
||||
ALG_ID m_alg_encrypt; ///< Bulk encryption algorithm
|
||||
size_t m_size_enc_key; ///< Encryption key size in bytes (has to comply with `m_alg_encrypt`)
|
||||
size_t m_size_enc_iv; ///< Encryption initialization vector size in bytes (has to comply with `m_alg_encrypt`)
|
||||
size_t m_size_enc_block; ///< Encryption block size in bytes (has to comply with `m_alg_encrypt`)
|
||||
winstd::crypt_key m_key; ///< Key for encrypting messages
|
||||
ALG_ID m_alg_mac; ///< Message authenticy check algorithm
|
||||
size_t m_size_mac_key; ///< Message authenticy check algorithm key size (has to comply with `m_alg_mac`)
|
||||
size_t m_size_mac_hash; ///< Message authenticy check algorithm result size (has to comply with `m_alg_mac`)
|
||||
hmac_padding m_padding_hmac; ///< Padding (key) for HMAC calculation
|
||||
};
|
||||
}
|
||||
|
@@ -254,7 +254,7 @@ tstring eap::credentials_tls::get_name() const
|
||||
}
|
||||
|
||||
|
||||
bool eap::credentials_tls::combine(
|
||||
eap::credentials::source_t eap::credentials_tls::combine(
|
||||
_In_ const credentials_tls *cred_cached,
|
||||
_In_ const config_method_tls &cfg,
|
||||
_In_opt_z_ LPCTSTR pszTargetName)
|
||||
@@ -263,14 +263,14 @@ bool eap::credentials_tls::combine(
|
||||
// Using EAP service cached credentials.
|
||||
*this = *cred_cached;
|
||||
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED1, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data::blank);
|
||||
return true;
|
||||
return source_cache;
|
||||
}
|
||||
|
||||
if (cfg.m_use_preshared) {
|
||||
// Using preshared credentials.
|
||||
*this = *(credentials_tls*)cfg.m_preshared.get();
|
||||
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_PRESHARED1, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data::blank);
|
||||
return true;
|
||||
return source_preshared;
|
||||
}
|
||||
|
||||
if (pszTargetName) {
|
||||
@@ -281,13 +281,13 @@ bool eap::credentials_tls::combine(
|
||||
// Using stored credentials.
|
||||
*this = std::move(cred_loaded);
|
||||
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_STORED1, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data::blank);
|
||||
return true;
|
||||
return source_storage;
|
||||
} catch (...) {
|
||||
// Not actually an error.
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return source_unknown;
|
||||
}
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -37,40 +37,7 @@ const eap::tls_version eap::tls_version_1_2 = { 3, 3 };
|
||||
// eap::tls_random
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
eap::tls_random::tls_random()
|
||||
{
|
||||
memset(data, 0, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
eap::tls_random::tls_random(_In_ const tls_random &other)
|
||||
{
|
||||
memcpy(data, other.data, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
eap::tls_random::~tls_random()
|
||||
{
|
||||
SecureZeroMemory(data, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
eap::tls_random& eap::tls_random::operator=(_In_ const tls_random &other)
|
||||
{
|
||||
if (this != std::addressof(other))
|
||||
memcpy(data, other.data, sizeof(data));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void eap::tls_random::clear()
|
||||
{
|
||||
memset(data, 0, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
void eap::tls_random::reset(_In_ HCRYPTPROV cp)
|
||||
void eap::tls_random::randomize(_In_ HCRYPTPROV cp)
|
||||
{
|
||||
_time32((__time32_t*)data);
|
||||
if (!CryptGenRandom(cp, sizeof(data) - sizeof(__time32_t), data + sizeof(__time32_t)))
|
||||
@@ -84,7 +51,6 @@ void eap::tls_random::reset(_In_ HCRYPTPROV cp)
|
||||
|
||||
eap::tls_master_secret::tls_master_secret()
|
||||
{
|
||||
memset(data, 0, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
@@ -98,30 +64,113 @@ eap::tls_master_secret::tls_master_secret(_In_ HCRYPTPROV cp, _In_ tls_version v
|
||||
}
|
||||
|
||||
|
||||
eap::tls_master_secret::tls_master_secret(_In_ const tls_master_secret &other)
|
||||
eap::tls_master_secret::tls_master_secret(_In_ const sanitizing_blob_f<48> &other) :
|
||||
sanitizing_blob_xf<48>(other)
|
||||
{
|
||||
memcpy(data, other.data, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
eap::tls_master_secret::~tls_master_secret()
|
||||
#ifdef _DEBUG
|
||||
|
||||
eap::tls_master_secret::tls_master_secret(_Inout_ sanitizing_blob_zf<48> &&other) :
|
||||
sanitizing_blob_xf<48>(std::move(other))
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// eap::hmac_padding
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
eap::hmac_padding::hmac_padding()
|
||||
{
|
||||
SecureZeroMemory(data, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
eap::tls_master_secret& eap::tls_master_secret::operator=(_In_ const tls_master_secret &other)
|
||||
eap::hmac_padding::hmac_padding(
|
||||
_In_ HCRYPTPROV cp,
|
||||
_In_ ALG_ID alg,
|
||||
_In_bytecount_(size_secret ) const void *secret,
|
||||
_In_ size_t size_secret,
|
||||
_In_opt_ unsigned char pad)
|
||||
{
|
||||
if (this != std::addressof(other))
|
||||
memcpy(data, other.data, sizeof(data));
|
||||
|
||||
return *this;
|
||||
if (size_secret > sizeof(hmac_padding)) {
|
||||
// If the secret is longer than padding, use secret's hash instead.
|
||||
crypt_hash hash;
|
||||
if (!hash.create(cp, alg))
|
||||
throw win_runtime_error(__FUNCTION__ " Error creating hash.");
|
||||
if (!CryptHashData(hash, (const BYTE*)secret, (DWORD)size_secret, 0))
|
||||
throw win_runtime_error(__FUNCTION__ " Error hashing.");
|
||||
DWORD size_hash = sizeof(hmac_padding);
|
||||
if (!CryptGetHashParam(hash, HP_HASHVAL, data, &size_hash, 0))
|
||||
throw win_runtime_error(__FUNCTION__ " Error finishing hash.");
|
||||
size_secret = size_hash;
|
||||
} else
|
||||
memcpy(data, secret, size_secret);
|
||||
for (size_t i = 0; i < size_secret; i++)
|
||||
data[i] ^= pad;
|
||||
memset(data + size_secret, pad, sizeof(hmac_padding) - size_secret);
|
||||
}
|
||||
|
||||
|
||||
void eap::tls_master_secret::clear()
|
||||
eap::hmac_padding::hmac_padding(_In_ const sanitizing_blob_f<64> &other) :
|
||||
sanitizing_blob_xf<64>(other)
|
||||
{
|
||||
memset(data, 0, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
eap::hmac_padding::hmac_padding(_Inout_ sanitizing_blob_zf<64> &&other) :
|
||||
sanitizing_blob_xf<64>(std::move(other))
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// eap::hmac_hash
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
eap::hmac_hash::hmac_hash(
|
||||
_In_ HCRYPTPROV cp,
|
||||
_In_ ALG_ID alg,
|
||||
_In_bytecount_(size_secret ) const void *secret,
|
||||
_In_ size_t size_secret)
|
||||
{
|
||||
// Prepare inner padding and forward to the other constructor.
|
||||
this->hmac_hash::hmac_hash(cp, alg, hmac_padding(cp, alg, secret, size_secret));
|
||||
}
|
||||
|
||||
|
||||
eap::hmac_hash::hmac_hash(
|
||||
_In_ HCRYPTPROV cp,
|
||||
_In_ ALG_ID alg,
|
||||
_In_ const hmac_padding &padding)
|
||||
{
|
||||
// Create inner hash.
|
||||
if (!m_hash_inner.create(cp, alg))
|
||||
throw win_runtime_error(__FUNCTION__ " Error creating inner hash.");
|
||||
|
||||
// Initialize it with the inner padding.
|
||||
if (!CryptHashData(m_hash_inner, padding.data, sizeof(hmac_padding), 0))
|
||||
throw win_runtime_error(__FUNCTION__ " Error hashing secret XOR inner padding.");
|
||||
|
||||
// Convert inner padding to outer padding for final calculation.
|
||||
hmac_padding padding_out;
|
||||
for (size_t i = 0; i < sizeof(hmac_padding); i++)
|
||||
padding_out.data[i] = padding.data[i] ^ (0x36 ^ 0x5c);
|
||||
|
||||
// Create outer hash.
|
||||
if (!m_hash_outer.create(cp, alg))
|
||||
throw win_runtime_error(__FUNCTION__ " Error creating outer hash.");
|
||||
|
||||
// Initialize it with the outer padding.
|
||||
if (!CryptHashData(m_hash_outer, padding_out.data, sizeof(hmac_padding), 0))
|
||||
throw win_runtime_error(__FUNCTION__ " Error hashing secret XOR inner padding.");
|
||||
}
|
||||
|
||||
|
||||
@@ -129,8 +178,10 @@ void eap::tls_master_secret::clear()
|
||||
// eap::tls_conn_state
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
eap::tls_conn_state::tls_conn_state() :
|
||||
m_alg_prf (0),
|
||||
eap::tls_conn_state::tls_conn_state()
|
||||
#ifdef _DEBUG
|
||||
// Initialize state primitive members for diagnostic purposes.
|
||||
:
|
||||
m_alg_encrypt (0),
|
||||
m_size_enc_key (0),
|
||||
m_size_enc_iv (0),
|
||||
@@ -138,32 +189,61 @@ eap::tls_conn_state::tls_conn_state() :
|
||||
m_alg_mac (0),
|
||||
m_size_mac_key (0),
|
||||
m_size_mac_hash (0)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
eap::tls_conn_state::tls_conn_state(_In_ const tls_conn_state &other) :
|
||||
m_master_secret(other.m_master_secret),
|
||||
m_random_client(other.m_random_client),
|
||||
m_random_server(other.m_random_server)
|
||||
m_alg_encrypt (other.m_alg_encrypt ),
|
||||
m_size_enc_key (other.m_size_enc_key ),
|
||||
m_size_enc_iv (other.m_size_enc_iv ),
|
||||
m_size_enc_block(other.m_size_enc_block),
|
||||
m_key (other.m_key ),
|
||||
m_alg_mac (other.m_alg_mac ),
|
||||
m_size_mac_key (other.m_size_mac_key ),
|
||||
m_size_mac_hash (other.m_size_mac_hash ),
|
||||
m_padding_hmac (other.m_padding_hmac )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
eap::tls_conn_state::tls_conn_state(_Inout_ tls_conn_state &&other) :
|
||||
m_master_secret(std::move(other.m_master_secret)),
|
||||
m_random_client(std::move(other.m_random_client)),
|
||||
m_random_server(std::move(other.m_random_server))
|
||||
m_alg_encrypt (std::move(other.m_alg_encrypt )),
|
||||
m_size_enc_key (std::move(other.m_size_enc_key )),
|
||||
m_size_enc_iv (std::move(other.m_size_enc_iv )),
|
||||
m_size_enc_block(std::move(other.m_size_enc_block)),
|
||||
m_key (std::move(other.m_key )),
|
||||
m_alg_mac (std::move(other.m_alg_mac )),
|
||||
m_size_mac_key (std::move(other.m_size_mac_key )),
|
||||
m_size_mac_hash (std::move(other.m_size_mac_hash )),
|
||||
m_padding_hmac (std::move(other.m_padding_hmac ))
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
// Reinitialize other state primitive members for diagnostic purposes.
|
||||
other.m_alg_encrypt = 0;
|
||||
other.m_size_enc_key = 0;
|
||||
other.m_size_enc_iv = 0;
|
||||
other.m_size_enc_block = 0;
|
||||
other.m_alg_mac = 0;
|
||||
other.m_size_mac_key = 0;
|
||||
other.m_size_mac_hash = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
eap::tls_conn_state& eap::tls_conn_state::operator=(_In_ const tls_conn_state &other)
|
||||
{
|
||||
if (this != std::addressof(other)) {
|
||||
m_master_secret = other.m_master_secret;
|
||||
m_random_client = other.m_random_client;
|
||||
m_random_server = other.m_random_server;
|
||||
m_alg_encrypt = other.m_alg_encrypt ;
|
||||
m_size_enc_key = other.m_size_enc_key ;
|
||||
m_size_enc_iv = other.m_size_enc_iv ;
|
||||
m_size_enc_block = other.m_size_enc_block;
|
||||
m_key = other.m_key ;
|
||||
m_alg_mac = other.m_alg_mac ;
|
||||
m_size_mac_key = other.m_size_mac_key ;
|
||||
m_size_mac_hash = other.m_size_mac_hash ;
|
||||
m_padding_hmac = other.m_padding_hmac ;
|
||||
}
|
||||
|
||||
return *this;
|
||||
@@ -173,83 +253,27 @@ eap::tls_conn_state& eap::tls_conn_state::operator=(_In_ const tls_conn_state &o
|
||||
eap::tls_conn_state& eap::tls_conn_state::operator=(_Inout_ tls_conn_state &&other)
|
||||
{
|
||||
if (this != std::addressof(other)) {
|
||||
m_master_secret = std::move(other.m_master_secret);
|
||||
m_random_client = std::move(other.m_random_client);
|
||||
m_random_server = std::move(other.m_random_server);
|
||||
m_alg_encrypt = std::move(other.m_alg_encrypt );
|
||||
m_size_enc_key = std::move(other.m_size_enc_key );
|
||||
m_size_enc_iv = std::move(other.m_size_enc_iv );
|
||||
m_size_enc_block = std::move(other.m_size_enc_block);
|
||||
m_key = std::move(other.m_key );
|
||||
m_alg_mac = std::move(other.m_alg_mac );
|
||||
m_size_mac_key = std::move(other.m_size_mac_key );
|
||||
m_size_mac_hash = std::move(other.m_size_mac_hash );
|
||||
m_padding_hmac = std::move(other.m_padding_hmac );
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Reinitialize other state primitive members for diagnostic purposes.
|
||||
other.m_alg_encrypt = 0;
|
||||
other.m_size_enc_key = 0;
|
||||
other.m_size_enc_iv = 0;
|
||||
other.m_size_enc_block = 0;
|
||||
other.m_alg_mac = 0;
|
||||
other.m_size_mac_key = 0;
|
||||
other.m_size_mac_hash = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// eap::hash_hmac
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
eap::hash_hmac::hash_hmac(
|
||||
_In_ HCRYPTPROV cp,
|
||||
_In_ ALG_ID alg,
|
||||
_In_bytecount_(size_secret ) const void *secret,
|
||||
_In_ size_t size_secret)
|
||||
{
|
||||
// Prepare padding.
|
||||
sanitizing_blob padding(sizeof(padding_t));
|
||||
inner_padding(cp, alg, secret, size_secret, padding.data());
|
||||
|
||||
// Continue with the other constructor.
|
||||
this->hash_hmac::hash_hmac(cp, alg, padding.data());
|
||||
}
|
||||
|
||||
|
||||
eap::hash_hmac::hash_hmac(
|
||||
_In_ HCRYPTPROV cp,
|
||||
_In_ ALG_ID alg,
|
||||
_In_ const padding_t padding)
|
||||
{
|
||||
// Create inner hash.
|
||||
if (!m_hash_inner.create(cp, alg))
|
||||
throw win_runtime_error(__FUNCTION__ " Error creating inner hash.");
|
||||
|
||||
// Initialize it with the inner padding.
|
||||
if (!CryptHashData(m_hash_inner, padding, sizeof(padding_t), 0))
|
||||
throw win_runtime_error(__FUNCTION__ " Error hashing secret XOR inner padding.");
|
||||
|
||||
// Convert inner padding to outer padding for final calculation.
|
||||
padding_t padding_out;
|
||||
for (size_t i = 0; i < sizeof(padding_t); i++)
|
||||
padding_out[i] = padding[i] ^ (0x36 ^ 0x5c);
|
||||
|
||||
// Create outer hash.
|
||||
if (!m_hash_outer.create(cp, alg))
|
||||
throw win_runtime_error(__FUNCTION__ " Error creating outer hash.");
|
||||
|
||||
// Initialize it with the outer padding.
|
||||
if (!CryptHashData(m_hash_outer, padding_out, sizeof(padding_t), 0))
|
||||
throw win_runtime_error(__FUNCTION__ " Error hashing secret XOR inner padding.");
|
||||
}
|
||||
|
||||
|
||||
void eap::hash_hmac::inner_padding(
|
||||
_In_ HCRYPTPROV cp,
|
||||
_In_ ALG_ID alg,
|
||||
_In_bytecount_(size_secret ) const void *secret,
|
||||
_In_ size_t size_secret,
|
||||
_Out_ padding_t padding)
|
||||
{
|
||||
if (size_secret > sizeof(padding_t)) {
|
||||
// If the secret is longer than padding, use secret's hash instead.
|
||||
crypt_hash hash;
|
||||
if (!hash.create(cp, alg))
|
||||
throw win_runtime_error(__FUNCTION__ " Error creating hash.");
|
||||
if (!CryptHashData(hash, (const BYTE*)secret, (DWORD)size_secret, 0))
|
||||
throw win_runtime_error(__FUNCTION__ " Error hashing.");
|
||||
DWORD size_hash = sizeof(padding_t);
|
||||
if (!CryptGetHashParam(hash, HP_HASHVAL, padding, &size_hash, 0))
|
||||
throw win_runtime_error(__FUNCTION__ " Error finishing hash.");
|
||||
size_secret = size_hash;
|
||||
} else
|
||||
memcpy(padding, secret, size_secret);
|
||||
for (size_t i = 0; i < size_secret; i++)
|
||||
padding[i] ^= 0x36;
|
||||
memset(padding + size_secret, 0x36, sizeof(padding_t) - size_secret);
|
||||
}
|
||||
|
@@ -32,6 +32,7 @@ namespace eap
|
||||
#include "../../PAP/include/Credentials.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace eap
|
||||
@@ -187,7 +188,7 @@ namespace eap
|
||||
/// - \c true if credentials were set;
|
||||
/// - \c false otherwise
|
||||
///
|
||||
bool combine(
|
||||
std::pair<source_t, source_t> combine(
|
||||
_In_ const credentials_ttls *cred_cached,
|
||||
_In_ const config_method_ttls &cfg,
|
||||
_In_opt_z_ LPCTSTR pszTargetName);
|
||||
|
@@ -63,13 +63,6 @@ namespace eap
|
||||
///
|
||||
method_ttls(_In_ module &module, _In_ config_provider_list &cfg, _In_ credentials_ttls &cred);
|
||||
|
||||
///
|
||||
/// Copies an EAP method
|
||||
///
|
||||
/// \param[in] other EAP method to copy from
|
||||
///
|
||||
method_ttls(_In_ const method_ttls &other);
|
||||
|
||||
///
|
||||
/// Moves an EAP method
|
||||
///
|
||||
@@ -77,15 +70,6 @@ namespace eap
|
||||
///
|
||||
method_ttls(_Inout_ method_ttls &&other);
|
||||
|
||||
///
|
||||
/// Copies an EAP method
|
||||
///
|
||||
/// \param[in] other EAP method to copy from
|
||||
///
|
||||
/// \returns Reference to this object
|
||||
///
|
||||
method_ttls& operator=(_In_ const method_ttls &other);
|
||||
|
||||
///
|
||||
/// Moves an EAP method
|
||||
///
|
||||
|
@@ -226,15 +226,12 @@ std::wstring eap::credentials_ttls::get_identity() const
|
||||
}
|
||||
|
||||
|
||||
bool eap::credentials_ttls::combine(
|
||||
pair<eap::credentials::source_t, eap::credentials::source_t> eap::credentials_ttls::combine(
|
||||
_In_ const credentials_ttls *cred_cached,
|
||||
_In_ const config_method_ttls &cfg,
|
||||
_In_opt_z_ LPCTSTR pszTargetName)
|
||||
{
|
||||
bool
|
||||
is_outer_set = credentials_tls::combine(cred_cached, cfg, pszTargetName),
|
||||
is_inner_set =
|
||||
dynamic_cast<const credentials_pap*>(m_inner.get()) ? ((credentials_pap*)m_inner.get())->combine(cred_cached ? (credentials_pap*)cred_cached->m_inner.get() : NULL, (const config_method_pap&)*cfg.m_inner, pszTargetName) : false;
|
||||
|
||||
return is_outer_set && is_inner_set;
|
||||
return pair<source_t, source_t>(
|
||||
credentials_tls::combine(cred_cached, cfg, pszTargetName),
|
||||
dynamic_cast<const credentials_pap*>(m_inner.get()) ? ((credentials_pap*)m_inner.get())->combine(cred_cached ? (credentials_pap*)cred_cached->m_inner.get() : NULL, (const config_method_pap&)*cfg.m_inner, pszTargetName) : source_unknown);
|
||||
}
|
||||
|
@@ -36,14 +36,6 @@ eap::method_ttls::method_ttls(_In_ module &module, _In_ config_provider_list &cf
|
||||
}
|
||||
|
||||
|
||||
eap::method_ttls::method_ttls(_In_ const method_ttls &other) :
|
||||
m_cred(other.m_cred),
|
||||
m_version(other.m_version),
|
||||
method_tls(other)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
eap::method_ttls::method_ttls(_Inout_ method_ttls &&other) :
|
||||
m_cred(other.m_cred),
|
||||
m_version(std::move(other.m_version)),
|
||||
@@ -52,17 +44,6 @@ eap::method_ttls::method_ttls(_Inout_ method_ttls &&other) :
|
||||
}
|
||||
|
||||
|
||||
eap::method_ttls& eap::method_ttls::operator=(_In_ const method_ttls &other)
|
||||
{
|
||||
if (this != std::addressof(other)) {
|
||||
(method_tls&)*this = other;
|
||||
m_version = other.m_version;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
eap::method_ttls& eap::method_ttls::operator=(_Inout_ method_ttls &&other)
|
||||
{
|
||||
if (this != std::addressof(other)) {
|
||||
@@ -88,29 +69,25 @@ void eap::method_ttls::process_request_packet(
|
||||
m_module.log_event(&EAPMETHOD_TTLS_HANDSHAKE_START, event_data((unsigned int)eap_type_ttls), event_data((unsigned char)m_version), event_data((unsigned char)ver_remote), event_data::blank);
|
||||
}
|
||||
|
||||
if (!m_server_finished) {
|
||||
// Do the TLS.
|
||||
method_tls::process_request_packet(pReceivedPacket, dwReceivedPacketSize, pEapOutput);
|
||||
|
||||
if (m_server_finished) {
|
||||
// Piggyback inner authentication.
|
||||
if (!m_cipher_spec)
|
||||
if (m_phase == phase_application_data) {
|
||||
// Send inner authentication.
|
||||
if (!m_state_client.m_alg_encrypt)
|
||||
throw runtime_error(__FUNCTION__ " Refusing to send credentials unencrypted.");
|
||||
|
||||
m_module.log_event(&EAPMETHOD_TTLS_INNER_CRED, event_data((unsigned int)eap_type_ttls), event_data(m_cred.m_inner->get_name()), event_data::blank);
|
||||
|
||||
m_packet_res.m_code = EapCodeResponse;
|
||||
m_packet_res.m_id = m_packet_req.m_id;
|
||||
m_packet_res.m_flags = 0;
|
||||
sanitizing_blob client(make_pap_client());
|
||||
sanitizing_blob application(make_message(tls_message_type_application_data, client, m_cipher_spec));
|
||||
m_packet_res.m_data.assign(application.begin(), application.end());
|
||||
sanitizing_blob msg_application(make_message(tls_message_type_application_data, make_pap_client()));
|
||||
m_packet_res.m_data.insert(m_packet_res.m_data.end(), msg_application.begin(), msg_application.end());
|
||||
|
||||
pEapOutput->fAllowNotifications = FALSE;
|
||||
pEapOutput->action = EapPeerMethodResponseActionSend;
|
||||
}
|
||||
} else {
|
||||
// Do the TLS. Again.
|
||||
method_tls::process_request_packet(pReceivedPacket, dwReceivedPacketSize, pEapOutput);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -131,20 +108,36 @@ void eap::method_ttls::get_result(
|
||||
_In_ EapPeerMethodResultReason reason,
|
||||
_Inout_ EapPeerMethodResult *ppResult)
|
||||
{
|
||||
if (!m_server_finished) {
|
||||
if (m_phase != phase_application_data) {
|
||||
// Do the TLS.
|
||||
method_tls::get_result(reason, ppResult);
|
||||
} else {
|
||||
// The TLS finished, this is inner authentication's bussines.
|
||||
config_provider &cfg_prov(m_cfg.m_providers.front());
|
||||
config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov.m_methods.front().get());
|
||||
assert(cfg_method);
|
||||
|
||||
// Mark credentials appropriately, so GUI can re-prompt user.
|
||||
cfg_method->m_inner->m_cred_failed = reason == EapPeerMethodResultFailure;
|
||||
switch (reason) {
|
||||
case EapPeerMethodResultSuccess: {
|
||||
m_module.log_event(&EAPMETHOD_TTLS_INNER_SUCCESS, event_data((unsigned int)eap_type_ttls), event_data::blank);
|
||||
cfg_method->m_inner->m_auth_failed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case EapPeerMethodResultFailure:
|
||||
m_module.log_event(&EAPMETHOD_TTLS_INNER_FAILURE, event_data((unsigned int)eap_type_ttls), event_data::blank);
|
||||
cfg_method->m_inner->m_auth_failed = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Not supported.");
|
||||
}
|
||||
|
||||
// The TLS was OK.
|
||||
method_tls::get_result(EapPeerMethodResultSuccess, ppResult);
|
||||
|
||||
// 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.
|
||||
//if (reason == EapPeerMethodResultFailure) {
|
||||
// ppResult->fIsSuccess = FALSE;
|
||||
// ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED;
|
||||
@@ -172,9 +165,9 @@ void eap::method_ttls::derive_msk()
|
||||
//
|
||||
static const unsigned char s_label[] = "ttls keying material";
|
||||
sanitizing_blob seed(s_label, s_label + _countof(s_label) - 1);
|
||||
seed.insert(seed.end(), (const unsigned char*)&m_state.m_random_client, (const unsigned char*)(&m_state.m_random_client + 1));
|
||||
seed.insert(seed.end(), (const unsigned char*)&m_state.m_random_server, (const unsigned char*)(&m_state.m_random_server + 1));
|
||||
sanitizing_blob key_block(prf(m_cp, CALG_TLS1PRF, m_state.m_master_secret, seed, 2*sizeof(tls_random)));
|
||||
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));
|
||||
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();
|
||||
|
||||
// MSK: MPPE-Recv-Key
|
||||
|
@@ -109,14 +109,17 @@ void eap::peer_ttls::get_identity(
|
||||
{
|
||||
// Combine credentials.
|
||||
user_impersonator impersonating(hTokenImpersonateUser);
|
||||
*pfInvokeUI = cred_out.combine(
|
||||
pair<eap::credentials::source_t, eap::credentials::source_t> cred_source(cred_out.combine(
|
||||
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
|
||||
&cred_in,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
*cfg_method,
|
||||
(dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL) ? FALSE : TRUE;
|
||||
(dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL));
|
||||
|
||||
// If either of credentials is unknown, request UI.
|
||||
*pfInvokeUI = cred_source.first == eap::credentials::source_unknown || cred_source.second == eap::credentials::source_unknown ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
if (*pfInvokeUI) {
|
||||
@@ -132,14 +135,14 @@ void eap::peer_ttls::get_identity(
|
||||
|
||||
// If we got here, we have all credentials we need. But, wait!
|
||||
|
||||
if (cfg_method->m_cred_failed) {
|
||||
if (cfg_method->m_auth_failed) {
|
||||
// Outer TLS: Credentials failed on last connection attempt.
|
||||
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)eap_type_tls), event_data::blank);
|
||||
*pfInvokeUI = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cfg_method->m_inner->m_cred_failed) {
|
||||
if (cfg_method->m_inner->m_auth_failed) {
|
||||
// Inner: Credentials failed on last connection attempt.
|
||||
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)type_inner), event_data::blank);
|
||||
*pfInvokeUI = TRUE;
|
||||
|
@@ -163,14 +163,14 @@ void eap::peer_ttls_ui::invoke_identity_ui(
|
||||
}
|
||||
|
||||
// Combine credentials.
|
||||
cred_out.combine(
|
||||
pair<eap::credentials::source_t, eap::credentials::source_t> cred_source(cred_out.combine(
|
||||
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
|
||||
&cred_in,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
*cfg_method,
|
||||
(dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL);
|
||||
(dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL));
|
||||
|
||||
if (dwFlags & EAP_FLAG_GUEST_ACCESS) {
|
||||
// Disable credential saving for guests.
|
||||
@@ -190,10 +190,18 @@ void eap::peer_ttls_ui::invoke_identity_ui(
|
||||
parent.AdoptAttributesFromHWND();
|
||||
wxTopLevelWindows.Append(&parent);
|
||||
|
||||
// Create and launch credentials dialog.
|
||||
// Create credentials dialog.
|
||||
wxEAPCredentialsDialog dlg(cfg_prov, &parent);
|
||||
wxTTLSCredentialsPanel *panel = new wxTTLSCredentialsPanel(cfg_prov, *cfg_method, cred_out, cfg_prov.m_id.c_str(), &dlg);
|
||||
dlg.AddContents((wxPanel**)&panel, 1);
|
||||
|
||||
// Set "Remember" checkboxes according to credential source,
|
||||
panel->m_outer_cred->SetRememberValue(cred_source.first == eap::credentials::source_storage);
|
||||
wxPAPCredentialsPanel *panel_inner_cred_pap = dynamic_cast<wxPAPCredentialsPanel*>(panel->m_inner_cred);
|
||||
if (panel_inner_cred_pap)
|
||||
panel_inner_cred_pap->SetRememberValue(cred_source.second == eap::credentials::source_storage);
|
||||
|
||||
// Centre and display dialog.
|
||||
dlg.Centre(wxBOTH);
|
||||
result = dlg.ShowModal();
|
||||
if (result == wxID_OK) {
|
||||
@@ -208,7 +216,6 @@ void eap::peer_ttls_ui::invoke_identity_ui(
|
||||
}
|
||||
}
|
||||
|
||||
wxPAPCredentialsPanel *panel_inner_cred_pap = dynamic_cast<wxPAPCredentialsPanel*>(panel->m_inner_cred);
|
||||
if (panel_inner_cred_pap && panel_inner_cred_pap->GetRememberValue()) {
|
||||
try {
|
||||
cred_out.m_inner->store(cfg_prov.m_id.c_str());
|
||||
|
@@ -226,7 +226,7 @@ wxTTLSCredentialsPanel::wxTTLSCredentialsPanel(const eap::config_provider &prov,
|
||||
|
||||
assert(m_cfg.m_inner);
|
||||
|
||||
if (m_cfg.m_inner->m_cred_failed)
|
||||
if (m_cfg.m_inner->m_auth_failed)
|
||||
sb_content->Add(new wxEAPCredentialWarningPanel(m_prov, this), 0, wxALL|wxEXPAND, 5);
|
||||
|
||||
const eap::config_method_pap *cfg_inner_pap = dynamic_cast<const eap::config_method_pap*>(m_cfg.m_inner.get());
|
||||
@@ -245,7 +245,7 @@ wxTTLSCredentialsPanel::wxTTLSCredentialsPanel(const eap::config_provider &prov,
|
||||
m_outer_title->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_INACTIVECAPTION ) );
|
||||
sb_content->Add(m_outer_title, 0, wxALL|wxALIGN_RIGHT, 5);
|
||||
|
||||
if (m_cfg.m_cred_failed)
|
||||
if (m_cfg.m_auth_failed)
|
||||
sb_content->Add(new wxEAPCredentialWarningPanel(m_prov, this), 0, wxALL|wxEXPAND, 5);
|
||||
|
||||
m_outer_cred = new wxTLSCredentialsPanel(m_prov, (const eap::config_method_tls&)m_cfg, (eap::credentials_tls&)cred, pszCredTarget, this, is_config);
|
||||
|
Submodule lib/WinStd updated: dfbe66a826...8a0799c2b7
Reference in New Issue
Block a user