Compare commits

...

4 Commits
1.3a ... 1.3b

Author SHA1 Message Date
d62089d5bd Fix initial keyboard focus
After rearranging the configuration dialog panels, the inner
authentication (PAP) is no longer the topmost panel/control.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-05-13 09:07:54 +02:00
a6bdb42ece Deprecate encrypted BLOB checksum
The MD5 checksum was calculated on unencrypted data. This offered a
possibility for a dictionary attack.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-05-13 08:26:07 +02:00
7897d0716c MSIBuild: Bump
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-05-13 07:33:42 +02:00
842f46dac8 Pre-set version to 1.3b
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-04-20 16:38:53 +02:00
6 changed files with 41 additions and 20 deletions

View File

@@ -34,7 +34,7 @@
// Product version as a single DWORD // Product version as a single DWORD
// Note: Used for version comparison within C/C++ code. // Note: Used for version comparison within C/C++ code.
// //
#define PRODUCT_VERSION 0x01030100 #define PRODUCT_VERSION 0x01030200
// //
// Product version by components // Product version by components
@@ -44,26 +44,26 @@
// //
#define PRODUCT_VERSION_MAJ 1 #define PRODUCT_VERSION_MAJ 1
#define PRODUCT_VERSION_MIN 3 #define PRODUCT_VERSION_MIN 3
#define PRODUCT_VERSION_REV 1 #define PRODUCT_VERSION_REV 2
#define PRODUCT_VERSION_BUILD 0 #define PRODUCT_VERSION_BUILD 0
// //
// Human readable product version and build year for UI // Human readable product version and build year for UI
// //
#define PRODUCT_VERSION_STR "1.3a" #define PRODUCT_VERSION_STR "1.3b"
#define PRODUCT_BUILD_YEAR_STR "2020" #define PRODUCT_BUILD_YEAR_STR "2020"
// //
// Numerical version presentation for ProductVersion propery in // Numerical version presentation for ProductVersion propery in
// MSI packages (syntax: N.N[.N[.N]]) // MSI packages (syntax: N.N[.N[.N]])
// //
#define PRODUCT_VERSION_INST "1.3.1" #define PRODUCT_VERSION_INST "1.3.2"
// //
// The product code for ProductCode property in MSI packages // The product code for ProductCode property in MSI packages
// Replace with new on every version change, regardless how minor it is. // Replace with new on every version change, regardless how minor it is.
// //
#define PRODUCT_VERSION_GUID "{1DD7E6F9-6728-4891-87F2-90280E691201}" #define PRODUCT_VERSION_GUID "{4532C9D1-E810-4CC8-A0F1-A10CFC2FFC34}"
// //
// Product vendor // Product vendor

View File

@@ -327,7 +327,8 @@ namespace eap
enum class enc_alg_t { enum class enc_alg_t {
unknown = -1, ///< Unknown encryption unknown = -1, ///< Unknown encryption
none = 0, ///< Unencrypted none = 0, ///< Unencrypted
native, ///< native module encryption native, ///< native module encryption (version 2)
native_v1, ///< native module encryption (version 1, deprecated)
kph, ///< KPH encryption kph, ///< KPH encryption
}; };

View File

@@ -364,6 +364,7 @@ namespace eap
/// ///
/// \returns Encrypted data with 16B MD5 hash appended /// \returns Encrypted data with 16B MD5 hash appended
/// ///
[[deprecated("Unencrypted hash allows dictionary attacks")]]
std::vector<unsigned char> encrypt_md5(_In_ HCRYPTPROV hProv, _In_bytecount_(size) const void *data, _In_ size_t size) const; std::vector<unsigned char> encrypt_md5(_In_ HCRYPTPROV hProv, _In_bytecount_(size) const void *data, _In_ size_t size) const;
@@ -376,6 +377,7 @@ namespace eap
/// \returns Encrypted data with 16B MD5 hash appended /// \returns Encrypted data with 16B MD5 hash appended
/// ///
template<class _Elem, class _Traits, class _Ax> template<class _Elem, class _Traits, class _Ax>
[[deprecated("Unencrypted hash allows dictionary attacks")]]
std::vector<unsigned char> encrypt_md5(_In_ HCRYPTPROV hProv, _In_ const std::basic_string<_Elem, _Traits, _Ax> &val) const std::vector<unsigned char> encrypt_md5(_In_ HCRYPTPROV hProv, _In_ const std::basic_string<_Elem, _Traits, _Ax> &val) const
{ {
return encrypt_md5(hProv, val.c_str(), val.length()*sizeof(_Elem)); return encrypt_md5(hProv, val.c_str(), val.length()*sizeof(_Elem));
@@ -391,6 +393,7 @@ namespace eap
/// \returns Encrypted data with 16B MD5 hash appended /// \returns Encrypted data with 16B MD5 hash appended
/// ///
template<class _Traits, class _Ax> template<class _Traits, class _Ax>
[[deprecated("Unencrypted hash allows dictionary attacks")]]
std::vector<unsigned char> encrypt_md5(_In_ HCRYPTPROV hProv, _In_ const std::basic_string<wchar_t, _Traits, _Ax> &val) const std::vector<unsigned char> encrypt_md5(_In_ HCRYPTPROV hProv, _In_ const std::basic_string<wchar_t, _Traits, _Ax> &val) const
{ {
winstd::sanitizing_string val_utf8; winstd::sanitizing_string val_utf8;
@@ -451,7 +454,7 @@ namespace eap
template<class _Elem, class _Traits, class _Ax> template<class _Elem, class _Traits, class _Ax>
std::basic_string<_Elem, _Traits, _Ax> decrypt_str(_In_ HCRYPTPROV hProv, _In_bytecount_(size) const void *data, _In_ size_t size, _In_opt_ HCRYPTHASH hHash = NULL) const std::basic_string<_Elem, _Traits, _Ax> decrypt_str(_In_ HCRYPTPROV hProv, _In_bytecount_(size) const void *data, _In_ size_t size, _In_opt_ HCRYPTHASH hHash = NULL) const
{ {
std::vector<_Elem, sanitizing_allocator<_Elem> > buf(std::move(decrypt(hProv, data, size, hHash))); std::vector<_Elem, sanitizing_allocator<_Elem> > buf(std::move(decrypt<_Elem, sanitizing_allocator<_Elem> >(hProv, data, size, hHash)));
return std::basic_string<_Elem, _Traits, _Ax>(buf.data(), buf.size()); return std::basic_string<_Elem, _Traits, _Ax>(buf.data(), buf.size());
} }
@@ -469,7 +472,7 @@ namespace eap
template<class _Traits, class _Ax> template<class _Traits, class _Ax>
std::basic_string<wchar_t, _Traits, _Ax> decrypt_str(_In_ HCRYPTPROV hProv, _In_bytecount_(size) const void *data, _In_ size_t size, _In_opt_ HCRYPTHASH hHash = NULL) const std::basic_string<wchar_t, _Traits, _Ax> decrypt_str(_In_ HCRYPTPROV hProv, _In_bytecount_(size) const void *data, _In_ size_t size, _In_opt_ HCRYPTHASH hHash = NULL) const
{ {
winstd::sanitizing_string buf(std::move(decrypt_str(hProv, data, size, hHash))); winstd::sanitizing_string buf(std::move(decrypt_str<char, std::char_traits<char>, sanitizing_allocator<char> >(hProv, data, size, hHash)));
std::basic_string<wchar_t, _Traits, _Ax> dec; std::basic_string<wchar_t, _Traits, _Ax> dec;
MultiByteToWideChar(CP_UTF8, 0, buf, dec); MultiByteToWideChar(CP_UTF8, 0, buf, dec);
return dec; return dec;
@@ -486,6 +489,7 @@ namespace eap
/// \returns Decrypted data /// \returns Decrypted data
/// ///
template<class _Ty, class _Ax> template<class _Ty, class _Ax>
[[deprecated("Unencrypted hash allows dictionary attacks")]]
std::vector<_Ty, _Ax> decrypt_md5(_In_ HCRYPTPROV hProv, _In_bytecount_(size) const void *data, _In_ size_t size) const std::vector<_Ty, _Ax> decrypt_md5(_In_ HCRYPTPROV hProv, _In_bytecount_(size) const void *data, _In_ size_t size) const
{ {
// Create hash. // Create hash.
@@ -522,6 +526,7 @@ namespace eap
/// \returns Decrypted string /// \returns Decrypted string
/// ///
template<class _Elem, class _Traits, class _Ax> template<class _Elem, class _Traits, class _Ax>
[[deprecated("Unencrypted hash allows dictionary attacks")]]
std::basic_string<_Elem, _Traits, _Ax> decrypt_str_md5(_In_ HCRYPTPROV hProv, _In_bytecount_(size) const void *data, _In_ size_t size) const std::basic_string<_Elem, _Traits, _Ax> decrypt_str_md5(_In_ HCRYPTPROV hProv, _In_bytecount_(size) const void *data, _In_ size_t size) const
{ {
std::vector<_Elem, sanitizing_allocator<_Elem> > buf(std::move(decrypt_md5<_Elem, sanitizing_allocator<_Elem> >(hProv, data, size))); std::vector<_Elem, sanitizing_allocator<_Elem> > buf(std::move(decrypt_md5<_Elem, sanitizing_allocator<_Elem> >(hProv, data, size)));
@@ -539,6 +544,7 @@ namespace eap
/// \returns Decrypted string /// \returns Decrypted string
/// ///
template<class _Traits, class _Ax> template<class _Traits, class _Ax>
[[deprecated("Unencrypted hash allows dictionary attacks")]]
std::basic_string<wchar_t, _Traits, _Ax> decrypt_str_md5(_In_ HCRYPTPROV hProv, _In_bytecount_(size) const void *data, _In_ size_t size) const std::basic_string<wchar_t, _Traits, _Ax> decrypt_str_md5(_In_ HCRYPTPROV hProv, _In_bytecount_(size) const void *data, _In_ size_t size) const
{ {
winstd::sanitizing_string buf(std::move(decrypt_str_md5<char, std::char_traits<char>, sanitizing_allocator<char> >(hProv, data, size))); winstd::sanitizing_string buf(std::move(decrypt_str_md5<char, std::char_traits<char>, sanitizing_allocator<char> >(hProv, data, size)));
@@ -573,7 +579,7 @@ namespace eap
throw winstd::win_runtime_error(__FUNCTION__ " CryptAcquireContext failed."); throw winstd::win_runtime_error(__FUNCTION__ " CryptAcquireContext failed.");
// Decrypt data. // Decrypt data.
return std::move(decrypt_md5<unsigned char, winstd::sanitizing_allocator<unsigned char> >(cp, pDataIn, dwDataInSize)); return std::move(decrypt<unsigned char, winstd::sanitizing_allocator<unsigned char> >(cp, pDataIn, dwDataInSize));
#else #else
return sanitizing_blob(pDataIn, pDataIn + dwDataInSize); return sanitizing_blob(pDataIn, pDataIn + dwDataInSize);
#endif #endif
@@ -602,7 +608,7 @@ namespace eap
throw winstd::win_runtime_error(__FUNCTION__ " CryptAcquireContext failed."); throw winstd::win_runtime_error(__FUNCTION__ " CryptAcquireContext failed.");
// Decrypt data. // Decrypt data.
std::vector<unsigned char, winstd::sanitizing_allocator<unsigned char> > data(std::move(decrypt_md5<unsigned char, winstd::sanitizing_allocator<unsigned char> >(cp, pDataIn, dwDataInSize))); std::vector<unsigned char, winstd::sanitizing_allocator<unsigned char> > data(std::move(decrypt<unsigned char, winstd::sanitizing_allocator<unsigned char> >(cp, pDataIn, dwDataInSize)));
cursor_in cursor = { data.data(), data.data() + data.size() }; cursor_in cursor = { data.data(), data.data() + data.size() };
#else #else
@@ -637,7 +643,7 @@ namespace eap
throw winstd::win_runtime_error(__FUNCTION__ " CryptAcquireContext failed."); throw winstd::win_runtime_error(__FUNCTION__ " CryptAcquireContext failed.");
// Encrypt BLOB. // Encrypt BLOB.
std::vector<unsigned char> data_enc(std::move(encrypt_md5(cp, data.data(), data.size()))); std::vector<unsigned char> data_enc(std::move(encrypt(cp, data.data(), data.size())));
// Copy encrypted BLOB to output. // Copy encrypted BLOB to output.
*pdwDataOutSize = (DWORD)data_enc.size(); *pdwDataOutSize = (DWORD)data_enc.size();
@@ -685,7 +691,7 @@ namespace eap
throw winstd::win_runtime_error(__FUNCTION__ " CryptAcquireContext failed."); throw winstd::win_runtime_error(__FUNCTION__ " CryptAcquireContext failed.");
// Encrypt BLOB. // Encrypt BLOB.
std::vector<unsigned char> data_enc(std::move(encrypt_md5(cp, data.data(), data.size()))); std::vector<unsigned char> data_enc(std::move(encrypt(cp, data.data(), data.size())));
// Copy encrypted BLOB to output. // Copy encrypted BLOB to output.
*pdwDataOutSize = (DWORD)data_enc.size(); *pdwDataOutSize = (DWORD)data_enc.size();

View File

@@ -436,12 +436,12 @@ void eap::credentials_pass::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *p
default: default:
// Use default encryption method for all others (including unencrypted). // Use default encryption method for all others (including unencrypted).
vector<unsigned char> password_enc(std::move(m_module.encrypt_md5(cp, m_password))); vector<unsigned char> password_enc(std::move(m_module.encrypt(cp, m_password)));
com_obj<IXMLDOMElement> pXmlElPassword; com_obj<IXMLDOMElement> pXmlElPassword;
if (FAILED(hr = eapxml::put_element_base64(pDoc, pConfigRoot, bstr(L"Password"), namespace_eapmetadata, password_enc.data(), password_enc.size(), std::addressof(pXmlElPassword)))) if (FAILED(hr = eapxml::put_element_base64(pDoc, pConfigRoot, bstr(L"Password"), namespace_eapmetadata, password_enc.data(), password_enc.size(), std::addressof(pXmlElPassword))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <Password> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <Password> element.");
pXmlElPassword->setAttribute(bstr(L"encryption"), variant(_L(PRODUCT_NAME_STR))); pXmlElPassword->setAttribute(bstr(L"encryption"), variant(_L(PRODUCT_NAME_STR) _L(" v2")));
} }
} }
@@ -464,7 +464,7 @@ void eap::credentials_pass::load(_In_ IXMLDOMNode *pConfigRoot)
if (FAILED(eapxml::get_attrib_value(pXmlElPassword, bstr(L"encryption"), encryption))) if (FAILED(eapxml::get_attrib_value(pXmlElPassword, bstr(L"encryption"), encryption)))
encryption = NULL; encryption = NULL;
if (encryption && CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, encryption, encryption.length(), _L(PRODUCT_NAME_STR), -1, NULL, NULL, 0) == CSTR_EQUAL) { if (encryption && CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, encryption, encryption.length(), _L(PRODUCT_NAME_STR) _L(" v2"), -1, NULL, NULL, 0) == CSTR_EQUAL) {
// Decode Base64. // Decode Base64.
winstd::base64_dec dec; winstd::base64_dec dec;
bool is_last; bool is_last;
@@ -476,8 +476,23 @@ void eap::credentials_pass::load(_In_ IXMLDOMNode *pConfigRoot)
if (!cp.create(NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) if (!cp.create(NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
throw win_runtime_error(__FUNCTION__ " CryptAcquireContext failed."); throw win_runtime_error(__FUNCTION__ " CryptAcquireContext failed.");
m_password = m_module.decrypt_str_md5<char_traits<wchar_t>, sanitizing_allocator<wchar_t> >(cp, password_enc.data(), password_enc.size()); m_password = m_module.decrypt_str<char_traits<wchar_t>, sanitizing_allocator<wchar_t> >(cp, password_enc.data(), password_enc.size());
m_enc_alg = enc_alg_t::native; m_enc_alg = enc_alg_t::native;
} else if (encryption && CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, encryption, encryption.length(), _L(PRODUCT_NAME_STR), -1, NULL, NULL, 0) == CSTR_EQUAL) {
// Decode Base64.
winstd::base64_dec dec;
bool is_last;
vector<unsigned char> password_enc;
dec.decode(password_enc, is_last, (BSTR)password, password.length());
// Prepare cryptographics provider.
crypt_prov cp;
if (!cp.create(NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
throw win_runtime_error(__FUNCTION__ " CryptAcquireContext failed.");
#pragma warning(suppress: 4996) // Support for backward compatibility.
m_password = m_module.decrypt_str_md5<char_traits<wchar_t>, sanitizing_allocator<wchar_t> >(cp, password_enc.data(), password_enc.size());
m_enc_alg = enc_alg_t::native_v1;
} else if (encryption && CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, encryption, encryption.length(), _L("KPH"), -1, NULL, NULL, 0) == CSTR_EQUAL) { } else if (encryption && CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, encryption, encryption.length(), _L("KPH"), -1, NULL, NULL, 0) == CSTR_EQUAL) {
// Decrypt password. // Decrypt password.
sanitizing_string password_utf8(std::move(kph_decrypt<OLECHAR>(password))); sanitizing_string password_utf8(std::move(kph_decrypt<OLECHAR>(password)));

View File

@@ -67,6 +67,8 @@ wxTLSTunnelConfigWindow::wxTLSTunnelConfigWindow(eap::config_provider &prov, eap
this->SetSizer(sb_content); this->SetSizer(sb_content);
this->Layout(); this->Layout();
m_outer_identity->SetFocusFromKbd();
this->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(wxTLSTunnelConfigWindow::OnUpdateUI)); this->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(wxTLSTunnelConfigWindow::OnUpdateUI));
} }
@@ -135,9 +137,6 @@ wxTTLSConfigWindow::wxTTLSConfigWindow(eap::config_provider &prov, eap::config_m
wxEapHostConfigPanel *panel_eaphost = new wxEapHostConfigPanel(m_prov, m_cfg_eaphost, m_inner_type); wxEapHostConfigPanel *panel_eaphost = new wxEapHostConfigPanel(m_prov, m_cfg_eaphost, m_inner_type);
m_inner_type->AddPage(panel_eaphost, _("Other EAP methods...")); m_inner_type->AddPage(panel_eaphost, _("Other EAP methods..."));
#endif #endif
// m_inner_type->SetFocusFromKbd(); // This control steals mouse-wheel scrolling for itself
panel_pap->SetFocusFromKbd();
} }