diff options
author | Brad King <brad.king@kitware.com> | 2015-08-31 13:48:39 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2015-08-31 13:48:39 (GMT) |
commit | 08ae6ced4d5bbdb536a79e561eed54b28ae56836 (patch) | |
tree | 37057ae8985f74c40a1ac591cae4f2d0f9a640f9 /Source/cmSystemTools.cxx | |
parent | e18f6fe276ea3ca576bb5f8fb910a6532280d900 (diff) | |
parent | ac0bb4333d13e633e26d107f288162d7d6a37b3a (diff) | |
download | CMake-08ae6ced4d5bbdb536a79e561eed54b28ae56836.zip CMake-08ae6ced4d5bbdb536a79e561eed54b28ae56836.tar.gz CMake-08ae6ced4d5bbdb536a79e561eed54b28ae56836.tar.bz2 |
Merge topic 'vs-store-phone-cert-thumbs'
ac0bb433 VS: Windows Store/Phone package cert thumbprint
92b835ec Simplify condition for using rpcrt4 library on Windows
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 3f03b51..0bf97fc 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1012,6 +1012,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) |