windows-nt/Source/XPSP1/NT/ds/security/cryptoapi/pkitrust/wintrust/catcache.cpp
2020-09-26 16:20:57 +08:00

380 lines
10 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows NT Security
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: catcache.cpp
//
// Contents: Implementation of Catalog Cache (see catcache.h for details)
//
// History: 26-May-98 kirtd Created
//
//----------------------------------------------------------------------------
#include <global.hxx>
//+---------------------------------------------------------------------------
//
// Member: CCatalogCache::Initialize, public
//
// Synopsis: initialize the cache
//
//----------------------------------------------------------------------------
BOOL
CCatalogCache::Initialize ()
{
LRU_CACHE_CONFIG Config;
__try
{
InitializeCriticalSection( &m_Lock );
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return ( FALSE );
}
memset( &Config, 0, sizeof( Config ) );
m_hCache = NULL;
Config.dwFlags = LRU_CACHE_NO_SERIALIZE;
Config.pfnFree = CatalogCacheFreeEntryData;
Config.pfnHash = CatalogCacheHashIdentifier;
Config.cBuckets = DEFAULT_CATALOG_CACHE_BUCKETS;
Config.MaxEntries = DEFAULT_CATALOG_CACHE_MAX_ENTRIES;
return( I_CryptCreateLruCache( &Config, &m_hCache ) );
}
//+---------------------------------------------------------------------------
//
// Member: CCatalogCache::Uninitialize, public
//
// Synopsis: uninitialize the cache
//
//----------------------------------------------------------------------------
VOID
CCatalogCache::Uninitialize ()
{
if ( m_hCache != NULL )
{
I_CryptFreeLruCache( m_hCache, 0, NULL );
}
DeleteCriticalSection( &m_Lock );
}
//+---------------------------------------------------------------------------
//
// Member: CCatalogCache::IsCacheableWintrustCall, public
//
// Synopsis: is this a cacheable call
//
//----------------------------------------------------------------------------
BOOL
CCatalogCache::IsCacheableWintrustCall (WINTRUST_DATA* pWintrustData)
{
if ( pWintrustData->dwUnionChoice != WTD_CHOICE_CATALOG )
{
return( FALSE );
}
if ( _ISINSTRUCT( WINTRUST_DATA, pWintrustData->cbStruct, hWVTStateData ) )
{
if ( ( pWintrustData->dwStateAction == WTD_STATEACTION_AUTO_CACHE ) ||
( pWintrustData->dwStateAction == WTD_STATEACTION_AUTO_CACHE_FLUSH ) )
{
return( TRUE );
}
}
return( FALSE );
}
//+---------------------------------------------------------------------------
//
// Member: CCatalogCache::AdjustWintrustDataToCachedState, public
//
// Synopsis: adjust the wintrust data structure
//
//----------------------------------------------------------------------------
VOID
CCatalogCache::AdjustWintrustDataToCachedState (
WINTRUST_DATA* pWintrustData,
PCATALOG_CACHED_STATE pCachedState,
BOOL fUndoAdjustment
)
{
PCRYPT_PROVIDER_DATA pProvData;
if ( fUndoAdjustment == FALSE )
{
pWintrustData->dwStateAction = WTD_STATEACTION_VERIFY;
if ( pCachedState != NULL )
{
pWintrustData->hWVTStateData = pCachedState->hStateData;
pProvData = WTHelperProvDataFromStateData( pCachedState->hStateData );
pProvData->pWintrustData = pWintrustData;
}
else
{
pWintrustData->hWVTStateData = NULL;
}
}
else
{
if ( pCachedState != NULL )
{
pProvData = WTHelperProvDataFromStateData( pCachedState->hStateData );
pProvData->pWintrustData = NULL;
}
pWintrustData->dwStateAction = WTD_STATEACTION_AUTO_CACHE;
pWintrustData->hWVTStateData = NULL;
}
}
//+---------------------------------------------------------------------------
//
// Member: CCatalogCache::CreateCachedStateFromWintrustData, public
//
// Synopsis: create cached state
//
//----------------------------------------------------------------------------
BOOL
CCatalogCache::CreateCachedStateFromWintrustData (
WINTRUST_DATA* pWintrustData,
PCATALOG_CACHED_STATE* ppCachedState
)
{
BOOL fResult;
PCATALOG_CACHED_STATE pCachedState;
CRYPT_DATA_BLOB Identifier;
PCRYPT_PROVIDER_DATA pProvData;
if ( pWintrustData->hWVTStateData == NULL )
{
return( FALSE );
}
pProvData = WTHelperProvDataFromStateData( pWintrustData->hWVTStateData );
if ( ( pProvData->padwTrustStepErrors[ TRUSTERROR_STEP_FINAL_INITPROV ] != ERROR_SUCCESS ) ||
( ( pProvData->padwTrustStepErrors[ TRUSTERROR_STEP_FINAL_OBJPROV ] != ERROR_SUCCESS ) &&
( pProvData->padwTrustStepErrors[ TRUSTERROR_STEP_FINAL_OBJPROV ] != TRUST_E_BAD_DIGEST ) ) ||
( pProvData->padwTrustStepErrors[ TRUSTERROR_STEP_FINAL_SIGPROV ] != ERROR_SUCCESS ) ||
( pProvData->hMsg == NULL ) )
{
return( FALSE );
}
assert( pProvData->hMsg != NULL );
pCachedState = new CATALOG_CACHED_STATE;
if ( pCachedState != NULL )
{
pCachedState->hStateData = pWintrustData->hWVTStateData;
pCachedState->hEntry = NULL;
Identifier.cbData = wcslen(
pWintrustData->pCatalog->pcwszCatalogFilePath
);
Identifier.cbData *= sizeof( WCHAR );
Identifier.pbData = (LPBYTE)pWintrustData->pCatalog->pcwszCatalogFilePath;
fResult = I_CryptCreateLruEntry(
m_hCache,
&Identifier,
pCachedState,
&pCachedState->hEntry
);
}
else
{
SetLastError( E_OUTOFMEMORY );
fResult = FALSE;
}
if ( fResult == TRUE )
{
*ppCachedState = pCachedState;
}
else
{
delete pCachedState;
}
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Member: CCatalogCache::ReleaseCachedState, public
//
// Synopsis: release the cached state
//
//----------------------------------------------------------------------------
VOID
CCatalogCache::ReleaseCachedState (PCATALOG_CACHED_STATE pCachedState)
{
if ( pCachedState == NULL )
{
return;
}
I_CryptReleaseLruEntry( pCachedState->hEntry );
}
//+---------------------------------------------------------------------------
//
// Member: CCatalogCache::AddCachedState, public
//
// Synopsis: add cached state
//
//----------------------------------------------------------------------------
VOID
CCatalogCache::AddCachedState (PCATALOG_CACHED_STATE pCachedState)
{
I_CryptInsertLruEntry( pCachedState->hEntry, NULL );
}
//+---------------------------------------------------------------------------
//
// Member: CCatalogCache::RemoveCachedState, public
//
// Synopsis: remove cached state
//
//----------------------------------------------------------------------------
VOID
CCatalogCache::RemoveCachedState (PCATALOG_CACHED_STATE pCachedState)
{
I_CryptRemoveLruEntry( pCachedState->hEntry, 0, NULL );
}
//+---------------------------------------------------------------------------
//
// Member: CCatalogCache::RemoveCachedState, public
//
// Synopsis: remove cached state
//
//----------------------------------------------------------------------------
VOID
CCatalogCache::RemoveCachedState (WINTRUST_DATA* pWintrustData)
{
PCATALOG_CACHED_STATE pCachedState;
pCachedState = FindCachedState( pWintrustData );
if ( pCachedState != NULL )
{
RemoveCachedState( pCachedState );
ReleaseCachedState( pCachedState );
}
}
//+---------------------------------------------------------------------------
//
// Member: CCatalogCache::FindCachedState, public
//
// Synopsis: find cached state, the state is addref'd via the entry
//
//----------------------------------------------------------------------------
PCATALOG_CACHED_STATE
CCatalogCache::FindCachedState (WINTRUST_DATA* pWintrustData)
{
PCATALOG_CACHED_STATE pCachedState;
CRYPT_DATA_BLOB Identifier;
HLRUENTRY hEntry;
Identifier.cbData = wcslen(
pWintrustData->pCatalog->pcwszCatalogFilePath
);
Identifier.cbData *= sizeof( WCHAR );
Identifier.pbData = (LPBYTE)pWintrustData->pCatalog->pcwszCatalogFilePath;
pCachedState = (PCATALOG_CACHED_STATE)I_CryptFindLruEntryData(
m_hCache,
&Identifier,
&hEntry
);
return( pCachedState );
}
//+---------------------------------------------------------------------------
//
// Member: CCatalogCache::FlushCache, public
//
// Synopsis: flush the cache
//
//----------------------------------------------------------------------------
VOID
CCatalogCache::FlushCache ()
{
I_CryptFlushLruCache( m_hCache, 0, NULL );
}
//+---------------------------------------------------------------------------
//
// Function: CatalogCacheFreeEntryData
//
// Synopsis: free entry data
//
//----------------------------------------------------------------------------
VOID WINAPI
CatalogCacheFreeEntryData (LPVOID pvData)
{
PCATALOG_CACHED_STATE pCachedState = (PCATALOG_CACHED_STATE)pvData;
WINTRUST_DATA WintrustData;
GUID ActionGuid;
memset( &ActionGuid, 0, sizeof( ActionGuid ) );
memset( &WintrustData, 0, sizeof( WintrustData ) );
WintrustData.cbStruct = sizeof( WintrustData );
WintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
WintrustData.hWVTStateData = pCachedState->hStateData;
WinVerifyTrust( NULL, &ActionGuid, &WintrustData );
delete pCachedState;
}
//+---------------------------------------------------------------------------
//
// Function: CatalogCacheHashIdentifier
//
// Synopsis: hash the name
//
//----------------------------------------------------------------------------
DWORD WINAPI
CatalogCacheHashIdentifier (PCRYPT_DATA_BLOB pIdentifier)
{
DWORD dwHash = 0;
DWORD cb = pIdentifier->cbData;
LPBYTE pb = pIdentifier->pbData;
while ( cb-- )
{
if ( dwHash & 0x80000000 )
{
dwHash = ( dwHash << 1 ) | 1;
}
else
{
dwHash = dwHash << 1;
}
dwHash += *pb++;
}
return( dwHash );
}