From f39cb94ee5c86a31281dce98166960071972ffb2 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Tue, 23 Aug 2016 14:42:11 +0200 Subject: [PATCH] Server names can be Unicode now --- lib/TLS/include/Config.h | 352 ++-- lib/TLS/src/Config.cpp | 603 ++++--- lib/TLS/src/Method.cpp | 18 +- lib/TLS_UI/include/TLS_UI.h | 684 ++++---- lib/TLS_UI/res/wxTLS_UI.cpp | 364 ++-- lib/TLS_UI/res/wxTLS_UI.fbp | 3250 +++++++++++++++++------------------ lib/TLS_UI/src/TLS_UI.cpp | 1246 +++++++------- 7 files changed, 3255 insertions(+), 3262 deletions(-) diff --git a/lib/TLS/include/Config.h b/lib/TLS/include/Config.h index 4798702..737eae7 100644 --- a/lib/TLS/include/Config.h +++ b/lib/TLS/include/Config.h @@ -1,176 +1,176 @@ -/* - Copyright 2015-2016 Amebis - Copyright 2016 GÉANT - - This file is part of GÉANTLink. - - GÉANTLink is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - GÉANTLink is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GÉANTLink. If not, see . -*/ - -#include - -#include -#include // Must include after - -#include - -namespace eap -{ - /// - /// TLS configuration - /// - class config_method_tls; - - /// - /// Helper function to compile human-readable certificate name for UI display - /// - winstd::tstring get_cert_title(PCCERT_CONTEXT cert); -} - -#pragma once - -#include "Credentials.h" -#include "Method.h" -#include "TLS.h" - -#include "../../EAPBase/include/Config.h" - -#include - -#include - -#include -#include - - -namespace eap -{ - class config_method_tls : public config_method_with_cred - { - public: - /// - /// Constructs configuration - /// - /// \param[in] mod EAP module to use for global services - /// - config_method_tls(_In_ module &mod); - - /// - /// Copies configuration - /// - /// \param[in] other Configuration to copy from - /// - config_method_tls(_In_ const config_method_tls &other); - - /// - /// Moves configuration - /// - /// \param[in] other Configuration to move from - /// - config_method_tls(_Inout_ config_method_tls &&other); - - /// - /// Copies configuration - /// - /// \param[in] other Configuration to copy from - /// - /// \returns Reference to this object - /// - config_method_tls& operator=(_In_ const config_method_tls &other); - - /// - /// Moves configuration - /// - /// \param[in] other Configuration to move from - /// - /// \returns Reference to this object - /// - config_method_tls& operator=(_Inout_ config_method_tls &&other); - - /// - /// Clones configuration - /// - /// \returns Pointer to cloned configuration - /// - virtual config* clone() const; - - /// \name XML configuration management - /// @{ - - /// - /// Save to XML document - /// - /// \param[in] pDoc XML document - /// \param[in] pConfigRoot Suggested root element for saving - /// - virtual void save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot) const; - - /// - /// Load from XML document - /// - /// \param[in] pConfigRoot Root element for loading - /// - virtual void load(_In_ IXMLDOMNode *pConfigRoot); - - /// @} - - /// \name BLOB management - /// @{ - - /// - /// Packs a configuration - /// - /// \param[inout] cursor Memory cursor - /// - virtual void operator<<(_Inout_ cursor_out &cursor) const; - - /// - /// Returns packed size of a configuration - /// - /// \returns Size of data when packed (in bytes) - /// - virtual size_t get_pk_size() const; - - /// - /// Unpacks a configuration - /// - /// \param[inout] cursor Memory cursor - /// - virtual void operator>>(_Inout_ cursor_in &cursor); - - /// @} - - /// - /// Returns EAP method type of this configuration - /// - /// \returns `eap::type_tls` - /// - virtual winstd::eap_type_t get_method_id() const; - - /// - /// Adds CA to the list of trusted root CA's - /// - /// \sa [CertCreateCertificateContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376033.aspx) - /// - bool add_trusted_ca(_In_ DWORD dwCertEncodingType, _In_ const BYTE *pbCertEncoded, _In_ DWORD cbCertEncoded); - - public: - std::list m_trusted_root_ca; ///< Trusted root CAs - std::list m_server_names; ///< Acceptable authenticating server names - - // Following members are used for session resumptions. They are not exported/imported to XML. - sanitizing_blob m_session_id; ///< TLS session ID - tls_master_secret m_master_secret; ///< TLS master secret - }; -} +/* + Copyright 2015-2016 Amebis + Copyright 2016 GÉANT + + This file is part of GÉANTLink. + + GÉANTLink is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + GÉANTLink is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GÉANTLink. If not, see . +*/ + +#include + +#include +#include // Must include after + +#include + +namespace eap +{ + /// + /// TLS configuration + /// + class config_method_tls; + + /// + /// Helper function to compile human-readable certificate name for UI display + /// + winstd::tstring get_cert_title(PCCERT_CONTEXT cert); +} + +#pragma once + +#include "Credentials.h" +#include "Method.h" +#include "TLS.h" + +#include "../../EAPBase/include/Config.h" + +#include + +#include + +#include +#include + + +namespace eap +{ + class config_method_tls : public config_method_with_cred + { + public: + /// + /// Constructs configuration + /// + /// \param[in] mod EAP module to use for global services + /// + config_method_tls(_In_ module &mod); + + /// + /// Copies configuration + /// + /// \param[in] other Configuration to copy from + /// + config_method_tls(_In_ const config_method_tls &other); + + /// + /// Moves configuration + /// + /// \param[in] other Configuration to move from + /// + config_method_tls(_Inout_ config_method_tls &&other); + + /// + /// Copies configuration + /// + /// \param[in] other Configuration to copy from + /// + /// \returns Reference to this object + /// + config_method_tls& operator=(_In_ const config_method_tls &other); + + /// + /// Moves configuration + /// + /// \param[in] other Configuration to move from + /// + /// \returns Reference to this object + /// + config_method_tls& operator=(_Inout_ config_method_tls &&other); + + /// + /// Clones configuration + /// + /// \returns Pointer to cloned configuration + /// + virtual config* clone() const; + + /// \name XML configuration management + /// @{ + + /// + /// Save to XML document + /// + /// \param[in] pDoc XML document + /// \param[in] pConfigRoot Suggested root element for saving + /// + virtual void save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot) const; + + /// + /// Load from XML document + /// + /// \param[in] pConfigRoot Root element for loading + /// + virtual void load(_In_ IXMLDOMNode *pConfigRoot); + + /// @} + + /// \name BLOB management + /// @{ + + /// + /// Packs a configuration + /// + /// \param[inout] cursor Memory cursor + /// + virtual void operator<<(_Inout_ cursor_out &cursor) const; + + /// + /// Returns packed size of a configuration + /// + /// \returns Size of data when packed (in bytes) + /// + virtual size_t get_pk_size() const; + + /// + /// Unpacks a configuration + /// + /// \param[inout] cursor Memory cursor + /// + virtual void operator>>(_Inout_ cursor_in &cursor); + + /// @} + + /// + /// Returns EAP method type of this configuration + /// + /// \returns `eap::type_tls` + /// + virtual winstd::eap_type_t get_method_id() const; + + /// + /// Adds CA to the list of trusted root CA's + /// + /// \sa [CertCreateCertificateContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376033.aspx) + /// + bool add_trusted_ca(_In_ DWORD dwCertEncodingType, _In_ const BYTE *pbCertEncoded, _In_ DWORD cbCertEncoded); + + public: + std::list m_trusted_root_ca; ///< Trusted root CAs + std::list m_server_names; ///< Acceptable authenticating server names + + // Following members are used for session resumptions. They are not exported/imported to XML. + sanitizing_blob m_session_id; ///< TLS session ID + tls_master_secret m_master_secret; ///< TLS master secret + }; +} diff --git a/lib/TLS/src/Config.cpp b/lib/TLS/src/Config.cpp index cead6b3..1fcad42 100644 --- a/lib/TLS/src/Config.cpp +++ b/lib/TLS/src/Config.cpp @@ -1,305 +1,298 @@ -/* - Copyright 2015-2016 Amebis - Copyright 2016 GÉANT - - This file is part of GÉANTLink. - - GÉANTLink is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - GÉANTLink is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GÉANTLink. If not, see . -*/ - -#include "StdAfx.h" - -#pragma comment(lib, "Cryptui.lib") - -using namespace std; -using namespace winstd; - - -////////////////////////////////////////////////////////////////////// -// eap::get_cert_title -////////////////////////////////////////////////////////////////////// - -tstring eap::get_cert_title(PCCERT_CONTEXT cert) -{ - tstring name, str, issuer, title; - FILETIME ft; - SYSTEMTIME st; - - // Prepare certificate information - CertGetNameString(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, name); - title += name; - - FileTimeToLocalFileTime(&(cert->pCertInfo->NotBefore), &ft); - FileTimeToSystemTime(&ft, &st); - GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, str); - title += _T(", "); - title += str; - - FileTimeToLocalFileTime(&(cert->pCertInfo->NotAfter ), &ft); - FileTimeToSystemTime(&ft, &st); - GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, str); - title += _T('-'); - title += str; - - CertGetNameString(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, issuer); - if (name != issuer) { - title += _T(", "); - title += issuer; - } - - return title; -} - - -////////////////////////////////////////////////////////////////////// -// eap::config_method_tls -////////////////////////////////////////////////////////////////////// - -eap::config_method_tls::config_method_tls(_In_ module &mod) : config_method_with_cred(mod) -{ - m_preshared.reset(new credentials_tls(mod)); -} - - -eap::config_method_tls::config_method_tls(_In_ const config_method_tls &other) : - m_trusted_root_ca(other.m_trusted_root_ca), - m_server_names(other.m_server_names), - m_session_id(other.m_session_id), - m_master_secret(other.m_master_secret), - config_method_with_cred(other) -{ -} - - -eap::config_method_tls::config_method_tls(_Inout_ config_method_tls &&other) : - m_trusted_root_ca(std::move(other.m_trusted_root_ca)), - m_server_names(std::move(other.m_server_names)), - m_session_id(std::move(other.m_session_id)), - m_master_secret(std::move(other.m_master_secret)), - config_method_with_cred(std::move(other)) -{ -} - - -eap::config_method_tls& eap::config_method_tls::operator=(_In_ const config_method_tls &other) -{ - if (this != &other) { - (config_method_with_cred&)*this = other; - m_trusted_root_ca = other.m_trusted_root_ca; - m_server_names = other.m_server_names; - m_session_id = other.m_session_id; - m_master_secret = other.m_master_secret; - } - - return *this; -} - - -eap::config_method_tls& eap::config_method_tls::operator=(_Inout_ config_method_tls &&other) -{ - if (this != &other) { - (config_method_with_cred&&)*this = std::move(other); - m_trusted_root_ca = std::move(other.m_trusted_root_ca); - m_server_names = std::move(other.m_server_names); - m_session_id = std::move(other.m_session_id); - m_master_secret = std::move(other.m_master_secret); - } - - return *this; -} - - -eap::config* eap::config_method_tls::clone() const -{ - return new config_method_tls(*this); -} - - -void eap::config_method_tls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot) const -{ - assert(pDoc); - assert(pConfigRoot); - - config_method_with_cred::save(pDoc, pConfigRoot); - - const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata"); - HRESULT hr; - - // - com_obj pXmlElServerSideCredential; - if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ServerSideCredential"), bstr(L"ServerSideCredential"), bstrNamespace, &pXmlElServerSideCredential))) - throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); - - for (list::const_iterator i = m_trusted_root_ca.begin(), i_end = m_trusted_root_ca.end(); i != i_end; ++i) { - // - com_obj pXmlElCA; - if (FAILED(hr = eapxml::create_element(pDoc, bstr(L"CA"), bstrNamespace, &pXmlElCA))) - throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); - - // / - if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElCA, bstr(L"format"), bstrNamespace, bstr(L"PEM")))) - throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); - - // / - const cert_context &cc = *i; - if (FAILED(hr = eapxml::put_element_base64(pDoc, pXmlElCA, bstr(L"cert-data"), bstrNamespace, cc->pbCertEncoded, cc->cbCertEncoded))) - throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); - - if (FAILED(hr = pXmlElServerSideCredential->appendChild(pXmlElCA, NULL))) - throw com_runtime_error(hr, __FUNCTION__ " Error appending element."); - } - - // - for (list::const_iterator i = m_server_names.begin(), i_end = m_server_names.end(); i != i_end; ++i) { - wstring str; - MultiByteToWideChar(CP_UTF8, 0, i->c_str(), (int)i->length(), str); - if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElServerSideCredential, bstr(L"ServerName"), bstrNamespace, bstr(str)))) - throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); - } -} - - -void eap::config_method_tls::load(_In_ IXMLDOMNode *pConfigRoot) -{ - assert(pConfigRoot); - - config_method_with_cred::load(pConfigRoot); - - std::wstring xpath(eapxml::get_xpath(pConfigRoot)); - - m_trusted_root_ca.clear(); - m_server_names.clear(); - - // - com_obj pXmlElServerSideCredential; - if (SUCCEEDED(eapxml::select_element(pConfigRoot, bstr(L"eap-metadata:ServerSideCredential"), &pXmlElServerSideCredential))) { - std::wstring xpathServerSideCredential(xpath + L"/ServerSideCredential"); - - // - com_obj pXmlListCAs; - long lCACount = 0; - if (SUCCEEDED(eapxml::select_nodes(pXmlElServerSideCredential, bstr(L"eap-metadata:CA"), &pXmlListCAs)) && SUCCEEDED(pXmlListCAs->get_length(&lCACount))) { - for (long j = 0; j < lCACount; j++) { - // Load CA certificate. - com_obj pXmlElCA; - pXmlListCAs->get_item(j, &pXmlElCA); - bstr bstrFormat; - if (FAILED(eapxml::get_element_value(pXmlElCA, bstr(L"eap-metadata:format"), &bstrFormat))) { - // not specified. - continue; - } - - if (CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, bstrFormat, bstrFormat.length(), L"PEM", -1, NULL, NULL, 0) != CSTR_EQUAL) { - // Certificate must be PEM encoded. - continue; - } - - vector aData; - if (FAILED(eapxml::get_element_base64(pXmlElCA, bstr(L"eap-metadata:cert-data"), aData))) { - // Error reading element. - continue; - } - - add_trusted_ca(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, aData.data(), (DWORD)aData.size()); - } - - // Log loaded CA certificates. - list cert_names; - for (std::list::const_iterator cert = m_trusted_root_ca.cbegin(), cert_end = m_trusted_root_ca.cend(); cert != cert_end; ++cert) - cert_names.push_back(std::move(get_cert_title(*cert))); - m_module.log_config((xpathServerSideCredential + L"/CA").c_str(), cert_names); - } - - // - com_obj pXmlListServerIDs; - long lServerIDCount = 0; - if (SUCCEEDED(eapxml::select_nodes(pXmlElServerSideCredential, bstr(L"eap-metadata:ServerName"), &pXmlListServerIDs)) && SUCCEEDED(pXmlListServerIDs->get_length(&lServerIDCount))) { - for (long j = 0; j < lServerIDCount; j++) { - // Load server name (). - com_obj pXmlElServerID; - pXmlListServerIDs->get_item(j, &pXmlElServerID); - bstr bstrServerID; - pXmlElServerID->get_text(&bstrServerID); - - // Server names (FQDNs) are always ASCII. Hopefully. Convert them to UTF-8 anyway for consistent comparison. CP_ANSI varies. - string str; - WideCharToMultiByte(CP_UTF8, 0, bstrServerID, bstrServerID.length(), str, NULL, NULL); - - m_server_names.push_back(str); - } - - m_module.log_config((xpathServerSideCredential + L"/ServerName").c_str(), m_server_names); - } - } -} - - -void eap::config_method_tls::operator<<(_Inout_ cursor_out &cursor) const -{ - config_method_with_cred::operator<<(cursor); - cursor << m_trusted_root_ca; - cursor << m_server_names ; - cursor << m_session_id ; - cursor << m_master_secret ; -} - - -size_t eap::config_method_tls::get_pk_size() const -{ - return - config_method_with_cred::get_pk_size() + - pksizeof(m_trusted_root_ca) + - pksizeof(m_server_names ) + - pksizeof(m_session_id ) + - pksizeof(m_master_secret ); -} - - -void eap::config_method_tls::operator>>(_Inout_ cursor_in &cursor) -{ - config_method_with_cred::operator>>(cursor); - cursor >> m_trusted_root_ca; - cursor >> m_server_names ; - cursor >> m_session_id ; - cursor >> m_master_secret ; -} - - -eap_type_t eap::config_method_tls::get_method_id() const -{ - return eap_type_tls; -} - - -bool eap::config_method_tls::add_trusted_ca(_In_ DWORD dwCertEncodingType, _In_ const BYTE *pbCertEncoded, _In_ DWORD cbCertEncoded) -{ - cert_context cert; - if (!cert.create(dwCertEncodingType, pbCertEncoded, cbCertEncoded)) { - // Invalid or unsupported certificate. - return false; - } - - for (list::const_iterator i = m_trusted_root_ca.cbegin(), i_end = m_trusted_root_ca.cend();; ++i) { - if (i != i_end) { - if (*i == cert) { - // This certificate is already on the list. - return false; - } - } else { - // End of list reached. Append certificate. - m_trusted_root_ca.push_back(std::move(cert)); - return true; - } - } -} +/* + Copyright 2015-2016 Amebis + Copyright 2016 GÉANT + + This file is part of GÉANTLink. + + GÉANTLink is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + GÉANTLink is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GÉANTLink. If not, see . +*/ + +#include "StdAfx.h" + +#pragma comment(lib, "Cryptui.lib") + +using namespace std; +using namespace winstd; + + +////////////////////////////////////////////////////////////////////// +// eap::get_cert_title +////////////////////////////////////////////////////////////////////// + +tstring eap::get_cert_title(PCCERT_CONTEXT cert) +{ + tstring name, str, issuer, title; + FILETIME ft; + SYSTEMTIME st; + + // Prepare certificate information + CertGetNameString(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, name); + title += name; + + FileTimeToLocalFileTime(&(cert->pCertInfo->NotBefore), &ft); + FileTimeToSystemTime(&ft, &st); + GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, str); + title += _T(", "); + title += str; + + FileTimeToLocalFileTime(&(cert->pCertInfo->NotAfter ), &ft); + FileTimeToSystemTime(&ft, &st); + GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, str); + title += _T('-'); + title += str; + + CertGetNameString(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, issuer); + if (name != issuer) { + title += _T(", "); + title += issuer; + } + + return title; +} + + +////////////////////////////////////////////////////////////////////// +// eap::config_method_tls +////////////////////////////////////////////////////////////////////// + +eap::config_method_tls::config_method_tls(_In_ module &mod) : config_method_with_cred(mod) +{ + m_preshared.reset(new credentials_tls(mod)); +} + + +eap::config_method_tls::config_method_tls(_In_ const config_method_tls &other) : + m_trusted_root_ca(other.m_trusted_root_ca), + m_server_names(other.m_server_names), + m_session_id(other.m_session_id), + m_master_secret(other.m_master_secret), + config_method_with_cred(other) +{ +} + + +eap::config_method_tls::config_method_tls(_Inout_ config_method_tls &&other) : + m_trusted_root_ca(std::move(other.m_trusted_root_ca)), + m_server_names(std::move(other.m_server_names)), + m_session_id(std::move(other.m_session_id)), + m_master_secret(std::move(other.m_master_secret)), + config_method_with_cred(std::move(other)) +{ +} + + +eap::config_method_tls& eap::config_method_tls::operator=(_In_ const config_method_tls &other) +{ + if (this != &other) { + (config_method_with_cred&)*this = other; + m_trusted_root_ca = other.m_trusted_root_ca; + m_server_names = other.m_server_names; + m_session_id = other.m_session_id; + m_master_secret = other.m_master_secret; + } + + return *this; +} + + +eap::config_method_tls& eap::config_method_tls::operator=(_Inout_ config_method_tls &&other) +{ + if (this != &other) { + (config_method_with_cred&&)*this = std::move(other); + m_trusted_root_ca = std::move(other.m_trusted_root_ca); + m_server_names = std::move(other.m_server_names); + m_session_id = std::move(other.m_session_id); + m_master_secret = std::move(other.m_master_secret); + } + + return *this; +} + + +eap::config* eap::config_method_tls::clone() const +{ + return new config_method_tls(*this); +} + + +void eap::config_method_tls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot) const +{ + assert(pDoc); + assert(pConfigRoot); + + config_method_with_cred::save(pDoc, pConfigRoot); + + const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata"); + HRESULT hr; + + // + com_obj pXmlElServerSideCredential; + if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ServerSideCredential"), bstr(L"ServerSideCredential"), bstrNamespace, &pXmlElServerSideCredential))) + throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); + + for (list::const_iterator i = m_trusted_root_ca.begin(), i_end = m_trusted_root_ca.end(); i != i_end; ++i) { + // + com_obj pXmlElCA; + if (FAILED(hr = eapxml::create_element(pDoc, bstr(L"CA"), bstrNamespace, &pXmlElCA))) + throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); + + // / + if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElCA, bstr(L"format"), bstrNamespace, bstr(L"PEM")))) + throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); + + // / + const cert_context &cc = *i; + if (FAILED(hr = eapxml::put_element_base64(pDoc, pXmlElCA, bstr(L"cert-data"), bstrNamespace, cc->pbCertEncoded, cc->cbCertEncoded))) + throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); + + if (FAILED(hr = pXmlElServerSideCredential->appendChild(pXmlElCA, NULL))) + throw com_runtime_error(hr, __FUNCTION__ " Error appending element."); + } + + // + for (list::const_iterator i = m_server_names.begin(), i_end = m_server_names.end(); i != i_end; ++i) { + if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElServerSideCredential, bstr(L"ServerName"), bstrNamespace, bstr(*i)))) + throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); + } +} + + +void eap::config_method_tls::load(_In_ IXMLDOMNode *pConfigRoot) +{ + assert(pConfigRoot); + + config_method_with_cred::load(pConfigRoot); + + std::wstring xpath(eapxml::get_xpath(pConfigRoot)); + + m_trusted_root_ca.clear(); + m_server_names.clear(); + + // + com_obj pXmlElServerSideCredential; + if (SUCCEEDED(eapxml::select_element(pConfigRoot, bstr(L"eap-metadata:ServerSideCredential"), &pXmlElServerSideCredential))) { + std::wstring xpathServerSideCredential(xpath + L"/ServerSideCredential"); + + // + com_obj pXmlListCAs; + long lCACount = 0; + if (SUCCEEDED(eapxml::select_nodes(pXmlElServerSideCredential, bstr(L"eap-metadata:CA"), &pXmlListCAs)) && SUCCEEDED(pXmlListCAs->get_length(&lCACount))) { + for (long j = 0; j < lCACount; j++) { + // Load CA certificate. + com_obj pXmlElCA; + pXmlListCAs->get_item(j, &pXmlElCA); + bstr bstrFormat; + if (FAILED(eapxml::get_element_value(pXmlElCA, bstr(L"eap-metadata:format"), &bstrFormat))) { + // not specified. + continue; + } + + if (CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, bstrFormat, bstrFormat.length(), L"PEM", -1, NULL, NULL, 0) != CSTR_EQUAL) { + // Certificate must be PEM encoded. + continue; + } + + vector aData; + if (FAILED(eapxml::get_element_base64(pXmlElCA, bstr(L"eap-metadata:cert-data"), aData))) { + // Error reading element. + continue; + } + + add_trusted_ca(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, aData.data(), (DWORD)aData.size()); + } + + // Log loaded CA certificates. + list cert_names; + for (std::list::const_iterator cert = m_trusted_root_ca.cbegin(), cert_end = m_trusted_root_ca.cend(); cert != cert_end; ++cert) + cert_names.push_back(std::move(get_cert_title(*cert))); + m_module.log_config((xpathServerSideCredential + L"/CA").c_str(), cert_names); + } + + // + com_obj pXmlListServerIDs; + long lServerIDCount = 0; + if (SUCCEEDED(eapxml::select_nodes(pXmlElServerSideCredential, bstr(L"eap-metadata:ServerName"), &pXmlListServerIDs)) && SUCCEEDED(pXmlListServerIDs->get_length(&lServerIDCount))) { + for (long j = 0; j < lServerIDCount; j++) { + // Load server name (). + com_obj pXmlElServerID; + pXmlListServerIDs->get_item(j, &pXmlElServerID); + bstr bstrServerID; + pXmlElServerID->get_text(&bstrServerID); + m_server_names.push_back(wstring(bstrServerID)); + } + + m_module.log_config((xpathServerSideCredential + L"/ServerName").c_str(), m_server_names); + } + } +} + + +void eap::config_method_tls::operator<<(_Inout_ cursor_out &cursor) const +{ + config_method_with_cred::operator<<(cursor); + cursor << m_trusted_root_ca; + cursor << m_server_names ; + cursor << m_session_id ; + cursor << m_master_secret ; +} + + +size_t eap::config_method_tls::get_pk_size() const +{ + return + config_method_with_cred::get_pk_size() + + pksizeof(m_trusted_root_ca) + + pksizeof(m_server_names ) + + pksizeof(m_session_id ) + + pksizeof(m_master_secret ); +} + + +void eap::config_method_tls::operator>>(_Inout_ cursor_in &cursor) +{ + config_method_with_cred::operator>>(cursor); + cursor >> m_trusted_root_ca; + cursor >> m_server_names ; + cursor >> m_session_id ; + cursor >> m_master_secret ; +} + + +eap_type_t eap::config_method_tls::get_method_id() const +{ + return eap_type_tls; +} + + +bool eap::config_method_tls::add_trusted_ca(_In_ DWORD dwCertEncodingType, _In_ const BYTE *pbCertEncoded, _In_ DWORD cbCertEncoded) +{ + cert_context cert; + if (!cert.create(dwCertEncodingType, pbCertEncoded, cbCertEncoded)) { + // Invalid or unsupported certificate. + return false; + } + + for (list::const_iterator i = m_trusted_root_ca.cbegin(), i_end = m_trusted_root_ca.cend();; ++i) { + if (i != i_end) { + if (*i == cert) { + // This certificate is already on the list. + return false; + } + } else { + // End of list reached. Append certificate. + m_trusted_root_ca.push_back(std::move(cert)); + return true; + } + } +} diff --git a/lib/TLS/src/Method.cpp b/lib/TLS/src/Method.cpp index 24c807a..e737fe6 100644 --- a/lib/TLS/src/Method.cpp +++ b/lib/TLS/src/Method.cpp @@ -1166,8 +1166,8 @@ void eap::method_tls::verify_server_trust() const assert(!m_server_cert_chain.empty()); const cert_context &cert = m_server_cert_chain.front(); - string subj; - if (!CertGetNameStringA(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, subj)) + wstring subj; + if (!CertGetNameStringW(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, subj)) throw win_runtime_error(__FUNCTION__ " Error retrieving server's certificate subject name."); const config_provider &cfg_prov(m_cfg.m_providers.front()); @@ -1176,29 +1176,29 @@ void eap::method_tls::verify_server_trust() const if (!cfg_method->m_server_names.empty()) { // Check server name. - for (list::const_iterator s = cfg_method->m_server_names.cbegin(), s_end = cfg_method->m_server_names.cend();; ++s) { + for (list::const_iterator s = cfg_method->m_server_names.cbegin(), s_end = cfg_method->m_server_names.cend();; ++s) { if (s != s_end) { - const char + const wchar_t *a = s->c_str(), *b = subj.c_str(); size_t len_a = s->length(), len_b = subj.length(); - if (_stricmp(a, b) == 0 || // Direct match - a[0] == '*' && len_b + 1 >= len_a && _stricmp(a + 1, b + len_b - (len_a - 1)) == 0) // "*..." wildchar match + if (_wcsicmp(a, b) == 0 || // Direct match + a[0] == '*' && len_b + 1 >= len_a && _wcsicmp(a + 1, b + len_b - (len_a - 1)) == 0) // "*..." wildchar match { - m_module.log_event(&EAPMETHOD_TLS_SERVER_NAME_TRUSTED, event_data(subj), event_data::blank); + m_module.log_event(&EAPMETHOD_TLS_SERVER_NAME_TRUSTED1, event_data(subj), event_data::blank); break; } } else - throw win_runtime_error(ERROR_INVALID_DOMAINNAME, string_printf(__FUNCTION__ " Server name %s is not on the list of trusted server names.", subj.c_str()).c_str()); + throw win_runtime_error(ERROR_INVALID_DOMAINNAME, string_printf(__FUNCTION__ " Server name %ls is not on the list of trusted server names.", subj.c_str()).c_str()); } } if (cert->pCertInfo->Issuer.cbData == cert->pCertInfo->Subject.cbData && memcmp(cert->pCertInfo->Issuer.pbData, cert->pCertInfo->Subject.pbData, cert->pCertInfo->Issuer.cbData) == 0) - throw com_runtime_error(CRYPT_E_SELF_SIGNED, string_printf(__FUNCTION__ " Server is using a self-signed certificate %s. Cannot trust it.", subj.c_str()).c_str()); + throw com_runtime_error(CRYPT_E_SELF_SIGNED, string_printf(__FUNCTION__ " Server is using a self-signed certificate %ls. Cannot trust it.", subj.c_str()).c_str()); // Create temporary certificate store of our trusted root CAs. cert_store store; diff --git a/lib/TLS_UI/include/TLS_UI.h b/lib/TLS_UI/include/TLS_UI.h index f1db3fd..f23bc7a 100644 --- a/lib/TLS_UI/include/TLS_UI.h +++ b/lib/TLS_UI/include/TLS_UI.h @@ -1,342 +1,342 @@ -/* - Copyright 2015-2016 Amebis - Copyright 2016 GÉANT - - This file is part of GÉANTLink. - - GÉANTLink is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - GÉANTLink is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GÉANTLink. If not, see . -*/ - -#include "../../EAPBase_UI/include/EAP_UI.h" -#include "../../TLS/include/Config.h" -#include "../../TLS/include/Credentials.h" - -#include - -#include -#include - -#include -#include -#include // Must include after - -#include -#include - - -/// -/// Helper class for auto-destroyable certificates used in wxWidget's item containers -/// -class wxCertificateClientData; - -/// -/// Validator for host name -/// -class wxHostNameValidator; - -/// -/// Validator for FQDN -/// -class wxFQDNValidator; - -/// -/// Validator for FQDN lists -/// -class wxFQDNListValidator; - -/// -/// TLS credential panel -/// -class wxTLSCredentialsPanel; - -/// -/// TLS server trust configuration panel -/// -class wxTLSServerTrustPanel; - -/// -/// TLS credentials configuration panel -/// -typedef wxEAPCredentialsConfigPanel wxTLSCredentialsConfigPanel; - -/// -/// TLS configuration panel -/// -class wxTLSConfigPanel; - -#pragma once - -#include "../res/wxTLS_UI.h" - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - - -class wxCertificateClientData : public wxClientData -{ -public: - /// - /// Constructs client data object with existing handle - /// - wxCertificateClientData(PCCERT_CONTEXT cert); - - /// - /// Releases certificate handle and destructs the object - /// - virtual ~wxCertificateClientData(); - -public: - PCCERT_CONTEXT m_cert; ///< Certificate -}; - - -class wxHostNameValidator : public wxValidator -{ - wxDECLARE_DYNAMIC_CLASS(wxHostNameValidator); - wxDECLARE_NO_ASSIGN_CLASS(wxHostNameValidator); - -public: - /// - /// Construct the validator with a value to store data - /// - wxHostNameValidator(std::string *val = NULL); - - /// - /// Copy constructor - /// - wxHostNameValidator(const wxHostNameValidator &other); - - /// - /// Copies this validator - /// - virtual wxObject* Clone() const; - - /// - /// Validates the value - /// - virtual bool Validate(wxWindow *parent); - - /// - /// Transfers the value to the window - /// - virtual bool TransferToWindow(); - - /// - /// Transfers the value from the window - /// - virtual bool TransferFromWindow(); - - /// - /// Parses FQDN value - /// - static bool Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, std::string *val_out = NULL); - -protected: - std::string *m_val; ///< Pointer to variable to receive control's parsed value -}; - - -class wxFQDNValidator : public wxValidator -{ - wxDECLARE_DYNAMIC_CLASS(wxFQDNValidator); - wxDECLARE_NO_ASSIGN_CLASS(wxFQDNValidator); - -public: - /// - /// Construct the validator with a value to store data - /// - wxFQDNValidator(std::string *val = NULL); - - /// - /// Copy constructor - /// - wxFQDNValidator(const wxFQDNValidator &other); - - /// - /// Copies this validator - /// - virtual wxObject* Clone() const; - - /// - /// Validates the value - /// - virtual bool Validate(wxWindow *parent); - - /// - /// Transfers the value to the window - /// - virtual bool TransferToWindow(); - - /// - /// Transfers the value from the window - /// - virtual bool TransferFromWindow(); - - /// - /// Parses FQDN value - /// - static bool Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, std::string *val_out = NULL); - -protected: - std::string *m_val; ///< Pointer to variable to receive control's parsed value -}; - - -class wxFQDNListValidator : public wxValidator -{ - wxDECLARE_DYNAMIC_CLASS(wxFQDNListValidator); - wxDECLARE_NO_ASSIGN_CLASS(wxFQDNListValidator); - -public: - /// - /// Construct the validator with a value to store data - /// - wxFQDNListValidator(std::list *val = NULL); - - /// - /// Copy constructor - /// - wxFQDNListValidator(const wxFQDNListValidator &other); - - /// - /// Copies this validator - /// - virtual wxObject* Clone() const; - - /// - /// Validates the value - /// - virtual bool Validate(wxWindow *parent); - - /// - /// Transfers the value to the window - /// - virtual bool TransferToWindow(); - - /// - /// Transfers the value from the window - /// - virtual bool TransferFromWindow(); - - /// - /// Parses FQDN list value - /// - static bool Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, std::list *val_out = NULL); - -protected: - std::list *m_val; ///< Pointer to variable to receive control's parsed value -}; - - -class wxTLSCredentialsPanel : public wxEAPCredentialsPanelBase -{ -public: - /// - /// Constructs a configuration panel - /// - /// \param[in] prov Provider configuration data - /// \param[in] cfg Configuration data - /// \param[inout] cred Credentials data - /// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name. - /// \param[in] parent Parent window - /// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled. - /// - wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, eap::credentials_tls &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false); - -protected: - /// \cond internal - virtual bool TransferDataToWindow(); - virtual bool TransferDataFromWindow(); - virtual void OnUpdateUI(wxUpdateUIEvent& event); - /// \endcond - -protected: - winstd::library m_shell32; ///< shell32.dll resource library reference - wxIcon m_icon; ///< Panel icon -}; - - -class wxTLSServerTrustPanel : public wxEAPTLSServerTrustConfigPanelBase -{ -public: - /// - /// Constructs a configuration panel - /// - wxTLSServerTrustPanel(const eap::config_provider &prov, eap::config_method_tls &cfg, wxWindow* parent); - -protected: - /// \cond internal - virtual bool TransferDataToWindow(); - virtual bool TransferDataFromWindow(); - virtual void OnUpdateUI(wxUpdateUIEvent& event); - virtual void OnRootCADClick(wxCommandEvent& event); - virtual void OnRootCAAddStore(wxCommandEvent& event); - virtual void OnRootCAAddFile(wxCommandEvent& event); - virtual void OnRootCARemove(wxCommandEvent& event); - /// \endcond - - /// - /// Adds a certificate to the list of trusted root CA list - /// - /// \param[in] cert Certificate - /// - /// \returns - /// - \c true if certificate was added; - /// - \c false if duplicate found or an error occured. - /// - bool AddRootCA(PCCERT_CONTEXT cert); - -protected: - const eap::config_provider &m_prov; ///< EAP provider - eap::config_method_tls &m_cfg; ///< TLS configuration - winstd::library m_certmgr; ///< certmgr.dll resource library reference - wxIcon m_icon; ///< Panel icon - std::list m_server_names_val; ///< Acceptable authenticating server names -}; - - -class wxTLSConfigPanel : public wxPanel -{ -public: - /// - /// Constructs a configuration panel - /// - wxTLSConfigPanel(const eap::config_provider &prov, eap::config_method_tls &cfg, LPCTSTR pszCredTarget, wxWindow* parent); - - /// - /// Destructs the configuration panel - /// - virtual ~wxTLSConfigPanel(); - -protected: - /// \cond internal - virtual void OnInitDialog(wxInitDialogEvent& event); - virtual bool TransferDataFromWindow(); - /// \endcond - -protected: - const eap::config_provider &m_prov; ///< EAP provider - eap::config_method_tls &m_cfg; ///< TLS configuration - wxTLSServerTrustPanel *m_server_trust; ///< Server trust configuration panel - wxTLSCredentialsConfigPanel *m_credentials; ///< Credentials configuration panel -}; +/* + Copyright 2015-2016 Amebis + Copyright 2016 GÉANT + + This file is part of GÉANTLink. + + GÉANTLink is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + GÉANTLink is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GÉANTLink. If not, see . +*/ + +#include "../../EAPBase_UI/include/EAP_UI.h" +#include "../../TLS/include/Config.h" +#include "../../TLS/include/Credentials.h" + +#include + +#include +#include + +#include +#include +#include // Must include after + +#include +#include + + +/// +/// Helper class for auto-destroyable certificates used in wxWidget's item containers +/// +class wxCertificateClientData; + +/// +/// Validator for host name +/// +class wxHostNameValidator; + +/// +/// Validator for FQDN +/// +class wxFQDNValidator; + +/// +/// Validator for FQDN lists +/// +class wxFQDNListValidator; + +/// +/// TLS credential panel +/// +class wxTLSCredentialsPanel; + +/// +/// TLS server trust configuration panel +/// +class wxTLSServerTrustPanel; + +/// +/// TLS credentials configuration panel +/// +typedef wxEAPCredentialsConfigPanel wxTLSCredentialsConfigPanel; + +/// +/// TLS configuration panel +/// +class wxTLSConfigPanel; + +#pragma once + +#include "../res/wxTLS_UI.h" + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + + +class wxCertificateClientData : public wxClientData +{ +public: + /// + /// Constructs client data object with existing handle + /// + wxCertificateClientData(PCCERT_CONTEXT cert); + + /// + /// Releases certificate handle and destructs the object + /// + virtual ~wxCertificateClientData(); + +public: + PCCERT_CONTEXT m_cert; ///< Certificate +}; + + +class wxHostNameValidator : public wxValidator +{ + wxDECLARE_DYNAMIC_CLASS(wxHostNameValidator); + wxDECLARE_NO_ASSIGN_CLASS(wxHostNameValidator); + +public: + /// + /// Construct the validator with a value to store data + /// + wxHostNameValidator(std::wstring *val = NULL); + + /// + /// Copy constructor + /// + wxHostNameValidator(const wxHostNameValidator &other); + + /// + /// Copies this validator + /// + virtual wxObject* Clone() const; + + /// + /// Validates the value + /// + virtual bool Validate(wxWindow *parent); + + /// + /// Transfers the value to the window + /// + virtual bool TransferToWindow(); + + /// + /// Transfers the value from the window + /// + virtual bool TransferFromWindow(); + + /// + /// Parses FQDN value + /// + static bool Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, std::wstring *val_out = NULL); + +protected: + std::wstring *m_val; ///< Pointer to variable to receive control's parsed value +}; + + +class wxFQDNValidator : public wxValidator +{ + wxDECLARE_DYNAMIC_CLASS(wxFQDNValidator); + wxDECLARE_NO_ASSIGN_CLASS(wxFQDNValidator); + +public: + /// + /// Construct the validator with a value to store data + /// + wxFQDNValidator(std::wstring *val = NULL); + + /// + /// Copy constructor + /// + wxFQDNValidator(const wxFQDNValidator &other); + + /// + /// Copies this validator + /// + virtual wxObject* Clone() const; + + /// + /// Validates the value + /// + virtual bool Validate(wxWindow *parent); + + /// + /// Transfers the value to the window + /// + virtual bool TransferToWindow(); + + /// + /// Transfers the value from the window + /// + virtual bool TransferFromWindow(); + + /// + /// Parses FQDN value + /// + static bool Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, std::wstring *val_out = NULL); + +protected: + std::wstring *m_val; ///< Pointer to variable to receive control's parsed value +}; + + +class wxFQDNListValidator : public wxValidator +{ + wxDECLARE_DYNAMIC_CLASS(wxFQDNListValidator); + wxDECLARE_NO_ASSIGN_CLASS(wxFQDNListValidator); + +public: + /// + /// Construct the validator with a value to store data + /// + wxFQDNListValidator(std::list *val = NULL); + + /// + /// Copy constructor + /// + wxFQDNListValidator(const wxFQDNListValidator &other); + + /// + /// Copies this validator + /// + virtual wxObject* Clone() const; + + /// + /// Validates the value + /// + virtual bool Validate(wxWindow *parent); + + /// + /// Transfers the value to the window + /// + virtual bool TransferToWindow(); + + /// + /// Transfers the value from the window + /// + virtual bool TransferFromWindow(); + + /// + /// Parses FQDN list value + /// + static bool Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, std::list *val_out = NULL); + +protected: + std::list *m_val; ///< Pointer to variable to receive control's parsed value +}; + + +class wxTLSCredentialsPanel : public wxEAPCredentialsPanelBase +{ +public: + /// + /// Constructs a configuration panel + /// + /// \param[in] prov Provider configuration data + /// \param[in] cfg Configuration data + /// \param[inout] cred Credentials data + /// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name. + /// \param[in] parent Parent window + /// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled. + /// + wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, eap::credentials_tls &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false); + +protected: + /// \cond internal + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + virtual void OnUpdateUI(wxUpdateUIEvent& event); + /// \endcond + +protected: + winstd::library m_shell32; ///< shell32.dll resource library reference + wxIcon m_icon; ///< Panel icon +}; + + +class wxTLSServerTrustPanel : public wxEAPTLSServerTrustConfigPanelBase +{ +public: + /// + /// Constructs a configuration panel + /// + wxTLSServerTrustPanel(const eap::config_provider &prov, eap::config_method_tls &cfg, wxWindow* parent); + +protected: + /// \cond internal + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + virtual void OnUpdateUI(wxUpdateUIEvent& event); + virtual void OnRootCADClick(wxCommandEvent& event); + virtual void OnRootCAAddStore(wxCommandEvent& event); + virtual void OnRootCAAddFile(wxCommandEvent& event); + virtual void OnRootCARemove(wxCommandEvent& event); + /// \endcond + + /// + /// Adds a certificate to the list of trusted root CA list + /// + /// \param[in] cert Certificate + /// + /// \returns + /// - \c true if certificate was added; + /// - \c false if duplicate found or an error occured. + /// + bool AddRootCA(PCCERT_CONTEXT cert); + +protected: + const eap::config_provider &m_prov; ///< EAP provider + eap::config_method_tls &m_cfg; ///< TLS configuration + winstd::library m_certmgr; ///< certmgr.dll resource library reference + wxIcon m_icon; ///< Panel icon + std::list m_server_names_val; ///< Acceptable authenticating server names +}; + + +class wxTLSConfigPanel : public wxPanel +{ +public: + /// + /// Constructs a configuration panel + /// + wxTLSConfigPanel(const eap::config_provider &prov, eap::config_method_tls &cfg, LPCTSTR pszCredTarget, wxWindow* parent); + + /// + /// Destructs the configuration panel + /// + virtual ~wxTLSConfigPanel(); + +protected: + /// \cond internal + virtual void OnInitDialog(wxInitDialogEvent& event); + virtual bool TransferDataFromWindow(); + /// \endcond + +protected: + const eap::config_provider &m_prov; ///< EAP provider + eap::config_method_tls &m_cfg; ///< TLS configuration + wxTLSServerTrustPanel *m_server_trust; ///< Server trust configuration panel + wxTLSCredentialsConfigPanel *m_credentials; ///< Credentials configuration panel +}; diff --git a/lib/TLS_UI/res/wxTLS_UI.cpp b/lib/TLS_UI/res/wxTLS_UI.cpp index 87e2cf3..9228335 100644 --- a/lib/TLS_UI/res/wxTLS_UI.cpp +++ b/lib/TLS_UI/res/wxTLS_UI.cpp @@ -1,182 +1,182 @@ -/////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jun 17 2015) -// http://www.wxformbuilder.org/ -// -// PLEASE DO "NOT" EDIT THIS FILE! -/////////////////////////////////////////////////////////////////////////// - -#include - -#include "wxTLS_UI.h" - -/////////////////////////////////////////////////////////////////////////// - -wxEAPTLSServerTrustConfigPanelBase::wxEAPTLSServerTrustConfigPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) -{ - wxStaticBoxSizer* sb_server_trust; - sb_server_trust = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Server Trust") ), wxVERTICAL ); - - wxBoxSizer* sb_server_trust_horiz; - sb_server_trust_horiz = new wxBoxSizer( wxHORIZONTAL ); - - m_server_trust_icon = new wxStaticBitmap( sb_server_trust->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); - sb_server_trust_horiz->Add( m_server_trust_icon, 0, wxALL, 5 ); - - wxBoxSizer* sb_server_trust_vert; - sb_server_trust_vert = new wxBoxSizer( wxVERTICAL ); - - m_server_trust_label = new wxStaticText( sb_server_trust->GetStaticBox(), wxID_ANY, _("Describe the servers you trust to prevent credential interception in case of man-in-the-middle attacks."), wxDefaultPosition, wxDefaultSize, 0 ); - m_server_trust_label->Wrap( 446 ); - sb_server_trust_vert->Add( m_server_trust_label, 0, wxALL|wxEXPAND, 5 ); - - wxBoxSizer* sb_root_ca; - sb_root_ca = new wxBoxSizer( wxVERTICAL ); - - m_root_ca_lbl = new wxStaticText( sb_server_trust->GetStaticBox(), wxID_ANY, _("Acceptable Certificate Authorities:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_root_ca_lbl->Wrap( -1 ); - sb_root_ca->Add( m_root_ca_lbl, 0, wxEXPAND|wxBOTTOM, 5 ); - - m_root_ca = new wxListBox( sb_server_trust->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SORT ); - m_root_ca->SetToolTip( _("List of certificate authorities server's certificate must be issued by") ); - - sb_root_ca->Add( m_root_ca, 1, wxEXPAND|wxBOTTOM, 5 ); - - wxBoxSizer* sb_root_ca_btn; - sb_root_ca_btn = new wxBoxSizer( wxHORIZONTAL ); - - m_root_ca_add_store = new wxButton( sb_server_trust->GetStaticBox(), wxID_ANY, _("Add CA from Store..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_root_ca_add_store->SetToolTip( _("Adds a new certificate authority from the certificate store to the list") ); - - sb_root_ca_btn->Add( m_root_ca_add_store, 0, wxRIGHT, 5 ); - - m_root_ca_add_file = new wxButton( sb_server_trust->GetStaticBox(), wxID_ANY, _("Add CA from File..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_root_ca_add_file->SetToolTip( _("Adds a new certificate authority from the file to the list") ); - - sb_root_ca_btn->Add( m_root_ca_add_file, 0, wxRIGHT|wxLEFT, 5 ); - - m_root_ca_remove = new wxButton( sb_server_trust->GetStaticBox(), wxID_ANY, _("&Remove CA"), wxDefaultPosition, wxDefaultSize, 0 ); - m_root_ca_remove->Enable( false ); - m_root_ca_remove->SetToolTip( _("Removes selected certificate authorities from the list") ); - - sb_root_ca_btn->Add( m_root_ca_remove, 0, wxLEFT, 5 ); - - - sb_root_ca->Add( sb_root_ca_btn, 0, wxALIGN_RIGHT, 5 ); - - - sb_server_trust_vert->Add( sb_root_ca, 1, wxEXPAND|wxALL, 5 ); - - wxBoxSizer* sb_server_names; - sb_server_names = new wxBoxSizer( wxVERTICAL ); - - m_server_names_label = new wxStaticText( sb_server_trust->GetStaticBox(), wxID_ANY, _("Acceptable server &names:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_server_names_label->Wrap( -1 ); - sb_server_names->Add( m_server_names_label, 0, wxBOTTOM, 5 ); - - m_server_names = new wxTextCtrl( sb_server_trust->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_server_names->SetToolTip( _("A semicolon delimited list of acceptable server FQDN names; blank to skip name check; \"*\" wildchar allowed") ); - - sb_server_names->Add( m_server_names, 0, wxEXPAND|wxBOTTOM, 5 ); - - m_server_names_note = new wxStaticText( sb_server_trust->GetStaticBox(), wxID_ANY, _("(Example: foo.bar.com;*.domain.org)"), wxDefaultPosition, wxDefaultSize, 0 ); - m_server_names_note->Wrap( -1 ); - sb_server_names->Add( m_server_names_note, 0, wxALIGN_RIGHT, 5 ); - - - sb_server_trust_vert->Add( sb_server_names, 0, wxEXPAND|wxALL, 5 ); - - - sb_server_trust_horiz->Add( sb_server_trust_vert, 1, wxEXPAND, 5 ); - - - sb_server_trust->Add( sb_server_trust_horiz, 1, wxEXPAND, 5 ); - - - this->SetSizer( sb_server_trust ); - this->Layout(); - - // Connect Events - this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnUpdateUI ) ); - m_root_ca->Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCADClick ), NULL, this ); - m_root_ca_add_store->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCAAddStore ), NULL, this ); - m_root_ca_add_file->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCAAddFile ), NULL, this ); - m_root_ca_remove->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCARemove ), NULL, this ); -} - -wxEAPTLSServerTrustConfigPanelBase::~wxEAPTLSServerTrustConfigPanelBase() -{ - // Disconnect Events - this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnUpdateUI ) ); - m_root_ca->Disconnect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCADClick ), NULL, this ); - m_root_ca_add_store->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCAAddStore ), NULL, this ); - m_root_ca_add_file->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCAAddFile ), NULL, this ); - m_root_ca_remove->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCARemove ), NULL, this ); - -} - -wxTLSCredentialsPanelBase::wxTLSCredentialsPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) -{ - wxStaticBoxSizer* sb_credentials; - sb_credentials = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("TLS Client Certificate") ), wxVERTICAL ); - - wxBoxSizer* sb_credentials_horiz; - sb_credentials_horiz = new wxBoxSizer( wxHORIZONTAL ); - - m_credentials_icon = new wxStaticBitmap( sb_credentials->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); - sb_credentials_horiz->Add( m_credentials_icon, 0, wxALL, 5 ); - - wxBoxSizer* sb_credentials_vert; - sb_credentials_vert = new wxBoxSizer( wxVERTICAL ); - - m_credentials_label = new wxStaticText( sb_credentials->GetStaticBox(), wxID_ANY, _("Please select your client certificate to use for authentication."), wxDefaultPosition, wxDefaultSize, 0 ); - m_credentials_label->Wrap( 446 ); - sb_credentials_vert->Add( m_credentials_label, 0, wxALL|wxEXPAND, 5 ); - - wxBoxSizer* sb_cert_radio; - sb_cert_radio = new wxBoxSizer( wxVERTICAL ); - - m_cert_none = new wxRadioButton( sb_credentials->GetStaticBox(), wxID_ANY, _("Co&nnect without providing a client certificate"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); - m_cert_none->SetToolTip( _("Select if your server does not require you to provide a client certificate") ); - - sb_cert_radio->Add( m_cert_none, 1, wxEXPAND, 5 ); - - wxBoxSizer* sb_cert_select; - sb_cert_select = new wxBoxSizer( wxHORIZONTAL ); - - m_cert_select = new wxRadioButton( sb_credentials->GetStaticBox(), wxID_ANY, _("Use the following &certificate:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_cert_select->SetToolTip( _("Select if you need to provide a client certificate when connecting") ); - - sb_cert_select->Add( m_cert_select, 0, wxEXPAND, 5 ); - - wxArrayString m_cert_select_valChoices; - m_cert_select_val = new wxChoice( sb_credentials->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_cert_select_valChoices, wxCB_SORT ); - m_cert_select_val->SetSelection( 0 ); - m_cert_select_val->SetToolTip( _("Client certificate to use for authentication") ); - - sb_cert_select->Add( m_cert_select_val, 1, wxEXPAND, 5 ); - - - sb_cert_radio->Add( sb_cert_select, 1, wxEXPAND, 5 ); - - - sb_credentials_vert->Add( sb_cert_radio, 0, wxEXPAND|wxALL, 5 ); - - m_remember = new wxCheckBox( sb_credentials->GetStaticBox(), wxID_ANY, _("&Remember"), wxDefaultPosition, wxDefaultSize, 0 ); - m_remember->SetHelpText( _("Check if you would like to save certificate selection") ); - - sb_credentials_vert->Add( m_remember, 0, wxALL|wxEXPAND, 5 ); - - - sb_credentials_horiz->Add( sb_credentials_vert, 1, wxEXPAND, 5 ); - - - sb_credentials->Add( sb_credentials_horiz, 0, wxEXPAND, 5 ); - - - this->SetSizer( sb_credentials ); - this->Layout(); -} - -wxTLSCredentialsPanelBase::~wxTLSCredentialsPanelBase() -{ -} +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Jun 17 2015) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include + +#include "wxTLS_UI.h" + +/////////////////////////////////////////////////////////////////////////// + +wxEAPTLSServerTrustConfigPanelBase::wxEAPTLSServerTrustConfigPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) +{ + wxStaticBoxSizer* sb_server_trust; + sb_server_trust = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Server Trust") ), wxVERTICAL ); + + wxBoxSizer* sb_server_trust_horiz; + sb_server_trust_horiz = new wxBoxSizer( wxHORIZONTAL ); + + m_server_trust_icon = new wxStaticBitmap( sb_server_trust->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); + sb_server_trust_horiz->Add( m_server_trust_icon, 0, wxALL, 5 ); + + wxBoxSizer* sb_server_trust_vert; + sb_server_trust_vert = new wxBoxSizer( wxVERTICAL ); + + m_server_trust_label = new wxStaticText( sb_server_trust->GetStaticBox(), wxID_ANY, _("Describe the servers you trust to prevent credential interception in case of man-in-the-middle attacks."), wxDefaultPosition, wxDefaultSize, 0 ); + m_server_trust_label->Wrap( 446 ); + sb_server_trust_vert->Add( m_server_trust_label, 0, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* sb_root_ca; + sb_root_ca = new wxBoxSizer( wxVERTICAL ); + + m_root_ca_lbl = new wxStaticText( sb_server_trust->GetStaticBox(), wxID_ANY, _("Acceptable Certificate Authorities:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_root_ca_lbl->Wrap( -1 ); + sb_root_ca->Add( m_root_ca_lbl, 0, wxEXPAND|wxBOTTOM, 5 ); + + m_root_ca = new wxListBox( sb_server_trust->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SORT ); + m_root_ca->SetToolTip( _("List of certificate authorities server's certificate must be issued by") ); + + sb_root_ca->Add( m_root_ca, 1, wxEXPAND|wxBOTTOM, 5 ); + + wxBoxSizer* sb_root_ca_btn; + sb_root_ca_btn = new wxBoxSizer( wxHORIZONTAL ); + + m_root_ca_add_store = new wxButton( sb_server_trust->GetStaticBox(), wxID_ANY, _("Add CA from Store..."), wxDefaultPosition, wxDefaultSize, 0 ); + m_root_ca_add_store->SetToolTip( _("Adds a new certificate authority from the certificate store to the list") ); + + sb_root_ca_btn->Add( m_root_ca_add_store, 0, wxRIGHT, 5 ); + + m_root_ca_add_file = new wxButton( sb_server_trust->GetStaticBox(), wxID_ANY, _("Add CA from File..."), wxDefaultPosition, wxDefaultSize, 0 ); + m_root_ca_add_file->SetToolTip( _("Adds a new certificate authority from the file to the list") ); + + sb_root_ca_btn->Add( m_root_ca_add_file, 0, wxRIGHT|wxLEFT, 5 ); + + m_root_ca_remove = new wxButton( sb_server_trust->GetStaticBox(), wxID_ANY, _("&Remove CA"), wxDefaultPosition, wxDefaultSize, 0 ); + m_root_ca_remove->Enable( false ); + m_root_ca_remove->SetToolTip( _("Removes selected certificate authorities from the list") ); + + sb_root_ca_btn->Add( m_root_ca_remove, 0, wxLEFT, 5 ); + + + sb_root_ca->Add( sb_root_ca_btn, 0, wxALIGN_RIGHT, 5 ); + + + sb_server_trust_vert->Add( sb_root_ca, 1, wxEXPAND|wxALL, 5 ); + + wxBoxSizer* sb_server_names; + sb_server_names = new wxBoxSizer( wxVERTICAL ); + + m_server_names_label = new wxStaticText( sb_server_trust->GetStaticBox(), wxID_ANY, _("Acceptable server &names:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_server_names_label->Wrap( -1 ); + sb_server_names->Add( m_server_names_label, 0, wxBOTTOM, 5 ); + + m_server_names = new wxTextCtrl( sb_server_trust->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_server_names->SetToolTip( _("A semicolon delimited list of acceptable server FQDN names; blank to skip name check; \"*\" wildchar allowed; Unicode characters allowed") ); + + sb_server_names->Add( m_server_names, 0, wxEXPAND|wxBOTTOM, 5 ); + + m_server_names_note = new wxStaticText( sb_server_trust->GetStaticBox(), wxID_ANY, _("(Example: foo.bar.com;*.domain.org)"), wxDefaultPosition, wxDefaultSize, 0 ); + m_server_names_note->Wrap( -1 ); + sb_server_names->Add( m_server_names_note, 0, wxALIGN_RIGHT, 5 ); + + + sb_server_trust_vert->Add( sb_server_names, 0, wxEXPAND|wxALL, 5 ); + + + sb_server_trust_horiz->Add( sb_server_trust_vert, 1, wxEXPAND, 5 ); + + + sb_server_trust->Add( sb_server_trust_horiz, 1, wxEXPAND, 5 ); + + + this->SetSizer( sb_server_trust ); + this->Layout(); + + // Connect Events + this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnUpdateUI ) ); + m_root_ca->Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCADClick ), NULL, this ); + m_root_ca_add_store->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCAAddStore ), NULL, this ); + m_root_ca_add_file->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCAAddFile ), NULL, this ); + m_root_ca_remove->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCARemove ), NULL, this ); +} + +wxEAPTLSServerTrustConfigPanelBase::~wxEAPTLSServerTrustConfigPanelBase() +{ + // Disconnect Events + this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnUpdateUI ) ); + m_root_ca->Disconnect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCADClick ), NULL, this ); + m_root_ca_add_store->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCAAddStore ), NULL, this ); + m_root_ca_add_file->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCAAddFile ), NULL, this ); + m_root_ca_remove->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPTLSServerTrustConfigPanelBase::OnRootCARemove ), NULL, this ); + +} + +wxTLSCredentialsPanelBase::wxTLSCredentialsPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) +{ + wxStaticBoxSizer* sb_credentials; + sb_credentials = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("TLS Client Certificate") ), wxVERTICAL ); + + wxBoxSizer* sb_credentials_horiz; + sb_credentials_horiz = new wxBoxSizer( wxHORIZONTAL ); + + m_credentials_icon = new wxStaticBitmap( sb_credentials->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); + sb_credentials_horiz->Add( m_credentials_icon, 0, wxALL, 5 ); + + wxBoxSizer* sb_credentials_vert; + sb_credentials_vert = new wxBoxSizer( wxVERTICAL ); + + m_credentials_label = new wxStaticText( sb_credentials->GetStaticBox(), wxID_ANY, _("Please select your client certificate to use for authentication."), wxDefaultPosition, wxDefaultSize, 0 ); + m_credentials_label->Wrap( 446 ); + sb_credentials_vert->Add( m_credentials_label, 0, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* sb_cert_radio; + sb_cert_radio = new wxBoxSizer( wxVERTICAL ); + + m_cert_none = new wxRadioButton( sb_credentials->GetStaticBox(), wxID_ANY, _("Co&nnect without providing a client certificate"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); + m_cert_none->SetToolTip( _("Select if your server does not require you to provide a client certificate") ); + + sb_cert_radio->Add( m_cert_none, 1, wxEXPAND, 5 ); + + wxBoxSizer* sb_cert_select; + sb_cert_select = new wxBoxSizer( wxHORIZONTAL ); + + m_cert_select = new wxRadioButton( sb_credentials->GetStaticBox(), wxID_ANY, _("Use the following &certificate:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_cert_select->SetToolTip( _("Select if you need to provide a client certificate when connecting") ); + + sb_cert_select->Add( m_cert_select, 0, wxEXPAND, 5 ); + + wxArrayString m_cert_select_valChoices; + m_cert_select_val = new wxChoice( sb_credentials->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_cert_select_valChoices, wxCB_SORT ); + m_cert_select_val->SetSelection( 0 ); + m_cert_select_val->SetToolTip( _("Client certificate to use for authentication") ); + + sb_cert_select->Add( m_cert_select_val, 1, wxEXPAND, 5 ); + + + sb_cert_radio->Add( sb_cert_select, 1, wxEXPAND, 5 ); + + + sb_credentials_vert->Add( sb_cert_radio, 0, wxEXPAND|wxALL, 5 ); + + m_remember = new wxCheckBox( sb_credentials->GetStaticBox(), wxID_ANY, _("&Remember"), wxDefaultPosition, wxDefaultSize, 0 ); + m_remember->SetHelpText( _("Check if you would like to save certificate selection") ); + + sb_credentials_vert->Add( m_remember, 0, wxALL|wxEXPAND, 5 ); + + + sb_credentials_horiz->Add( sb_credentials_vert, 1, wxEXPAND, 5 ); + + + sb_credentials->Add( sb_credentials_horiz, 0, wxEXPAND, 5 ); + + + this->SetSizer( sb_credentials ); + this->Layout(); +} + +wxTLSCredentialsPanelBase::~wxTLSCredentialsPanelBase() +{ +} diff --git a/lib/TLS_UI/res/wxTLS_UI.fbp b/lib/TLS_UI/res/wxTLS_UI.fbp index dfeba30..252438a 100644 --- a/lib/TLS_UI/res/wxTLS_UI.fbp +++ b/lib/TLS_UI/res/wxTLS_UI.fbp @@ -1,1625 +1,1625 @@ - - - - - ; - C++ - 1 - source_name - 0 - 0 - . - UTF-8 - connect - wxTLS_UI - 1000 - none - 1 - wxTLS_UI - - . - #include <StdAfx.h> - 1 - 1 - 1 - 1 - UI - 1 - 1 - - 0 - wxAUI_MGR_DEFAULT - - - 1 - 1 - impl_virtual - - - 0 - wxID_ANY - - - wxEAPTLSServerTrustConfigPanelBase - - 500,-1 - - - - - wxTAB_TRAVERSAL - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OnUpdateUI - - wxID_ANY - Server Trust - - sb_server_trust - wxVERTICAL - none - - - 5 - wxEXPAND - 1 - - - sb_server_trust_horiz - wxHORIZONTAL - none - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - Load From Icon Resource; ; [32; 32] - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_server_trust_icon - 1 - - - protected - 1 - - Resizable - 1 - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND - 1 - - - sb_server_trust_vert - wxVERTICAL - none - - 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Describe the servers you trust to prevent credential interception in case of man-in-the-middle attacks. - - 0 - - - 0 - - 1 - m_server_trust_label - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - 446 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxALL - 1 - - - sb_root_ca - wxVERTICAL - none - - 5 - wxEXPAND|wxBOTTOM - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Acceptable Certificate Authorities: - - 0 - - - 0 - - 1 - m_root_ca_lbl - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxBOTTOM - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_root_ca - 1 - - - protected - 1 - - Resizable - 1 - - wxLB_SORT - - 0 - List of certificate authorities server's certificate must be issued by - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - OnRootCADClick - - - - - - - - - - - - - - - - - 5 - wxALIGN_RIGHT - 0 - - - sb_root_ca_btn - wxHORIZONTAL - none - - 5 - wxRIGHT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Add CA from Store... - - 0 - - - 0 - - 1 - m_root_ca_add_store - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Adds a new certificate authority from the certificate store to the list - - wxFILTER_NONE - wxDefaultValidator - - - - - OnRootCAAddStore - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Add CA from File... - - 0 - - - 0 - - 1 - m_root_ca_add_file - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Adds a new certificate authority from the file to the list - - wxFILTER_NONE - wxDefaultValidator - - - - - OnRootCAAddFile - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 0 - - 1 - - 0 - 0 - wxID_ANY - &Remove CA - - 0 - - - 0 - - 1 - m_root_ca_remove - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Removes selected certificate authorities from the list - - wxFILTER_NONE - wxDefaultValidator - - - - - OnRootCARemove - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxALL - 0 - - - sb_server_names - wxVERTICAL - none - - 5 - wxBOTTOM - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Acceptable server &names: - - 0 - - - 0 - - 1 - m_server_names_label - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxBOTTOM - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - - 0 - - 1 - m_server_names - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - A semicolon delimited list of acceptable server FQDN names; blank to skip name check; "*" wildchar allowed - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_RIGHT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - (Example: foo.bar.com;*.domain.org) - - 0 - - - 0 - - 1 - m_server_names_note - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - wxAUI_MGR_DEFAULT - - - 1 - 1 - impl_virtual - - - 0 - wxID_ANY - - - wxTLSCredentialsPanelBase - - 500,-1 - - - - - wxTAB_TRAVERSAL - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - wxID_ANY - TLS Client Certificate - - sb_credentials - wxVERTICAL - none - - - 5 - wxEXPAND - 0 - - - sb_credentials_horiz - wxHORIZONTAL - none - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - Load From Icon Resource; ; [32; 32] - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_credentials_icon - 1 - - - protected - 1 - - Resizable - 1 - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND - 1 - - - sb_credentials_vert - wxVERTICAL - none - - 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Please select your client certificate to use for authentication. - - 0 - - - 0 - - 1 - m_credentials_label - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - 446 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxALL - 0 - - - sb_cert_radio - wxVERTICAL - none - - 5 - wxEXPAND - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Co&nnect without providing a client certificate - - 0 - - - 0 - - 1 - m_cert_none - 1 - - - protected - 1 - - Resizable - 1 - - wxRB_GROUP - - 0 - Select if your server does not require you to provide a client certificate - - wxFILTER_NONE - wxDefaultValidator - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND - 1 - - - sb_cert_select - wxHORIZONTAL - none - - 5 - wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Use the following &certificate: - - 0 - - - 0 - - 1 - m_cert_select - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Select if you need to provide a client certificate when connecting - - wxFILTER_NONE - wxDefaultValidator - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_cert_select_val - 1 - - - protected - 1 - - Resizable - 0 - 1 - - wxCB_SORT - ; - 0 - Client certificate to use for authentication - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 0 - 1 - Check if you would like to save certificate selection - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - &Remember - - 0 - - - 0 - - 1 - m_remember - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + ; + C++ + 1 + source_name + 0 + 0 + . + UTF-8 + connect + wxTLS_UI + 1000 + none + 1 + wxTLS_UI + + . + #include <StdAfx.h> + 1 + 1 + 1 + 1 + UI + 1 + 1 + + 0 + wxAUI_MGR_DEFAULT + + + 1 + 1 + impl_virtual + + + 0 + wxID_ANY + + + wxEAPTLSServerTrustConfigPanelBase + + 500,-1 + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnUpdateUI + + wxID_ANY + Server Trust + + sb_server_trust + wxVERTICAL + none + + + 5 + wxEXPAND + 1 + + + sb_server_trust_horiz + wxHORIZONTAL + none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + Load From Icon Resource; ; [32; 32] + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_server_trust_icon + 1 + + + protected + 1 + + Resizable + 1 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + sb_server_trust_vert + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Describe the servers you trust to prevent credential interception in case of man-in-the-middle attacks. + + 0 + + + 0 + + 1 + m_server_trust_label + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + 446 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 1 + + + sb_root_ca + wxVERTICAL + none + + 5 + wxEXPAND|wxBOTTOM + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Acceptable Certificate Authorities: + + 0 + + + 0 + + 1 + m_root_ca_lbl + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_root_ca + 1 + + + protected + 1 + + Resizable + 1 + + wxLB_SORT + + 0 + List of certificate authorities server's certificate must be issued by + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + OnRootCADClick + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + + sb_root_ca_btn + wxHORIZONTAL + none + + 5 + wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Add CA from Store... + + 0 + + + 0 + + 1 + m_root_ca_add_store + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Adds a new certificate authority from the certificate store to the list + + wxFILTER_NONE + wxDefaultValidator + + + + + OnRootCAAddStore + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Add CA from File... + + 0 + + + 0 + + 1 + m_root_ca_add_file + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Adds a new certificate authority from the file to the list + + wxFILTER_NONE + wxDefaultValidator + + + + + OnRootCAAddFile + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 0 + + 1 + + 0 + 0 + wxID_ANY + &Remove CA + + 0 + + + 0 + + 1 + m_root_ca_remove + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Removes selected certificate authorities from the list + + wxFILTER_NONE + wxDefaultValidator + + + + + OnRootCARemove + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + + sb_server_names + wxVERTICAL + none + + 5 + wxBOTTOM + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Acceptable server &names: + + 0 + + + 0 + + 1 + m_server_names_label + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_server_names + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + A semicolon delimited list of acceptable server FQDN names; blank to skip name check; "*" wildchar allowed; Unicode characters allowed + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + (Example: foo.bar.com;*.domain.org) + + 0 + + + 0 + + 1 + m_server_names_note + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + wxAUI_MGR_DEFAULT + + + 1 + 1 + impl_virtual + + + 0 + wxID_ANY + + + wxTLSCredentialsPanelBase + + 500,-1 + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wxID_ANY + TLS Client Certificate + + sb_credentials + wxVERTICAL + none + + + 5 + wxEXPAND + 0 + + + sb_credentials_horiz + wxHORIZONTAL + none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + Load From Icon Resource; ; [32; 32] + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_credentials_icon + 1 + + + protected + 1 + + Resizable + 1 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + sb_credentials_vert + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Please select your client certificate to use for authentication. + + 0 + + + 0 + + 1 + m_credentials_label + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + 446 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + + sb_cert_radio + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Co&nnect without providing a client certificate + + 0 + + + 0 + + 1 + m_cert_none + 1 + + + protected + 1 + + Resizable + 1 + + wxRB_GROUP + + 0 + Select if your server does not require you to provide a client certificate + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + sb_cert_select + wxHORIZONTAL + none + + 5 + wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Use the following &certificate: + + 0 + + + 0 + + 1 + m_cert_select + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Select if you need to provide a client certificate when connecting + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_cert_select_val + 1 + + + protected + 1 + + Resizable + 0 + 1 + + wxCB_SORT + ; + 0 + Client certificate to use for authentication + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + Check if you would like to save certificate selection + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + &Remember + + 0 + + + 0 + + 1 + m_remember + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/TLS_UI/src/TLS_UI.cpp b/lib/TLS_UI/src/TLS_UI.cpp index f9f63c6..300988a 100644 --- a/lib/TLS_UI/src/TLS_UI.cpp +++ b/lib/TLS_UI/src/TLS_UI.cpp @@ -1,623 +1,623 @@ -/* - Copyright 2015-2016 Amebis - Copyright 2016 GÉANT - - This file is part of GÉANTLink. - - GÉANTLink is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - GÉANTLink is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GÉANTLink. If not, see . -*/ - -#include "StdAfx.h" - -#pragma comment(lib, "Crypt32.lib") - - -////////////////////////////////////////////////////////////////////// -// wxCertificateClientData -////////////////////////////////////////////////////////////////////// - -wxCertificateClientData::wxCertificateClientData(PCCERT_CONTEXT cert) : m_cert(cert) -{ -} - - -wxCertificateClientData::~wxCertificateClientData() -{ - if (m_cert) - CertFreeCertificateContext(m_cert); -} - - -////////////////////////////////////////////////////////////////////// -// wxHostNameValidator -////////////////////////////////////////////////////////////////////// - -wxIMPLEMENT_DYNAMIC_CLASS(wxHostNameValidator, wxValidator); - - -wxHostNameValidator::wxHostNameValidator(std::string *val) : - m_val(val), - wxValidator() -{ -} - - -wxHostNameValidator::wxHostNameValidator(const wxHostNameValidator &other) : - m_val(other.m_val), - wxValidator(other) -{ -} - - -wxObject* wxHostNameValidator::Clone() const -{ - return new wxHostNameValidator(*this); -} - - -bool wxHostNameValidator::Validate(wxWindow *parent) -{ - wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); - wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); - if (!ctrl->IsEnabled()) return true; - - wxString val(ctrl->GetValue()); - return Parse(val, 0, val.Length(), ctrl, parent); -} - - -bool wxHostNameValidator::TransferToWindow() -{ - wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); - - if (m_val) - ((wxTextCtrl*)GetWindow())->SetValue(*m_val); - - return true; -} - - -bool wxHostNameValidator::TransferFromWindow() -{ - wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); - wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); - - wxString val(ctrl->GetValue()); - return Parse(val, 0, val.Length(), ctrl, NULL, m_val); -} - - -bool wxHostNameValidator::Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, std::string *val_out) -{ - const wxStringCharType *buf = val_in; - - size_t i = i_start; - for (;;) { - if (i >= i_end) { - // End of host name found. - if (val_out) val_out->assign(val_in.c_str() + i_start, i - i_start); - return true; - } else if (_tcschr(wxT("abcdefghijklmnopqrstuvwxyz0123456789-*"), buf[i])) { - // Valid character found. - i++; - } else { - // Invalid character found. - ctrl->SetFocus(); - ctrl->SetSelection(i, i + 1); - wxMessageBox(wxString::Format(_("Invalid character in host name found: %c"), buf[i]), _("Validation conflict"), wxOK | wxICON_EXCLAMATION, parent); - return false; - } - } -} - - -////////////////////////////////////////////////////////////////////// -// wxFQDNValidator -////////////////////////////////////////////////////////////////////// - -wxIMPLEMENT_DYNAMIC_CLASS(wxFQDNValidator, wxValidator); - - -wxFQDNValidator::wxFQDNValidator(std::string *val) : - m_val(val), - wxValidator() -{ -} - - -wxFQDNValidator::wxFQDNValidator(const wxFQDNValidator &other) : - m_val(other.m_val), - wxValidator(other) -{ -} - - -wxObject* wxFQDNValidator::Clone() const -{ - return new wxFQDNValidator(*this); -} - - -bool wxFQDNValidator::Validate(wxWindow *parent) -{ - wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); - wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); - if (!ctrl->IsEnabled()) return true; - - wxString val(ctrl->GetValue()); - return Parse(val, 0, val.Length(), ctrl, parent); -} - - -bool wxFQDNValidator::TransferToWindow() -{ - wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); - - if (m_val) - ((wxTextCtrl*)GetWindow())->SetValue(*m_val); - - return true; -} - - -bool wxFQDNValidator::TransferFromWindow() -{ - wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); - wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); - - wxString val(ctrl->GetValue()); - return Parse(val, 0, val.Length(), ctrl, NULL, m_val); -} - - -bool wxFQDNValidator::Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, std::string *val_out) -{ - const wxStringCharType *buf = val_in; - - size_t i = i_start; - for (;;) { - const wxStringCharType *buf_next; - if ((buf_next = wmemchr(buf + i, L'.', i_end - i)) != NULL) { - // FQDN separator found. - if (!wxHostNameValidator::Parse(val_in, i, buf_next - buf, ctrl, parent)) - return false; - i = buf_next - buf + 1; - } else if (wxHostNameValidator::Parse(val_in, i, i_end, ctrl, parent)) { - // The rest of the FQDN parsed succesfully. - if (val_out) val_out->assign(val_in.c_str() + i_start, i_end - i_start); - return true; - } else - return false; - } -} - - -////////////////////////////////////////////////////////////////////// -// wxFQDNListValidator -////////////////////////////////////////////////////////////////////// - -wxIMPLEMENT_DYNAMIC_CLASS(wxFQDNListValidator, wxValidator); - - -wxFQDNListValidator::wxFQDNListValidator(std::list *val) : - m_val(val), - wxValidator() -{ -} - - -wxFQDNListValidator::wxFQDNListValidator(const wxFQDNListValidator &other) : - m_val(other.m_val), - wxValidator(other) -{ -} - - -wxObject* wxFQDNListValidator::Clone() const -{ - return new wxFQDNListValidator(*this); -} - - -bool wxFQDNListValidator::Validate(wxWindow *parent) -{ - wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); - if (!ctrl->IsEnabled()) return true; - - wxString val(ctrl->GetValue()); - return Parse(val, 0, val.Length(), ctrl, parent); -} - - -bool wxFQDNListValidator::TransferToWindow() -{ - wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); - - if (m_val) { - wxString str; - for (std::list::const_iterator name = m_val->cbegin(), name_end = m_val->cend(); name != name_end; ++name) { - if (!str.IsEmpty()) str += wxT("; "); - str += *name; - } - ((wxTextCtrl*)GetWindow())->SetValue(str); - } - - return true; -} - - -bool wxFQDNListValidator::TransferFromWindow() -{ - wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); - wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); - - wxString val(ctrl->GetValue()); - return Parse(val, 0, val.Length(), ctrl, NULL, m_val); -} - - -bool wxFQDNListValidator::Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, std::list *val_out) -{ - const wxStringCharType *buf = val_in; - std::string _fqdn, *fqdn = val_out ? &_fqdn : NULL; - std::list _val_out; - - size_t i = i_start; - for (;;) { - // Skip initial white-space. - for (; i < i_end && _istspace(buf[i]); i++); - - const wxStringCharType *buf_next; - if ((buf_next = wmemchr(buf + i, L';', i_end - i)) != NULL) { - // FQDN list separator found. - - // Skip trailing white-space. - size_t i_next = buf_next - buf; - for (; i < i_next && _istspace(buf[i_next - 1]); i_next--); - - if (!wxFQDNValidator::Parse(val_in, i, i_next, ctrl, parent, fqdn)) - return false; - if (fqdn && !fqdn->empty()) _val_out.push_back(std::move(*fqdn)); - - i = buf_next - buf + 1; - } else { - // Skip trailing white-space. - for (; i < i_end && _istspace(buf[i_end - 1]); i_end--); - - if (wxFQDNValidator::Parse(val_in, i, i_end, ctrl, parent, fqdn)) { - // The rest of the FQDN list parsed succesfully. - if (fqdn && !fqdn->empty()) _val_out.push_back(std::move(*fqdn)); - if (val_out) *val_out = std::move(_val_out); - return true; - } else - return false; - } - } -} - - -////////////////////////////////////////////////////////////////////// -// wxTLSCredentialsPanel -////////////////////////////////////////////////////////////////////// - -wxTLSCredentialsPanel::wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, eap::credentials_tls &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) : - wxEAPCredentialsPanelBase(prov, cfg, cred, pszCredTarget, parent, is_config) -{ - // Load and set icon. - if (m_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)) - wxSetIconFromResource(m_credentials_icon, m_icon, m_shell32, MAKEINTRESOURCE(269)); -} - - -bool wxTLSCredentialsPanel::TransferDataToWindow() -{ - // Populate certificate list. - bool is_found = false; - winstd::cert_store store; - if (store.create(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (HCRYPTPROV)NULL, CERT_SYSTEM_STORE_CURRENT_USER, _T("My"))) { - for (PCCERT_CONTEXT cert = NULL; (cert = CertEnumCertificatesInStore(store, cert)) != NULL;) { - DWORD dwKeySpec = 0, dwSize = sizeof(dwKeySpec); - if (!CertGetCertificateContextProperty(cert, CERT_KEY_SPEC_PROP_ID, &dwKeySpec, &dwSize) || !dwKeySpec) { - // Skip certificates without private key. - continue; - } - - // Prepare certificate information. - std::unique_ptr data(new wxCertificateClientData(CertDuplicateCertificateContext(cert))); - - // Add to list. - bool is_selected = - m_cred.m_cert && - m_cred.m_cert->cbCertEncoded == data->m_cert->cbCertEncoded && - memcmp(m_cred.m_cert->pbCertEncoded, data->m_cert->pbCertEncoded, m_cred.m_cert->cbCertEncoded) == 0; - winstd::tstring name(std::move(eap::get_cert_title(cert))); - int i = m_cert_select_val->Append(name, data.release()); - if (is_selected) { - m_cert_select_val->SetSelection(i); - is_found = true; - } - } - } - - if (is_found) { - m_cert_select->SetValue(true); - } else { - m_cert_none->SetValue(true); - if (!m_cert_select_val->IsEmpty()) - m_cert_select_val->SetSelection(0); - } - - return wxEAPCredentialsPanelBase::TransferDataToWindow(); -} - - -bool wxTLSCredentialsPanel::TransferDataFromWindow() -{ - if (m_cert_none->GetValue()) - m_cred.m_cert.free(); - else { - const wxCertificateClientData *data = dynamic_cast(m_cert_select_val->GetClientObject(m_cert_select_val->GetSelection())); - if (data) - m_cred.m_cert.attach_duplicated(data->m_cert); - else - m_cred.m_cert.free(); - } - - // Inherited TransferDataFromWindow() calls m_cred.store(). - // Therefore, call it only now, that m_cred is set. - return wxEAPCredentialsPanelBase::TransferDataFromWindow(); -} - - -void wxTLSCredentialsPanel::OnUpdateUI(wxUpdateUIEvent& event) -{ - if (!m_is_config && m_cfg.m_use_preshared) { - // Credential prompt mode & Using pre-shared credentials - // To avoid run-away selection of radio buttons, disable the selected one last. - if (m_cert_none->GetValue()) { - m_cert_select->Enable(false); - m_cert_none ->Enable(false); - } else { - m_cert_none ->Enable(false); - m_cert_select->Enable(false); - } - m_cert_select_val->Enable(false); - } else { - // Configuration mode or using own credentials. Selectively enable/disable controls. - m_cert_select_val->Enable(m_cert_select->GetValue()); - } - - wxEAPCredentialsPanelBase::OnUpdateUI(event); -} - - -////////////////////////////////////////////////////////////////////// -// wxTLSServerTrustPanel -////////////////////////////////////////////////////////////////////// - -wxTLSServerTrustPanel::wxTLSServerTrustPanel(const eap::config_provider &prov, eap::config_method_tls &cfg, wxWindow* parent) : - m_prov(prov), - m_cfg(cfg), - wxEAPTLSServerTrustConfigPanelBase(parent) -{ - // Load and set icon. - if (m_certmgr.load(_T("certmgr.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)) - wxSetIconFromResource(m_server_trust_icon, m_icon, m_certmgr, MAKEINTRESOURCE(218)); - - // Do not use cfg.m_server_names directly, so we can decide not to store the value in case of provider-locked configuration. - // Never rely on control disabled state alone, as they can be enabled using external tool like Spy++. - m_server_names->SetValidator(wxFQDNListValidator(&m_server_names_val)); -} - - -bool wxTLSServerTrustPanel::TransferDataToWindow() -{ - // Populate trusted CA list. - for (std::list::const_iterator cert = m_cfg.m_trusted_root_ca.cbegin(), cert_end = m_cfg.m_trusted_root_ca.cend(); cert != cert_end; ++cert) - m_root_ca->Append(wxString(eap::get_cert_title(*cert)), new wxCertificateClientData(cert->duplicate())); - - // Set server acceptable names. The edit control will get populated by validator. - m_server_names_val = m_cfg.m_server_names; - - return wxEAPTLSServerTrustConfigPanelBase::TransferDataToWindow(); -} - - -bool wxTLSServerTrustPanel::TransferDataFromWindow() -{ - wxCHECK(wxEAPTLSServerTrustConfigPanelBase::TransferDataFromWindow(), false); - - if (!m_prov.m_read_only) { - // This is not a provider-locked configuration. Save the data. - - // Parse trusted CA list. - m_cfg.m_trusted_root_ca.clear(); - for (unsigned int i = 0, i_end = m_root_ca->GetCount(); i < i_end; i++) { - wxCertificateClientData *cert = dynamic_cast(m_root_ca->GetClientObject(i)); - if (cert) - m_cfg.add_trusted_ca(cert->m_cert->dwCertEncodingType, cert->m_cert->pbCertEncoded, cert->m_cert->cbCertEncoded); - } - - // Save acceptable server names. - m_cfg.m_server_names = m_server_names_val; - } - - return true; -} - - -void wxTLSServerTrustPanel::OnUpdateUI(wxUpdateUIEvent& event) -{ - UNREFERENCED_PARAMETER(event); - - if (m_prov.m_read_only) { - // This is provider-locked configuration. Disable controls. - m_root_ca_add_store->Enable(false); - m_root_ca_add_file ->Enable(false); - m_root_ca_remove ->Enable(false); - m_server_names ->Enable(false); - } else { - // This is not a provider-locked configuration. Selectively enable/disable controls. - m_root_ca_add_store->Enable(true); - m_root_ca_add_file ->Enable(true); - wxArrayInt selections; - m_root_ca_remove->Enable(m_root_ca->GetSelections(selections) ? true : false); - m_server_names ->Enable(true); - } -} - - -void wxTLSServerTrustPanel::OnRootCADClick(wxCommandEvent& event) -{ - wxCertificateClientData *cert = dynamic_cast(event.GetClientObject()); - if (cert) - CryptUIDlgViewContext(CERT_STORE_CERTIFICATE_CONTEXT, cert->m_cert, this->GetHWND(), NULL, 0, NULL); -} - - -void wxTLSServerTrustPanel::OnRootCAAddStore(wxCommandEvent& event) -{ - UNREFERENCED_PARAMETER(event); - - winstd::cert_store store; - if (store.create(NULL, _T("ROOT"))) { - winstd::cert_context cert; - cert.attach(CryptUIDlgSelectCertificateFromStore(store, this->GetHWND(), NULL, NULL, 0, 0, NULL)); - if (cert) - AddRootCA(cert); - } -} - - -void wxTLSServerTrustPanel::OnRootCAAddFile(wxCommandEvent& event) -{ - UNREFERENCED_PARAMETER(event); - - const wxString separator(wxT("|")); - wxFileDialog open_dialog(this, _("Add Certificate"), wxEmptyString, wxEmptyString, - _("Certificate Files (*.cer;*.crt;*.der;*.p7b;*.pem)") + separator + wxT("*.cer;*.crt;*.der;*.p7b;*.pem") + separator + - _("X.509 Certificate Files (*.cer;*.crt;*.der;*.pem)") + separator + wxT("*.cer;*.crt;*.der;*.pem") + separator + - _("PKCS #7 Certificate Files (*.p7b)") + separator + wxT("*.p7b") + separator + - _("All Files (*.*)") + separator + wxT("*.*"), - wxFD_OPEN|wxFD_FILE_MUST_EXIST|wxFD_MULTIPLE); - if (open_dialog.ShowModal() == wxID_CANCEL) { - event.Skip(); - return; - } - - wxArrayString paths; - open_dialog.GetPaths(paths); - for (size_t i = 0, i_end = paths.GetCount(); i < i_end; i++) { - // Load certificate(s) from file. - winstd::cert_store cs; - if (cs.create(CERT_STORE_PROV_FILENAME, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, (LPCTSTR)(paths[i]))) { - for (PCCERT_CONTEXT cert = NULL; (cert = CertEnumCertificatesInStore(cs, cert)) != NULL;) - AddRootCA(cert); - } else - wxMessageBox(wxString::Format(_("Invalid or unsupported certificate file %s"), paths[i]), _("Error"), wxOK | wxICON_EXCLAMATION, this); - } -} - - -void wxTLSServerTrustPanel::OnRootCARemove(wxCommandEvent& event) -{ - UNREFERENCED_PARAMETER(event); - - wxArrayInt selections; - for (int i = m_root_ca->GetSelections(selections); i--; ) - m_root_ca->Delete(selections[i]); -} - - -bool wxTLSServerTrustPanel::AddRootCA(PCCERT_CONTEXT cert) -{ - for (unsigned int i = 0, i_end = m_root_ca->GetCount(); i < i_end; i++) { - wxCertificateClientData *c = dynamic_cast(m_root_ca->GetClientObject(i)); - if (c && c->m_cert && - c->m_cert->cbCertEncoded == cert->cbCertEncoded && - memcmp(c->m_cert->pbCertEncoded, cert->pbCertEncoded, cert->cbCertEncoded) == 0) - { - // This certificate is already on the list. - m_root_ca->SetSelection(i); - return false; - } - } - - // Add certificate to the list. - int i = m_root_ca->Append(wxString(eap::get_cert_title(cert)), new wxCertificateClientData(CertDuplicateCertificateContext(cert))); - if (0 <= i) - m_root_ca->SetSelection(i); - - return true; -} - - -////////////////////////////////////////////////////////////////////// -// wxTLSConfigPanel -////////////////////////////////////////////////////////////////////// - -wxTLSConfigPanel::wxTLSConfigPanel(const eap::config_provider &prov, eap::config_method_tls &cfg, LPCTSTR pszCredTarget, wxWindow* parent) : - m_prov(prov), - m_cfg(cfg), - wxPanel(parent) -{ - wxBoxSizer* sb_content; - sb_content = new wxBoxSizer( wxVERTICAL ); - - m_server_trust = new wxTLSServerTrustPanel(prov, cfg, this); - sb_content->Add(m_server_trust, 0, wxDOWN|wxEXPAND, 5); - - m_credentials = new wxTLSCredentialsConfigPanel(prov, cfg, pszCredTarget, this); - sb_content->Add(m_credentials, 0, wxUP|wxEXPAND, 5); - - this->SetSizer(sb_content); - this->Layout(); - - // Connect Events - this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(wxTLSConfigPanel::OnInitDialog)); -} - - -wxTLSConfigPanel::~wxTLSConfigPanel() -{ - // Disconnect Events - this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(wxTLSConfigPanel::OnInitDialog)); -} - - -void wxTLSConfigPanel::OnInitDialog(wxInitDialogEvent& event) -{ - // Forward the event to child panels. - m_server_trust->GetEventHandler()->ProcessEvent(event); - if (m_credentials) - m_credentials->GetEventHandler()->ProcessEvent(event); -} - - -bool wxTLSConfigPanel::TransferDataFromWindow() -{ - wxCHECK(wxPanel::TransferDataFromWindow(), false); - - if (!m_prov.m_read_only) { - // This is not a provider-locked configuration. The data will get saved. - - // Reset session ID and master secret to force clean connect next time. - m_cfg.m_session_id.clear(); - m_cfg.m_master_secret.clear(); - } - - return true; -} - - +/* + Copyright 2015-2016 Amebis + Copyright 2016 GÉANT + + This file is part of GÉANTLink. + + GÉANTLink is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + GÉANTLink is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GÉANTLink. If not, see . +*/ + +#include "StdAfx.h" + +#pragma comment(lib, "Crypt32.lib") + + +////////////////////////////////////////////////////////////////////// +// wxCertificateClientData +////////////////////////////////////////////////////////////////////// + +wxCertificateClientData::wxCertificateClientData(PCCERT_CONTEXT cert) : m_cert(cert) +{ +} + + +wxCertificateClientData::~wxCertificateClientData() +{ + if (m_cert) + CertFreeCertificateContext(m_cert); +} + + +////////////////////////////////////////////////////////////////////// +// wxHostNameValidator +////////////////////////////////////////////////////////////////////// + +wxIMPLEMENT_DYNAMIC_CLASS(wxHostNameValidator, wxValidator); + + +wxHostNameValidator::wxHostNameValidator(std::wstring *val) : + m_val(val), + wxValidator() +{ +} + + +wxHostNameValidator::wxHostNameValidator(const wxHostNameValidator &other) : + m_val(other.m_val), + wxValidator(other) +{ +} + + +wxObject* wxHostNameValidator::Clone() const +{ + return new wxHostNameValidator(*this); +} + + +bool wxHostNameValidator::Validate(wxWindow *parent) +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); + if (!ctrl->IsEnabled()) return true; + + wxString val(ctrl->GetValue()); + return Parse(val, 0, val.Length(), ctrl, parent); +} + + +bool wxHostNameValidator::TransferToWindow() +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + + if (m_val) + ((wxTextCtrl*)GetWindow())->SetValue(*m_val); + + return true; +} + + +bool wxHostNameValidator::TransferFromWindow() +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); + + wxString val(ctrl->GetValue()); + return Parse(val, 0, val.Length(), ctrl, NULL, m_val); +} + + +bool wxHostNameValidator::Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, std::wstring *val_out) +{ + const wxStringCharType *buf = val_in; + + size_t i = i_start; + for (;;) { + if (i >= i_end) { + // End of host name found. + if (val_out) val_out->assign(val_in.c_str() + i_start, i - i_start); + return true; + } else if (buf[i] == _T('-') || buf[i] == _T('_') || buf[i] == _T('*') || _istalnum(buf[i])) { + // Valid character found. + i++; + } else { + // Invalid character found. + ctrl->SetFocus(); + ctrl->SetSelection(i, i + 1); + wxMessageBox(wxString::Format(_("Invalid character in host name found: %c"), buf[i]), _("Validation conflict"), wxOK | wxICON_EXCLAMATION, parent); + return false; + } + } +} + + +////////////////////////////////////////////////////////////////////// +// wxFQDNValidator +////////////////////////////////////////////////////////////////////// + +wxIMPLEMENT_DYNAMIC_CLASS(wxFQDNValidator, wxValidator); + + +wxFQDNValidator::wxFQDNValidator(std::wstring *val) : + m_val(val), + wxValidator() +{ +} + + +wxFQDNValidator::wxFQDNValidator(const wxFQDNValidator &other) : + m_val(other.m_val), + wxValidator(other) +{ +} + + +wxObject* wxFQDNValidator::Clone() const +{ + return new wxFQDNValidator(*this); +} + + +bool wxFQDNValidator::Validate(wxWindow *parent) +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); + if (!ctrl->IsEnabled()) return true; + + wxString val(ctrl->GetValue()); + return Parse(val, 0, val.Length(), ctrl, parent); +} + + +bool wxFQDNValidator::TransferToWindow() +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + + if (m_val) + ((wxTextCtrl*)GetWindow())->SetValue(*m_val); + + return true; +} + + +bool wxFQDNValidator::TransferFromWindow() +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); + + wxString val(ctrl->GetValue()); + return Parse(val, 0, val.Length(), ctrl, NULL, m_val); +} + + +bool wxFQDNValidator::Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, std::wstring *val_out) +{ + const wxStringCharType *buf = val_in; + + size_t i = i_start; + for (;;) { + const wxStringCharType *buf_next; + if ((buf_next = wmemchr(buf + i, L'.', i_end - i)) != NULL) { + // FQDN separator found. + if (!wxHostNameValidator::Parse(val_in, i, buf_next - buf, ctrl, parent)) + return false; + i = buf_next - buf + 1; + } else if (wxHostNameValidator::Parse(val_in, i, i_end, ctrl, parent)) { + // The rest of the FQDN parsed succesfully. + if (val_out) val_out->assign(val_in.c_str() + i_start, i_end - i_start); + return true; + } else + return false; + } +} + + +////////////////////////////////////////////////////////////////////// +// wxFQDNListValidator +////////////////////////////////////////////////////////////////////// + +wxIMPLEMENT_DYNAMIC_CLASS(wxFQDNListValidator, wxValidator); + + +wxFQDNListValidator::wxFQDNListValidator(std::list *val) : + m_val(val), + wxValidator() +{ +} + + +wxFQDNListValidator::wxFQDNListValidator(const wxFQDNListValidator &other) : + m_val(other.m_val), + wxValidator(other) +{ +} + + +wxObject* wxFQDNListValidator::Clone() const +{ + return new wxFQDNListValidator(*this); +} + + +bool wxFQDNListValidator::Validate(wxWindow *parent) +{ + wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); + if (!ctrl->IsEnabled()) return true; + + wxString val(ctrl->GetValue()); + return Parse(val, 0, val.Length(), ctrl, parent); +} + + +bool wxFQDNListValidator::TransferToWindow() +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + + if (m_val) { + wxString str; + for (std::list::const_iterator name = m_val->cbegin(), name_end = m_val->cend(); name != name_end; ++name) { + if (!str.IsEmpty()) str += wxT("; "); + str += *name; + } + ((wxTextCtrl*)GetWindow())->SetValue(str); + } + + return true; +} + + +bool wxFQDNListValidator::TransferFromWindow() +{ + wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl))); + wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow(); + + wxString val(ctrl->GetValue()); + return Parse(val, 0, val.Length(), ctrl, NULL, m_val); +} + + +bool wxFQDNListValidator::Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, std::list *val_out) +{ + const wxStringCharType *buf = val_in; + std::wstring _fqdn, *fqdn = val_out ? &_fqdn : NULL; + std::list _val_out; + + size_t i = i_start; + for (;;) { + // Skip initial white-space. + for (; i < i_end && _istspace(buf[i]); i++); + + const wxStringCharType *buf_next; + if ((buf_next = wmemchr(buf + i, L';', i_end - i)) != NULL) { + // FQDN list separator found. + + // Skip trailing white-space. + size_t i_next = buf_next - buf; + for (; i < i_next && _istspace(buf[i_next - 1]); i_next--); + + if (!wxFQDNValidator::Parse(val_in, i, i_next, ctrl, parent, fqdn)) + return false; + if (fqdn && !fqdn->empty()) _val_out.push_back(std::move(*fqdn)); + + i = buf_next - buf + 1; + } else { + // Skip trailing white-space. + for (; i < i_end && _istspace(buf[i_end - 1]); i_end--); + + if (wxFQDNValidator::Parse(val_in, i, i_end, ctrl, parent, fqdn)) { + // The rest of the FQDN list parsed succesfully. + if (fqdn && !fqdn->empty()) _val_out.push_back(std::move(*fqdn)); + if (val_out) *val_out = std::move(_val_out); + return true; + } else + return false; + } + } +} + + +////////////////////////////////////////////////////////////////////// +// wxTLSCredentialsPanel +////////////////////////////////////////////////////////////////////// + +wxTLSCredentialsPanel::wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, eap::credentials_tls &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) : + wxEAPCredentialsPanelBase(prov, cfg, cred, pszCredTarget, parent, is_config) +{ + // Load and set icon. + if (m_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)) + wxSetIconFromResource(m_credentials_icon, m_icon, m_shell32, MAKEINTRESOURCE(269)); +} + + +bool wxTLSCredentialsPanel::TransferDataToWindow() +{ + // Populate certificate list. + bool is_found = false; + winstd::cert_store store; + if (store.create(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (HCRYPTPROV)NULL, CERT_SYSTEM_STORE_CURRENT_USER, _T("My"))) { + for (PCCERT_CONTEXT cert = NULL; (cert = CertEnumCertificatesInStore(store, cert)) != NULL;) { + DWORD dwKeySpec = 0, dwSize = sizeof(dwKeySpec); + if (!CertGetCertificateContextProperty(cert, CERT_KEY_SPEC_PROP_ID, &dwKeySpec, &dwSize) || !dwKeySpec) { + // Skip certificates without private key. + continue; + } + + // Prepare certificate information. + std::unique_ptr data(new wxCertificateClientData(CertDuplicateCertificateContext(cert))); + + // Add to list. + bool is_selected = + m_cred.m_cert && + m_cred.m_cert->cbCertEncoded == data->m_cert->cbCertEncoded && + memcmp(m_cred.m_cert->pbCertEncoded, data->m_cert->pbCertEncoded, m_cred.m_cert->cbCertEncoded) == 0; + winstd::tstring name(std::move(eap::get_cert_title(cert))); + int i = m_cert_select_val->Append(name, data.release()); + if (is_selected) { + m_cert_select_val->SetSelection(i); + is_found = true; + } + } + } + + if (is_found) { + m_cert_select->SetValue(true); + } else { + m_cert_none->SetValue(true); + if (!m_cert_select_val->IsEmpty()) + m_cert_select_val->SetSelection(0); + } + + return wxEAPCredentialsPanelBase::TransferDataToWindow(); +} + + +bool wxTLSCredentialsPanel::TransferDataFromWindow() +{ + if (m_cert_none->GetValue()) + m_cred.m_cert.free(); + else { + const wxCertificateClientData *data = dynamic_cast(m_cert_select_val->GetClientObject(m_cert_select_val->GetSelection())); + if (data) + m_cred.m_cert.attach_duplicated(data->m_cert); + else + m_cred.m_cert.free(); + } + + // Inherited TransferDataFromWindow() calls m_cred.store(). + // Therefore, call it only now, that m_cred is set. + return wxEAPCredentialsPanelBase::TransferDataFromWindow(); +} + + +void wxTLSCredentialsPanel::OnUpdateUI(wxUpdateUIEvent& event) +{ + if (!m_is_config && m_cfg.m_use_preshared) { + // Credential prompt mode & Using pre-shared credentials + // To avoid run-away selection of radio buttons, disable the selected one last. + if (m_cert_none->GetValue()) { + m_cert_select->Enable(false); + m_cert_none ->Enable(false); + } else { + m_cert_none ->Enable(false); + m_cert_select->Enable(false); + } + m_cert_select_val->Enable(false); + } else { + // Configuration mode or using own credentials. Selectively enable/disable controls. + m_cert_select_val->Enable(m_cert_select->GetValue()); + } + + wxEAPCredentialsPanelBase::OnUpdateUI(event); +} + + +////////////////////////////////////////////////////////////////////// +// wxTLSServerTrustPanel +////////////////////////////////////////////////////////////////////// + +wxTLSServerTrustPanel::wxTLSServerTrustPanel(const eap::config_provider &prov, eap::config_method_tls &cfg, wxWindow* parent) : + m_prov(prov), + m_cfg(cfg), + wxEAPTLSServerTrustConfigPanelBase(parent) +{ + // Load and set icon. + if (m_certmgr.load(_T("certmgr.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)) + wxSetIconFromResource(m_server_trust_icon, m_icon, m_certmgr, MAKEINTRESOURCE(218)); + + // Do not use cfg.m_server_names directly, so we can decide not to store the value in case of provider-locked configuration. + // Never rely on control disabled state alone, as they can be enabled using external tool like Spy++. + m_server_names->SetValidator(wxFQDNListValidator(&m_server_names_val)); +} + + +bool wxTLSServerTrustPanel::TransferDataToWindow() +{ + // Populate trusted CA list. + for (std::list::const_iterator cert = m_cfg.m_trusted_root_ca.cbegin(), cert_end = m_cfg.m_trusted_root_ca.cend(); cert != cert_end; ++cert) + m_root_ca->Append(wxString(eap::get_cert_title(*cert)), new wxCertificateClientData(cert->duplicate())); + + // Set server acceptable names. The edit control will get populated by validator. + m_server_names_val = m_cfg.m_server_names; + + return wxEAPTLSServerTrustConfigPanelBase::TransferDataToWindow(); +} + + +bool wxTLSServerTrustPanel::TransferDataFromWindow() +{ + wxCHECK(wxEAPTLSServerTrustConfigPanelBase::TransferDataFromWindow(), false); + + if (!m_prov.m_read_only) { + // This is not a provider-locked configuration. Save the data. + + // Parse trusted CA list. + m_cfg.m_trusted_root_ca.clear(); + for (unsigned int i = 0, i_end = m_root_ca->GetCount(); i < i_end; i++) { + wxCertificateClientData *cert = dynamic_cast(m_root_ca->GetClientObject(i)); + if (cert) + m_cfg.add_trusted_ca(cert->m_cert->dwCertEncodingType, cert->m_cert->pbCertEncoded, cert->m_cert->cbCertEncoded); + } + + // Save acceptable server names. + m_cfg.m_server_names = m_server_names_val; + } + + return true; +} + + +void wxTLSServerTrustPanel::OnUpdateUI(wxUpdateUIEvent& event) +{ + UNREFERENCED_PARAMETER(event); + + if (m_prov.m_read_only) { + // This is provider-locked configuration. Disable controls. + m_root_ca_add_store->Enable(false); + m_root_ca_add_file ->Enable(false); + m_root_ca_remove ->Enable(false); + m_server_names ->Enable(false); + } else { + // This is not a provider-locked configuration. Selectively enable/disable controls. + m_root_ca_add_store->Enable(true); + m_root_ca_add_file ->Enable(true); + wxArrayInt selections; + m_root_ca_remove->Enable(m_root_ca->GetSelections(selections) ? true : false); + m_server_names ->Enable(true); + } +} + + +void wxTLSServerTrustPanel::OnRootCADClick(wxCommandEvent& event) +{ + wxCertificateClientData *cert = dynamic_cast(event.GetClientObject()); + if (cert) + CryptUIDlgViewContext(CERT_STORE_CERTIFICATE_CONTEXT, cert->m_cert, this->GetHWND(), NULL, 0, NULL); +} + + +void wxTLSServerTrustPanel::OnRootCAAddStore(wxCommandEvent& event) +{ + UNREFERENCED_PARAMETER(event); + + winstd::cert_store store; + if (store.create(NULL, _T("ROOT"))) { + winstd::cert_context cert; + cert.attach(CryptUIDlgSelectCertificateFromStore(store, this->GetHWND(), NULL, NULL, 0, 0, NULL)); + if (cert) + AddRootCA(cert); + } +} + + +void wxTLSServerTrustPanel::OnRootCAAddFile(wxCommandEvent& event) +{ + UNREFERENCED_PARAMETER(event); + + const wxString separator(wxT("|")); + wxFileDialog open_dialog(this, _("Add Certificate"), wxEmptyString, wxEmptyString, + _("Certificate Files (*.cer;*.crt;*.der;*.p7b;*.pem)") + separator + wxT("*.cer;*.crt;*.der;*.p7b;*.pem") + separator + + _("X.509 Certificate Files (*.cer;*.crt;*.der;*.pem)") + separator + wxT("*.cer;*.crt;*.der;*.pem") + separator + + _("PKCS #7 Certificate Files (*.p7b)") + separator + wxT("*.p7b") + separator + + _("All Files (*.*)") + separator + wxT("*.*"), + wxFD_OPEN|wxFD_FILE_MUST_EXIST|wxFD_MULTIPLE); + if (open_dialog.ShowModal() == wxID_CANCEL) { + event.Skip(); + return; + } + + wxArrayString paths; + open_dialog.GetPaths(paths); + for (size_t i = 0, i_end = paths.GetCount(); i < i_end; i++) { + // Load certificate(s) from file. + winstd::cert_store cs; + if (cs.create(CERT_STORE_PROV_FILENAME, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, (LPCTSTR)(paths[i]))) { + for (PCCERT_CONTEXT cert = NULL; (cert = CertEnumCertificatesInStore(cs, cert)) != NULL;) + AddRootCA(cert); + } else + wxMessageBox(wxString::Format(_("Invalid or unsupported certificate file %s"), paths[i]), _("Error"), wxOK | wxICON_EXCLAMATION, this); + } +} + + +void wxTLSServerTrustPanel::OnRootCARemove(wxCommandEvent& event) +{ + UNREFERENCED_PARAMETER(event); + + wxArrayInt selections; + for (int i = m_root_ca->GetSelections(selections); i--; ) + m_root_ca->Delete(selections[i]); +} + + +bool wxTLSServerTrustPanel::AddRootCA(PCCERT_CONTEXT cert) +{ + for (unsigned int i = 0, i_end = m_root_ca->GetCount(); i < i_end; i++) { + wxCertificateClientData *c = dynamic_cast(m_root_ca->GetClientObject(i)); + if (c && c->m_cert && + c->m_cert->cbCertEncoded == cert->cbCertEncoded && + memcmp(c->m_cert->pbCertEncoded, cert->pbCertEncoded, cert->cbCertEncoded) == 0) + { + // This certificate is already on the list. + m_root_ca->SetSelection(i); + return false; + } + } + + // Add certificate to the list. + int i = m_root_ca->Append(wxString(eap::get_cert_title(cert)), new wxCertificateClientData(CertDuplicateCertificateContext(cert))); + if (0 <= i) + m_root_ca->SetSelection(i); + + return true; +} + + +////////////////////////////////////////////////////////////////////// +// wxTLSConfigPanel +////////////////////////////////////////////////////////////////////// + +wxTLSConfigPanel::wxTLSConfigPanel(const eap::config_provider &prov, eap::config_method_tls &cfg, LPCTSTR pszCredTarget, wxWindow* parent) : + m_prov(prov), + m_cfg(cfg), + wxPanel(parent) +{ + wxBoxSizer* sb_content; + sb_content = new wxBoxSizer( wxVERTICAL ); + + m_server_trust = new wxTLSServerTrustPanel(prov, cfg, this); + sb_content->Add(m_server_trust, 0, wxDOWN|wxEXPAND, 5); + + m_credentials = new wxTLSCredentialsConfigPanel(prov, cfg, pszCredTarget, this); + sb_content->Add(m_credentials, 0, wxUP|wxEXPAND, 5); + + this->SetSizer(sb_content); + this->Layout(); + + // Connect Events + this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(wxTLSConfigPanel::OnInitDialog)); +} + + +wxTLSConfigPanel::~wxTLSConfigPanel() +{ + // Disconnect Events + this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(wxTLSConfigPanel::OnInitDialog)); +} + + +void wxTLSConfigPanel::OnInitDialog(wxInitDialogEvent& event) +{ + // Forward the event to child panels. + m_server_trust->GetEventHandler()->ProcessEvent(event); + if (m_credentials) + m_credentials->GetEventHandler()->ProcessEvent(event); +} + + +bool wxTLSConfigPanel::TransferDataFromWindow() +{ + wxCHECK(wxPanel::TransferDataFromWindow(), false); + + if (!m_prov.m_read_only) { + // This is not a provider-locked configuration. The data will get saved. + + // Reset session ID and master secret to force clean connect next time. + m_cfg.m_session_id.clear(); + m_cfg.m_master_secret.clear(); + } + + return true; +} + +