Commit ac0bb433 authored by Gilles Khouzam's avatar Gilles Khouzam Committed by Brad King

VS: Windows Store/Phone package cert thumbprint

Add the PackageCertificateThumbprint property when there is a
certificate on a WindowsStore or Phone app.
parent 92b835ec
......@@ -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"
......
......@@ -558,7 +558,8 @@ endif()
if(WIN32 AND NOT UNIX)
# We need the rpcrt4 library on Windows.
target_link_libraries(CMakeLib rpcrt4)
# We need the crypt32 library on Windows for crypto/cert APIs.
target_link_libraries(CMakeLib rpcrt4 crypt32)
endif()
#
......
......@@ -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)
......
......@@ -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
*
......
......@@ -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);
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment