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
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);
|
|
}
|