我从您的问题中了解到,您需要使用分离签名验证 PKC7。为此,您可以使用函数CryptVerifyDetachedMessageSignature。
示例代码:
CRYPT_VERIFY_MESSAGE_PARA vparam = { 0 };
vparam.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
vparam.dwMsgAndCertEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
vparam.pfnGetSignerCertificate = nullptr;
vparam.pvGetArg = nullptr;
/* read your files somehow */
std::vector<char> sig;
if (!ReadFile("LOCALSIG.DSA", &sig))
{
std::cout << "Failed to read file" << std::endl;
return;
}
std::vector<char> mes;
if (!ReadFile("LOCALSIG.SF", &mes))
{
std::cout << "Failed to read file" << std::endl;
return;
}
/* CryptVerifyDetachedMessageSignature requires array of messages to verify */
const BYTE* marray[] = {
reinterpret_cast<BYTE*>(mes.data())
};
DWORD marray_len[] = {
static_cast<DWORD>(mes.size())
};
if (!CryptVerifyDetachedMessageSignature(vparam,
0,
reinterpret_cast<BYTE*>(sig.data()),
static_cast<DWORD>(sig.size()),
1, /* number of messages in marray */
marray,
marray_len,
nullptr))
{
std::cout << "Failed to verify signature, error: " << GetLastError() << std::endl;
}
else
{
std::cout << "Verify success, signature valid" << std::endl;
}
更新
要验证证书链,您需要使用CertGetCertificateChain
示例代码:
PCCERT_CHAIN_CONTEXT pChain = nullptr;
CERT_CHAIN_PARA chainPara = {0};
HCERTSTORE hStore = nullptr;
/* you sig file */
DATA_BLOB db = {
static_cast<DWORD>(sig.size()), reinterpret_cast<BYTE *>(sig.data())};
/* you can open your sig file as certificate store */
hStore = CertOpenStore(CERT_STORE_PROV_PKCS7, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, 0, reinterpret_cast<BYTE *>(&db));
if (!hStore)
{
goto Exit;
}
chainPara.cbSize = sizeof(CERT_CHAIN_PARA);
chainPara.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
chainPara.RequestedUsage.Usage.cUsageIdentifier = 0;
if (!CertGetCertificateChain(NULL, /* use default chain engine */
pCert, /* pCert - pointer to signer cert structure (the parameter that was obtained in the previous step) */
NULL,
hStore, /* point to additional store where need to search for certificates to build chain */
&chainPara,
CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT,
NULL,
&pChain))
{
std::cout << "failed to build chain: " << GetLastError();
goto Exit;
}
if (pChain->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR)
{
std::cout << "certificate valid";
goto Exit;
}
if (pChain->TrustStatus.dwErrorStatus & CERT_TRUST_REVOCATION_STATUS_UNKNOWN)
{
std::cout << "certificate revocation status unknown";
}
/* you need to place root certificate to the Trusted Root Store */
if (pChain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_UNTRUSTED_ROOT)
{
std::cout << "untrusted CA";
}
/* and so on */
Exit :
if (pCert)
{
CertFreeCertificateContext(pCert);
}
if (pChain)
{
CertFreeCertificateChain(pChain);
}
if (hStore)
{
CertCloseStore(hStore, 0);
}