VS: Windows Store/Phone package cert thumbprint
Add the PackageCertificateThumbprint property when there is a certificate on a WindowsStore or Phone app.
This commit is contained in:
parent
92b835ec9d
commit
ac0bb4333d
|
@ -32,6 +32,7 @@ set(CTEST_CUSTOM_WARNING_EXCEPTION
|
||||||
"remark: .*LOOP WAS VECTORIZED"
|
"remark: .*LOOP WAS VECTORIZED"
|
||||||
"warning .980: wrong number of actual arguments to intrinsic function .std::basic_"
|
"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.*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.*PSAPI.DLL.*discarded by /OPT:REF"
|
||||||
"LINK : warning LNK4089: all references to.*RPCRT4.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"
|
"LINK : warning LNK4089: all references to.*SHELL32.dll.*discarded by /OPT:REF"
|
||||||
|
|
|
@ -558,7 +558,8 @@ endif()
|
||||||
|
|
||||||
if(WIN32 AND NOT UNIX)
|
if(WIN32 AND NOT UNIX)
|
||||||
# We need the rpcrt4 library on Windows.
|
# 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()
|
endif()
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -1013,6 +1013,94 @@ std::string cmSystemTools::ComputeStringMD5(const std::string& input)
|
||||||
#endif
|
#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,
|
void cmSystemTools::Glob(const std::string& directory,
|
||||||
const std::string& regexp,
|
const std::string& regexp,
|
||||||
std::vector<std::string>& files)
|
std::vector<std::string>& files)
|
||||||
|
|
|
@ -194,6 +194,9 @@ public:
|
||||||
/** Compute the md5sum of a string. */
|
/** Compute the md5sum of a string. */
|
||||||
static std::string ComputeStringMD5(const std::string& input);
|
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
|
* Run a single executable command
|
||||||
*
|
*
|
||||||
|
|
|
@ -2893,7 +2893,7 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile()
|
||||||
(*this->BuildFileStream) << cmVS10EscapeXML(artifactDir) <<
|
(*this->BuildFileStream) << cmVS10EscapeXML(artifactDir) <<
|
||||||
"\\</AppxPackageArtifactsDir>\n";
|
"\\</AppxPackageArtifactsDir>\n";
|
||||||
this->WriteString("<ProjectPriFullPath>"
|
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
|
// If we are missing files and we don't have a certificate and
|
||||||
// aren't targeting WP8.0, add a default certificate
|
// aren't targeting WP8.0, add a default certificate
|
||||||
|
@ -2911,6 +2911,13 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile()
|
||||||
this->WriteString("<", 2);
|
this->WriteString("<", 2);
|
||||||
(*this->BuildFileStream) << "PackageCertificateKeyFile>"
|
(*this->BuildFileStream) << "PackageCertificateKeyFile>"
|
||||||
<< pfxFile << "</PackageCertificateKeyFile>\n";
|
<< 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);
|
this->WriteString("</PropertyGroup>\n", 1);
|
||||||
}
|
}
|
||||||
else if(!pfxFile.empty())
|
else if(!pfxFile.empty())
|
||||||
|
@ -2919,6 +2926,13 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile()
|
||||||
this->WriteString("<", 2);
|
this->WriteString("<", 2);
|
||||||
(*this->BuildFileStream) << "PackageCertificateKeyFile>"
|
(*this->BuildFileStream) << "PackageCertificateKeyFile>"
|
||||||
<< pfxFile << "</PackageCertificateKeyFile>\n";
|
<< 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);
|
this->WriteString("</PropertyGroup>\n", 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue