cmSystemTools: move ComputeCertificateThumbprint to the only consumer

There's no need to have this API on `cmSystemTools` with only a single
consumer.
This commit is contained in:
Ben Boeckel
2023-08-07 21:21:47 -04:00
parent a4e4daceaf
commit 36bd3d82f8
3 changed files with 71 additions and 85 deletions

View File

@@ -47,12 +47,6 @@
# endif
#endif
#if !defined(CMAKE_BOOTSTRAP)
# if defined(_WIN32)
# include <cm/memory>
# endif
#endif
#if defined(CMake_USE_MACH_PARSER)
# include "cmMachO.h"
#endif
@@ -1307,76 +1301,6 @@ void cmSystemTools::MoveFileIfDifferent(const std::string& source,
RemoveFile(source);
}
#ifndef CMAKE_BOOTSTRAP
# ifdef _WIN32
std::string cmSystemTools::ComputeCertificateThumbprint(
const std::string& source)
{
std::string thumbprint;
CRYPT_INTEGER_BLOB cryptBlob;
HCERTSTORE certStore = nullptr;
PCCERT_CONTEXT certContext = nullptr;
HANDLE certFile = CreateFileW(
cmsys::Encoding::ToWide(source.c_str()).c_str(), GENERIC_READ,
FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (certFile != INVALID_HANDLE_VALUE && certFile != nullptr) {
DWORD fileSize = GetFileSize(certFile, nullptr);
if (fileSize != INVALID_FILE_SIZE) {
auto certData = cm::make_unique<BYTE[]>(fileSize);
if (certData != nullptr) {
DWORD dwRead = 0;
if (ReadFile(certFile, certData.get(), fileSize, &dwRead, nullptr)) {
cryptBlob.cbData = fileSize;
cryptBlob.pbData = certData.get();
// Verify that this is a valid cert
if (PFXIsPFXBlob(&cryptBlob)) {
// Open the certificate as a store
certStore =
PFXImportCertStore(&cryptBlob, nullptr, CRYPT_EXPORTABLE);
if (certStore != nullptr) {
// There should only be 1 cert.
certContext =
CertEnumCertificatesInStore(certStore, certContext);
if (certContext != nullptr) {
// The hash is 20 bytes
BYTE hashData[20];
DWORD hashLength = 20;
// Buffer to print the hash. Each byte takes 2 chars +
// terminating character
char hashPrint[41];
char* pHashPrint = hashPrint;
// Get the hash property from the certificate
if (CertGetCertificateContextProperty(
certContext, CERT_HASH_PROP_ID, hashData, &hashLength)) {
for (DWORD i = 0; i < hashLength; i++) {
// Convert each byte to hexadecimal
snprintf(pHashPrint, 3, "%02X", hashData[i]);
pHashPrint += 2;
}
*pHashPrint = '\0';
thumbprint = hashPrint;
}
CertFreeCertificateContext(certContext);
}
CertCloseStore(certStore, 0);
}
}
}
}
}
CloseHandle(certFile);
}
return thumbprint;
}
# endif
#endif
void cmSystemTools::Glob(const std::string& directory,
const std::string& regexp,
std::vector<std::string>& files)

View File

@@ -213,13 +213,6 @@ public:
static void MoveFileIfDifferent(const std::string& source,
const std::string& destination);
#ifndef CMAKE_BOOTSTRAP
# ifdef _WIN32
//! Get the SHA thumbprint for a certificate file
static std::string ComputeCertificateThumbprint(const std::string& source);
# endif
#endif
/**
* Run a single executable command
*

View File

@@ -17,6 +17,8 @@
#include <cmext/string_view>
#include "windows.h"
// include wincrypt.h after windows.h
#include <wincrypt.h>
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
@@ -4867,6 +4869,73 @@ void cmVisualStudio10TargetGenerator::WriteSingleSDKReference(
.Attribute("Include", cmStrCat(extension, ", Version=", version));
}
namespace {
std::string ComputeCertificateThumbprint(const std::string& source)
{
std::string thumbprint;
CRYPT_INTEGER_BLOB cryptBlob;
HCERTSTORE certStore = nullptr;
PCCERT_CONTEXT certContext = nullptr;
HANDLE certFile = CreateFileW(
cmsys::Encoding::ToWide(source.c_str()).c_str(), GENERIC_READ,
FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (certFile != INVALID_HANDLE_VALUE && certFile != nullptr) {
DWORD fileSize = GetFileSize(certFile, nullptr);
if (fileSize != INVALID_FILE_SIZE) {
auto certData = cm::make_unique<BYTE[]>(fileSize);
if (certData != nullptr) {
DWORD dwRead = 0;
if (ReadFile(certFile, certData.get(), fileSize, &dwRead, nullptr)) {
cryptBlob.cbData = fileSize;
cryptBlob.pbData = certData.get();
// Verify that this is a valid cert
if (PFXIsPFXBlob(&cryptBlob)) {
// Open the certificate as a store
certStore =
PFXImportCertStore(&cryptBlob, nullptr, CRYPT_EXPORTABLE);
if (certStore != nullptr) {
// There should only be 1 cert.
certContext =
CertEnumCertificatesInStore(certStore, certContext);
if (certContext != nullptr) {
// The hash is 20 bytes
BYTE hashData[20];
DWORD hashLength = 20;
// Buffer to print the hash. Each byte takes 2 chars +
// terminating character
char hashPrint[41];
char* pHashPrint = hashPrint;
// Get the hash property from the certificate
if (CertGetCertificateContextProperty(
certContext, CERT_HASH_PROP_ID, hashData, &hashLength)) {
for (DWORD i = 0; i < hashLength; i++) {
// Convert each byte to hexadecimal
snprintf(pHashPrint, 3, "%02X", hashData[i]);
pHashPrint += 2;
}
*pHashPrint = '\0';
thumbprint = hashPrint;
}
CertFreeCertificateContext(certContext);
}
CertCloseStore(certStore, 0);
}
}
}
}
}
CloseHandle(certFile);
}
return thumbprint;
}
}
void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile(
Elem& e0)
{
@@ -4913,14 +4982,14 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile(
}
e1.Element("PackageCertificateKeyFile", pfxFile);
std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile);
std::string thumb = ComputeCertificateThumbprint(pfxFile);
if (!thumb.empty()) {
e1.Element("PackageCertificateThumbprint", thumb);
}
} else if (!pfxFile.empty()) {
Elem e1(e0, "PropertyGroup");
e1.Element("PackageCertificateKeyFile", pfxFile);
std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile);
std::string thumb = ComputeCertificateThumbprint(pfxFile);
if (!thumb.empty()) {
e1.Element("PackageCertificateThumbprint", thumb);
}