如何以编程方式区分EV和OV代码签名证书?

时间:2018-06-26 09:04:58

标签: c++ winapi code-signing authenticode

我知道Microsoft现在要求某些重要的OS组件必须是signed with Extended Validation(或EV)代码签名证书(相对于Standard或OV证书)。

我正在尝试看看如何在一个签名的二进制文件中区分这两者?

我的目标是(对于我自己的报告工具)以编程方式执行此操作。因此,我发现具有CertVerifyCertificateChainPolicy参数的CERT_CHAIN_POLICY_EV函数。绝对没有有关如何调用它的文档。

PS。但是作为附带的问题,除了以编程方式区分它们之外,是否有办法在Windows资源管理器中做到这一点? (仅出于测试目的。)

这是我想出的代码:

//No error checks for brevity!

HCERTSTORE hStore = NULL;
HCRYPTMSG hMsg = NULL;

CryptQueryObject(CERT_QUERY_OBJECT_FILE,
    pBinaryFilePath,
    CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
    CERT_QUERY_FORMAT_FLAG_BINARY,
    0,
    NULL,
    NULL,
    NULL,
    &hStore,
    &hMsg,
    NULL);

DWORD dwcbSz;
CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwcbSz);

PCMSG_SIGNER_INFO pSignerInfo = (PCMSG_SIGNER_INFO)new (std::nothrow) BYTE[dwcbSz];
CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, pSignerInfo, &dwcbSz);

CERT_INFO ci = {0};
ci.Issuer = pSignerInfo->Issuer;
ci.SerialNumber = pSignerInfo->SerialNumber;

PCCERT_CONTEXT pCertContext = CertFindCertificateInStore(hStore,
        ENCODING, 0, CERT_FIND_SUBJECT_CERT,
        (PVOID)&ci, pCertContext);


//Check for EV cert
const char* usagesEV[] = { szOID_PKIX_KP_CODE_SIGNING };

CERT_CHAIN_PARA paramsEV = { 0 };
paramsEV.cbSize = sizeof(paramsEV);
paramsEV.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
paramsEV.RequestedUsage.Usage.cUsageIdentifier = _countof(usagesEV);
paramsEV.RequestedUsage.Usage.rgpszUsageIdentifier = (LPSTR*)usagesEV;

PCCERT_CHAIN_CONTEXT pChainEV = NULL;
if(CertGetCertificateChain(NULL, pCertContext, NULL, NULL, &paramsEV, 
    CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, NULL, &pChainEV))
{
    EV_EXTRA_CERT_CHAIN_POLICY_PARA extraPolocyRV = {0};
    extraPolocyRV.cbSize = sizeof(extraPolocyRV);
    extraPolocyRV.dwRootProgramQualifierFlags = CERT_ROOT_PROGRAM_FLAG_ADDRESS;

    CERT_CHAIN_POLICY_PARA paramsPolicyEV = {0};
    paramsPolicyEV.cbSize = sizeof(paramsPolicyEV);
    paramsPolicyEV.pvExtraPolicyPara = &extraPolocyRV;

    CERT_CHAIN_POLICY_STATUS policyStatusEV = {0};
    policyStatusEV.cbSize = sizeof(policyStatusEV);

    if(CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_EV, pChainEV, 
        &paramsPolicyEV, (PCERT_CHAIN_POLICY_STATUS)&policyStatusEV))
    {
        //I'm always getting here with 'policyStatusEV.dwError' being 0x800b0110
        policyStatusEV.dwError;

        ....
    }
    else
    {
        //Did not verify for EV -- but my code never gets here
    }
}


CertFreeCertificateContext(pCertContext);
delete[] pSignerInfo;
CertCloseStore(hStore, 0);
CryptMsgClose(hMsg);

不幸的是,我可能没有使用正确的参数调用EV部件,因此它返回的结果相同。 (请参阅代码中的注释。)

0 个答案:

没有答案