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 | |
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
-rw-r--r-- | CMakeLists.txt | 11 | ||||
-rw-r--r-- | CTestCustom.cmake.in | 1 | ||||
-rw-r--r-- | Source/CMakeLists.txt | 7 | ||||
-rw-r--r-- | Source/cmSystemTools.cxx | 88 | ||||
-rw-r--r-- | Source/cmSystemTools.h | 3 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 16 |
6 files changed, 111 insertions, 15 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 36244dd..5e13a7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,17 +144,6 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES) endmacro() - - - -if(NOT CMake_TEST_EXTERNAL_CMAKE) - set(CMAKE_BUILD_ON_VISUAL_STUDIO 0) - if(WIN32 AND NOT UNIX AND NOT MINGW) - set(CMAKE_BUILD_ON_VISUAL_STUDIO 1) - endif() -endif() - - #----------------------------------------------------------------------- # a macro to determine the generator and ctest executable to use # for testing. Simply to improve readability of the main script. diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in index f29ac70..d3cff51 100644 --- a/CTestCustom.cmake.in +++ b/CTestCustom.cmake.in @@ -32,6 +32,7 @@ set(CTEST_CUSTOM_WARNING_EXCEPTION "remark: .*LOOP WAS VECTORIZED" "warning .980: wrong number of actual arguments to intrinsic function .std::basic_" "LINK : warning LNK4089: all references to.*ADVAPI32.dll.*discarded by /OPT:REF" + "LINK : warning LNK4089: all references to.*CRYPT32.dll.*discarded by /OPT:REF" "LINK : warning LNK4089: all references to.*PSAPI.DLL.*discarded by /OPT:REF" "LINK : warning LNK4089: all references to.*RPCRT4.dll.*discarded by /OPT:REF" "LINK : warning LNK4089: all references to.*SHELL32.dll.*discarded by /OPT:REF" diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 428b364..16b9ea1 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -556,9 +556,10 @@ if(APPLE) target_link_libraries(CMakeLib "-framework CoreFoundation") endif() -if(CMAKE_BUILD_ON_VISUAL_STUDIO OR MINGW) - # We need the rpcrt4 library for at least the VS7-VC10 generators. - target_link_libraries(CMakeLib rpcrt4) +if(WIN32 AND NOT UNIX) + # We need the rpcrt4 library on Windows. + # We need the crypt32 library on Windows for crypto/cert APIs. + target_link_libraries(CMakeLib rpcrt4 crypt32) endif() # 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) diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index fb58307..c12a1db 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -194,6 +194,9 @@ public: /** Compute the md5sum of a string. */ static std::string ComputeStringMD5(const std::string& input); + ///! Get the SHA thumbprint for a certificate file + static std::string ComputeCertificateThumbprint(const std::string& source); + /** * Run a single executable command * diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index e7716d8..4c380f7 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2893,7 +2893,7 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile() (*this->BuildFileStream) << cmVS10EscapeXML(artifactDir) << "\\</AppxPackageArtifactsDir>\n"; this->WriteString("<ProjectPriFullPath>" - "$(TargetDir)resources.pri</ProjectPriFullPath>", 2); + "$(TargetDir)resources.pri</ProjectPriFullPath>\n", 2); // If we are missing files and we don't have a certificate and // aren't targeting WP8.0, add a default certificate @@ -2911,6 +2911,13 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile() this->WriteString("<", 2); (*this->BuildFileStream) << "PackageCertificateKeyFile>" << pfxFile << "</PackageCertificateKeyFile>\n"; + std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile); + if (!thumb.empty()) + { + this->WriteString("<PackageCertificateThumbprint>", 2); + (*this->BuildFileStream) << thumb + << "</PackageCertificateThumbprint>\n"; + } this->WriteString("</PropertyGroup>\n", 1); } else if(!pfxFile.empty()) @@ -2919,6 +2926,13 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile() this->WriteString("<", 2); (*this->BuildFileStream) << "PackageCertificateKeyFile>" << pfxFile << "</PackageCertificateKeyFile>\n"; + std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile); + if (!thumb.empty()) + { + this->WriteString("<PackageCertificateThumbprint>", 2); + (*this->BuildFileStream) << thumb + << "</PackageCertificateThumbprint>\n"; + } this->WriteString("</PropertyGroup>\n", 1); } } |