|
@@ -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);
|
|
|
}
|