Как отличить EV от сертификатов подписи кода OV программно?

Я знаю, что Microsoft теперь требует определенных важных компонентов ОС для подписано с расширенной проверки (или EV) сертификаты для подписи кода (по сравнению со Standard или сертификатами OV.)

Я пытаюсь понять, как отличить эти две записи в двоичном файле со знаком?

Моя цель состоит в том, чтобы сделать это программно (для моего собственного инструмента отчетности). Поэтому я нашел CertVerifyCertificateChainPolicy функция, которая имеет CERT_CHAIN_POLICY_EV параметр. И абсолютно нет документации о том, как это назвать.

PS. Но, как побочный вопрос, помимо программного способа их различения, есть ли способ сделать это даже в Windows Explorer? (Только для целей тестирования.)

Вот код, который я придумал:

//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

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …