Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

638 lines
22 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: chainprv.cpp
//
// Contents: Microsoft Internet Security Generic Chain Policy Provider
//
// Functions: GenericChainRegisterServer
// GenericChainUnregisterServer
// GenericChainCertificateTrust
// GenericChainFinalProv
//
// History: 21-Feb-1998 philh created
//
//--------------------------------------------------------------------------
#include "global.hxx"
//////////////////////////////////////////////////////////////////////////////
//
// GenericChainRegisterServer
//----------------------------------------------------------------------------
// Register the GenericChain provider
//
STDAPI GenericChainRegisterServer(void)
{
GUID gGenericChainProv = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY;
BOOL fRet;
CRYPT_REGISTER_ACTIONID sRegAID;
fRet = TRUE;
memset(&sRegAID, 0x00, sizeof(CRYPT_REGISTER_ACTIONID));
sRegAID.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
// Authenticode initialization provider
sRegAID.sInitProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sInitProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
sRegAID.sInitProvider.pwszFunctionName = SP_INIT_FUNCTION;
// Authenticode object provider
sRegAID.sObjectProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sObjectProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
sRegAID.sObjectProvider.pwszFunctionName = SP_OBJTRUST_FUNCTION;
// Authenticode signature provider
sRegAID.sSignatureProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sSignatureProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
sRegAID.sSignatureProvider.pwszFunctionName = SP_SIGTRUST_FUNCTION;
//------------------------------------------------------------------------
// Our Generic Chain certificate provider (builds the chain)
//+-----------------------------------------------------------------------
sRegAID.sCertificateProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sCertificateProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
sRegAID.sCertificateProvider.pwszFunctionName = GENERIC_CHAIN_CERTTRUST_FUNCTION;
// authenticode cert policy
sRegAID.sCertificatePolicyProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sCertificatePolicyProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
sRegAID.sCertificatePolicyProvider.pwszFunctionName = SP_CHKCERT_FUNCTION;
//------------------------------------------------------------------------
// Our Generic Chain final provider (chain policy callback)
//+-----------------------------------------------------------------------
sRegAID.sFinalPolicyProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sFinalPolicyProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
sRegAID.sFinalPolicyProvider.pwszFunctionName = GENERIC_CHAIN_FINALPOLICY_FUNCTION;
// Authenticode cleanup -- we don't store any data.
sRegAID.sCleanupProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sCleanupProvider.pwszDLLName = SP_POLICY_PROVIDER_DLL_NAME;
sRegAID.sCleanupProvider.pwszFunctionName = SP_CLEANUPPOLICY_FUNCTION;
fRet &= WintrustAddActionID(&gGenericChainProv, 0, &sRegAID);
return((fRet) ? S_OK : S_FALSE);
}
//////////////////////////////////////////////////////////////////////////////
//
// DllUnregisterServer
//----------------------------------------------------------------------------
// unregisters GenericChain provider
//
STDAPI GenericChainUnregisterServer(void)
{
GUID gGenericChainProv = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY;
WintrustRemoveActionID(&gGenericChainProv);
return(S_OK);
}
//////////////////////////////////////////////////////////////////////////////
//
// GenericChainCertificateTrust
//----------------------------------------------------------------------------
// Creates the chains for the signers and counter signers
//
void GenericChainWalkSigner(
IN OUT PCRYPT_PROVIDER_DATA pProvData,
IN OUT PCRYPT_PROVIDER_SGNR pSgnr,
IN PWTD_GENERIC_CHAIN_POLICY_CREATE_INFO pChainInfo
);
HRESULT
WINAPI
GenericChainCertificateTrust(
IN OUT PCRYPT_PROVIDER_DATA pProvData
)
{
HRESULT hr;
WTD_GENERIC_CHAIN_POLICY_DATA DefaultPolicyData;
PWTD_GENERIC_CHAIN_POLICY_DATA pPolicyData;
if (_ISINSTRUCT(CRYPT_PROVIDER_DATA, pProvData->cbStruct,
fRecallWithState) && pProvData->fRecallWithState == TRUE)
return S_OK;
pPolicyData = (PWTD_GENERIC_CHAIN_POLICY_DATA)
pProvData->pWintrustData->pPolicyCallbackData;
if (NULL == pPolicyData) {
memset(&DefaultPolicyData, 0, sizeof(DefaultPolicyData));
DefaultPolicyData.cbSize = sizeof(DefaultPolicyData);
pPolicyData = &DefaultPolicyData;
}
if (!_ISINSTRUCT(WTD_GENERIC_CHAIN_POLICY_DATA,
pPolicyData->cbSize, pvPolicyArg) ||
!_ISINSTRUCT(CRYPT_PROVIDER_DATA, pProvData->cbStruct, dwProvFlags) ||
(pProvData->dwProvFlags & WTD_USE_IE4_TRUST_FLAG)) {
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] =
ERROR_INVALID_PARAMETER;
return S_FALSE;
}
if (pProvData->csSigners < 1) {
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] =
TRUST_E_NOSIGNATURE;
return S_FALSE;
}
pProvData->dwProvFlags |= CPD_USE_NT5_CHAIN_FLAG;
hr = S_OK;
//
// loop through all signers
//
for (DWORD i = 0; i < pProvData->csSigners; i++) {
PCRYPT_PROVIDER_SGNR pSgnr;
pSgnr = WTHelperGetProvSignerFromChain(pProvData, i, FALSE, 0);
if (pSgnr->csCertChain < 1) {
pSgnr->dwError = TRUST_E_NO_SIGNER_CERT;
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] =
TRUST_E_NO_SIGNER_CERT;
hr = S_FALSE;
continue;
}
GenericChainWalkSigner(
pProvData,
pSgnr,
pPolicyData->pSignerChainInfo
);
//
// loop through all counter signers
//
for (DWORD j = 0; j < pSgnr->csCounterSigners; j++) {
PCRYPT_PROVIDER_SGNR pCounterSgnr;
pCounterSgnr = WTHelperGetProvSignerFromChain(
pProvData, i, TRUE, j);
if (pCounterSgnr->csCertChain < 1) {
pCounterSgnr->dwError = TRUST_E_NO_SIGNER_CERT;
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] =
TRUST_E_COUNTER_SIGNER;
hr = S_FALSE;
continue;
}
GenericChainWalkSigner(
pProvData,
pCounterSgnr,
pPolicyData->pCounterSignerChainInfo
);
}
}
return hr;
}
HCERTSTORE GenericChainGetAdditionalStore(
IN CRYPT_PROVIDER_DATA *pProvData
)
{
if (0 == pProvData->chStores)
return NULL;
if (1 < pProvData->chStores) {
HCERTSTORE hCollectionStore;
if (hCollectionStore = CertOpenStore(
CERT_STORE_PROV_COLLECTION,
0, // dwEncodingType
0, // hCryptProv
0, // dwFlags
NULL // pvPara
)) {
DWORD i;
for (i = 0; i < pProvData->chStores; i++)
CertAddStoreToCollection(
hCollectionStore,
pProvData->pahStores[i],
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG,
0 // dwPriority
);
}
return hCollectionStore;
} else
return CertDuplicateStore(pProvData->pahStores[0]);
}
void GenericChainWalkSigner(
IN OUT PCRYPT_PROVIDER_DATA pProvData,
IN OUT PCRYPT_PROVIDER_SGNR pSgnr,
IN PWTD_GENERIC_CHAIN_POLICY_CREATE_INFO pChainInfo
)
{
DWORD dwSgnrError;
WTD_GENERIC_CHAIN_POLICY_CREATE_INFO DefaultChainInfo;
CERT_CHAIN_PARA ChainPara;
HCERTSTORE hAdditionalStore = NULL;
PCCERT_CHAIN_CONTEXT pChainContext;
PCRYPT_PROVIDER_CERT pCert = NULL;
if (pChainInfo) {
if (!_ISINSTRUCT(WTD_GENERIC_CHAIN_POLICY_CREATE_INFO,
pChainInfo->cbSize, pvReserved)) {
dwSgnrError = ERROR_INVALID_PARAMETER;
goto InvalidParameter;
}
} else {
memset(&ChainPara, 0, sizeof(ChainPara));
ChainPara.cbSize = sizeof(ChainPara);
memset(&DefaultChainInfo, 0, sizeof(DefaultChainInfo));
DefaultChainInfo.cbSize = sizeof(DefaultChainInfo);
DefaultChainInfo.pChainPara = &ChainPara;
pChainInfo = &DefaultChainInfo;
}
hAdditionalStore = GenericChainGetAdditionalStore(pProvData);
pCert = WTHelperGetProvCertFromChain(pSgnr, 0);
if (pCert == NULL)
{
// Not really sure what error to put here
pProvData->dwError = E_UNEXPECTED;
dwSgnrError = E_UNEXPECTED;
goto ErrorReturn;
}
if (!CertGetCertificateChain (
pChainInfo->hChainEngine,
pCert->pCert,
&pSgnr->sftVerifyAsOf,
hAdditionalStore,
pChainInfo->pChainPara,
pChainInfo->dwFlags,
pChainInfo->pvReserved,
&pChainContext
)) {
pProvData->dwError = GetLastError();
dwSgnrError = TRUST_E_SYSTEM_ERROR;
goto GetChainError;
}
pSgnr->pChainContext = pChainContext;
CommonReturn:
if (hAdditionalStore)
CertCloseStore(hAdditionalStore, 0);
return;
ErrorReturn:
pSgnr->dwError = dwSgnrError;
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] =
dwSgnrError;
goto CommonReturn;
TRACE_ERROR_EX(DBG_SS, InvalidParameter)
TRACE_ERROR_EX(DBG_SS, GetChainError)
}
//////////////////////////////////////////////////////////////////////////////
//
// Final Policy Provider function: GenericChainFinalProv
//----------------------------------------------------------------------------
// Check the outcome of the previous functions and display UI based on this.
//
DWORD GenericChainGetErrorBasedOnStepErrors(
IN PCRYPT_PROVIDER_DATA pProvData
);
HRESULT
WINAPI
GenericChainDefaultPolicyCallback(
IN PCRYPT_PROVIDER_DATA pProvData,
IN DWORD dwStepError,
IN DWORD dwRegPolicySettings,
IN DWORD cSigner,
IN PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO *rgpSigner,
IN void *pvPolicyArg
);
HRESULT
WINAPI
GenericChainFinalProv(
IN OUT PCRYPT_PROVIDER_DATA pProvData
)
{
HRESULT hr;
WTD_GENERIC_CHAIN_POLICY_DATA DefaultPolicyData;
PWTD_GENERIC_CHAIN_POLICY_DATA pPolicyData;
DWORD dwStepError;
DWORD cSigner = 0;
DWORD i;
PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO *ppSignerInfo = NULL;
PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO pSignerInfo; // not allocated
PFN_WTD_GENERIC_CHAIN_POLICY_CALLBACK pfnPolicyCallback;
pPolicyData = (PWTD_GENERIC_CHAIN_POLICY_DATA)
pProvData->pWintrustData->pPolicyCallbackData;
if (NULL == pPolicyData) {
memset(&DefaultPolicyData, 0, sizeof(DefaultPolicyData));
DefaultPolicyData.cbSize = sizeof(DefaultPolicyData);
pPolicyData = &DefaultPolicyData;
}
if (!_ISINSTRUCT(WTD_GENERIC_CHAIN_POLICY_DATA,
pPolicyData->cbSize, pvPolicyArg) ||
!_ISINSTRUCT(CRYPT_PROVIDER_DATA, pProvData->cbStruct, dwFinalError) ||
(pProvData->dwProvFlags & WTD_USE_IE4_TRUST_FLAG) ||
0 == (pProvData->dwProvFlags & CPD_USE_NT5_CHAIN_FLAG))
goto InvalidParameter;
dwStepError = GenericChainGetErrorBasedOnStepErrors(pProvData);
cSigner = pProvData->csSigners;
if (0 == cSigner)
goto NoSignature;
if (NULL == (ppSignerInfo =
(PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO *) malloc(
sizeof(PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO) * cSigner +
sizeof(WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO) * cSigner)))
goto OutOfMemory;
memset(ppSignerInfo, 0,
sizeof(PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO) * cSigner +
sizeof(WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO) * cSigner);
//
// Update allocated info for each signer
//
pSignerInfo = (PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO)
&ppSignerInfo[cSigner];
i = 0;
for ( ; i < cSigner; i++, pSignerInfo++) {
CRYPT_PROVIDER_SGNR *pSgnr;
DWORD cCounterSigner;
ppSignerInfo[i] = pSignerInfo;
pSignerInfo->cbSize = sizeof(WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO);
pSgnr = WTHelperGetProvSignerFromChain(pProvData, i, FALSE, 0);
pSignerInfo->pChainContext = pSgnr->pChainContext;
pSignerInfo->dwSignerType = pSgnr->dwSignerType;
pSignerInfo->pMsgSignerInfo = pSgnr->psSigner;
pSignerInfo->dwError = pSgnr->dwError;
cCounterSigner = pSgnr->csCounterSigners;
if (cCounterSigner) {
DWORD j;
PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO *ppCounterSignerInfo;
PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO pCounterSignerInfo;
if (NULL == (ppCounterSignerInfo =
(PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO *) malloc(
sizeof(PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO) *
cCounterSigner +
sizeof(WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO) *
cCounterSigner)))
goto OutOfMemory;
memset(ppCounterSignerInfo, 0,
sizeof(PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO) * cCounterSigner +
sizeof(WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO) * cCounterSigner);
pSignerInfo->cCounterSigner = cCounterSigner;
pSignerInfo->rgpCounterSigner = ppCounterSignerInfo;
//
// Update allocated info for each counter signer
//
pCounterSignerInfo = (PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO)
&ppCounterSignerInfo[cCounterSigner];
j = 0;
for ( ; j < cCounterSigner; j++, pCounterSignerInfo++) {
PCRYPT_PROVIDER_SGNR pCounterSgnr;
ppCounterSignerInfo[j] = pCounterSignerInfo;
pCounterSignerInfo->cbSize =
sizeof(WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO);
pCounterSgnr = WTHelperGetProvSignerFromChain(pProvData, i,
TRUE, j);
pCounterSignerInfo->pChainContext = pCounterSgnr->pChainContext;
pCounterSignerInfo->dwSignerType = pCounterSgnr->dwSignerType;
pCounterSignerInfo->pMsgSignerInfo = pCounterSgnr->psSigner;
pCounterSignerInfo->dwError = pCounterSgnr->dwError;
}
}
}
if (pPolicyData->pfnPolicyCallback)
pfnPolicyCallback = pPolicyData->pfnPolicyCallback;
else
pfnPolicyCallback = GenericChainDefaultPolicyCallback;
hr = pfnPolicyCallback(
pProvData,
dwStepError,
pProvData->dwRegPolicySettings,
cSigner,
ppSignerInfo,
pPolicyData->pvPolicyArg
);
CommonReturn:
if (ppSignerInfo) {
while (cSigner--) {
pSignerInfo = ppSignerInfo[cSigner];
if (pSignerInfo && pSignerInfo->rgpCounterSigner)
free(pSignerInfo->rgpCounterSigner);
}
free(ppSignerInfo);
}
pProvData->dwFinalError = (DWORD) hr;
return hr;
ErrorReturn:
hr = (HRESULT) GetLastError();
if (S_OK == hr)
hr = E_UNEXPECTED;
goto CommonReturn;
SET_ERROR_EX(DBG_SS, InvalidParameter, ERROR_INVALID_PARAMETER)
SET_ERROR_EX(DBG_SS, OutOfMemory, ERROR_NOT_ENOUGH_MEMORY)
SET_ERROR_EX(DBG_SS, NoSignature, TRUST_E_NOSIGNATURE);
}
DWORD GenericChainGetErrorBasedOnStepErrors(
IN PCRYPT_PROVIDER_DATA pProvData
)
{
//
// initial allocation of the step errors?
//
if (NULL == pProvData->padwTrustStepErrors)
return ERROR_NOT_ENOUGH_MEMORY;
// problem with file
if ((pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FILEIO] != 0) ||
(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_CATALOGFILE] != 0))
{
return(CRYPT_E_FILE_ERROR);
}
//
// did we fail in one of the last steps?
//
if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] != 0)
{
return(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV]);
}
if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] != 0)
{
return(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
}
if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] != 0)
{
return(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV]);
}
if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] != 0)
{
return(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV]);
}
if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTCHKPROV] != 0)
{
return(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTCHKPROV]);
}
if (pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV] != 0)
{
return(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV]);
}
return(ERROR_SUCCESS);
}
HRESULT
WINAPI
GenericChainDefaultPolicyCallback(
IN PCRYPT_PROVIDER_DATA pProvData,
IN DWORD dwStepError,
IN DWORD dwRegPolicySettings,
IN DWORD cSigner,
IN PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO *rgpSigner,
IN void *pvPolicyArg
)
{
HRESULT hr;
DWORD i;
AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA ExtraPolicyPara;
memset(&ExtraPolicyPara, 0, sizeof(ExtraPolicyPara));
ExtraPolicyPara.cbSize = sizeof(ExtraPolicyPara);
ExtraPolicyPara.dwRegPolicySettings = dwRegPolicySettings;
CERT_CHAIN_POLICY_PARA PolicyPara;
memset(&PolicyPara, 0, sizeof(PolicyPara));
PolicyPara.cbSize = sizeof(PolicyPara);
PolicyPara.pvExtraPolicyPara = (void *) &ExtraPolicyPara;
AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_STATUS ExtraPolicyStatus;
memset(&ExtraPolicyStatus, 0, sizeof(ExtraPolicyStatus));
ExtraPolicyStatus.cbSize = sizeof(ExtraPolicyStatus);
CERT_CHAIN_POLICY_STATUS PolicyStatus;
memset(&PolicyStatus, 0, sizeof(PolicyStatus));
PolicyStatus.cbSize = sizeof(PolicyStatus);
PolicyStatus.pvExtraPolicyStatus = (void *) &ExtraPolicyStatus;
//
// check the high level error codes.
//
if (0 != dwStepError) {
hr = (HRESULT) dwStepError;
goto CommonReturn;
}
//
// check each signer
//
for (i = 0; i < cSigner; i++) {
PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO pSigner = rgpSigner[i];
ExtraPolicyPara.pSignerInfo = pSigner->pMsgSignerInfo;
if (!CertVerifyCertificateChainPolicy(
CERT_CHAIN_POLICY_AUTHENTICODE,
pSigner->pChainContext,
&PolicyPara,
&PolicyStatus
)) {
hr = TRUST_E_SYSTEM_ERROR;
goto CommonReturn;
}
if (0 != PolicyStatus.dwError) {
hr = (HRESULT) PolicyStatus.dwError;
goto CommonReturn;
}
if (pSigner->cCounterSigner) {
AUTHENTICODE_TS_EXTRA_CERT_CHAIN_POLICY_PARA TSExtraPolicyPara;
memset(&TSExtraPolicyPara, 0, sizeof(TSExtraPolicyPara));
TSExtraPolicyPara.cbSize = sizeof(TSExtraPolicyPara);
TSExtraPolicyPara.dwRegPolicySettings = dwRegPolicySettings;
TSExtraPolicyPara.fCommercial = ExtraPolicyStatus.fCommercial;
CERT_CHAIN_POLICY_PARA TSPolicyPara;
memset(&TSPolicyPara, 0, sizeof(TSPolicyPara));
TSPolicyPara.cbSize = sizeof(TSPolicyPara);
TSPolicyPara.pvExtraPolicyPara = (void *) &TSExtraPolicyPara;
CERT_CHAIN_POLICY_STATUS TSPolicyStatus;
memset(&TSPolicyStatus, 0, sizeof(TSPolicyStatus));
TSPolicyStatus.cbSize = sizeof(TSPolicyStatus);
//
// check counter signers
//
for (DWORD j = 0; j < pSigner->cCounterSigner; j++) {
PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO pCounterSigner =
pSigner->rgpCounterSigner[j];
//
// do we care about this counter signer?
//
if (pCounterSigner->dwSignerType != SGNR_TYPE_TIMESTAMP)
continue;
if (!CertVerifyCertificateChainPolicy(
CERT_CHAIN_POLICY_AUTHENTICODE_TS,
pCounterSigner->pChainContext,
&TSPolicyPara,
&TSPolicyStatus
)) {
hr = TRUST_E_SYSTEM_ERROR;
goto CommonReturn;
} else if (0 != TSPolicyStatus.dwError) {
hr = (HRESULT) TSPolicyStatus.dwError;
goto CommonReturn;
}
}
}
}
hr = S_OK;
CommonReturn:
return hr;
}