|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows NT Security
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: callctx.cpp
//
// Contents: Certificate Chaining Infrastructure Call Context
//
// History: 02-Mar-98 kirtd Created
//
//----------------------------------------------------------------------------
#include <global.hxx>
//+---------------------------------------------------------------------------
//
// Member: CChainCallContext::CChainCallContext, public
//
// Synopsis: Constructor
//
//----------------------------------------------------------------------------
CChainCallContext::CChainCallContext ( IN PCCERTCHAINENGINE pChainEngine, IN OPTIONAL LPFILETIME pRequestedTime, IN OPTIONAL PCERT_CHAIN_PARA pChainPara, IN DWORD dwFlags, OUT BOOL& rfResult ) { LRU_CACHE_CONFIG Config;
m_hObjectCreationCache = NULL; m_pChainEngine = pChainEngine; GetSystemTimeAsFileTime(&m_CurrentTime); if (pRequestedTime) m_RequestedTime = *pRequestedTime; else m_RequestedTime = m_CurrentTime; m_dwCallFlags = dwFlags; m_dwStatus = 0; m_dwTouchEngineCount = 0; // m_RevEndTime = // Initialized by RevocationUrlRetrievalTimeout()
m_dwAIAUrlRetrievalCount = 0; // m_AIAEndTime = // Initialized by AIAUrlRetrievalTimeout()
memset(&m_ChainPara, 0, sizeof(m_ChainPara)); if (NULL != pChainPara) memcpy(&m_ChainPara, pChainPara, min(pChainPara->cbSize, sizeof(m_ChainPara))); m_ChainPara.cbSize = sizeof(m_ChainPara);
if (0 == m_ChainPara.dwUrlRetrievalTimeout) { m_ChainPara.dwUrlRetrievalTimeout = pChainEngine->UrlRetrievalTimeout(); m_fDefaultUrlRetrievalTimeout = pChainEngine->HasDefaultUrlRetrievalTimeout(); } else m_fDefaultUrlRetrievalTimeout = FALSE;
memset( &Config, 0, sizeof( Config ) );
Config.dwFlags = LRU_CACHE_NO_SERIALIZE | LRU_CACHE_NO_COPY_IDENTIFIER; Config.pfnHash = CertObjectCacheHashMd5Identifier; Config.pfnOnRemoval = CallContextOnCreationCacheObjectRemoval; Config.cBuckets = DEFAULT_CREATION_CACHE_BUCKETS;
rfResult = I_CryptCreateLruCache( &Config, &m_hObjectCreationCache ); }
//+---------------------------------------------------------------------------
//
// Member: CChainCallContext::~CChainCallContext, public
//
// Synopsis: Destructor
//
//----------------------------------------------------------------------------
CChainCallContext::~CChainCallContext () { if ( m_hObjectCreationCache != NULL ) { I_CryptFreeLruCache( m_hObjectCreationCache, 0, NULL ); } }
//+---------------------------------------------------------------------------
//
// Member: CChainCallContext::AddPathObjectToCreationCache, public
//
// Synopsis: add a path object to the creation cache
//
//----------------------------------------------------------------------------
BOOL CChainCallContext::AddPathObjectToCreationCache ( IN PCCHAINPATHOBJECT pPathObject ) { BOOL fResult; CRYPT_DATA_BLOB DataBlob; HLRUENTRY hEntry;
DataBlob.cbData = CHAINHASHLEN; DataBlob.pbData = pPathObject->CertObject()->CertHash();
fResult = I_CryptCreateLruEntry( m_hObjectCreationCache, &DataBlob, pPathObject, &hEntry );
if ( fResult == TRUE ) { I_CryptInsertLruEntry( hEntry, pPathObject ); I_CryptReleaseLruEntry( hEntry ); }
return( fResult ); }
//+---------------------------------------------------------------------------
//
// Member: CChainCallContext::FindPathObjectInCreationCache, public
//
// Synopsis: find a path object in the creation cache
//
//----------------------------------------------------------------------------
PCCHAINPATHOBJECT CChainCallContext::FindPathObjectInCreationCache ( IN BYTE rgbCertHash[ CHAINHASHLEN ] ) { HLRUENTRY hFound; PCCHAINPATHOBJECT pFound = NULL; CRYPT_DATA_BLOB DataBlob;
DataBlob.cbData = CHAINHASHLEN; DataBlob.pbData = rgbCertHash;
hFound = I_CryptFindLruEntry( m_hObjectCreationCache, &DataBlob ); if ( hFound != NULL ) { pFound = (PCCHAINPATHOBJECT)I_CryptGetLruEntryData( hFound );
I_CryptReleaseLruEntry( hFound ); }
return( pFound ); }
//+---------------------------------------------------------------------------
//
// Member: CChainCallContext::RemovePathObjectFromCreationCache, public
//
// Synopsis: remove the specified path object from the creation cache
//
//----------------------------------------------------------------------------
VOID CChainCallContext::RemovePathObjectFromCreationCache ( IN PCCHAINPATHOBJECT pPathObject ) { HLRUENTRY hEntry; CRYPT_DATA_BLOB DataBlob;
DataBlob.cbData = CHAINHASHLEN; DataBlob.pbData = pPathObject->CertObject()->CertHash();
hEntry = I_CryptFindLruEntry( m_hObjectCreationCache, &DataBlob ); while (NULL != hEntry) { PCCHAINPATHOBJECT pFound;
pFound = (PCCHAINPATHOBJECT) I_CryptGetLruEntryData( hEntry ); if (pFound == pPathObject) { I_CryptReleaseLruEntry( hEntry ); I_CryptRemoveLruEntry( hEntry, 0, this ); break; }
hEntry = I_CryptEnumMatchingLruEntries(hEntry); } }
DWORD CChainCallContext::RevocationUrlRetrievalTimeout() { DWORD dwRevTimeout;
if (m_dwCallFlags & CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT) { if (m_dwStatus & CHAINCALLCONTEXT_REV_END_TIME_FLAG) { dwRevTimeout = I_CryptRemainingMilliseconds(&m_RevEndTime); if (0 == dwRevTimeout) dwRevTimeout = 1; } else { FILETIME ftCurrent;
if (m_fDefaultUrlRetrievalTimeout) dwRevTimeout = DEFAULT_REV_ACCUMULATIVE_URL_RETRIEVAL_TIMEOUT; else dwRevTimeout = m_ChainPara.dwUrlRetrievalTimeout;
GetSystemTimeAsFileTime(&ftCurrent); I_CryptIncrementFileTimeByMilliseconds(&ftCurrent, dwRevTimeout, &m_RevEndTime); m_dwStatus |= CHAINCALLCONTEXT_REV_END_TIME_FLAG; } } else { dwRevTimeout = m_ChainPara.dwUrlRetrievalTimeout; }
return dwRevTimeout; }
DWORD CChainCallContext::AIAUrlRetrievalTimeout() { DWORD dwAIATimeout;
if (m_dwStatus & CHAINCALLCONTEXT_AIA_END_TIME_FLAG) { dwAIATimeout = I_CryptRemainingMilliseconds(&m_AIAEndTime) / 2; if (0 == dwAIATimeout) dwAIATimeout = 1; } else { FILETIME ftCurrent;
dwAIATimeout = m_ChainPara.dwUrlRetrievalTimeout;
GetSystemTimeAsFileTime(&ftCurrent); I_CryptIncrementFileTimeByMilliseconds(&ftCurrent, dwAIATimeout * 2, &m_AIAEndTime); m_dwStatus |= CHAINCALLCONTEXT_AIA_END_TIME_FLAG; }
return dwAIATimeout; }
BOOL CChainCallContext::IsOnline () { if ( !(m_dwStatus & CHAINCALLCONTEXT_CHECKED_ONLINE_FLAG) ) { if (!(m_pChainEngine->Flags() & CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL) && !(m_dwCallFlags & CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL)) { if ( ChainIsConnected() ) { m_dwStatus |= CHAINCALLCONTEXT_ONLINE_FLAG; } } m_dwStatus |= CHAINCALLCONTEXT_CHECKED_ONLINE_FLAG; }
if (m_dwStatus & CHAINCALLCONTEXT_ONLINE_FLAG) { return TRUE; } else { return FALSE; } }
BOOL CChainCallContext::IsTouchedEngine () { if (m_dwTouchEngineCount == m_pChainEngine->TouchEngineCount()) return FALSE; else return TRUE; }
//+---------------------------------------------------------------------------
//
// Function: CallContextCreateCallObject
//
// Synopsis: create a chain call context object
//
//----------------------------------------------------------------------------
BOOL WINAPI CallContextCreateCallObject ( IN PCCERTCHAINENGINE pChainEngine, IN OPTIONAL LPFILETIME pRequestedTime, IN OPTIONAL PCERT_CHAIN_PARA pChainPara, IN DWORD dwFlags, OUT PCCHAINCALLCONTEXT* ppCallContext ) { BOOL fResult = FALSE; PCCHAINCALLCONTEXT pCallContext;
pCallContext = new CChainCallContext( pChainEngine, pRequestedTime, pChainPara, dwFlags, fResult ); if ( pCallContext == NULL ) { SetLastError( (DWORD) E_OUTOFMEMORY ); return( FALSE ); }
if ( fResult == TRUE ) { *ppCallContext = pCallContext; } else { CallContextFreeCallObject( pCallContext ); }
return( fResult ); }
//+---------------------------------------------------------------------------
//
// Function: CallContextFreeCallObject
//
// Synopsis: free the chain call context object
//
//----------------------------------------------------------------------------
VOID WINAPI CallContextFreeCallObject ( IN PCCHAINCALLCONTEXT pCallContext ) { delete pCallContext; }
//+---------------------------------------------------------------------------
//
// Function: CallContextOnCreationCacheObjectRemoval
//
// Synopsis: removal notification callback
//
//----------------------------------------------------------------------------
VOID WINAPI CallContextOnCreationCacheObjectRemoval ( IN LPVOID pv, IN LPVOID pvRemovalContext ) { delete (PCCHAINPATHOBJECT) pv; }
|