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.
355 lines
10 KiB
355 lines
10 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// 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;
|
|
}
|
|
|