Reputation: 27
(Sorry for my bad English.) I have some problems in my code.so I will try to explain my problem. I have a simple exe file with signed(pkcs7). I want to verify this file (without an internet connection). I don't want to use WinVerifyTrust()
because I want to know how windows verify PE file. I wrote some code that first calls CryptQueryObject()
with BLOB_DATA(mapped pe file), and it works fine. Then I can get certificate information: signer, serial, etc. (with CryptGetMsgParam()
) and it also works fine; but, when I go to verify it with CertGetCertificateChain()
I get and error. So, can you help me to solve this problem, which I think is that I don't use CertGetCertificateChain()
correctly?
BOOL bRet = FALSE;
DWORD dwMsgAndCertEncodingType = 0;
DWORD dwContentType = 0;
DWORD dwFormatType = 0;
HCERTSTORE hStore = NULL;
HCRYPTMSG hMsg = NULL;
PCCERT_CONTEXT pCertContext = NULL;
CERT_BLOB blob_data = { 0 };
// CERT_INFO CertInfo = { 0 };
DWORD dwSignerInfo = 0;
PCCERT_CHAIN_CONTEXT pChainContext = NULL;
PCMSG_SIGNER_INFO pSignerInfo = NULL;
CERT_CHAIN_PARA ChainPara = { 0 };
blob_data.pbData = pBuff;
blob_data.cbData = dwSize;
ChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
bRet = CryptQueryObject(CERT_QUERY_OBJECT_BLOB,
&blob_data,
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
CERT_QUERY_FORMAT_FLAG_BINARY,
0,
NULL,
&dwContentType,
NULL,
&hStore,
&hMsg,
&pCertContext);
if (bRet != TRUE)
{
printf("Error CryptQueryObject\n");
return FALSE;
}
if (dwContentType != CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED)
{
printf("Error type\n");
return FALSE;
}
CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSignerInfo);
pSignerInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSignerInfo);
CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, pSignerInfo, &dwSignerInfo);
bRet = CertGetCertificateChain(NULL, (PCCERT_CONTEXT)pCertContext, NULL, NULL, NULL, CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY,
NULL, &pChainContext);
if (bRet != TRUE)
{
printf("Error there\n");
}
Upvotes: 1
Views: 600
Reputation: 51825
One problem (though maybe not the only one) is the fact that your fifth parameter to CertGetCertificateChain()
is NULL
? This should point to a CERT_CHAIN_PARA
structure. (You have one declared but don't appear to either initialize or use it.)
I don't know exactly what data you should put in this, but here's an example using code taken from a real (working) program (one of my own making) that checks digital certificates:
//...
CERT_CHAIN_PARA ChainPara; memset(&ChainPara, 0, sizeof(CERT_CHAIN_PARA));
ChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
ChainPara.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
ChainPara.RequestedUsage.Usage.cUsageIdentifier = 0;
//...
bRet = CertGetCertificateChain(NULL, (PCCERT_CONTEXT)pCertContext, NULL, NULL, &ChainPara,
CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY, NULL, &pChainContext);
//...
You can look at the documentation for CERT_CHAIN_PARA
to get some hints on what actual data/values you should set.
Hope this helps! (Feel free to ask for further clarification and or suggestions.)
Upvotes: 1