credentials_tls: Keep thumbprint rather than client certificate
By storing the client certificate the certificate became detached from its private key stored in user certificate store. This rendered client certificates useless for client TLS authentication. Now, the client certificate thumbprint is stored instead. The client certificate is looked up in the user certificate store as required. This breaks profile XML and BLOB backward compatibility. Since the client certificate support was broken, nobody probably used those in the settings before. Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
@@ -34,14 +34,14 @@ eap::credentials_tls::credentials_tls(_In_ module &mod) : credentials(mod)
|
||||
|
||||
|
||||
eap::credentials_tls::credentials_tls(_In_ const credentials_tls &other) :
|
||||
m_cert(other.m_cert),
|
||||
m_cert_hash(other.m_cert_hash),
|
||||
credentials(other)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
eap::credentials_tls::credentials_tls(_Inout_ credentials_tls &&other) noexcept :
|
||||
m_cert(std::move(other.m_cert)),
|
||||
m_cert_hash(std::move(other.m_cert_hash)),
|
||||
credentials(std::move(other))
|
||||
{
|
||||
}
|
||||
@@ -51,7 +51,7 @@ eap::credentials_tls& eap::credentials_tls::operator=(_In_ const credentials_tls
|
||||
{
|
||||
if (this != &other) {
|
||||
(credentials&)*this = other;
|
||||
m_cert = other.m_cert;
|
||||
m_cert_hash = other.m_cert_hash;
|
||||
}
|
||||
|
||||
return *this;
|
||||
@@ -62,7 +62,7 @@ eap::credentials_tls& eap::credentials_tls::operator=(_Inout_ credentials_tls &&
|
||||
{
|
||||
if (this != &other) {
|
||||
(credentials&)*this = std::move(other);
|
||||
m_cert = std::move(other.m_cert);
|
||||
m_cert_hash = std::move(other.m_cert_hash);
|
||||
}
|
||||
|
||||
return *this;
|
||||
@@ -78,13 +78,13 @@ eap::config* eap::credentials_tls::clone() const
|
||||
void eap::credentials_tls::clear()
|
||||
{
|
||||
credentials::clear();
|
||||
m_cert.free();
|
||||
m_cert_hash.clear();
|
||||
}
|
||||
|
||||
|
||||
bool eap::credentials_tls::empty() const
|
||||
{
|
||||
return !m_cert;
|
||||
return m_cert_hash.empty();
|
||||
}
|
||||
|
||||
|
||||
@@ -102,14 +102,10 @@ void eap::credentials_tls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pC
|
||||
if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ClientCertificate"), bstr(L"ClientCertificate"), namespace_eapmetadata, pXmlElClientCertificate)))
|
||||
throw com_runtime_error(hr, __FUNCTION__ " Error creating <ClientCertificate> element.");
|
||||
|
||||
if (m_cert) {
|
||||
// <ClientCertificate>/<format>
|
||||
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElClientCertificate, bstr(L"format"), namespace_eapmetadata, bstr(L"PEM"))))
|
||||
throw com_runtime_error(hr, __FUNCTION__ " Error creating <format> element.");
|
||||
|
||||
// <ClientCertificate>/<cert-data>
|
||||
if (FAILED(hr = eapxml::put_element_base64(pDoc, pXmlElClientCertificate, bstr(L"cert-data"), namespace_eapmetadata, m_cert->pbCertEncoded, m_cert->cbCertEncoded)))
|
||||
throw com_runtime_error(hr, __FUNCTION__ " Error creating <cert-data> element.");
|
||||
if (!m_cert_hash.empty()) {
|
||||
// <ClientCertificate>/<hash>
|
||||
if (FAILED(hr = eapxml::put_element_hex(pDoc, pXmlElClientCertificate, bstr(L"hash"), namespace_eapmetadata, m_cert_hash.data(), m_cert_hash.size())))
|
||||
throw com_runtime_error(hr, __FUNCTION__ " Error creating <hash> element.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,35 +119,24 @@ void eap::credentials_tls::load(_In_ IXMLDOMNode *pConfigRoot)
|
||||
|
||||
std::wstring xpath(eapxml::get_xpath(pConfigRoot));
|
||||
|
||||
m_cert.free();
|
||||
m_cert_hash.clear();
|
||||
|
||||
// <ClientCertificate>
|
||||
com_obj<IXMLDOMElement> pXmlElClientCertificate;
|
||||
if (FAILED(hr = eapxml::select_element(pConfigRoot, bstr(L"eap-metadata:ClientCertificate"), pXmlElClientCertificate)))
|
||||
throw com_runtime_error(hr, __FUNCTION__ " Error reading <ClientCertificate> element.");
|
||||
|
||||
// <ClientCertificate>/<format>
|
||||
bstr bstrFormat;
|
||||
if (SUCCEEDED(eapxml::get_element_value(pXmlElClientCertificate, bstr(L"eap-metadata:format"), bstrFormat))) {
|
||||
if (CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, bstrFormat, bstrFormat.length(), L"PEM", -1, NULL, NULL, 0) == CSTR_EQUAL) {
|
||||
// <ClientCertificate>/<cert-data>
|
||||
vector<unsigned char> aData;
|
||||
if (SUCCEEDED(eapxml::get_element_base64(pXmlElClientCertificate, bstr(L"eap-metadata:cert-data"), aData)))
|
||||
m_cert.create(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, aData.data(), (DWORD)aData.size());
|
||||
}
|
||||
}
|
||||
// <ClientCertificate>/<hash>
|
||||
eapxml::get_element_hex(pXmlElClientCertificate, bstr(L"eap-metadata:hash"), m_cert_hash);
|
||||
|
||||
if (m_cert)
|
||||
m_module.log_config_discrete((xpath + L"/ClientCertificate").c_str(), m_cert->pbCertEncoded, m_cert->cbCertEncoded);
|
||||
else
|
||||
m_module.log_config_discrete((xpath + L"/ClientCertificate").c_str(), NULL, 0);
|
||||
m_module.log_config((xpath + L"/ClientCertificateHash").c_str(), m_cert_hash.data(), (ULONG)m_cert_hash.size());
|
||||
}
|
||||
|
||||
|
||||
void eap::credentials_tls::operator<<(_Inout_ cursor_out &cursor) const
|
||||
{
|
||||
credentials::operator<<(cursor);
|
||||
cursor << m_cert;
|
||||
cursor << m_cert_hash;
|
||||
}
|
||||
|
||||
|
||||
@@ -159,34 +144,24 @@ size_t eap::credentials_tls::get_pk_size() const
|
||||
{
|
||||
return
|
||||
credentials::get_pk_size() +
|
||||
pksizeof(m_cert);
|
||||
pksizeof(m_cert_hash);
|
||||
}
|
||||
|
||||
|
||||
void eap::credentials_tls::operator>>(_Inout_ cursor_in &cursor)
|
||||
{
|
||||
credentials::operator>>(cursor);
|
||||
cursor >> m_cert;
|
||||
cursor >> m_cert_hash;
|
||||
}
|
||||
|
||||
|
||||
void eap::credentials_tls::store(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level) const
|
||||
{
|
||||
assert(pszTargetName);
|
||||
|
||||
data_blob cred_enc;
|
||||
if (m_cert) {
|
||||
// Encrypt the certificate using user's key.
|
||||
DATA_BLOB cred_blob = { m_cert->cbCertEncoded, m_cert->pbCertEncoded };
|
||||
DATA_BLOB entropy_blob = { sizeof(s_entropy) , const_cast<LPBYTE>(s_entropy) };
|
||||
if (!CryptProtectData(&cred_blob, NULL, &entropy_blob, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN | CRYPTPROTECT_AUDIT, &cred_enc))
|
||||
throw win_runtime_error(__FUNCTION__ " CryptProtectData failed.");
|
||||
}
|
||||
|
||||
tstring target(target_name(pszTargetName, level));
|
||||
|
||||
// Write credentials.
|
||||
assert(cred_enc.cbData < CRED_MAX_CREDENTIAL_BLOB_SIZE);
|
||||
assert(m_cert_hash.size() < CRED_MAX_CREDENTIAL_BLOB_SIZE);
|
||||
assert(m_identity.length() < CRED_MAX_USERNAME_LENGTH );
|
||||
CREDENTIAL cred = {
|
||||
0, // Flags
|
||||
@@ -194,8 +169,8 @@ void eap::credentials_tls::store(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int
|
||||
const_cast<LPTSTR>(target.c_str()), // TargetName
|
||||
_T(""), // Comment
|
||||
{ 0, 0 }, // LastWritten
|
||||
cred_enc.cbData, // CredentialBlobSize
|
||||
cred_enc.pbData, // CredentialBlob
|
||||
(DWORD)m_cert_hash.size(), // CredentialBlobSize
|
||||
(LPBYTE)m_cert_hash.data(), // CredentialBlob
|
||||
CRED_PERSIST_ENTERPRISE, // Persist
|
||||
0, // AttributeCount
|
||||
NULL, // Attributes
|
||||
@@ -216,20 +191,10 @@ void eap::credentials_tls::retrieve(_In_z_ LPCTSTR pszTargetName, _In_ unsigned
|
||||
if (!CredRead(target_name(pszTargetName, level).c_str(), CRED_TYPE_GENERIC, 0, (PCREDENTIAL*)&cred))
|
||||
throw win_runtime_error(__FUNCTION__ " CredRead failed.");
|
||||
|
||||
if (cred->CredentialBlobSize) {
|
||||
// Decrypt the certificate using user's key.
|
||||
DATA_BLOB cred_enc = { cred->CredentialBlobSize, cred->CredentialBlob };
|
||||
DATA_BLOB entropy_blob = { sizeof(s_entropy) , const_cast<LPBYTE>(s_entropy) };
|
||||
data_blob cred_int;
|
||||
if (!CryptUnprotectData(&cred_enc, NULL, &entropy_blob, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN | CRYPTPROTECT_VERIFY_PROTECTION, &cred_int))
|
||||
throw win_runtime_error(__FUNCTION__ " CryptUnprotectData failed.");
|
||||
|
||||
bool bResult = m_cert.create(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cred_int.pbData, cred_int.cbData);
|
||||
SecureZeroMemory(cred_int.pbData, cred_int.cbData);
|
||||
if (!bResult)
|
||||
throw win_runtime_error(__FUNCTION__ " Error loading certificate.");
|
||||
} else
|
||||
m_cert.free();
|
||||
if (cred->CredentialBlobSize)
|
||||
m_cert_hash.assign(cred->CredentialBlob, cred->CredentialBlob + cred->CredentialBlobSize);
|
||||
else
|
||||
m_cert_hash.clear();
|
||||
|
||||
if (cred->UserName)
|
||||
m_identity = cred->UserName;
|
||||
@@ -238,10 +203,7 @@ void eap::credentials_tls::retrieve(_In_z_ LPCTSTR pszTargetName, _In_ unsigned
|
||||
|
||||
wstring xpath(pszTargetName);
|
||||
m_module.log_config((xpath + L"/Identity").c_str(), m_identity.c_str());
|
||||
if (m_cert)
|
||||
m_module.log_config_discrete((xpath + L"/Certificate").c_str(), m_cert->pbCertEncoded, m_cert->cbCertEncoded);
|
||||
else
|
||||
m_module.log_config_discrete((xpath + L"/Certificate").c_str(), NULL, 0);
|
||||
m_module.log_config((xpath + L"/CertificateHash").c_str(), m_cert_hash.data(), (ULONG)m_cert_hash.size());
|
||||
}
|
||||
|
||||
|
||||
@@ -255,10 +217,21 @@ std::wstring eap::credentials_tls::get_identity() const
|
||||
{
|
||||
if (!m_identity.empty()) {
|
||||
return m_identity;
|
||||
} else if (m_cert) {
|
||||
wstring name;
|
||||
CertGetNameStringW(m_cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, name);
|
||||
return name;
|
||||
} else if (!m_cert_hash.empty()) {
|
||||
// Find certificate in the store.
|
||||
winstd::cert_store store;
|
||||
vector<unsigned char> hash;
|
||||
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;) {
|
||||
if (CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID, hash) &&
|
||||
hash == m_cert_hash)
|
||||
{
|
||||
wstring name;
|
||||
CertGetNameStringW(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, name);
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return L"";
|
||||
@@ -304,73 +277,3 @@ eap::credentials::source_t eap::credentials_tls::combine(
|
||||
|
||||
return source_t::unknown;
|
||||
}
|
||||
|
||||
|
||||
/// \cond internal
|
||||
const unsigned char eap::credentials_tls::s_entropy[1024] = {
|
||||
0xb9, 0xd1, 0x62, 0xd4, 0x1c, 0xe6, 0x8c, 0x25, 0x98, 0x9b, 0x1d, 0xbc, 0x40, 0x46, 0x9e, 0x6d,
|
||||
0x63, 0xba, 0xda, 0x78, 0x65, 0x56, 0x97, 0x4f, 0xa0, 0x89, 0xf4, 0xc5, 0x1b, 0xf5, 0x8d, 0x69,
|
||||
0xa1, 0x8c, 0xf3, 0xf9, 0x91, 0x86, 0x7f, 0xf3, 0x47, 0x2e, 0x23, 0x61, 0xde, 0x4f, 0x61, 0x94,
|
||||
0xba, 0xba, 0x27, 0x63, 0x0b, 0xf0, 0x4e, 0xa0, 0x24, 0xab, 0x17, 0x62, 0x3f, 0xc4, 0xd8, 0xad,
|
||||
0xd6, 0x03, 0x1f, 0x3b, 0xdd, 0x88, 0xf7, 0x9a, 0x56, 0xf4, 0x0d, 0xce, 0x9b, 0x18, 0x33, 0x54,
|
||||
0x5a, 0x1a, 0x3b, 0x91, 0x70, 0xf5, 0x95, 0x1c, 0x39, 0xe8, 0x42, 0x6c, 0x6e, 0xe6, 0x4d, 0xb8,
|
||||
0x1c, 0xa6, 0xce, 0xad, 0xcd, 0x9e, 0x55, 0x88, 0x90, 0xff, 0x5e, 0x81, 0xdf, 0x08, 0x68, 0x54,
|
||||
0xa1, 0x60, 0xfb, 0x41, 0x8a, 0xc1, 0xf2, 0xf0, 0xc4, 0x0e, 0xb9, 0xd1, 0x61, 0xa5, 0xc4, 0x02,
|
||||
0xd9, 0x43, 0xbb, 0x16, 0x9f, 0x9a, 0xc3, 0xe0, 0x61, 0xf8, 0x57, 0x16, 0xb1, 0x7f, 0x00, 0x53,
|
||||
0xf6, 0x8b, 0x97, 0x8f, 0xec, 0x3f, 0x72, 0x32, 0x0c, 0x0a, 0x80, 0x00, 0x4f, 0x87, 0x36, 0x2e,
|
||||
0x24, 0x1d, 0xb4, 0xe5, 0x6c, 0x41, 0x34, 0xe9, 0x75, 0x4c, 0xf2, 0xdb, 0x16, 0xb5, 0x9a, 0x54,
|
||||
0x40, 0xe9, 0x1f, 0xc0, 0xf1, 0xc5, 0x0d, 0x5d, 0xa7, 0xb5, 0x51, 0x15, 0x05, 0x95, 0xe2, 0x46,
|
||||
0x9d, 0xc7, 0x74, 0xd7, 0xab, 0x93, 0xce, 0x7d, 0xf9, 0x61, 0x9d, 0x2b, 0xe7, 0x45, 0x61, 0x0b,
|
||||
0xcc, 0x18, 0xf1, 0xf4, 0x00, 0xb9, 0x78, 0x23, 0x45, 0x8a, 0xd6, 0x1d, 0x95, 0x6b, 0x99, 0xe0,
|
||||
0x21, 0x6b, 0x98, 0x91, 0xcb, 0x0e, 0x50, 0x9a, 0x2e, 0x64, 0xa2, 0xe9, 0x1b, 0x1f, 0x6e, 0x69,
|
||||
0x78, 0x1d, 0xd1, 0xa1, 0xe5, 0x95, 0x34, 0x78, 0xf2, 0x8b, 0xe6, 0x38, 0x74, 0xd6, 0x48, 0x69,
|
||||
0x62, 0xf6, 0xd3, 0x18, 0x1c, 0xb1, 0x0e, 0xc0, 0xdf, 0xff, 0x2e, 0xd3, 0xbc, 0x4e, 0xae, 0xd7,
|
||||
0xe0, 0xb8, 0x47, 0x15, 0xcc, 0x10, 0xc3, 0x3a, 0x3d, 0x67, 0x79, 0x33, 0x1d, 0xb1, 0x73, 0xdf,
|
||||
0xfb, 0xb2, 0x89, 0xbb, 0x04, 0x76, 0xec, 0x4a, 0x73, 0x73, 0xa8, 0x07, 0xb7, 0xb0, 0xbe, 0x15,
|
||||
0xac, 0xc3, 0x32, 0x1e, 0x70, 0xc2, 0x0e, 0x8c, 0x29, 0x2e, 0x2d, 0xfc, 0x36, 0x1f, 0x9d, 0x90,
|
||||
0x86, 0x1b, 0x12, 0xca, 0x82, 0x4d, 0xea, 0x9e, 0xb4, 0x5e, 0xb0, 0x33, 0xc4, 0x19, 0x25, 0x3f,
|
||||
0x27, 0x11, 0x5a, 0x79, 0x91, 0x44, 0x2c, 0x50, 0x56, 0xe0, 0xd2, 0xb3, 0x81, 0x17, 0x3f, 0x06,
|
||||
0x57, 0x39, 0x18, 0x2c, 0xd4, 0x1e, 0xf3, 0x90, 0x7e, 0xc3, 0x08, 0x50, 0x89, 0x7a, 0xf7, 0x7f,
|
||||
0xe9, 0xf1, 0x2d, 0x73, 0x95, 0xd9, 0x2e, 0x83, 0xc8, 0x93, 0x33, 0xd9, 0x00, 0xc3, 0xa0, 0x43,
|
||||
0x32, 0x57, 0x7b, 0xa9, 0xbf, 0x55, 0xfc, 0x35, 0xfb, 0x85, 0x08, 0x1c, 0x84, 0xa7, 0xce, 0xb0,
|
||||
0x8b, 0xab, 0x56, 0xfa, 0x70, 0x9c, 0xd5, 0x8f, 0x21, 0xf6, 0x8f, 0x5e, 0xd5, 0x1b, 0x81, 0x17,
|
||||
0xf7, 0x82, 0xb2, 0x28, 0xde, 0xc5, 0xc1, 0xba, 0xe7, 0xfa, 0x21, 0x06, 0xff, 0xf3, 0x27, 0xf8,
|
||||
0x3a, 0x7d, 0xbc, 0x96, 0x5e, 0xdf, 0xf4, 0x89, 0x9f, 0x1c, 0x40, 0x03, 0x1a, 0xd2, 0x53, 0xb9,
|
||||
0xe4, 0xeb, 0x16, 0xbf, 0xaa, 0xe3, 0xdf, 0x5d, 0x2a, 0xef, 0x16, 0x6f, 0x5d, 0x2b, 0x75, 0x4c,
|
||||
0x0e, 0xe0, 0xda, 0xc4, 0xd7, 0x05, 0x52, 0x28, 0x25, 0xc4, 0x3f, 0xe0, 0x55, 0x07, 0x93, 0x21,
|
||||
0x80, 0x2b, 0x49, 0x0c, 0x00, 0xd7, 0x13, 0xb3, 0xe0, 0x29, 0x93, 0x66, 0x0a, 0x4b, 0x88, 0x63,
|
||||
0xac, 0x14, 0x5f, 0x9b, 0x1c, 0xf4, 0xe3, 0xe7, 0xeb, 0xac, 0x2d, 0xe3, 0x08, 0x7d, 0xcf, 0xce,
|
||||
0x12, 0xf0, 0xcd, 0x68, 0x6e, 0xe2, 0x06, 0x16, 0x38, 0x17, 0x93, 0xbc, 0xf9, 0xfe, 0x8e, 0xb2,
|
||||
0x14, 0x99, 0x76, 0x82, 0xf7, 0xc2, 0x93, 0x46, 0x95, 0xd7, 0x81, 0x03, 0x16, 0xae, 0xfc, 0x39,
|
||||
0xb0, 0x26, 0xd1, 0x74, 0x73, 0x82, 0x21, 0xdb, 0x74, 0x48, 0xd7, 0xc2, 0xae, 0x73, 0x2d, 0x81,
|
||||
0x84, 0x61, 0x6d, 0x1d, 0x8a, 0xb4, 0x9d, 0xb3, 0x2a, 0xa7, 0x9b, 0x08, 0x89, 0x2a, 0x96, 0x98,
|
||||
0xc1, 0x64, 0xf2, 0x10, 0x8b, 0x8d, 0xaa, 0xbe, 0x0d, 0x37, 0xaa, 0x42, 0x94, 0x9f, 0xae, 0x18,
|
||||
0x64, 0xcd, 0x77, 0x24, 0x41, 0xc8, 0x6a, 0xbc, 0x80, 0x7f, 0xd8, 0x1f, 0x94, 0x29, 0xe7, 0x38,
|
||||
0xb8, 0x7f, 0x90, 0x54, 0xe4, 0xb6, 0xb8, 0x30, 0x7f, 0x40, 0xeb, 0x60, 0x6c, 0x6a, 0x07, 0x36,
|
||||
0x5b, 0xfc, 0x09, 0x72, 0xff, 0x02, 0x96, 0xce, 0xd6, 0xdc, 0x07, 0x80, 0x25, 0x70, 0x6f, 0x9e,
|
||||
0x63, 0xac, 0x97, 0x1d, 0x3d, 0x3a, 0x26, 0x83, 0xc8, 0xe3, 0x99, 0xa8, 0x10, 0xf4, 0x68, 0xf4,
|
||||
0xf3, 0x8c, 0x38, 0x8d, 0xd2, 0x13, 0xd5, 0x95, 0xce, 0x80, 0x1e, 0xcf, 0x14, 0xb8, 0x16, 0x64,
|
||||
0x28, 0xf1, 0x40, 0xd9, 0xa0, 0x24, 0x13, 0x84, 0x3b, 0x8b, 0x92, 0x73, 0x67, 0x77, 0x93, 0xfe,
|
||||
0x07, 0x67, 0x7d, 0xcf, 0x7f, 0x9e, 0x7b, 0x74, 0x6a, 0x07, 0xb8, 0x1f, 0xdc, 0xa6, 0xdd, 0xbb,
|
||||
0x63, 0xc8, 0x5d, 0xde, 0x48, 0x93, 0x34, 0xf3, 0x3b, 0xa6, 0x4d, 0x08, 0xdf, 0xd4, 0x40, 0x55,
|
||||
0x0c, 0x85, 0x6c, 0xda, 0x41, 0xc2, 0xd5, 0x4f, 0x08, 0xfc, 0x87, 0x43, 0x22, 0x42, 0x59, 0x53,
|
||||
0xbe, 0x21, 0xe4, 0x09, 0xcc, 0x6a, 0xa2, 0x50, 0x6e, 0x2d, 0x9a, 0x61, 0xdc, 0x36, 0xd0, 0x51,
|
||||
0xab, 0xdb, 0x24, 0xad, 0x37, 0xe5, 0x47, 0x93, 0xcd, 0x74, 0x94, 0x17, 0x71, 0x8f, 0xc1, 0xca,
|
||||
0x3f, 0xfa, 0x4f, 0xd8, 0xb5, 0xbb, 0xb6, 0xf3, 0xab, 0x7d, 0xa6, 0x65, 0x24, 0x42, 0x2a, 0x4b,
|
||||
0x3a, 0xbb, 0x7c, 0xcf, 0x1e, 0x32, 0x12, 0xf4, 0xe1, 0x90, 0xb3, 0x50, 0xb1, 0xfc, 0x7c, 0x6b,
|
||||
0x91, 0x06, 0x18, 0x02, 0x33, 0x83, 0x4b, 0x20, 0x75, 0xf5, 0xad, 0x37, 0x5d, 0xb8, 0xc2, 0xb5,
|
||||
0x23, 0x28, 0x32, 0x50, 0x36, 0xd8, 0x6d, 0x65, 0x98, 0xca, 0x58, 0x51, 0x91, 0x72, 0x3b, 0x42,
|
||||
0xd5, 0xcd, 0x09, 0x1e, 0xcf, 0x8c, 0x88, 0x4c, 0xf4, 0x4d, 0x31, 0x0b, 0xd3, 0x81, 0xe8, 0x28,
|
||||
0x2b, 0xf6, 0x6d, 0x70, 0x34, 0x0f, 0x7e, 0x8d, 0xfc, 0x03, 0xc4, 0x8c, 0xf2, 0xc5, 0x6c, 0xbd,
|
||||
0xf8, 0x14, 0xec, 0x2b, 0x0a, 0xb7, 0x7e, 0x8b, 0xcf, 0xb5, 0x58, 0xa5, 0x4d, 0x34, 0x61, 0x58,
|
||||
0xa3, 0xfd, 0x72, 0x4e, 0x20, 0xbe, 0x96, 0xc4, 0x6c, 0xec, 0x1f, 0xb6, 0x0c, 0x15, 0xbc, 0x71,
|
||||
0x30, 0xa1, 0x57, 0x13, 0x85, 0x5c, 0xf3, 0x36, 0x42, 0x8b, 0x22, 0x26, 0x5b, 0xfb, 0x76, 0x01,
|
||||
0xf3, 0xf3, 0xff, 0xe1, 0x6b, 0xf3, 0x8c, 0x25, 0xe3, 0x60, 0xee, 0xc8, 0x8f, 0xe3, 0xdb, 0xa8,
|
||||
0x6e, 0xed, 0x1e, 0x5a, 0xd4, 0xd2, 0xff, 0x28, 0xea, 0x63, 0x56, 0xc1, 0xc3, 0xee, 0x37, 0x57,
|
||||
0xd7, 0x6d, 0x92, 0xf8, 0x2b, 0x9a, 0x55, 0x62, 0x7b, 0x08, 0x27, 0xde, 0x13, 0x27, 0x35, 0x30,
|
||||
0x20, 0xb3, 0x43, 0x31, 0xeb, 0xf6, 0x28, 0xb4, 0x6e, 0x92, 0x82, 0x48, 0x1e, 0xbf, 0xe6, 0x3d,
|
||||
0x84, 0x0d, 0x9f, 0x5f, 0x55, 0x97, 0x96, 0x26, 0x65, 0x59, 0xfa, 0x6a, 0x72, 0xc6, 0x49, 0xa5,
|
||||
0x0d, 0xd0, 0x84, 0x17, 0x97, 0x56, 0x2e, 0xff, 0x82, 0x76, 0x61, 0x75, 0x9f, 0x15, 0xd2, 0x08,
|
||||
0xbb, 0x24, 0xb5, 0xba, 0xaa, 0x5e, 0x20, 0xdd, 0x03, 0x4c, 0x3c, 0x54, 0xd8, 0x8f, 0x87, 0x49,
|
||||
};
|
||||
/// \endcond
|
||||
|
@@ -208,33 +208,44 @@ void eap::method_tls::begin_session(
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!m_store.create(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (HCRYPTPROV)NULL, CERT_SYSTEM_STORE_CURRENT_USER, _T("My")))
|
||||
throw win_runtime_error(__FUNCTION__ " CertOpenStore failed.");
|
||||
|
||||
// Prepare client credentials for Schannel.
|
||||
PCCERT_CONTEXT certs[] = { m_cred.m_cert ? (PCCERT_CONTEXT)m_cred.m_cert : NULL };
|
||||
vector<PCCERT_CONTEXT> certs;
|
||||
if (!m_cred.empty()) {
|
||||
vector<unsigned char> hash;
|
||||
for (PCCERT_CONTEXT cert = NULL; (cert = CertEnumCertificatesInStore(m_store, cert)) != NULL;) {
|
||||
if (CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID, hash) &&
|
||||
hash == m_cred.m_cert_hash)
|
||||
certs.push_back(cert);
|
||||
}
|
||||
}
|
||||
SCHANNEL_CRED cred = {
|
||||
SCHANNEL_CRED_VERSION, // dwVersion
|
||||
m_cred.m_cert ? 1ul : 0ul, // cCreds
|
||||
certs, // paCred
|
||||
NULL, // hRootStore: Not valid for client credentials
|
||||
0, // cMappers
|
||||
NULL, // aphMappers
|
||||
0, // cSupportedAlgs: Use system configured default
|
||||
NULL, // palgSupportedAlgs: Use system configured default
|
||||
SP_PROT_TLS1_X_CLIENT | (SP_PROT_TLS1_2_CLIENT<<2), // grbitEnabledProtocols: TLS 1.x
|
||||
0, // dwMinimumCipherStrength: Use system configured default
|
||||
0, // dwMaximumCipherStrength: Use system configured default
|
||||
0, // dwSessionLifespan: Use system configured default = 10hr
|
||||
SCHANNEL_CRED_VERSION, // dwVersion
|
||||
(DWORD)certs.size(), // cCreds
|
||||
certs.data(), // paCred
|
||||
NULL, // hRootStore: Not valid for client credentials
|
||||
0, // cMappers
|
||||
NULL, // aphMappers
|
||||
0, // cSupportedAlgs: Use system configured default
|
||||
NULL, // palgSupportedAlgs: Use system configured default
|
||||
SP_PROT_TLS1_X_CLIENT | (SP_PROT_TLS1_2_CLIENT<<2), // grbitEnabledProtocols: TLS 1.x
|
||||
0, // dwMinimumCipherStrength: Use system configured default
|
||||
0, // dwMaximumCipherStrength: Use system configured default
|
||||
0, // dwSessionLifespan: Use system configured default = 10hr
|
||||
#if EAP_TLS >= EAP_TLS_SCHANNEL_FULL
|
||||
SCH_CRED_AUTO_CRED_VALIDATION | // dwFlags: Let Schannel verify server certificate
|
||||
SCH_CRED_AUTO_CRED_VALIDATION | // dwFlags: Let Schannel verify server certificate
|
||||
#else
|
||||
SCH_CRED_MANUAL_CRED_VALIDATION | // dwFlags: Prevent Schannel verify server certificate (we want to use custom root CA store and multiple name checking)
|
||||
SCH_CRED_MANUAL_CRED_VALIDATION | // dwFlags: Prevent Schannel verify server certificate (we want to use custom root CA store and multiple name checking)
|
||||
#endif
|
||||
SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE | // dwFlags: Do not attempt online revocation check - we do not expect to have network connection yet
|
||||
SCH_CRED_IGNORE_NO_REVOCATION_CHECK | // dwFlags: Ignore no-revocation-check errors - as we cannot check for revocation, it makes little sense to insist certificate has to have revocation set-up
|
||||
SCH_CRED_IGNORE_REVOCATION_OFFLINE | // dwFlags: Ignore offline-revocation errors - we do not expect to have network connection yet
|
||||
SCH_CRED_NO_DEFAULT_CREDS | // dwFlags: If client certificate we provided is not acceptable, do not try to select one on your own
|
||||
(m_cfg.m_server_names.empty() ? SCH_CRED_NO_SERVERNAME_CHECK : 0) | // dwFlags: When no expected server name is given, do not do the server name check.
|
||||
0x00400000ul /*SCH_USE_STRONG_CRYPTO*/, // dwFlags: Do not use broken ciphers
|
||||
0 // dwCredFormat
|
||||
SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE | // dwFlags: Do not attempt online revocation check - we do not expect to have network connection yet
|
||||
SCH_CRED_IGNORE_NO_REVOCATION_CHECK | // dwFlags: Ignore no-revocation-check errors - as we cannot check for revocation, it makes little sense to insist certificate has to have revocation set-up
|
||||
SCH_CRED_IGNORE_REVOCATION_OFFLINE | // dwFlags: Ignore offline-revocation errors - we do not expect to have network connection yet
|
||||
SCH_CRED_NO_DEFAULT_CREDS | // dwFlags: If client certificate we provided is not acceptable, do not try to select one on your own
|
||||
(m_cfg.m_server_names.empty() ? SCH_CRED_NO_SERVERNAME_CHECK : 0) | // dwFlags: When no expected server name is given, do not do the server name check.
|
||||
0x00400000ul /*SCH_USE_STRONG_CRYPTO*/, // dwFlags: Do not use broken ciphers
|
||||
0 // dwCredFormat
|
||||
};
|
||||
SECURITY_STATUS stat = m_sc_cred.acquire(NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, &cred);
|
||||
if (FAILED(stat))
|
||||
@@ -244,6 +255,14 @@ void eap::method_tls::begin_session(
|
||||
}
|
||||
|
||||
|
||||
void eap::method_tls::end_session()
|
||||
{
|
||||
m_store.free();
|
||||
|
||||
method::end_session();
|
||||
}
|
||||
|
||||
|
||||
EapPeerMethodResponseAction eap::method_tls::process_request_packet(
|
||||
_In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
|
||||
_In_ DWORD dwReceivedPacketSize)
|
||||
|
Reference in New Issue
Block a user