WinStd/src/Crypt.cpp
Simon Rozman 0d56d79c35 Update Copyright year
Signed-off-by: Simon Rozman <simon@rozman.si>
2022-01-07 11:20:07 +01:00

213 lines
5.5 KiB
C++

/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 1991-2022 Amebis
Copyright © 2016 GÉANT
*/
#include "PCH.h"
#pragma comment(lib, "Crypt32.lib")
//////////////////////////////////////////////////////////////////////
// winstd::cert_context
//////////////////////////////////////////////////////////////////////
winstd::cert_context::~cert_context()
{
if (m_h != invalid)
CertFreeCertificateContext(m_h);
}
void winstd::cert_context::free_internal() noexcept
{
CertFreeCertificateContext(m_h);
}
winstd::cert_context::handle_type winstd::cert_context::duplicate_internal(_In_ handle_type h) const noexcept
{
return CertDuplicateCertificateContext(h);
}
//////////////////////////////////////////////////////////////////////
// winstd::cert_chain_context
//////////////////////////////////////////////////////////////////////
winstd::cert_chain_context::~cert_chain_context()
{
if (m_h != invalid)
CertFreeCertificateChain(m_h);
}
void winstd::cert_chain_context::free_internal() noexcept
{
CertFreeCertificateChain(m_h);
}
winstd::cert_chain_context::handle_type winstd::cert_chain_context::duplicate_internal(_In_ handle_type h) const noexcept
{
return CertDuplicateCertificateChain(h);
}
//////////////////////////////////////////////////////////////////////
// winstd::cert_store
//////////////////////////////////////////////////////////////////////
winstd::cert_store::~cert_store()
{
if (m_h != invalid)
CertCloseStore(m_h, 0);
}
void winstd::cert_store::free_internal() noexcept
{
CertCloseStore(m_h, 0);
}
//////////////////////////////////////////////////////////////////////
// winstd::crypt_prov
//////////////////////////////////////////////////////////////////////
winstd::crypt_prov::~crypt_prov()
{
if (m_h != invalid)
CryptReleaseContext(m_h, 0);
}
void winstd::crypt_prov::free_internal() noexcept
{
CryptReleaseContext(m_h, 0);
}
//////////////////////////////////////////////////////////////////////
// winstd::crypt_hash
//////////////////////////////////////////////////////////////////////
winstd::crypt_hash::~crypt_hash()
{
if (m_h != invalid)
CryptDestroyHash(m_h);
}
void winstd::crypt_hash::free_internal() noexcept
{
CryptDestroyHash(m_h);
}
winstd::crypt_hash::handle_type winstd::crypt_hash::duplicate_internal(_In_ handle_type h) const noexcept
{
handle_type hNew = invalid;
return CryptDuplicateHash(h, NULL, 0, &hNew) ? hNew : invalid;
}
//////////////////////////////////////////////////////////////////////
// winstd::crypt_key
//////////////////////////////////////////////////////////////////////
winstd::crypt_key::~crypt_key()
{
if (m_h != invalid)
CryptDestroyKey(m_h);
}
bool winstd::crypt_key::create_exp1(_In_ HCRYPTPROV hProv, _In_ DWORD dwKeySpec)
{
if (dwKeySpec != AT_KEYEXCHANGE && dwKeySpec != AT_SIGNATURE) {
SetLastError(ERROR_INVALID_PARAMETER);
return false;
}
// Generate the private key.
handle_type h;
if (CryptGenKey(hProv, dwKeySpec, CRYPT_EXPORTABLE, &h)) {
// Export the private key, we'll convert it to a private exponent of one key.
std::vector<BYTE, sanitizing_allocator<BYTE>> key_blob;
if (CryptExportKey(h, 0, PRIVATEKEYBLOB, 0, key_blob)) {
CryptDestroyKey(h);
// Get the byte length of the key.
size_t
size_key = *reinterpret_cast<DWORD*>(&key_blob[12])/8,
size_prime = size_key/2;
// Modify the Exponent in Key BLOB format
// Key BLOB format is documented in SDK
// Convert pubexp in rsapubkey to 1
LPBYTE ptr = &key_blob[16];
*reinterpret_cast<DWORD*>(ptr) = 1;
ptr += sizeof(DWORD);
// Skip modulus, prime1, prime2
ptr += size_key;
ptr += size_prime;
ptr += size_prime;
// Convert exponent1 to 1
ptr[0] = 1;
memset(ptr + 1, 0, size_prime - 1);
ptr += size_prime;
// Convert exponent2 to 1
ptr[0] = 1;
memset(ptr + 1, 0, size_prime - 1);
ptr += size_prime;
// Skip coefficient
ptr += size_prime;
// Convert privateExponent to 1
ptr[0] = 1;
memset(ptr + 1, 0, size_key - 1);
// Import the exponent-of-one private key.
if (CryptImportKey(hProv, key_blob.data(), static_cast<DWORD>(key_blob.size()), 0, 0, &h)) {
attach(h);
return true;
}
} else
CryptDestroyKey(h);
}
return false;
}
void winstd::crypt_key::free_internal() noexcept
{
CryptDestroyKey(m_h);
}
winstd::crypt_key::handle_type winstd::crypt_key::duplicate_internal(_In_ handle_type h) const noexcept
{
handle_type hNew = invalid;
return CryptDuplicateKey(h, NULL, 0, &hNew) ? hNew : invalid;
}
//////////////////////////////////////////////////////////////////////
// winstd::data_blob
//////////////////////////////////////////////////////////////////////
#pragma warning(suppress: 26432) // Copy constructor and assignment operator are also present, but not detected by code analysis as they are using base type source object reference.
winstd::data_blob::~data_blob()
{
if (pbData != NULL)
LocalFree(pbData);
}