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