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.
 
 
 
 
 
 

791 lines
24 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: testprov.cpp
//
// Contents: Microsoft Internet Security Trust Provider
//
// Functions: DllRegisterServer
// DllUnregisterServer
// TestprovInitialize
// TestprovObjectProv
// TestprovSigProv
// TestprovCertCheckProv
// TestprovFinalProv
// TestprovCleanup
// TestprovTester
//
// History: 28-Jul-1997 pberkman created
//
//--------------------------------------------------------------------------
#include <windows.h>
#include <ole2.h>
#include <wincrypt.h>
#include <wintrust.h> // structures and APIs
#include "wintrustp.h" // structures and APIs
#include <softpub.h> // reference for Authenticode
#include <acui.h> // ui module DACUI.DLL
#include "testprov.h" // my stuff
HRESULT CallUI(CRYPT_PROVIDER_DATA *pProvData, DWORD dwError);
DWORD GetErrorBasedOnStepErrors(CRYPT_PROVIDER_DATA *pProvData);
HRESULT CheckCertificateChain(CRYPT_PROVIDER_DATA *pProvData, CRYPT_PROVIDER_SGNR *pProvSgnr);
HRESULT CheckRevocation(CRYPT_PROVIDER_DATA *pProvData, CRYPT_PROVIDER_SGNR *pSgnr);
BOOL CheckCertAnyUnknownCriticalExtensions(CRYPT_PROVIDER_DATA *pProvData, PCERT_INFO pCertInfo);
//////////////////////////////////////////////////////////////////////////////
//
// DllRegisterServer
//----------------------------------------------------------------------------
// Register "my" provider
//
STDAPI DllRegisterServer(void)
{
GUID gTestprov = TESTPROV_ACTION_TEST;
CRYPT_REGISTER_ACTIONID sRegAID;
memset(&sRegAID, 0x00, sizeof(CRYPT_REGISTER_ACTIONID));
sRegAID.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
sRegAID.sInitProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sInitProvider.pwszDLLName = TP_DLL_NAME;
sRegAID.sInitProvider.pwszFunctionName = TP_INIT_FUNCTION;
sRegAID.sObjectProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sObjectProvider.pwszDLLName = TP_DLL_NAME;
sRegAID.sObjectProvider.pwszFunctionName = TP_OBJTRUST_FUNCTION;
sRegAID.sSignatureProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sSignatureProvider.pwszDLLName = TP_DLL_NAME;
sRegAID.sSignatureProvider.pwszFunctionName = TP_SIGTRUST_FUNCTION;
sRegAID.sCertificateProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sCertificateProvider.pwszDLLName = WT_PROVIDER_DLL_NAME; // set to wintrust.dll
sRegAID.sCertificateProvider.pwszFunctionName = WT_PROVIDER_CERTTRUST_FUNCTION; // use wintrust's standard!
sRegAID.sCertificatePolicyProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sCertificatePolicyProvider.pwszDLLName = TP_DLL_NAME;
sRegAID.sCertificatePolicyProvider.pwszFunctionName = TP_CHKCERT_FUNCTION;
sRegAID.sFinalPolicyProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sFinalPolicyProvider.pwszDLLName = TP_DLL_NAME;
sRegAID.sFinalPolicyProvider.pwszFunctionName = TP_FINALPOLICY_FUNCTION;
sRegAID.sCleanupProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sCleanupProvider.pwszDLLName = TP_DLL_NAME;
sRegAID.sCleanupProvider.pwszFunctionName = TP_CLEANUPPOLICY_FUNCTION;
sRegAID.sTestPolicyProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
sRegAID.sTestPolicyProvider.pwszDLLName = TP_DLL_NAME;
sRegAID.sTestPolicyProvider.pwszFunctionName = TP_TESTDUMPPOLICY_FUNCTION_TEST;
if (WintrustAddActionID(&gTestprov, 0, &sRegAID))
{
return(S_OK);
}
return(S_FALSE);
}
//////////////////////////////////////////////////////////////////////////////
//
// DllUnregisterServer
//----------------------------------------------------------------------------
// unregisters "my" provider
//
STDAPI DllUnregisterServer(void)
{
GUID gTestprov = TESTPROV_ACTION_TEST;
WintrustRemoveActionID(&gTestprov);
return(S_OK);
}
//////////////////////////////////////////////////////////////////////////////
//
// Initialization Provider function: testprovInitialize
//----------------------------------------------------------------------------
// allocates and sets up "my" data.
//
HRESULT WINAPI TestprovInitialize(CRYPT_PROVIDER_DATA *pProvData)
{
if (!(pProvData->padwTrustStepErrors) ||
(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT] != ERROR_SUCCESS))
{
return(S_FALSE);
}
//
// add our private data to the array...
//
CRYPT_PROVIDER_PRIVDATA sMyData;
TESTPROV_PRIVATE_DATA *pMyData;
GUID gMyId = TESTPROV_ACTION_TEST;
memset(&sMyData, 0x00, sizeof(CRYPT_PROVIDER_PRIVDATA));
sMyData.cbStruct = sizeof(CRYPT_PROVIDER_PRIVDATA);
memcpy(&sMyData.gProviderID, &gMyId, sizeof(GUID));
if (!(sMyData.pvProvData = pProvData->psPfns->pfnAlloc(sizeof(TESTPROV_PRIVATE_DATA))))
{
pProvData->dwError = GetLastError();
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] = TRUST_E_SYSTEM_ERROR;
return(S_FALSE);
}
memset(sMyData.pvProvData, 0x00, sizeof(TESTPROV_PRIVATE_DATA));
pMyData = (TESTPROV_PRIVATE_DATA *)sMyData.pvProvData;
pMyData->cbStruct = sizeof(TESTPROV_PRIVATE_DATA);
//
// fill in the Authenticode Functions
//
GUID gSP = WINTRUST_ACTION_TRUSTPROVIDER_TEST;
pMyData->sAuthenticodePfns.cbStruct = sizeof(CRYPT_PROVIDER_FUNCTIONS_ORMORE);
if (!(WintrustLoadFunctionPointers(&gSP, (CRYPT_PROVIDER_FUNCTIONS *)&pMyData->sAuthenticodePfns)))
{
pProvData->psPfns->pfnFree(sMyData.pvProvData);
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] = TRUST_E_PROVIDER_UNKNOWN;
return(S_FALSE);
}
//
// add my data to the chain!
//
pProvData->psPfns->pfnAddPrivData2Chain(pProvData, &sMyData);
return(pMyData->sAuthenticodePfns.pfnInitialize(pProvData));
}
//////////////////////////////////////////////////////////////////////////////
//
// Object Provider function: TestprovObjectProv
//----------------------------------------------------------------------------
// we don't do anything here -- we're not authenticating a signed object.
//
HRESULT WINAPI TestprovObjectProv(CRYPT_PROVIDER_DATA *pProvData)
{
if (!(pProvData->padwTrustStepErrors) ||
(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT] != ERROR_SUCCESS) ||
(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] != ERROR_SUCCESS))
{
return(S_FALSE);
}
CRYPT_PROVIDER_PRIVDATA *pPrivData;
TESTPROV_PRIVATE_DATA *pMyData;
GUID gMyId = TESTPROV_ACTION_TEST;
if (!(pPrivData = WTHelperGetProvPrivateDataFromChain(pProvData, &gMyId)))
{
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] = ERROR_INVALID_PARAMETER;
return(S_FALSE);
}
pMyData = (TESTPROV_PRIVATE_DATA *)pPrivData->pvProvData;
//
// we are verifying a low-level type choice (eg: cert or signer)
//
switch (pProvData->pWintrustData->dwUnionChoice)
{
case WTD_CHOICE_CERT:
case WTD_CHOICE_SIGNER:
break;
default:
return(pMyData->sAuthenticodePfns.pfnObjectTrust(pProvData));
}
//
// no object to be verified here!
//
return(ERROR_SUCCESS);
}
//////////////////////////////////////////////////////////////////////////////
//
// Signature Provider function: TestprovInitialize
//----------------------------------------------------------------------------
// We are going to let Authenticode take care of most of this stuff!
//
HRESULT WINAPI TestprovSigProv(CRYPT_PROVIDER_DATA *pProvData)
{
if (!(pProvData->padwTrustStepErrors) ||
(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT] != ERROR_SUCCESS) ||
(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] != ERROR_SUCCESS) ||
(pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] != ERROR_SUCCESS))
{
return(S_FALSE);
}
CRYPT_PROVIDER_PRIVDATA *pPrivData;
TESTPROV_PRIVATE_DATA *pMyData;
GUID gMyId = TESTPROV_ACTION_TEST;
if (!(pPrivData = WTHelperGetProvPrivateDataFromChain(pProvData, &gMyId)))
{
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] = ERROR_INVALID_PARAMETER;
return(S_FALSE);
}
pMyData = (TESTPROV_PRIVATE_DATA *)pPrivData->pvProvData;
//
// we are verifying a low-level type choice (eg: cert or signer)
//
switch (pProvData->pWintrustData->dwUnionChoice)
{
case WTD_CHOICE_CERT:
case WTD_CHOICE_SIGNER:
break;
default:
return(pMyData->sAuthenticodePfns.pfnSignatureTrust(pProvData));
}
if (pMyData->sAuthenticodePfns.pfnSignatureTrust)
{
return(pMyData->sAuthenticodePfns.pfnSignatureTrust(pProvData));
}
return(S_FALSE);
}
//////////////////////////////////////////////////////////////////////////////
//
// Certificate Check Provider function: TestprovCertCheckProv
//----------------------------------------------------------------------------
// just check basic stuff about a certificate. return FALSE to stop
// building the chain, TRUE to continue.
//
BOOL WINAPI TestprovCheckCertProv(CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner,
BOOL fCounterSignerChain, DWORD idxCounterSigner)
{
CRYPT_PROVIDER_SGNR *pSgnr;
CRYPT_PROVIDER_CERT *pCert;
PCCERT_CONTEXT pCertContext;
pSgnr = WTHelperGetProvSignerFromChain(pProvData, idxSigner, fCounterSignerChain, idxCounterSigner);
pCert = WTHelperGetProvCertFromChain(pSgnr, pSgnr->csCertChain - 1);
pCert->fTrustedRoot = FALSE;
//
// only self signed certificates in the root store are "trusted" roots
//
if (pCert->fSelfSigned)
{
pCertContext = pCert->pCert;
if (pCertContext)
{
if (pProvData->chStores > 0)
{
if (pCertContext->hCertStore == pProvData->pahStores[0])
{
//
// it's in the root store!
//
pCert->fTrustedRoot = TRUE;
return(FALSE);
}
}
if (!(pCert->fTrustedRoot))
{
if (pCert->fTestCert)
{
//
// check the policy flags (setreg.exe) to see if we trust
// the test root.
//
if (pProvData->dwRegPolicySettings & WTPF_TRUSTTEST)
{
pCert->fTrustedRoot = TRUE;
return(FALSE);
}
}
}
}
//
// the cert is self-signed... we need to stop regardless
//
return(FALSE);
}
return(TRUE);
}
//////////////////////////////////////////////////////////////////////////////
//
// Final Policy Provider function: TestprovFinalProv
//----------------------------------------------------------------------------
// Check the outcome of the previous functions and display UI based on this.
//
HRESULT WINAPI TestprovFinalProv(CRYPT_PROVIDER_DATA *pProvData)
{
CRYPT_PROVIDER_SGNR *pSigner;
DWORD dwError;
if ((dwError = GetErrorBasedOnStepErrors(pProvData)) != ERROR_SUCCESS)
{
return(CallUI(pProvData, dwError));
}
pSigner = WTHelperGetProvSignerFromChain(pProvData, 0, FALSE, 0);
if ((dwError = CheckCertificateChain(pProvData, pSigner)) != ERROR_SUCCESS)
{
return(CallUI(pProvData, dwError));
}
return(CallUI(pProvData, dwError));
}
//////////////////////////////////////////////////////////////////////////////
//
// Cleanup Provider function: TestprovCleanup
//----------------------------------------------------------------------------
// call all other policy provider cleanup functions, then, free "my" stuff.
//
HRESULT WINAPI TestprovCleanup(CRYPT_PROVIDER_DATA *pProvData)
{
GUID gMyId = TESTPROV_ACTION_TEST;
CRYPT_PROVIDER_PRIVDATA *pPrivData;
TESTPROV_PRIVATE_DATA *pMyData;
//
// we have used the Authenticode Provider. we need to call its
// cleanup routine just in case.... so, get our private data
// which will have the Authenticode functions in our structure..
//
if (!(pPrivData = WTHelperGetProvPrivateDataFromChain(pProvData, &gMyId)))
{
return(S_FALSE);
}
if (!(pPrivData->pvProvData))
{
return(S_FALSE);
}
pMyData = (TESTPROV_PRIVATE_DATA *)pPrivData->pvProvData;
if (pMyData->sAuthenticodePfns.pfnCleanupPolicy)
{
pMyData->sAuthenticodePfns.pfnCleanupPolicy(pProvData);
}
//
// now, we need to delete our private data
//
pProvData->psPfns->pfnFree(pPrivData->pvProvData);
pPrivData->cbProvData = 0;
pPrivData->pvProvData = NULL;
return(ERROR_SUCCESS);
}
//////////////////////////////////////////////////////////////////////////////
//
// Test Provider function: TestprovTester
//----------------------------------------------------------------------------
// In here, we are going to check an environment variable and if set we
// will call Authenticode's "dump" function.
//
HRESULT WINAPI TestprovTester(CRYPT_PROVIDER_DATA *pProvData)
{
BYTE abEnv[MAX_PATH + 1];
CRYPT_PROVIDER_PRIVDATA *pPrivData;
TESTPROV_PRIVATE_DATA *pMyData;
GUID gMyId = TESTPROV_ACTION_TEST;
abEnv[0] = NULL;
if (GetEnvironmentVariable("TestProvUseDump", (char *)&abEnv[0], MAX_PATH) < 1)
{
return(ERROR_SUCCESS);
}
if ((abEnv[0] != '1') && (toupper(abEnv[0]) != 'T'))
{
return(ERROR_SUCCESS);
}
if (!(pPrivData = WTHelperGetProvPrivateDataFromChain(pProvData, &gMyId)))
{
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_INITPROV] = ERROR_INVALID_PARAMETER;
return(S_FALSE);
}
pMyData = (TESTPROV_PRIVATE_DATA *)pPrivData->pvProvData;
if (pMyData->sAuthenticodePfns.pfnTestFinalPolicy)
{
return(pMyData->sAuthenticodePfns.pfnTestFinalPolicy(pProvData));
}
return(S_FALSE);
}
///////////////////////////////////////////////////////////////////////////////////
//
// Local Functions
//
///////////////////////////////////////////////////////////////////////////////////
DWORD GetErrorBasedOnStepErrors(CRYPT_PROVIDER_DATA *pProvData)
{
//
// initial allocation of the step errors?
//
if (!(pProvData->padwTrustStepErrors))
{
return(ERROR_NOT_ENOUGH_MEMORY);
}
//
// 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 CheckCertificateChain(CRYPT_PROVIDER_DATA *pProvData, CRYPT_PROVIDER_SGNR *pProvSgnr)
{
CRYPT_PROVIDER_CERT *pCert;
for (int i = 0; i < (int)pProvSgnr->csCertChain; i++)
{
pCert = WTHelperGetProvCertFromChain(pProvSgnr, i);
if (!(pProvData->dwRegPolicySettings & WTPF_IGNOREEXPIRATION))
{
//
// this check was done in the Certificate Provider, however, it may not have passed
// because all its looking for is a confidence level and didn't check the end..
//
if (CertVerifyTimeValidity(&pProvSgnr->sftVerifyAsOf, pCert->pCert->pCertInfo) != 0)
{
pCert->dwError = CERT_E_EXPIRED;
return(pCert->dwError);
}
}
//
// check any unknown critical extensions
//
if (!(CheckCertAnyUnknownCriticalExtensions(pProvData, pCert->pCert->pCertInfo)))
{
pCert->dwError = CERT_E_MALFORMED;
return(pCert->dwError);
}
if ((i + 1) < (int)pProvSgnr->csCertChain)
{
//
// check time nesting...
//
if (!(pCert->dwConfidence & CERT_CONFIDENCE_TIMENEST))
{
pCert->dwError = CERT_E_VALIDITYPERIODNESTING;
return(pCert->dwError);
}
}
}
if (!(pProvData->dwRegPolicySettings & WTPF_IGNOREREVOKATION))
{
// root cert is test?
pCert = WTHelperGetProvCertFromChain(pProvSgnr, pProvSgnr->csCertChain - 1);
if (pCert)
{
if (!(pCert->fTestCert))
{
//
// if the caller already told WVT to check, we don't have to!
//
if (pProvData->pWintrustData->fdwRevocationChecks != WTD_REVOKE_NONE)
{
//
// not a test root, check signer cert for revocation
//
pCert = WTHelperGetProvCertFromChain(pProvSgnr, 0);
return(CheckRevocation(pProvData, pProvSgnr));
}
}
}
}
return(ERROR_SUCCESS);
}
HRESULT CallUI(CRYPT_PROVIDER_DATA *pProvData, DWORD dwError)
{
HRESULT hr;
HINSTANCE hModule;
ACUI_INVOKE_INFO aii;
pfnACUIProviderInvokeUI pfn;
DWORD idxSigner;
BOOL fTrusted;
BOOL fCommercial;
DWORD dwUIChoice;
CRYPT_PROVIDER_SGNR *pRootSigner;
CRYPT_PROVIDER_CERT *pPubCert;
hr = E_NOTIMPL;
pfn = NULL;
fTrusted = FALSE;
fCommercial = FALSE;
idxSigner = 0;
dwUIChoice = pProvData->pWintrustData->dwUIChoice;
pRootSigner = WTHelperGetProvSignerFromChain(pProvData, 0, FALSE, 0);
if ((dwUIChoice == WTD_UI_NONE) ||
((dwUIChoice == WTD_UI_NOBAD) && (dwError != ERROR_SUCCESS)) ||
((dwUIChoice == WTD_UI_NOGOOD) && (dwError == ERROR_SUCCESS)))
{
return(dwError);
}
//
// Setup the UI invokation
//
memset(&aii, 0x00, sizeof(ACUI_INVOKE_INFO));
aii.cbSize = sizeof(ACUI_INVOKE_INFO);
aii.hDisplay = pProvData->hWndParent;
aii.pProvData = pProvData;
aii.hrInvokeReason = dwError;
aii.pwcsAltDisplayName = WTHelperGetFileName(pProvData->pWintrustData);
//
// Load the default authenticode UI.
//
if (hModule = LoadLibrary("dacui.dll"))
{
pfn = (pfnACUIProviderInvokeUI)GetProcAddress(hModule, "ACUIProviderInvokeUI");
}
//
// Invoke the UI
//
if (pfn)
{
hr = (*pfn)(&aii);
}
else if ((pProvData->pWintrustData->dwUIChoice != WTD_UI_NONE) &&
(pProvData->pWintrustData->dwUIChoice != WTD_UI_NOBAD))
{
//TBDTBD!!!
//
// display error dialog "unable to load UI provider"
//
if (hr == E_NOTIMPL)
{
hr = TRUST_E_PROVIDER_UNKNOWN;
}
pProvData->dwError = hr;
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_UIPROV] = hr;
}
//
// free the ui library
//
if (hModule)
{
FreeLibrary(hModule);
}
//
// Return the appropriate code
//
return(hr);
}
static const char *rgpszKnownExtObjId[] =
{
szOID_AUTHORITY_KEY_IDENTIFIER,
szOID_KEY_ATTRIBUTES,
szOID_KEY_USAGE_RESTRICTION,
szOID_SUBJECT_ALT_NAME,
szOID_ISSUER_ALT_NAME,
szOID_BASIC_CONSTRAINTS,
SPC_COMMON_NAME_OBJID,
SPC_SP_AGENCY_INFO_OBJID,
SPC_MINIMAL_CRITERIA_OBJID,
SPC_FINANCIAL_CRITERIA_OBJID,
szOID_CERT_POLICIES,
szOID_POLICY_MAPPINGS,
szOID_SUBJECT_DIR_ATTRS,
NULL
};
BOOL CheckCertAnyUnknownCriticalExtensions(CRYPT_PROVIDER_DATA *pProvData, PCERT_INFO pCertInfo)
{
PCERT_EXTENSION pExt;
DWORD cExt;
const char **ppszObjId;
const char *pszObjId;
cExt = pCertInfo->cExtension;
pExt = pCertInfo->rgExtension;
for ( ; cExt > 0; cExt--, pExt++)
{
if (pExt->fCritical)
{
ppszObjId = (const char **)rgpszKnownExtObjId;
while (pszObjId = *ppszObjId++)
{
if (strcmp(pszObjId, pExt->pszObjId) == 0)
{
break;
}
}
if (!(pszObjId))
{
return(FALSE);
}
}
}
return(TRUE);
}
HRESULT CheckRevocation(CRYPT_PROVIDER_DATA *pProvData, CRYPT_PROVIDER_SGNR *pSgnr)
{
CERT_REVOCATION_PARA sRevPara;
CERT_REVOCATION_STATUS sRevStatus;
PCERT_CONTEXT pasCertContext[1];
CRYPT_PROVIDER_CERT *pCert;
memset(&sRevPara, 0x00, sizeof(CERT_REVOCATION_PARA));
sRevPara.cbSize = sizeof(CERT_REVOCATION_PARA);
// issuer cert = 1
pCert = WTHelperGetProvCertFromChain(pSgnr, 1);
sRevPara.pIssuerCert = pCert->pCert;
memset(&sRevStatus, 0x00, sizeof(CERT_REVOCATION_STATUS));
sRevStatus.cbSize = sizeof(CERT_REVOCATION_STATUS);
// publisher cert = 0
pCert = WTHelperGetProvCertFromChain(pSgnr, 0);
pasCertContext[0] = (PCERT_CONTEXT)pCert->pCert;
if (!(CertVerifyRevocation(pProvData->dwEncoding,
CERT_CONTEXT_REVOCATION_TYPE,
1,
(void **)pasCertContext,
0, // CERT_VERIFY_REV_CHAIN_FLAG,
&sRevPara,
&sRevStatus)))
{
pCert->dwRevokedReason = sRevStatus.dwReason;
switch(sRevStatus.dwError)
{
case CRYPT_E_REVOKED:
return(CERT_E_REVOKED);
case CRYPT_E_NOT_IN_REVOCATION_DATABASE:
return(ERROR_SUCCESS);
case CRYPT_E_REVOCATION_OFFLINE:
if ((pProvData->dwRegPolicySettings & WTPF_OFFLINEOK_IND) ||
(pProvData->dwRegPolicySettings & WTPF_OFFLINEOKNBU_IND))
{
return(ERROR_SUCCESS);
}
return(CERT_E_REVOCATION_FAILURE);
default:
return(CERT_E_REVOCATION_FAILURE);
}
}
return(ERROR_SUCCESS);
}