cryptnet: Set cache expiration time of objects that have an expiration time to the object's expiration time, rather than relying on the HTTP Expires header.
This commit is contained in:
parent
da605a935b
commit
6b8fb4ed9b
|
@ -400,7 +400,6 @@ static BOOL CRYPT_GetObjectFromFile(HANDLE hFile, PCRYPT_BLOB_ARRAY pObject)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: should make wininet cache all downloads instead */
|
|
||||||
static BOOL CRYPT_GetObjectFromCache(LPCWSTR pszURL, PCRYPT_BLOB_ARRAY pObject,
|
static BOOL CRYPT_GetObjectFromCache(LPCWSTR pszURL, PCRYPT_BLOB_ARRAY pObject,
|
||||||
PCRYPT_RETRIEVE_AUX_INFO pAuxInfo)
|
PCRYPT_RETRIEVE_AUX_INFO pAuxInfo)
|
||||||
{
|
{
|
||||||
|
@ -605,30 +604,73 @@ static BOOL CRYPT_DownloadObject(DWORD dwRetrievalFlags, HINTERNET hHttp,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Finds the object specified by pszURL in the cache. If it's not found,
|
||||||
|
* creates a new cache entry for the object and writes the object to it.
|
||||||
|
* Sets the expiration time of the cache entry to expires.
|
||||||
|
*/
|
||||||
static void CRYPT_CacheURL(LPCWSTR pszURL, PCRYPT_BLOB_ARRAY pObject,
|
static void CRYPT_CacheURL(LPCWSTR pszURL, PCRYPT_BLOB_ARRAY pObject,
|
||||||
DWORD dwRetrievalFlags, FILETIME expires)
|
DWORD dwRetrievalFlags, FILETIME expires)
|
||||||
{
|
{
|
||||||
WCHAR cacheFileName[MAX_PATH];
|
WCHAR cacheFileName[MAX_PATH];
|
||||||
|
DWORD size = 0;
|
||||||
|
BOOL ret, create = FALSE;
|
||||||
|
|
||||||
/* FIXME: let wininet directly cache instead */
|
GetUrlCacheEntryInfoW(pszURL, NULL, &size);
|
||||||
if (CreateUrlCacheEntryW(pszURL, pObject->rgBlob[0].cbData, NULL,
|
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||||||
cacheFileName, 0))
|
|
||||||
{
|
{
|
||||||
HANDLE hCacheFile = CreateFileW(cacheFileName, GENERIC_WRITE, 0, NULL,
|
INTERNET_CACHE_ENTRY_INFOW *info = CryptMemAlloc(size);
|
||||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
|
|
||||||
if (hCacheFile != INVALID_HANDLE_VALUE)
|
if (info)
|
||||||
{
|
{
|
||||||
DWORD bytesWritten, entryType;
|
FILETIME ft;
|
||||||
FILETIME ft = { 0 };
|
|
||||||
|
|
||||||
|
ret = GetUrlCacheEntryInfoW(pszURL, info, &size);
|
||||||
|
if (ret)
|
||||||
|
lstrcpyW(cacheFileName, info->lpszLocalFileName);
|
||||||
|
/* Check if the existing cache entry is up to date. If it isn't,
|
||||||
|
* overwite it with the new value.
|
||||||
|
*/
|
||||||
|
GetSystemTimeAsFileTime(&ft);
|
||||||
|
if (CompareFileTime(&info->ExpireTime, &ft) < 0)
|
||||||
|
create = TRUE;
|
||||||
|
CryptMemFree(info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = CreateUrlCacheEntryW(pszURL, pObject->rgBlob[0].cbData, NULL,
|
||||||
|
cacheFileName, 0);
|
||||||
|
create = TRUE;
|
||||||
|
}
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
DWORD entryType;
|
||||||
|
FILETIME ft = { 0 };
|
||||||
|
|
||||||
|
if (create)
|
||||||
|
{
|
||||||
|
HANDLE hCacheFile = CreateFileW(cacheFileName, GENERIC_WRITE, 0,
|
||||||
|
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|
||||||
|
if (hCacheFile != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
DWORD bytesWritten;
|
||||||
|
|
||||||
|
WriteFile(hCacheFile, pObject->rgBlob[0].pbData,
|
||||||
|
pObject->rgBlob[0].cbData, &bytesWritten, NULL);
|
||||||
|
CloseHandle(hCacheFile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
if (!(dwRetrievalFlags & CRYPT_STICKY_CACHE_RETRIEVAL))
|
if (!(dwRetrievalFlags & CRYPT_STICKY_CACHE_RETRIEVAL))
|
||||||
entryType = NORMAL_CACHE_ENTRY;
|
entryType = NORMAL_CACHE_ENTRY;
|
||||||
else
|
else
|
||||||
entryType = STICKY_CACHE_ENTRY;
|
entryType = STICKY_CACHE_ENTRY;
|
||||||
WriteFile(hCacheFile, pObject->rgBlob[0].pbData,
|
|
||||||
pObject->rgBlob[0].cbData, &bytesWritten, NULL);
|
|
||||||
CloseHandle(hCacheFile);
|
|
||||||
CommitUrlCacheEntryW(pszURL, cacheFileName, expires, ft, entryType,
|
CommitUrlCacheEntryW(pszURL, cacheFileName, expires, ft, entryType,
|
||||||
NULL, 0, NULL, NULL);
|
NULL, 0, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
@ -1280,6 +1322,63 @@ static BOOL CRYPT_GetCreateFunction(LPCSTR pszObjectOid,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef BOOL (*get_object_expiration_func)(void *pvContext,
|
||||||
|
FILETIME *expiration);
|
||||||
|
|
||||||
|
static BOOL CRYPT_GetExpirationFromCert(void *pvObject, FILETIME *expiration)
|
||||||
|
{
|
||||||
|
PCCERT_CONTEXT cert = (PCCERT_CONTEXT)pvObject;
|
||||||
|
|
||||||
|
*expiration = cert->pCertInfo->NotAfter;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL CRYPT_GetExpirationFromCRL(void *pvObject, FILETIME *expiration)
|
||||||
|
{
|
||||||
|
PCCRL_CONTEXT cert = (PCCRL_CONTEXT)pvObject;
|
||||||
|
|
||||||
|
*expiration = cert->pCrlInfo->NextUpdate;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL CRYPT_GetExpirationFromCTL(void *pvObject, FILETIME *expiration)
|
||||||
|
{
|
||||||
|
PCCTL_CONTEXT cert = (PCCTL_CONTEXT)pvObject;
|
||||||
|
|
||||||
|
*expiration = cert->pCtlInfo->NextUpdate;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL CRYPT_GetExpirationFunction(LPCSTR pszObjectOid,
|
||||||
|
get_object_expiration_func *getExpiration)
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
if (!HIWORD(pszObjectOid))
|
||||||
|
{
|
||||||
|
switch (LOWORD(pszObjectOid))
|
||||||
|
{
|
||||||
|
case LOWORD(CONTEXT_OID_CERTIFICATE):
|
||||||
|
*getExpiration = CRYPT_GetExpirationFromCert;
|
||||||
|
ret = TRUE;
|
||||||
|
break;
|
||||||
|
case LOWORD(CONTEXT_OID_CRL):
|
||||||
|
*getExpiration = CRYPT_GetExpirationFromCRL;
|
||||||
|
ret = TRUE;
|
||||||
|
break;
|
||||||
|
case LOWORD(CONTEXT_OID_CTL):
|
||||||
|
*getExpiration = CRYPT_GetExpirationFromCTL;
|
||||||
|
ret = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = FALSE;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* CryptRetrieveObjectByUrlW (CRYPTNET.@)
|
* CryptRetrieveObjectByUrlW (CRYPTNET.@)
|
||||||
*/
|
*/
|
||||||
|
@ -1316,7 +1415,17 @@ BOOL WINAPI CryptRetrieveObjectByUrlW(LPCWSTR pszURL, LPCSTR pszObjectOid,
|
||||||
pAuxInfo);
|
pAuxInfo);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
|
get_object_expiration_func getExpiration;
|
||||||
|
|
||||||
ret = create(pszObjectOid, dwRetrievalFlags, &object, ppvObject);
|
ret = create(pszObjectOid, dwRetrievalFlags, &object, ppvObject);
|
||||||
|
if (ret && !(dwRetrievalFlags & CRYPT_DONT_CACHE_RESULT) &&
|
||||||
|
CRYPT_GetExpirationFunction(pszObjectOid, &getExpiration))
|
||||||
|
{
|
||||||
|
FILETIME expires;
|
||||||
|
|
||||||
|
if (getExpiration(*ppvObject, &expires))
|
||||||
|
CRYPT_CacheURL(pszURL, &object, dwRetrievalFlags, expires);
|
||||||
|
}
|
||||||
freeObject(pszObjectOid, &object, freeContext);
|
freeObject(pszObjectOid, &object, freeContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue