Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1924 lines
58 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows NT Security
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: tvo.cpp
//
// Contents: Implementation of CryptGetTimeValidObject
//
// History: 25-Sep-97 kirtd Created
//
//----------------------------------------------------------------------------
#include <global.hxx>
//+---------------------------------------------------------------------------
//
// Function: CryptGetTimeValidObject
//
// Synopsis: get a time valid CAPI2 object
//
//----------------------------------------------------------------------------
BOOL WINAPI
CryptGetTimeValidObject (
IN LPCSTR pszTimeValidOid,
IN LPVOID pvPara,
IN PCCERT_CONTEXT pIssuer,
IN LPFILETIME pftValidFor,
IN DWORD dwFlags,
IN DWORD dwTimeout,
OUT OPTIONAL LPVOID* ppvObject,
IN OPTIONAL PCRYPT_CREDENTIALS pCredentials,
IN OPTIONAL LPVOID pvReserved
)
{
BOOL fResult;
HCRYPTOIDFUNCADDR hGetTimeValidObject;
PFN_GET_TIME_VALID_OBJECT_FUNC pfnGetTimeValidObject;
DWORD LastError;
FILETIME CurrentTime;
if ( CryptGetOIDFunctionAddress(
hGetTimeValidObjectFuncSet,
X509_ASN_ENCODING,
pszTimeValidOid,
0,
(LPVOID *)&pfnGetTimeValidObject,
&hGetTimeValidObject
) == FALSE )
{
return( FALSE );
}
if ( pftValidFor == NULL )
{
GetSystemTimeAsFileTime( &CurrentTime );
pftValidFor = &CurrentTime;
}
fResult = ( *pfnGetTimeValidObject )(
pszTimeValidOid,
pvPara,
pIssuer,
pftValidFor,
dwFlags,
dwTimeout,
ppvObject,
pCredentials,
pvReserved
);
LastError = GetLastError();
CryptFreeOIDFunctionAddress( hGetTimeValidObject, 0 );
SetLastError( LastError );
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Function: CtlGetTimeValidObject
//
// Synopsis: get a time valid CTL
//
//----------------------------------------------------------------------------
BOOL WINAPI
CtlGetTimeValidObject (
IN LPCSTR pszTimeValidOid,
IN LPVOID pvPara,
IN PCCERT_CONTEXT pIssuer,
IN LPFILETIME pftValidFor,
IN DWORD dwFlags,
IN DWORD dwTimeout,
OUT OPTIONAL LPVOID* ppvObject,
IN OPTIONAL PCRYPT_CREDENTIALS pCredentials,
IN OPTIONAL LPVOID pvReserved
)
{
return( g_pProcessTVOAgent->GetTimeValidObject(
pszTimeValidOid,
pvPara,
CONTEXT_OID_CTL,
pIssuer,
pftValidFor,
dwFlags,
dwTimeout,
ppvObject,
pCredentials,
pvReserved
) );
}
//+---------------------------------------------------------------------------
//
// Function: CrlGetTimeValidObject
//
// Synopsis: get a time valid CRL
//
//----------------------------------------------------------------------------
BOOL WINAPI
CrlGetTimeValidObject (
IN LPCSTR pszTimeValidOid,
IN LPVOID pvPara,
IN PCCERT_CONTEXT pIssuer,
IN LPFILETIME pftValidFor,
IN DWORD dwFlags,
IN DWORD dwTimeout,
OUT OPTIONAL LPVOID* ppvObject,
IN OPTIONAL PCRYPT_CREDENTIALS pCredentials,
IN OPTIONAL LPVOID pvReserved
)
{
return( g_pProcessTVOAgent->GetTimeValidObject(
pszTimeValidOid,
pvPara,
CONTEXT_OID_CRL,
pIssuer,
pftValidFor,
dwFlags,
dwTimeout,
ppvObject,
pCredentials,
pvReserved
) );
}
//+---------------------------------------------------------------------------
//
// Function: CrlFromCertGetTimeValidObject
//
// Synopsis: get a time valid CRL from a subject certificate
//
//----------------------------------------------------------------------------
BOOL WINAPI
CrlFromCertGetTimeValidObject (
IN LPCSTR pszTimeValidOid,
IN LPVOID pvPara,
IN PCCERT_CONTEXT pIssuer,
IN LPFILETIME pftValidFor,
IN DWORD dwFlags,
IN DWORD dwTimeout,
OUT OPTIONAL LPVOID* ppvObject,
IN OPTIONAL PCRYPT_CREDENTIALS pCredentials,
IN OPTIONAL LPVOID pvReserved
)
{
return( g_pProcessTVOAgent->GetTimeValidObject(
pszTimeValidOid,
pvPara,
CONTEXT_OID_CRL,
pIssuer,
pftValidFor,
dwFlags,
dwTimeout,
ppvObject,
pCredentials,
pvReserved
) );
}
//+---------------------------------------------------------------------------
//
// Function: FreshestCrlFromCertGetTimeValidObject
//
// Synopsis: get a time valid freshest, delta CRL from a subject certificate
//
//----------------------------------------------------------------------------
BOOL WINAPI
FreshestCrlFromCertGetTimeValidObject (
IN LPCSTR pszTimeValidOid,
IN LPVOID pvPara,
IN PCCERT_CONTEXT pIssuer,
IN LPFILETIME pftValidFor,
IN DWORD dwFlags,
IN DWORD dwTimeout,
OUT OPTIONAL LPVOID* ppvObject,
IN OPTIONAL PCRYPT_CREDENTIALS pCredentials,
IN OPTIONAL LPVOID pvReserved
)
{
return( g_pProcessTVOAgent->GetTimeValidObject(
pszTimeValidOid,
pvPara,
CONTEXT_OID_CRL,
pIssuer,
pftValidFor,
dwFlags,
dwTimeout,
ppvObject,
pCredentials,
pvReserved
) );
}
//+---------------------------------------------------------------------------
//
// Function: FreshestCrlFromCrlGetTimeValidObject
//
// Synopsis: get a time valid freshest, delta CRL from a base CRL
//
//----------------------------------------------------------------------------
BOOL WINAPI
FreshestCrlFromCrlGetTimeValidObject (
IN LPCSTR pszTimeValidOid,
IN LPVOID pvPara,
IN PCCERT_CONTEXT pIssuer,
IN LPFILETIME pftValidFor,
IN DWORD dwFlags,
IN DWORD dwTimeout,
OUT OPTIONAL LPVOID* ppvObject,
IN OPTIONAL PCRYPT_CREDENTIALS pCredentials,
IN OPTIONAL LPVOID pvReserved
)
{
return( g_pProcessTVOAgent->GetTimeValidObject(
pszTimeValidOid,
pvPara,
CONTEXT_OID_CRL,
pIssuer,
pftValidFor,
dwFlags,
dwTimeout,
ppvObject,
pCredentials,
pvReserved
) );
}
//+---------------------------------------------------------------------------
//
// Function: CryptFlushTimeValidObject
//
// Synopsis: flush the object from the "TVO" system
//
//----------------------------------------------------------------------------
BOOL WINAPI
CryptFlushTimeValidObject (
IN LPCSTR pszFlushTimeValidOid,
IN LPVOID pvPara,
IN PCCERT_CONTEXT pIssuer,
IN DWORD dwFlags,
IN LPVOID pvReserved
)
{
BOOL fResult;
HCRYPTOIDFUNCADDR hFlushTimeValidObject;
PFN_FLUSH_TIME_VALID_OBJECT_FUNC pfnFlushTimeValidObject;
DWORD LastError;
if ( CryptGetOIDFunctionAddress(
hFlushTimeValidObjectFuncSet,
X509_ASN_ENCODING,
pszFlushTimeValidOid,
0,
(LPVOID *)&pfnFlushTimeValidObject,
&hFlushTimeValidObject
) == FALSE )
{
return( FALSE );
}
fResult = ( *pfnFlushTimeValidObject )(
pszFlushTimeValidOid,
pvPara,
pIssuer,
dwFlags,
pvReserved
);
LastError = GetLastError();
CryptFreeOIDFunctionAddress( hFlushTimeValidObject, 0 );
SetLastError( LastError );
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Function: CtlFlushTimeValidObject
//
// Synopsis: flush a CTL from the "TVO" system
//
//----------------------------------------------------------------------------
BOOL WINAPI
CtlFlushTimeValidObject (
IN LPCSTR pszFlushTimeValidOid,
IN LPVOID pvPara,
IN PCCERT_CONTEXT pIssuer,
IN DWORD dwFlags,
IN LPVOID pvReserved
)
{
return( g_pProcessTVOAgent->FlushTimeValidObject(
pszFlushTimeValidOid,
pvPara,
CONTEXT_OID_CTL,
pIssuer,
dwFlags,
pvReserved
) );
}
//+---------------------------------------------------------------------------
//
// Function: CrlFlushTimeValidObject
//
// Synopsis: flush a CRL from the "TVO" system
//
//----------------------------------------------------------------------------
BOOL WINAPI
CrlFlushTimeValidObject (
IN LPCSTR pszFlushTimeValidOid,
IN LPVOID pvPara,
IN PCCERT_CONTEXT pIssuer,
IN DWORD dwFlags,
IN LPVOID pvReserved
)
{
return( g_pProcessTVOAgent->FlushTimeValidObject(
pszFlushTimeValidOid,
pvPara,
CONTEXT_OID_CRL,
pIssuer,
dwFlags,
pvReserved
) );
}
//+---------------------------------------------------------------------------
//
// Function: CrlFromCertFlushTimeValidObject
//
// Synopsis: flush a CRL from the "TVO" system given a subject cert
//
//----------------------------------------------------------------------------
BOOL WINAPI
CrlFromCertFlushTimeValidObject (
IN LPCSTR pszFlushTimeValidOid,
IN LPVOID pvPara,
IN PCCERT_CONTEXT pIssuer,
IN DWORD dwFlags,
IN LPVOID pvReserved
)
{
return( g_pProcessTVOAgent->FlushTimeValidObject(
pszFlushTimeValidOid,
pvPara,
CONTEXT_OID_CRL,
pIssuer,
dwFlags,
pvReserved
) );
}
//+---------------------------------------------------------------------------
//
// Function: FreshedtCrlFromCertFlushTimeValidObject
//
// Synopsis: flush a freshest, delta CRL from the "TVO" system given a
// subject cert
//
//----------------------------------------------------------------------------
BOOL WINAPI
FreshestCrlFromCertFlushTimeValidObject (
IN LPCSTR pszFlushTimeValidOid,
IN LPVOID pvPara,
IN PCCERT_CONTEXT pIssuer,
IN DWORD dwFlags,
IN LPVOID pvReserved
)
{
return( g_pProcessTVOAgent->FlushTimeValidObject(
pszFlushTimeValidOid,
pvPara,
CONTEXT_OID_CRL,
pIssuer,
dwFlags,
pvReserved
) );
}
//+---------------------------------------------------------------------------
//
// Function: FreshestCrlFromCrlFlushTimeValidObject
//
// Synopsis: flush a freshest, delta CRL from the "TVO" system given a
// base CRL
//
//----------------------------------------------------------------------------
BOOL WINAPI
FreshestCrlFromCrlFlushTimeValidObject (
IN LPCSTR pszFlushTimeValidOid,
IN LPVOID pvPara,
IN PCCERT_CONTEXT pIssuer,
IN DWORD dwFlags,
IN LPVOID pvReserved
)
{
return( g_pProcessTVOAgent->FlushTimeValidObject(
pszFlushTimeValidOid,
pvPara,
CONTEXT_OID_CRL,
pIssuer,
dwFlags,
pvReserved
) );
}
//+---------------------------------------------------------------------------
//
// Member: CTVOCache::CTVOCache, public
//
// Synopsis: Constructor
//
//----------------------------------------------------------------------------
CTVOCache::CTVOCache (
DWORD cCacheBuckets,
DWORD MaxCacheEntries,
BOOL& rfResult
)
{
LRU_CACHE_CONFIG CacheConfig;
assert( MaxCacheEntries > 0 );
memset( &CacheConfig, 0, sizeof( CacheConfig ) );
CacheConfig.dwFlags = LRU_CACHE_NO_SERIALIZE | LRU_CACHE_NO_COPY_IDENTIFIER;
CacheConfig.cBuckets = cCacheBuckets;
CacheConfig.MaxEntries = MaxCacheEntries;
CacheConfig.pfnHash = TVOCacheHashOriginIdentifier;
CacheConfig.pfnOnRemoval = TVOCacheOnRemoval;
rfResult = I_CryptCreateLruCache( &CacheConfig, &m_hCache );
}
//+---------------------------------------------------------------------------
//
// Member: CTVOCache::~CTVOCache, public
//
// Synopsis: Destructor
//
//----------------------------------------------------------------------------
CTVOCache::~CTVOCache ()
{
I_CryptFreeLruCache( m_hCache, 0, NULL );
}
//+---------------------------------------------------------------------------
//
// Member: CTVOCache::InsertCacheEntry, public
//
// Synopsis: insert entry into cache
//
//----------------------------------------------------------------------------
VOID
CTVOCache::InsertCacheEntry (PTVO_CACHE_ENTRY pEntry)
{
I_CryptInsertLruEntry( pEntry->hLruEntry, NULL );
}
//+---------------------------------------------------------------------------
//
// Member: CTVOCache::RemoveCacheEntry, public
//
// Synopsis: remove entry from cache
//
//----------------------------------------------------------------------------
VOID
CTVOCache::RemoveCacheEntry (PTVO_CACHE_ENTRY pEntry, BOOL fSuppressFree)
{
DWORD dwFlags = 0;
if ( fSuppressFree == TRUE )
{
dwFlags = LRU_SUPPRESS_REMOVAL_NOTIFICATION;
}
I_CryptRemoveLruEntry( pEntry->hLruEntry, dwFlags, NULL );
}
//+---------------------------------------------------------------------------
//
// Member: CTVOCache::TouchCacheEntry, public
//
// Synopsis: touch an entry
//
//----------------------------------------------------------------------------
VOID
CTVOCache::TouchCacheEntry (PTVO_CACHE_ENTRY pEntry)
{
I_CryptTouchLruEntry( pEntry->hLruEntry, 0 );
}
//+---------------------------------------------------------------------------
//
// Member: CTVOCache::FindCacheEntry, public
//
// Synopsis: find an entry in the cache given the origin identifier.
// Skip entries that aren't valid for the subject.
//
//----------------------------------------------------------------------------
PTVO_CACHE_ENTRY
CTVOCache::FindCacheEntry (
CRYPT_ORIGIN_IDENTIFIER OriginIdentifier,
LPCSTR pszContextOid,
LPVOID pvSubject
)
{
HLRUENTRY hEntry;
CRYPT_DATA_BLOB DataBlob;
PTVO_CACHE_ENTRY pEntry = NULL;
DataBlob.cbData = MD5DIGESTLEN;
DataBlob.pbData = OriginIdentifier;
hEntry = I_CryptFindLruEntry( m_hCache, &DataBlob );
while ( hEntry != NULL )
{
pEntry = (PTVO_CACHE_ENTRY)I_CryptGetLruEntryData( hEntry );
assert(pEntry);
assert(pszContextOid == pEntry->pszContextOid);
if (pszContextOid == pEntry->pszContextOid &&
ObjectContextIsValidForSubject (
pszContextOid,
pEntry->pvContext,
pvSubject,
NULL // pvExtraInfo
))
{
I_CryptReleaseLruEntry( hEntry );
break;
}
else
{
pEntry = NULL;
hEntry = I_CryptEnumMatchingLruEntries ( hEntry );
}
}
return( pEntry );
}
//+---------------------------------------------------------------------------
//
// Member: CTVOCache::RemoveAllCacheEntries, public
//
// Synopsis: remove all cache entries
//
//----------------------------------------------------------------------------
VOID
CTVOCache::RemoveAllCacheEntries ()
{
I_CryptFlushLruCache( m_hCache, 0, NULL );
}
//+---------------------------------------------------------------------------
//
// Function: TVOCacheHashOriginIdentifier
//
// Synopsis: hash the origin identifier to a DWORD, since the origin
// identifier is already a unique MD5 hash our algorithm is
// to simply use some of the bytes
//
//----------------------------------------------------------------------------
DWORD WINAPI
TVOCacheHashOriginIdentifier (PCRYPT_DATA_BLOB pIdentifier)
{
DWORD Hash;
assert( pIdentifier->cbData == MD5DIGESTLEN );
memcpy( &Hash, pIdentifier->pbData, sizeof( DWORD ) );
return( Hash );
}
//+---------------------------------------------------------------------------
//
// Function: TVOCacheOnRemoval
//
// Synopsis: removal notification callback
//
//----------------------------------------------------------------------------
VOID WINAPI
TVOCacheOnRemoval (LPVOID pvData, LPVOID pvRemovalContext)
{
ObjectContextFreeTVOCacheEntry( (PTVO_CACHE_ENTRY)pvData );
}
//+---------------------------------------------------------------------------
//
// Member: CTVOAgent::CTVOAgent, public
//
// Synopsis: Constructor
//
//----------------------------------------------------------------------------
CTVOAgent::CTVOAgent (
DWORD cCacheBuckets,
DWORD MaxCacheEntries,
BOOL& rfResult
)
: m_Cache( cCacheBuckets, MaxCacheEntries, rfResult )
{
if (!Pki_InitializeCriticalSection( &m_Lock ))
{
rfResult = FALSE;
}
}
//+---------------------------------------------------------------------------
//
// Member: CTVOAgent::~CTVOAgent, public
//
// Synopsis: Destructor
//
//----------------------------------------------------------------------------
CTVOAgent::~CTVOAgent ()
{
m_Cache.RemoveAllCacheEntries();
DeleteCriticalSection( &m_Lock );
}
//+---------------------------------------------------------------------------
//
// Member: CTVOAgent::GetTimeValidObject, public
//
// Synopsis: get a time valid CAPI2 object
//
//----------------------------------------------------------------------------
BOOL
CTVOAgent::GetTimeValidObject (
IN LPCSTR pszTimeValidOid,
IN LPVOID pvPara,
IN LPCSTR pszContextOid,
IN PCCERT_CONTEXT pIssuer,
IN LPFILETIME pftValidFor,
IN DWORD dwFlags,
IN DWORD dwTimeout,
OUT OPTIONAL LPVOID* ppvObject,
IN OPTIONAL PCRYPT_CREDENTIALS pCredentials,
IN OPTIONAL LPVOID pvReserved
)
{
BOOL fResult = TRUE;
CRYPT_ORIGIN_IDENTIFIER OriginIdentifier;
PTVO_CACHE_ENTRY pCacheEntry = NULL;
DWORD PreferredUrlIndex = 0;
PCRYPT_URL_ARRAY pUrlArray = NULL;
DWORD cb = 0;
DWORD cbUrlArray = 0;
PCRYPT_URL_ARRAY pCacheUrlArray = NULL;
LPWSTR pwszUrlHint = NULL;
BOOL fHintInArray = FALSE;
BOOL fArrayOwned = FALSE;
BOOL fCrlFromCert = FALSE;
LPCSTR pszUrlOidCrlFromCert = NULL;
LPVOID pvSubject = NULL;
BOOL fFreshest = FALSE;
if ( pszTimeValidOid == TIME_VALID_OID_GET_CRL_FROM_CERT )
{
fCrlFromCert = TRUE;
pszUrlOidCrlFromCert = URL_OID_CERTIFICATE_CRL_DIST_POINT;
pvSubject = pvPara;
}
else if ( pszTimeValidOid == TIME_VALID_OID_GET_FRESHEST_CRL_FROM_CERT )
{
fCrlFromCert = TRUE;
pszUrlOidCrlFromCert = URL_OID_CERTIFICATE_FRESHEST_CRL;
pvSubject = pvPara;
fFreshest = TRUE;
}
else if ( pszTimeValidOid == TIME_VALID_OID_GET_FRESHEST_CRL_FROM_CRL )
{
fCrlFromCert = TRUE;
pszUrlOidCrlFromCert = URL_OID_CRL_FRESHEST_CRL;
pvSubject = (LPVOID) ((PCCERT_CRL_CONTEXT_PAIR)pvPara)->pCertContext;
fFreshest = TRUE;
}
if (fCrlFromCert)
{
if ( CrlGetOriginIdentifierFromSubjectCert(
(PCCERT_CONTEXT)pvSubject,
pIssuer,
fFreshest,
OriginIdentifier
) == FALSE )
{
return( FALSE );
}
assert( pszContextOid == CONTEXT_OID_CRL );
}
else
{
if ( ObjectContextGetOriginIdentifier(
pszContextOid,
pvPara,
pIssuer,
0,
OriginIdentifier
) == FALSE )
{
return( FALSE );
}
}
PreferredUrlIndex = 0;
pUrlArray = NULL;
EnterCriticalSection( &m_Lock );
pCacheEntry = m_Cache.FindCacheEntry(
OriginIdentifier,
pszContextOid,
pvSubject
);
if ( pCacheEntry != NULL )
{
if ( !( dwFlags & CRYPT_WIRE_ONLY_RETRIEVAL ) )
{
if ( ( dwFlags & CRYPT_DONT_CHECK_TIME_VALIDITY ) ||
IsValidCreateOrExpireTime (
0 != (dwFlags & CRYPT_CHECK_FRESHNESS_TIME_VALIDITY),
pftValidFor,
&pCacheEntry->CreateTime,
&pCacheEntry->ExpireTime ) )
{
m_Cache.TouchCacheEntry( pCacheEntry );
if ( ppvObject != NULL )
{
*ppvObject = ObjectContextDuplicate(
pCacheEntry->pszContextOid,
pCacheEntry->pvContext
);
}
LeaveCriticalSection( &m_Lock );
return( TRUE );
}
}
if ( !( dwFlags & CRYPT_CACHE_ONLY_RETRIEVAL ) )
{
if ( GetOfflineUrlTimeStatus(&pCacheEntry->OfflineUrlTimeInfo) < 0
||
!I_CryptNetIsConnected() )
{
if ( dwFlags & CRYPT_WIRE_ONLY_RETRIEVAL )
{
LeaveCriticalSection( &m_Lock );
SetLastError( (DWORD) ERROR_NOT_CONNECTED );
return( FALSE );
}
else
{
dwFlags |= CRYPT_CACHE_ONLY_RETRIEVAL;
}
}
}
if ( pCacheEntry->pUrlArrayNext != NULL )
{
cbUrlArray = pCacheEntry->cbUrlArrayNext;
pCacheUrlArray = pCacheEntry->pUrlArrayNext;
PreferredUrlIndex = pCacheEntry->UrlIndexNext;
}
else
{
cbUrlArray = pCacheEntry->cbUrlArrayThis;
pCacheUrlArray = pCacheEntry->pUrlArrayThis;
PreferredUrlIndex = pCacheEntry->UrlIndexThis;
}
}
else if ( !( dwFlags & CRYPT_CACHE_ONLY_RETRIEVAL ) )
{
if ( !I_CryptNetIsConnected() )
{
if ( dwFlags & CRYPT_WIRE_ONLY_RETRIEVAL )
{
LeaveCriticalSection( &m_Lock );
SetLastError( (DWORD) ERROR_NOT_CONNECTED );
return( FALSE );
}
else
{
dwFlags |= CRYPT_CACHE_ONLY_RETRIEVAL;
}
}
}
if ( ( fResult == TRUE ) && ( pUrlArray == NULL ) )
{
if ( pCacheEntry != NULL )
{
pwszUrlHint = pCacheUrlArray->rgwszUrl[ PreferredUrlIndex ];
}
if ( fCrlFromCert )
{
fResult = CertificateGetCrlDistPointUrl(
pszUrlOidCrlFromCert,
pvPara,
pwszUrlHint,
&pUrlArray,
&cb,
&PreferredUrlIndex,
&fHintInArray
);
}
else if ( pszTimeValidOid == TIME_VALID_OID_GET_CTL )
{
fResult = ObjectContextGetNextUpdateUrl(
pszContextOid,
pvPara,
pIssuer,
pwszUrlHint,
&pUrlArray,
&cb,
&PreferredUrlIndex,
&fHintInArray
);
}
else
{
SetLastError( (DWORD) CRYPT_E_NOT_FOUND );
fResult = FALSE;
}
if ( fResult == TRUE )
{
cbUrlArray = cb;
}
else if ( pCacheEntry != NULL )
{
pUrlArray = (PCRYPT_URL_ARRAY)new BYTE [ cbUrlArray ];
if ( pUrlArray != NULL )
{
if (CopyUrlArray( pUrlArray, pCacheUrlArray, cbUrlArray ))
{
fHintInArray = TRUE;
fResult = TRUE;
}
else
{
delete [] (BYTE *) pUrlArray;
pUrlArray = NULL;
SetLastError( (DWORD) E_INVALIDARG );
}
}
else
{
SetLastError( (DWORD) E_OUTOFMEMORY );
}
}
}
LeaveCriticalSection( &m_Lock );
if ( fResult == TRUE )
{
fResult = GetTimeValidObjectByUrl(
cbUrlArray,
pUrlArray,
PreferredUrlIndex,
pszContextOid,
pIssuer,
pvSubject,
OriginIdentifier,
pftValidFor,
dwFlags,
dwTimeout,
ppvObject,
pCredentials,
NULL,
&fArrayOwned,
pvReserved
);
}
if ( fArrayOwned == FALSE )
{
delete [] (BYTE *) pUrlArray;
}
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Member: CTVOAgent::GetTimeValidObjectByUrl, public
//
// Synopsis: get a time valid object using URL
//
//----------------------------------------------------------------------------
BOOL
CTVOAgent::GetTimeValidObjectByUrl (
IN DWORD cbUrlArray,
IN PCRYPT_URL_ARRAY pUrlArray,
IN DWORD PreferredUrlIndex,
IN LPCSTR pszContextOid,
IN PCCERT_CONTEXT pIssuer,
IN LPVOID pvSubject,
IN CRYPT_ORIGIN_IDENTIFIER OriginIdentifier,
IN LPFILETIME pftValidFor,
IN DWORD dwFlags,
IN DWORD dwTimeout,
OUT OPTIONAL LPVOID* ppvObject,
IN OPTIONAL PCRYPT_CREDENTIALS pCredentials,
IN OPTIONAL LPWSTR pwszUrlExtra,
OUT BOOL* pfArrayOwned,
IN OPTIONAL LPVOID pvReserved
)
{
BOOL fResult = FALSE;
DWORD cCount;
LPWSTR pwsz;
LPVOID pvContext = NULL;
PTVO_CACHE_ENTRY pEntry = NULL;
PTVO_CACHE_ENTRY pFound;
DWORD LastError;
// Following is only used for CRYPT_ACCUMULATIVE_TIMEOUT
FILETIME ftEndUrlRetrieval;
if ( PreferredUrlIndex != 0 )
{
pwsz = pUrlArray->rgwszUrl[PreferredUrlIndex];
pUrlArray->rgwszUrl[PreferredUrlIndex] = pUrlArray->rgwszUrl[0];
pUrlArray->rgwszUrl[0] = pwsz;
}
if (dwFlags & CRYPT_ACCUMULATIVE_TIMEOUT)
{
if (0 == dwTimeout)
{
dwFlags &= ~CRYPT_ACCUMULATIVE_TIMEOUT;
}
else
{
FILETIME ftStartUrlRetrieval;
GetSystemTimeAsFileTime(&ftStartUrlRetrieval);
I_CryptIncrementFileTimeByMilliseconds(
&ftStartUrlRetrieval, dwTimeout,
&ftEndUrlRetrieval);
}
}
for ( cCount = 0; cCount < pUrlArray->cUrl; cCount++ )
{
if (dwFlags & CRYPT_ACCUMULATIVE_TIMEOUT)
{
// Limit each URL timeout to half of the remaining time
dwTimeout = I_CryptRemainingMilliseconds(&ftEndUrlRetrieval) / 2;
if (0 == dwTimeout)
{
dwTimeout = 1;
}
}
fResult = RetrieveTimeValidObjectByUrl(
pUrlArray->rgwszUrl[cCount],
pszContextOid,
pftValidFor,
dwFlags,
dwTimeout,
pCredentials,
pIssuer,
pvSubject,
OriginIdentifier,
&pvContext,
pvReserved
);
if ( fResult == TRUE )
{
fResult = ObjectContextCreateTVOCacheEntry(
m_Cache.LruCacheHandle(),
pszContextOid,
pvContext,
OriginIdentifier,
cbUrlArray,
pUrlArray,
cCount,
pIssuer,
&pEntry
);
*pfArrayOwned = fResult;
break;
}
}
if ( ( PreferredUrlIndex != 0 ) && ( *pfArrayOwned == FALSE ) )
{
pwsz = pUrlArray->rgwszUrl[PreferredUrlIndex];
pUrlArray->rgwszUrl[PreferredUrlIndex] = pUrlArray->rgwszUrl[0];
pUrlArray->rgwszUrl[0] = pwsz;
}
if ( ( fResult == FALSE ) && ( pwszUrlExtra != NULL ) )
{
if (dwFlags & CRYPT_ACCUMULATIVE_TIMEOUT)
{
// Limit each URL timeout to half of the remaining time
dwTimeout = I_CryptRemainingMilliseconds(&ftEndUrlRetrieval) / 2;
if (0 == dwTimeout)
{
dwTimeout = 1;
}
}
fResult = RetrieveTimeValidObjectByUrl(
pwszUrlExtra,
pszContextOid,
pftValidFor,
dwFlags,
dwTimeout,
pCredentials,
pIssuer,
pvSubject,
OriginIdentifier,
&pvContext,
pvReserved
);
if ( fResult == TRUE )
{
CCryptUrlArray cua( pUrlArray->cUrl + 1, 5, fResult );
DWORD cb = 0;
PCRYPT_URL_ARRAY pcua = NULL;
if ( fResult == TRUE )
{
for ( cCount = 0; cCount < pUrlArray->cUrl; cCount++ )
{
fResult = cua.AddUrl( pUrlArray->rgwszUrl[cCount], FALSE );
if ( fResult == FALSE )
{
break;
}
}
}
if ( fResult == TRUE )
{
fResult = cua.GetArrayInSingleBufferEncodedForm(
&pcua,
&cb
);
}
if ( fResult == TRUE )
{
fResult = ObjectContextCreateTVOCacheEntry(
m_Cache.LruCacheHandle(),
pszContextOid,
pvContext,
OriginIdentifier,
cb,
pcua,
pUrlArray->cUrl,
pIssuer,
&pEntry
);
if ( fResult == FALSE )
{
CryptMemFree( pcua );
}
}
cua.FreeArray( FALSE );
}
}
LastError = GetLastError();
EnterCriticalSection( &m_Lock );
pFound = m_Cache.FindCacheEntry(
OriginIdentifier,
pszContextOid,
pvSubject
);
if ( !fResult && pFound && !( dwFlags & CRYPT_CACHE_ONLY_RETRIEVAL ) )
{
SetOfflineUrlTime( &pFound->OfflineUrlTimeInfo );
}
if ( ( fResult == TRUE ) && !( dwFlags & CRYPT_DONT_VERIFY_SIGNATURE ) )
{
if ( ( pFound != NULL ) &&
( CompareFileTime(
&pFound->CreateTime,
&pEntry->CreateTime
) >= 0 ) )
{
ObjectContextFree( pszContextOid, pvContext );
pvContext = ObjectContextDuplicate(
pFound->pszContextOid,
pFound->pvContext
);
SetOnlineUrlTime( &pFound->OfflineUrlTimeInfo );
ObjectContextFreeTVOCacheEntry( pEntry );
}
else
{
if ( pFound != NULL )
{
m_Cache.RemoveCacheEntry( pFound );
}
m_Cache.InsertCacheEntry( pEntry );
}
}
else if ( pEntry != NULL )
{
ObjectContextFreeTVOCacheEntry( pEntry );
}
LeaveCriticalSection( &m_Lock );
if ( pvContext != NULL )
{
if ( ( ppvObject != NULL ) && ( fResult == TRUE ) )
{
*ppvObject = pvContext;
}
else
{
ObjectContextFree( pszContextOid, pvContext );
}
}
SetLastError( LastError );
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Member: CTVOAgent::FlushTimeValidObject, public
//
// Synopsis: flush time valid object
//
//----------------------------------------------------------------------------
BOOL
CTVOAgent::FlushTimeValidObject (
IN LPCSTR pszFlushTimeValidOid,
IN LPVOID pvPara,
IN LPCSTR pszFlushContextOid,
IN PCCERT_CONTEXT pIssuer,
IN DWORD dwFlags,
IN LPVOID pvReserved
)
{
BOOL fResult = TRUE;
CRYPT_ORIGIN_IDENTIFIER OriginIdentifier;
PTVO_CACHE_ENTRY pCacheEntry = NULL;
PCRYPT_URL_ARRAY pUrlArray = NULL;
DWORD cbUrlArray;
DWORD dwError = 0;
DWORD cCount;
BOOL fCrlFromCert = FALSE;
LPCSTR pszUrlOidCrlFromCert = NULL;
LPVOID pvSubject = NULL;
BOOL fFreshest = FALSE;
if ( pszFlushTimeValidOid == TIME_VALID_OID_GET_CRL_FROM_CERT )
{
fCrlFromCert = TRUE;
pszUrlOidCrlFromCert = URL_OID_CERTIFICATE_CRL_DIST_POINT;
pvSubject = pvPara;
}
else if ( pszFlushTimeValidOid == TIME_VALID_OID_GET_FRESHEST_CRL_FROM_CERT )
{
fCrlFromCert = TRUE;
pszUrlOidCrlFromCert = URL_OID_CERTIFICATE_FRESHEST_CRL;
pvSubject = pvPara;
fFreshest = TRUE;
}
else if ( pszFlushTimeValidOid == TIME_VALID_OID_GET_FRESHEST_CRL_FROM_CRL )
{
fCrlFromCert = TRUE;
pszUrlOidCrlFromCert = URL_OID_CRL_FRESHEST_CRL;
pvSubject = (LPVOID) ((PCCERT_CRL_CONTEXT_PAIR)pvPara)->pCertContext;
fFreshest = TRUE;
}
if (fCrlFromCert)
{
if ( CrlGetOriginIdentifierFromSubjectCert(
(PCCERT_CONTEXT)pvSubject,
pIssuer,
fFreshest,
OriginIdentifier
) == FALSE )
{
return( FALSE );
}
assert( pszFlushContextOid == CONTEXT_OID_CRL );
}
else
{
if ( ObjectContextGetOriginIdentifier(
pszFlushContextOid,
pvPara,
pIssuer,
0,
OriginIdentifier
) == FALSE )
{
return( FALSE );
}
}
EnterCriticalSection( &m_Lock );
pCacheEntry = m_Cache.FindCacheEntry(
OriginIdentifier,
pszFlushContextOid,
pvSubject
);
if ( pCacheEntry != NULL )
{
// Remove the entry but suppress the freeing of it since we are going
// to use the data structure later
m_Cache.RemoveCacheEntry( pCacheEntry, TRUE );
}
LeaveCriticalSection( &m_Lock );
if ( pCacheEntry != NULL )
{
if ( pCacheEntry->pUrlArrayThis != NULL )
{
for ( cCount = 0;
cCount < pCacheEntry->pUrlArrayThis->cUrl;
cCount++ )
{
if ( ( SchemeDeleteUrlCacheEntry(
pCacheEntry->pUrlArrayThis->rgwszUrl[cCount]
) == FALSE ) &&
( GetLastError() != ERROR_FILE_NOT_FOUND ) )
{
dwError = GetLastError();
}
}
}
if ( pCacheEntry->pUrlArrayNext != NULL )
{
for ( cCount = 0;
cCount < pCacheEntry->pUrlArrayNext->cUrl;
cCount++ )
{
if ( ( SchemeDeleteUrlCacheEntry(
pCacheEntry->pUrlArrayNext->rgwszUrl[cCount]
) == FALSE ) &&
( GetLastError() != ERROR_FILE_NOT_FOUND ) )
{
dwError = GetLastError();
}
}
}
//
// Can place optimization here where if the hashes of the
// cache object and the passed in object are the same,
// we don't need to do any more work
//
ObjectContextFreeTVOCacheEntry( pCacheEntry );
}
if ( fCrlFromCert )
{
fResult = CertificateGetCrlDistPointUrl(
pszUrlOidCrlFromCert,
pvPara,
NULL, // pwszUrlHint
&pUrlArray,
&cbUrlArray,
NULL, // pPreferredUrlIndex
NULL // pfHintInArray
);
}
else if ( pszFlushTimeValidOid == TIME_VALID_OID_GET_CTL )
{
fResult = ObjectContextGetNextUpdateUrl(
pszFlushContextOid,
pvPara,
pIssuer,
NULL,
&pUrlArray,
&cbUrlArray,
NULL,
NULL
);
}
if ( ( fResult == TRUE ) && ( pUrlArray != NULL ) )
{
for ( cCount = 0; cCount < pUrlArray->cUrl; cCount++ )
{
if ( ( SchemeDeleteUrlCacheEntry(
pUrlArray->rgwszUrl[cCount]
) == FALSE ) &&
( GetLastError() != ERROR_FILE_NOT_FOUND ) )
{
dwError = GetLastError();
}
}
}
if ( pUrlArray )
{
delete [] (BYTE *) pUrlArray;
}
if ( ( fResult == TRUE ) && ( dwError != 0 ) )
{
SetLastError( dwError );
fResult = FALSE;
}
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Function: IsValidCreateOrExpireTime
//
// Synopsis: for fCheckFreshnessTime, checks if the
// specified time is before or the same as the create time.
// Otherwise, checks if the specified time is before or the
// same as the expire time. A zero expire time matches any time.
//
//----------------------------------------------------------------------------
BOOL WINAPI
IsValidCreateOrExpireTime (
IN BOOL fCheckFreshnessTime,
IN LPFILETIME pftValidFor,
IN LPFILETIME pftCreateTime,
IN LPFILETIME pftExpireTime
)
{
if (fCheckFreshnessTime) {
if (CompareFileTime(pftValidFor, pftCreateTime) <= 0)
return TRUE;
else
return FALSE;
} else {
if (CompareFileTime(pftValidFor, pftExpireTime) <= 0 ||
I_CryptIsZeroFileTime(pftExpireTime))
return TRUE;
else
return FALSE;
}
}
//+---------------------------------------------------------------------------
//
// Function: ObjectContextCreateTVOCacheEntry
//
// Synopsis: create a TVO cache entry
//
//----------------------------------------------------------------------------
BOOL WINAPI
ObjectContextCreateTVOCacheEntry (
IN HLRUCACHE hCache,
IN LPCSTR pszContextOid,
IN LPVOID pvContext,
IN CRYPT_ORIGIN_IDENTIFIER OriginIdentifier,
IN DWORD cbUrlArrayThis,
IN PCRYPT_URL_ARRAY pUrlArrayThis,
IN DWORD UrlIndexThis,
IN PCCERT_CONTEXT pIssuer,
OUT PTVO_CACHE_ENTRY* ppEntry
)
{
BOOL fResult = TRUE;
PTVO_CACHE_ENTRY pEntry;
CRYPT_DATA_BLOB DataBlob;
pEntry = new TVO_CACHE_ENTRY;
if ( pEntry == NULL )
{
SetLastError( (DWORD) E_OUTOFMEMORY );
return( FALSE );
}
memset( pEntry, 0, sizeof( TVO_CACHE_ENTRY ) );
// NOTENOTE: This presumes a predefined context oid constant
pEntry->pszContextOid = pszContextOid;
pEntry->pvContext = ObjectContextDuplicate( pszContextOid, pvContext );
memcpy(pEntry->OriginIdentifier, OriginIdentifier,
sizeof(pEntry->OriginIdentifier));
DataBlob.cbData = MD5DIGESTLEN;
DataBlob.pbData = pEntry->OriginIdentifier;
fResult = I_CryptCreateLruEntry(
hCache,
&DataBlob,
pEntry,
&pEntry->hLruEntry
);
if ( fResult == TRUE )
{
ObjectContextGetNextUpdateUrl(
pszContextOid,
pvContext,
pIssuer,
pUrlArrayThis->rgwszUrl[UrlIndexThis],
&pEntry->pUrlArrayNext,
&pEntry->cbUrlArrayNext,
&pEntry->UrlIndexNext,
NULL
);
fResult = ObjectContextGetCreateAndExpireTimes(
pszContextOid,
pvContext,
&pEntry->CreateTime,
&pEntry->ExpireTime
);
}
if ( fResult == TRUE )
{
pEntry->cbUrlArrayThis = cbUrlArrayThis;
pEntry->pUrlArrayThis = pUrlArrayThis;
pEntry->UrlIndexThis = UrlIndexThis;
*ppEntry = pEntry;
}
else
{
ObjectContextFreeTVOCacheEntry( pEntry );
}
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Function: ObjectContextFreeTVOCacheEntry
//
// Synopsis: free TVO cache entry
//
//----------------------------------------------------------------------------
VOID WINAPI
ObjectContextFreeTVOCacheEntry (
IN PTVO_CACHE_ENTRY pEntry
)
{
if ( pEntry->hLruEntry != NULL )
{
I_CryptReleaseLruEntry( pEntry->hLruEntry );
}
delete [] (BYTE *) pEntry->pUrlArrayThis;
delete [] (BYTE *) pEntry->pUrlArrayNext;
if ( pEntry->pvContext != NULL )
{
ObjectContextFree( pEntry->pszContextOid, pEntry->pvContext );
}
delete pEntry;
}
//+---------------------------------------------------------------------------
//
// Function: CertificateGetCrlDistPointUrl
//
// Synopsis: get crl dist point URL from certificate
//
//----------------------------------------------------------------------------
BOOL WINAPI
CertificateGetCrlDistPointUrl (
IN LPCSTR pszUrlOid,
IN LPVOID pvPara,
IN LPWSTR pwszUrlHint,
OUT PCRYPT_URL_ARRAY* ppUrlArray,
OUT DWORD* pcbUrlArray,
OUT DWORD* pPreferredUrlIndex,
OUT BOOL* pfHintInArray
)
{
BOOL fResult;
DWORD cbUrlArray;
PCRYPT_URL_ARRAY pUrlArray = NULL;
DWORD PreferredUrlIndex;
fResult = CryptGetObjectUrl(
pszUrlOid,
pvPara,
0,
NULL,
&cbUrlArray,
NULL,
NULL,
NULL
);
if ( fResult == TRUE )
{
pUrlArray = (PCRYPT_URL_ARRAY)new BYTE [ cbUrlArray ];
if ( pUrlArray != NULL )
{
fResult = CryptGetObjectUrl(
pszUrlOid,
pvPara,
0,
pUrlArray,
&cbUrlArray,
NULL,
NULL,
NULL
);
}
else
{
SetLastError( (DWORD) E_OUTOFMEMORY );
fResult = FALSE;
}
}
if ( fResult == TRUE )
{
BOOL fHintInArray = FALSE;
GetUrlArrayIndex(
pUrlArray,
pwszUrlHint,
0,
&PreferredUrlIndex,
&fHintInArray
);
*ppUrlArray = pUrlArray;
*pcbUrlArray = cbUrlArray;
if ( pfHintInArray != NULL )
{
*pfHintInArray = fHintInArray;
}
if ( pPreferredUrlIndex != NULL )
{
*pPreferredUrlIndex = PreferredUrlIndex;
}
}
else
{
if ( pUrlArray )
{
delete [] (BYTE *) pUrlArray;
}
}
return( fResult );
}
BOOL WINAPI
RetrieveObjectByUrlValidForSubject(
IN LPWSTR pwszUrl,
IN LPCSTR pszContextOid,
IN BOOL fCheckFreshnessTime,
IN LPFILETIME pftValidFor,
IN DWORD dwRetrievalFlags,
IN DWORD dwTimeout,
IN PCRYPT_CREDENTIALS pCredentials,
IN PCCERT_CONTEXT pSigner,
IN LPVOID pvSubject,
IN CRYPT_ORIGIN_IDENTIFIER OriginIdentifier,
OUT LPVOID* ppvObject,
IN OPTIONAL LPVOID pvReserved
)
{
BOOL fResult;
HCERTSTORE hUrlStore = NULL;
LPVOID pvObject;
fResult = CryptRetrieveObjectByUrlW(
pwszUrl,
pszContextOid,
(dwRetrievalFlags |
CRYPT_RETRIEVE_MULTIPLE_OBJECTS |
CRYPT_LDAP_SCOPE_BASE_ONLY_RETRIEVAL) &
~CRYPT_VERIFY_CONTEXT_SIGNATURE,
dwTimeout,
(LPVOID *) &hUrlStore,
NULL, // hAsyncRetrieve
NULL, // pCredentials
NULL, // pSigner
NULL // pvReserved
);
if (!fResult)
goto CommonReturn;
pvObject = NULL;
while (pvObject = ObjectContextEnumObjectsInStore (
hUrlStore,
pszContextOid,
pvObject
))
{
CRYPT_ORIGIN_IDENTIFIER ObjectOriginIdentifier;
if (!ObjectContextGetOriginIdentifier(
pszContextOid,
pvObject,
pSigner,
0,
ObjectOriginIdentifier
))
continue;
if (0 != memcmp(OriginIdentifier, ObjectOriginIdentifier,
sizeof(ObjectOriginIdentifier)))
continue;
if (dwRetrievalFlags & CRYPT_VERIFY_CONTEXT_SIGNATURE) {
if (!ObjectContextVerifySignature (
pszContextOid,
pvObject,
pSigner
))
continue;
}
if (!ObjectContextIsValidForSubject (
pszContextOid,
pvObject,
pvSubject,
pvReserved
))
continue;
if (NULL != pftValidFor) {
FILETIME CreateTime;
FILETIME ExpireTime;
if (!ObjectContextGetCreateAndExpireTimes(
pszContextOid,
pvObject,
&CreateTime,
&ExpireTime
))
continue;
if (!IsValidCreateOrExpireTime (
fCheckFreshnessTime,
pftValidFor,
&CreateTime,
&ExpireTime ) )
continue;
}
*ppvObject = pvObject;
fResult = TRUE;
goto CommonReturn;
}
// Make sure the error isn't CRYPT_E_NOT_FOUND. msrevoke will
// return CRYPT_E_NO_REVOCATION_CHECK instead of
// CRYPT_E_REVOCATION_OFFLINE for CRYPT_E_NOT_FOUND.
SetLastError(ERROR_FILE_NOT_FOUND);
fResult = FALSE;
CommonReturn:
if (hUrlStore)
CertCloseStore(hUrlStore, 0);
return fResult;
}
//+---------------------------------------------------------------------------
//
// Function: RetrieveTimeValidObjectByUrl
//
// Synopsis: retrieve a time valid object given an URL
//
//----------------------------------------------------------------------------
BOOL WINAPI
RetrieveTimeValidObjectByUrl (
IN LPWSTR pwszUrl,
IN LPCSTR pszContextOid,
IN LPFILETIME pftValidFor,
IN DWORD dwFlags,
IN DWORD dwTimeout,
IN PCRYPT_CREDENTIALS pCredentials,
IN PCCERT_CONTEXT pSigner,
IN LPVOID pvSubject,
IN CRYPT_ORIGIN_IDENTIFIER OriginIdentifier,
OUT LPVOID* ppvObject,
IN OPTIONAL LPVOID pvReserved
)
{
BOOL fResult = FALSE;
LPVOID pvContext = NULL;
DWORD dwVerifyFlags = 0;
DWORD dwCacheStoreFlags = CRYPT_DONT_CACHE_RESULT;
if ( dwFlags & CRYPT_DONT_CHECK_TIME_VALIDITY )
{
pftValidFor = NULL;
}
if ( !( dwFlags & CRYPT_DONT_VERIFY_SIGNATURE ) )
{
dwVerifyFlags |= CRYPT_VERIFY_CONTEXT_SIGNATURE;
dwCacheStoreFlags &= ~CRYPT_DONT_CACHE_RESULT;
}
if ( !( dwFlags & CRYPT_WIRE_ONLY_RETRIEVAL ) )
{
fResult = RetrieveObjectByUrlValidForSubject(
pwszUrl,
pszContextOid,
0 != (dwFlags & CRYPT_CHECK_FRESHNESS_TIME_VALIDITY),
pftValidFor,
CRYPT_CACHE_ONLY_RETRIEVAL |
dwVerifyFlags,
0, // dwTimeout
NULL, // pCredentials
pSigner,
pvSubject,
OriginIdentifier,
&pvContext,
pvReserved
);
}
if ( fResult == FALSE )
{
if ( !( dwFlags & CRYPT_CACHE_ONLY_RETRIEVAL ) )
{
DWORD dwRetrievalFlags = CRYPT_WIRE_ONLY_RETRIEVAL |
dwCacheStoreFlags |
dwVerifyFlags;
LONG lStatus;
// +1 - Online
// 0 - Offline, current time >= earliest online time, hit the wire
// -1 - Offline, current time < earliest onlime time
lStatus = GetOriginUrlStatusW(
OriginIdentifier,
pwszUrl,
pszContextOid,
dwRetrievalFlags
);
if (lStatus >= 0)
{
fResult = RetrieveObjectByUrlValidForSubject(
pwszUrl,
pszContextOid,
0 != (dwFlags & CRYPT_CHECK_FRESHNESS_TIME_VALIDITY),
pftValidFor,
dwRetrievalFlags,
dwTimeout,
pCredentials,
pSigner,
pvSubject,
OriginIdentifier,
&pvContext,
pvReserved
);
if (!fResult)
{
DWORD dwErr = GetLastError();
SetOfflineOriginUrlW(
OriginIdentifier,
pwszUrl,
pszContextOid,
dwRetrievalFlags
);
SetLastError( dwErr );
}
else if (lStatus == 0)
{
// Remove from offline list
SetOnlineOriginUrlW(
OriginIdentifier,
pwszUrl,
pszContextOid,
dwRetrievalFlags
);
}
}
}
}
*ppvObject = pvContext;
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Function: CreateProcessTVOAgent
//
// Synopsis: create process TVO agent
//
//----------------------------------------------------------------------------
BOOL WINAPI
CreateProcessTVOAgent (
OUT CTVOAgent** ppAgent
)
{
BOOL fResult = FALSE;
HKEY hKey = NULL;
DWORD dwType = REG_DWORD;
DWORD dwSize = sizeof( DWORD );
DWORD cCacheBuckets;
DWORD MaxCacheEntries;
CTVOAgent* pAgent;
if ( RegOpenKeyA(
HKEY_LOCAL_MACHINE,
TVO_KEY_NAME,
&hKey
) == ERROR_SUCCESS )
{
if ( RegQueryValueExA(
hKey,
TVO_CACHE_BUCKETS_VALUE_NAME,
NULL,
&dwType,
(LPBYTE)&cCacheBuckets,
&dwSize
) != ERROR_SUCCESS )
{
cCacheBuckets = TVO_DEFAULT_CACHE_BUCKETS;
}
if ( RegQueryValueExA(
hKey,
TVO_MAX_CACHE_ENTRIES_VALUE_NAME,
NULL,
&dwType,
(LPBYTE)&MaxCacheEntries,
&dwSize
) != ERROR_SUCCESS )
{
MaxCacheEntries = TVO_DEFAULT_MAX_CACHE_ENTRIES;
}
RegCloseKey(hKey);
}
else
{
cCacheBuckets = TVO_DEFAULT_CACHE_BUCKETS;
MaxCacheEntries = TVO_DEFAULT_MAX_CACHE_ENTRIES;
}
pAgent = new CTVOAgent( cCacheBuckets, MaxCacheEntries, fResult );
if ( pAgent == NULL )
{
SetLastError( (DWORD) E_OUTOFMEMORY );
return( FALSE );
}
if ( fResult == TRUE )
{
*ppAgent = pAgent;
}
else
{
delete pAgent;
}
return( fResult );
}