diff options
author | Gilles Khouzam <gillesk@microsoft.com> | 2015-08-21 21:15:38 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2015-08-27 17:35:18 (GMT) |
commit | ac0bb4333d13e633e26d107f288162d7d6a37b3a (patch) | |
tree | 469045dc2e7aa66efe3da92cf3b8832e1ba3dbd0 /Source/cmSystemTools.cxx | |
parent | 92b835ec9d17b190b13da93702f0eb416b665a48 (diff) | |
download | CMake-ac0bb4333d13e633e26d107f288162d7d6a37b3a.zip CMake-ac0bb4333d13e633e26d107f288162d7d6a37b3a.tar.gz CMake-ac0bb4333d13e633e26d107f288162d7d6a37b3a.tar.bz2 |
VS: Windows Store/Phone package cert thumbprint
Add the PackageCertificateThumbprint property when there is a
certificate on a WindowsStore or Phone app.
Diffstat (limited to 'Source/cmSystemTools.cxx')
-rw-r--r-- | Source/cmSystemTools.cxx | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index a117238..583e1d0 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1013,6 +1013,94 @@ std::string cmSystemTools::ComputeStringMD5(const std::string& input) #endif } +//---------------------------------------------------------------------------- +std::string cmSystemTools::ComputeCertificateThumbprint( + const std::string& source) +{ + std::string thumbprint; + +#ifdef _WIN32 + BYTE* certData = NULL; + CRYPT_INTEGER_BLOB cryptBlob; + HCERTSTORE certStore = NULL; + PCCERT_CONTEXT certContext = NULL; + + HANDLE certFile = CreateFile(cmsys::Encoding::ToWide(source.c_str()).c_str(), + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (certFile != INVALID_HANDLE_VALUE && certFile != NULL) + { + DWORD fileSize = GetFileSize(certFile, NULL); + if (fileSize != INVALID_FILE_SIZE) + { + certData = new BYTE[fileSize]; + if (certData != NULL) + { + DWORD dwRead = 0; + if (ReadFile(certFile, certData, fileSize, &dwRead, NULL)) + { + cryptBlob.cbData = fileSize; + cryptBlob.pbData = certData; + + // Verify that this is a valid cert + if (PFXIsPFXBlob(&cryptBlob)) + { + // Open the certificate as a store + certStore = PFXImportCertStore( + &cryptBlob, NULL, CRYPT_EXPORTABLE); + if (certStore != NULL) + { + // There should only be 1 cert. + certContext = CertEnumCertificatesInStore(certStore, + certContext); + if (certContext != NULL) + { + // 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 + sprintf(pHashPrint, "%02X", hashData[i]); + pHashPrint += 2; + } + *pHashPrint = '\0'; + thumbprint = hashPrint; + } + CertFreeCertificateContext(certContext); + } + CertCloseStore(certStore, 0); + } + } + } + delete[] certData; + } + } + CloseHandle(certFile); + } +#else + (void)source; + cmSystemTools::Message("ComputeCertificateThumbprint is not implemented", + "Error"); +#endif + + return thumbprint; +} + void cmSystemTools::Glob(const std::string& directory, const std::string& regexp, std::vector<std::string>& files) |