From 36bd3d82f8d69710eaba11f3cefc09db1a1904f5 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Mon, 7 Aug 2023 21:21:47 -0400 Subject: cmSystemTools: move `ComputeCertificateThumbprint` to the only consumer There's no need to have this API on `cmSystemTools` with only a single consumer. --- Source/cmSystemTools.cxx | 76 ------------------------------ Source/cmSystemTools.h | 7 --- Source/cmVisualStudio10TargetGenerator.cxx | 73 +++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 85 deletions(-) diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 74171f4..2bdc928 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -47,12 +47,6 @@ # endif #endif -#if !defined(CMAKE_BOOTSTRAP) -# if defined(_WIN32) -# include -# 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(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& files) diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 5c8d981..9563fd6 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -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 * diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 4bc3ce3..48f3197 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -17,6 +17,8 @@ #include #include "windows.h" +// include wincrypt.h after windows.h +#include #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(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); } -- cgit v0.12