windows-nt/Source/XPSP1/NT/ds/security/cryptoapi/pkitrust/wintrust/winvtrst.cpp

958 lines
29 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: winvtrst.cpp
//
// Contents: Microsoft Internet Security Trust Provider
//
// Functions: WinVerifyTrustEx
// WinVerifyTrust
// WTHelperGetFileHash
//
// *** local functions ***
// _VerifyTrust
// _FillProviderData
// _CleanupProviderData
// _CleanupProviderNonStateData
// _WVTSipFreeSubjectInfo
// _WVTSipFreeSubjectInfoKeepState
// _WVTSetupProviderData
//
// History: 31-May-1997 pberkman created
//
//--------------------------------------------------------------------------
#include "global.hxx"
#include "wvtver1.h"
#include "softpub.h"
#include "imagehlp.h"
LONG _VerifyTrust(
IN HWND hWnd,
IN GUID *pgActionID,
IN OUT PWINTRUST_DATA pWinTrustData,
OUT OPTIONAL BYTE *pbSubjectHash,
IN OPTIONAL OUT DWORD *pcbSubjectHash,
OUT OPTIONAL ALG_ID *pHashAlgid
);
BOOL _FillProviderData(CRYPT_PROVIDER_DATA *pProvData, HWND hWnd, WINTRUST_DATA *pWinTrustData);
void _CleanupProviderData(CRYPT_PROVIDER_DATA *pProvData);
void _CleanupProviderNonStateData(CRYPT_PROVIDER_DATA *ProvData);
BOOL _WVTSipFreeSubjectInfo(SIP_SUBJECTINFO *pSubj);
BOOL _WVTSetupProviderData(CRYPT_PROVIDER_DATA *psProvData,
CRYPT_PROVIDER_DATA *psStateProvData);
BOOL _WVTSipFreeSubjectInfoKeepState(SIP_SUBJECTINFO *pSubj);
VOID FreeWintrustStateData (WINTRUST_DATA* pWintrustData);
extern CCatalogCache g_CatalogCache;
//////////////////////////////////////////////////////////////////////////////////////
//
// WinVerifyTrustEx
//
//
extern "C" HRESULT WINAPI WinVerifyTrustEx(HWND hWnd, GUID *pgActionID, WINTRUST_DATA *pWinTrustData)
{
return((HRESULT)WinVerifyTrust(hWnd, pgActionID, pWinTrustData));
}
#define PE_EXE_HEADER_TAG "MZ"
#define PE_EXE_HEADER_TAG_LEN 2
BOOL _IsUnsignedPEFile(
PWINTRUST_FILE_INFO pFileInfo
)
{
BOOL fIsUnsignedPEFile = FALSE;
HANDLE hFile = NULL;
BOOL fCloseFile = FALSE;
BYTE rgbHeader[PE_EXE_HEADER_TAG_LEN];
DWORD dwBytesRead;
DWORD dwCertCnt;
hFile = pFileInfo->hFile;
if (NULL == hFile || INVALID_HANDLE_VALUE == hFile) {
hFile = CreateFileU(
pFileInfo->pcwszFilePath,
GENERIC_READ,
FILE_SHARE_READ,
NULL, // lpsa
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL // hTemplateFile
);
if (INVALID_HANDLE_VALUE == hFile)
goto CreateFileError;
fCloseFile = TRUE;
}
if (0 != SetFilePointer(
hFile,
0, // lDistanceToMove
NULL, // lpDistanceToMoveHigh
FILE_BEGIN
))
goto SetFilePointerError;
dwBytesRead = 0;
if (!ReadFile(
hFile,
rgbHeader,
PE_EXE_HEADER_TAG_LEN,
&dwBytesRead,
NULL // lpOverlapped
) || PE_EXE_HEADER_TAG_LEN != dwBytesRead)
goto ReadFileError;
if (0 != memcmp(rgbHeader, PE_EXE_HEADER_TAG, PE_EXE_HEADER_TAG_LEN))
goto NotPEFile;
// Now see if the PE file is signed
dwCertCnt = 0;
if (!ImageEnumerateCertificates(
hFile,
CERT_SECTION_TYPE_ANY,
&dwCertCnt,
NULL, // Indices
0 // IndexCount
) || 0 == dwCertCnt)
fIsUnsignedPEFile = TRUE;
CommonReturn:
if (fCloseFile)
CloseHandle(hFile);
return fIsUnsignedPEFile;
ErrorReturn:
goto CommonReturn;
TRACE_ERROR(CreateFileError)
TRACE_ERROR(SetFilePointerError)
TRACE_ERROR(ReadFileError)
TRACE_ERROR(NotPEFile)
}
extern "C" LONG WINAPI WinVerifyTrust(HWND hWnd, GUID *pgActionID, LPVOID pOld)
{
PWINTRUST_DATA pWinTrustData = (PWINTRUST_DATA) pOld;
// For SAFER, see if this is a unsigned PE file
if (_ISINSTRUCT(WINTRUST_DATA, pWinTrustData->cbStruct, dwProvFlags) &&
(pWinTrustData->dwProvFlags & WTD_SAFER_FLAG) &&
(WTD_STATEACTION_IGNORE == pWinTrustData->dwStateAction) &&
(WTD_CHOICE_FILE == pWinTrustData->dwUnionChoice)) {
if (_IsUnsignedPEFile(pWinTrustData->pFile)) {
SetLastError((DWORD) TRUST_E_NOSIGNATURE);
return (LONG) TRUST_E_NOSIGNATURE;
}
}
return _VerifyTrust(
hWnd,
pgActionID,
pWinTrustData,
NULL, // pbSubjectHash
NULL, // pcbSubjectHash
NULL // pHashAlgid
);
}
// Returns S_OK and the hash if the file was signed and contains a valid
// hash
extern "C" LONG WINAPI WTHelperGetFileHash(
IN LPCWSTR pwszFilename,
IN DWORD dwFlags,
IN OUT OPTIONAL PVOID *pvReserved,
OUT OPTIONAL BYTE *pbFileHash,
IN OUT OPTIONAL DWORD *pcbFileHash,
OUT OPTIONAL ALG_ID *pHashAlgid
)
{
GUID wvtFileActionID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
WINTRUST_FILE_INFO wvtFileInfo;
WINTRUST_DATA wvtData;
//
// Initialize the _VerifyTrust input data structure
//
memset(&wvtData, 0, sizeof(wvtData)); // default all fields to 0
wvtData.cbStruct = sizeof(wvtData);
// wvtData.pPolicyCallbackData = // use default code signing EKU
// wvtData.pSIPClientData = // no data to pass to SIP
wvtData.dwUIChoice = WTD_UI_NONE;
// wvtData.fdwRevocationChecks = // do revocation checking if
// enabled by admin policy or
// IE advanced user options
wvtData.dwUnionChoice = WTD_CHOICE_FILE;
wvtData.pFile = &wvtFileInfo;
// wvtData.dwStateAction = // default verification
// wvtData.hWVTStateData = // not applicable for default
// wvtData.pwszURLReference = // not used
// Only want to get the hash
wvtData.dwProvFlags = WTD_HASH_ONLY_FLAG;
//
// Initialize the WinVerifyTrust file info data structure
//
memset(&wvtFileInfo, 0, sizeof(wvtFileInfo)); // default all fields to 0
wvtFileInfo.cbStruct = sizeof(wvtFileInfo);
wvtFileInfo.pcwszFilePath = pwszFilename;
// wvtFileInfo.hFile = // allow WVT to open
// wvtFileInfo.pgKnownSubject // allow WVT to determine
//
// Call _VerifyTrust
//
return _VerifyTrust(
NULL, // hWnd
&wvtFileActionID,
&wvtData,
pbFileHash,
pcbFileHash,
pHashAlgid
);
}
LONG _VerifyTrust(
IN HWND hWnd,
IN GUID *pgActionID,
IN OUT PWINTRUST_DATA pWinTrustData,
OUT OPTIONAL BYTE *pbSubjectHash,
IN OPTIONAL OUT DWORD *pcbSubjectHash,
OUT OPTIONAL ALG_ID *pHashAlgid
)
{
CRYPT_PROVIDER_DATA sProvData;
CRYPT_PROVIDER_DATA *pStateProvData;
HRESULT hr;
BOOL fVersion1;
BOOL fCacheableCall;
PCATALOG_CACHED_STATE pCachedState = NULL;
BOOL fVersion1WVTCalled = FALSE;
DWORD cbInSubjectHash;
DWORD dwLastError = 0;
hr = TRUST_E_PROVIDER_UNKNOWN;
pStateProvData = NULL;
if (pcbSubjectHash)
{
cbInSubjectHash = *pcbSubjectHash;
*pcbSubjectHash = 0;
}
else
{
cbInSubjectHash = 0;
}
if (pHashAlgid)
*pHashAlgid = 0;
fCacheableCall = g_CatalogCache.IsCacheableWintrustCall( pWinTrustData );
if ( fCacheableCall == TRUE )
{
g_CatalogCache.LockCache();
if ( pWinTrustData->dwStateAction == WTD_STATEACTION_AUTO_CACHE_FLUSH )
{
g_CatalogCache.FlushCache();
g_CatalogCache.UnlockCache();
return( ERROR_SUCCESS );
}
pCachedState = g_CatalogCache.FindCachedState( pWinTrustData );
g_CatalogCache.AdjustWintrustDataToCachedState(
pWinTrustData,
pCachedState,
FALSE
);
}
if (WintrustIsVersion1ActionID(pgActionID))
{
fVersion1 = TRUE;
}
else
{
fVersion1 = FALSE;
if (_ISINSTRUCT(WINTRUST_DATA, pWinTrustData->cbStruct, hWVTStateData))
{
if ((pWinTrustData->dwStateAction == WTD_STATEACTION_VERIFY) ||
(pWinTrustData->dwStateAction == WTD_STATEACTION_CLOSE))
{
pStateProvData = WTHelperProvDataFromStateData(pWinTrustData->hWVTStateData);
if (pWinTrustData->dwStateAction == WTD_STATEACTION_CLOSE)
{
if (pWinTrustData->hWVTStateData)
{
_CleanupProviderData(pStateProvData);
DELETE_OBJECT(pWinTrustData->hWVTStateData);
}
assert( fCacheableCall == FALSE );
return(ERROR_SUCCESS);
}
}
}
}
if (_WVTSetupProviderData(&sProvData, pStateProvData))
{
sProvData.pgActionID = pgActionID;
if (!(pStateProvData))
{
if (!(WintrustLoadFunctionPointers(pgActionID, sProvData.psPfns)))
{
//
// it may be that we are looking for a version 1 trust provider.
//
hr = Version1_WinVerifyTrust(hWnd, pgActionID, pWinTrustData);
fVersion1WVTCalled = TRUE;
}
if ( fVersion1WVTCalled == FALSE )
{
if (fVersion1)
{
//
// backwards compatibility with IE3.x and previous
//
WINTRUST_DATA sWinTrustData;
WINTRUST_FILE_INFO sWinTrustFileInfo;
pWinTrustData = ConvertDataFromVersion1(hWnd, pgActionID, &sWinTrustData, &sWinTrustFileInfo,
pWinTrustData);
}
if (!_FillProviderData(&sProvData, hWnd, pWinTrustData))
{
hr = ERROR_NOT_ENOUGH_MEMORY;
goto ErrorCase;
}
}
}
// On July 27, 2000 removed support for the IE4 way of chain building.
sProvData.dwProvFlags |= CPD_USE_NT5_CHAIN_FLAG;
if ( fVersion1WVTCalled == FALSE )
{
if (sProvData.psPfns->pfnInitialize)
{
(*sProvData.psPfns->pfnInitialize)(&sProvData);
}
if (sProvData.psPfns->pfnObjectTrust)
{
(*sProvData.psPfns->pfnObjectTrust)(&sProvData);
}
if (sProvData.psPfns->pfnSignatureTrust)
{
(*sProvData.psPfns->pfnSignatureTrust)(&sProvData);
}
if (sProvData.psPfns->pfnCertificateTrust)
{
(*sProvData.psPfns->pfnCertificateTrust)(&sProvData);
}
if (sProvData.psPfns->pfnFinalPolicy)
{
hr = (*sProvData.psPfns->pfnFinalPolicy)(&sProvData);
}
if (sProvData.psPfns->pfnTestFinalPolicy)
{
(*sProvData.psPfns->pfnTestFinalPolicy)(&sProvData);
}
if (sProvData.psPfns->pfnCleanupPolicy)
{
(*sProvData.psPfns->pfnCleanupPolicy)(&sProvData);
}
dwLastError = sProvData.dwFinalError;
if (0 == dwLastError)
{
dwLastError = (DWORD) hr;
}
if (pcbSubjectHash && hr != TRUST_E_NOSIGNATURE)
{
// Return the subject's hash
DWORD cbHash;
if (sProvData.pPDSip && sProvData.pPDSip->psIndirectData)
{
cbHash = sProvData.pPDSip->psIndirectData->Digest.cbData;
}
else
{
cbHash = 0;
}
if (cbHash > 0)
{
*pcbSubjectHash = cbHash;
if (pbSubjectHash)
{
if (cbInSubjectHash >= cbHash)
{
memcpy(pbSubjectHash,
sProvData.pPDSip->psIndirectData->Digest.pbData,
cbHash);
}
else if (S_OK == hr)
{
hr = ERROR_MORE_DATA;
}
}
if (pHashAlgid)
{
*pHashAlgid = CertOIDToAlgId(
sProvData.pPDSip->psIndirectData->DigestAlgorithm.pszObjId);
}
}
}
if (!(pStateProvData))
{
//
// no previous state saved
//
if ((_ISINSTRUCT(WINTRUST_DATA, pWinTrustData->cbStruct, hWVTStateData)) &&
(pWinTrustData->dwStateAction == WTD_STATEACTION_VERIFY))
{
//
// first time call and asking to maintain state...
//
if (!(pWinTrustData->hWVTStateData = (HANDLE)WVTNew(sizeof(CRYPT_PROVIDER_DATA))))
{
_CleanupProviderData(&sProvData);
hr = ERROR_NOT_ENOUGH_MEMORY;
}
else
{
_CleanupProviderNonStateData(&sProvData);
memcpy(pWinTrustData->hWVTStateData, &sProvData, sizeof(CRYPT_PROVIDER_DATA));
}
}
else
{
_CleanupProviderData(&sProvData);
}
}
else
{
//
// only free up memory specific to this object/member
//
_CleanupProviderNonStateData(&sProvData);
memcpy(pWinTrustData->hWVTStateData, &sProvData, sizeof(CRYPT_PROVIDER_DATA));
}
//
// in version 1, when called by IE3.x and earlier, if security level is HIGH,
// then the no bad UI is set. If we had an error, we want to
// set the error to TRUST_E_FAIL. If we do not trust the object, every other
// case sets it to TRUST_E_SUBJECT_NOT_TRUSTED and IE throws NO UI....
//
if (fVersion1)
{
if (hr != ERROR_SUCCESS)
{
if ((pWinTrustData) &&
(_ISINSTRUCT(WINTRUST_DATA, pWinTrustData->cbStruct, dwUIChoice)))
{
if (pWinTrustData->dwUIChoice == WTD_UI_NOBAD)
{
hr = TRUST_E_FAIL; // ie throws UI.
}
else
{
hr = TRUST_E_SUBJECT_NOT_TRUSTED; // ie throws no UI.
}
}
else
{
hr = TRUST_E_SUBJECT_NOT_TRUSTED; // ie throws no UI.
}
}
}
}
}
else
{
hr = TRUST_E_SYSTEM_ERROR;
}
ErrorCase:
if ( fCacheableCall == TRUE )
{
if ( pCachedState == NULL )
{
if ( g_CatalogCache.CreateCachedStateFromWintrustData(
pWinTrustData,
&pCachedState
) == TRUE )
{
g_CatalogCache.AddCachedState( pCachedState );
}
}
if ( pCachedState == NULL )
{
FreeWintrustStateData( pWinTrustData );
}
g_CatalogCache.AdjustWintrustDataToCachedState(
pWinTrustData,
pCachedState,
TRUE
);
g_CatalogCache.ReleaseCachedState( pCachedState );
g_CatalogCache.UnlockCache();
}
SetLastError(dwLastError);
return (LONG) hr;
}
//////////////////////////////////////////////////////////////////////////////////////
//
// local utility functions
//
//
BOOL _FillProviderData(CRYPT_PROVIDER_DATA *pProvData, HWND hWnd, WINTRUST_DATA *pWinTrustData)
{
BOOL fHasTrustPubFlags;
//
// remember: we do NOT want to return FALSE unless it is an absolutely
// catastrophic error! Let the Trust provider handle (eg: none!)
//
if (pWinTrustData && _ISINSTRUCT(WINTRUST_DATA,
pWinTrustData->cbStruct, dwProvFlags))
pProvData->dwProvFlags = pWinTrustData->dwProvFlags &
WTD_PROV_FLAGS_MASK;
if ((hWnd == INVALID_HANDLE_VALUE) || !(hWnd))
{
if (pWinTrustData->dwUIChoice != WTD_UI_NONE)
{
hWnd = GetDesktopWindow();
}
}
pProvData->hWndParent = hWnd;
pProvData->hProv = I_CryptGetDefaultCryptProv(0); // get the default and DONT RELEASE IT!!!!
pProvData->dwEncoding = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
pProvData->pWintrustData = pWinTrustData;
pProvData->dwError = ERROR_SUCCESS;
// allocate errors
if (!(pProvData->padwTrustStepErrors))
{
if (!(pProvData->padwTrustStepErrors = (DWORD *)WVTNew(TRUSTERROR_MAX_STEPS * sizeof(DWORD))))
{
pProvData->dwError = GetLastError();
//
// NOTE!! this is currently the only FALSE return, so the caller will
// assume ERROR_NOT_ENOUGH_MEMORY if FALSE is returned from this function
//
return(FALSE);
}
pProvData->cdwTrustStepErrors = TRUSTERROR_MAX_STEPS;
}
memset(pProvData->padwTrustStepErrors, 0x00, sizeof(DWORD) * TRUSTERROR_MAX_STEPS);
WintrustGetRegPolicyFlags(&pProvData->dwRegPolicySettings);
GetRegSecuritySettings(&pProvData->dwRegSecuritySettings);
fHasTrustPubFlags = I_CryptReadTrustedPublisherDWORDValueFromRegistry(
CERT_TRUST_PUB_AUTHENTICODE_FLAGS_VALUE_NAME,
&pProvData->dwTrustPubSettings
);
if (fHasTrustPubFlags)
{
if (pProvData->dwTrustPubSettings &
(CERT_TRUST_PUB_ALLOW_MACHINE_ADMIN_TRUST |
CERT_TRUST_PUB_ALLOW_ENTERPRISE_ADMIN_TRUST))
{
// End User trust not allowed
pProvData->dwRegPolicySettings =
WTPF_IGNOREREVOKATION |
WTPF_IGNOREREVOCATIONONTS |
WTPF_OFFLINEOK_IND |
WTPF_OFFLINEOK_COM |
WTPF_OFFLINEOKNBU_IND |
WTPF_OFFLINEOKNBU_COM |
WTPF_ALLOWONLYPERTRUST;
}
// Allow the safer UI to enable revocation checking
if (pProvData->dwTrustPubSettings &
CERT_TRUST_PUB_CHECK_PUBLISHER_REV_FLAG)
{
pProvData->dwRegPolicySettings &= ~WTPF_IGNOREREVOKATION;
pProvData->dwRegPolicySettings |=
WTPF_OFFLINEOK_IND |
WTPF_OFFLINEOK_COM |
WTPF_OFFLINEOKNBU_IND |
WTPF_OFFLINEOKNBU_COM;
}
if (pProvData->dwTrustPubSettings &
CERT_TRUST_PUB_CHECK_TIMESTAMP_REV_FLAG)
{
pProvData->dwRegPolicySettings &= ~WTPF_IGNOREREVOCATIONONTS;
pProvData->dwRegPolicySettings |=
WTPF_OFFLINEOK_IND |
WTPF_OFFLINEOK_COM |
WTPF_OFFLINEOKNBU_IND |
WTPF_OFFLINEOKNBU_COM;
}
}
if (!(pWinTrustData) ||
!(_ISINSTRUCT(WINTRUST_DATA, pWinTrustData->cbStruct, dwUIChoice)))
{
pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT] = (DWORD)ERROR_INVALID_PARAMETER;
}
return(TRUE);
}
void _CleanupProviderData(CRYPT_PROVIDER_DATA *pProvData)
{
// pProvData->hProv: we're using crypt32's default
// pProvData->pWintrustData->xxx->hFile
if ((pProvData->fOpenedFile) && (pProvData->pWintrustData != NULL))
{
HANDLE *phFile;
phFile = NULL;
switch (pProvData->pWintrustData->dwUnionChoice)
{
case WTD_CHOICE_FILE:
phFile = &pProvData->pWintrustData->pFile->hFile;
break;
case WTD_CHOICE_CATALOG:
phFile = &pProvData->pWintrustData->pCatalog->hMemberFile;
break;
}
if ((phFile) && (*phFile) && (*phFile != INVALID_HANDLE_VALUE))
{
CloseHandle(*phFile);
*phFile = INVALID_HANDLE_VALUE;
pProvData->fOpenedFile = FALSE;
}
}
if (pProvData->dwSubjectChoice == CPD_CHOICE_SIP)
{
DELETE_OBJECT(pProvData->pPDSip->pSip);
DELETE_OBJECT(pProvData->pPDSip->pCATSip);
_WVTSipFreeSubjectInfo(pProvData->pPDSip->psSipSubjectInfo);
DELETE_OBJECT(pProvData->pPDSip->psSipSubjectInfo);
_WVTSipFreeSubjectInfo(pProvData->pPDSip->psSipCATSubjectInfo);
DELETE_OBJECT(pProvData->pPDSip->psSipCATSubjectInfo);
TrustFreeDecode(WVT_MODID_WINTRUST, (BYTE **)&pProvData->pPDSip->psIndirectData);
DELETE_OBJECT(pProvData->pPDSip);
}
if (pProvData->hMsg)
{
CryptMsgClose(pProvData->hMsg);
pProvData->hMsg = NULL;
}
// signer structure
for (int i = 0; i < (int)pProvData->csSigners; i++)
{
TrustFreeDecode(WVT_MODID_WINTRUST, (BYTE **)&pProvData->pasSigners[i].psSigner);
DeallocateCertChain(pProvData->pasSigners[i].csCertChain,
&pProvData->pasSigners[i].pasCertChain);
DELETE_OBJECT(pProvData->pasSigners[i].pasCertChain);
if (_ISINSTRUCT(CRYPT_PROVIDER_SGNR,
pProvData->pasSigners[i].cbStruct, pChainContext) &&
pProvData->pasSigners[i].pChainContext)
CertFreeCertificateChain(pProvData->pasSigners[i].pChainContext);
// counter signers
for (int i2 = 0; i2 < (int)pProvData->pasSigners[i].csCounterSigners; i2++)
{
TrustFreeDecode(WVT_MODID_WINTRUST, (BYTE **)&pProvData->pasSigners[i].pasCounterSigners[i2].psSigner);
DeallocateCertChain(pProvData->pasSigners[i].pasCounterSigners[i2].csCertChain,
&pProvData->pasSigners[i].pasCounterSigners[i2].pasCertChain);
DELETE_OBJECT(pProvData->pasSigners[i].pasCounterSigners[i2].pasCertChain);
if (_ISINSTRUCT(CRYPT_PROVIDER_SGNR,
pProvData->pasSigners[i].pasCounterSigners[i2].cbStruct,
pChainContext) &&
pProvData->pasSigners[i].pasCounterSigners[i2].pChainContext)
CertFreeCertificateChain(
pProvData->pasSigners[i].pasCounterSigners[i2].pChainContext);
}
DELETE_OBJECT(pProvData->pasSigners[i].pasCounterSigners);
}
DELETE_OBJECT(pProvData->pasSigners);
// MUST BE DONE LAST!!! Using the force flag!!!
if (pProvData->pahStores)
{
DeallocateStoreChain(pProvData->chStores, pProvData->pahStores);
DELETE_OBJECT(pProvData->pahStores);
}
pProvData->chStores = 0;
// pProvData->padwTrustStepErrors
DELETE_OBJECT(pProvData->padwTrustStepErrors);
// pProvData->pasProvPrivData
DELETE_OBJECT(pProvData->pasProvPrivData);
pProvData->csProvPrivData = 0;
// pProvData->psPfns
if (pProvData->psPfns)
{
if (pProvData->psPfns->psUIpfns)
{
DELETE_OBJECT(pProvData->psPfns->psUIpfns->psUIData);
DELETE_OBJECT(pProvData->psPfns->psUIpfns);
}
DELETE_OBJECT(pProvData->psPfns);
}
}
void _CleanupProviderNonStateData(CRYPT_PROVIDER_DATA *pProvData)
{
// pProvData->hProv: we're using default!
// pProvData->pWintrustData->xxx->hFile: close!
if ((pProvData->fOpenedFile) && (pProvData->pWintrustData != NULL))
{
HANDLE *phFile;
phFile = NULL;
switch (pProvData->pWintrustData->dwUnionChoice)
{
case WTD_CHOICE_FILE:
phFile = &pProvData->pWintrustData->pFile->hFile;
break;
case WTD_CHOICE_CATALOG:
phFile = &pProvData->pWintrustData->pCatalog->hMemberFile;
break;
}
if ((phFile) && (*phFile) && (*phFile != INVALID_HANDLE_VALUE))
{
CloseHandle(*phFile);
*phFile = INVALID_HANDLE_VALUE;
pProvData->fOpenedFile = FALSE;
}
}
if (pProvData->dwSubjectChoice == CPD_CHOICE_SIP)
{
DELETE_OBJECT(pProvData->pPDSip->pSip);
_WVTSipFreeSubjectInfoKeepState(pProvData->pPDSip->psSipSubjectInfo);
// pProvData->pPDSip->psSipSubjectInfo: keep
// pProvData->pPDSip->pCATSip: keep
// pProvData->pPDSip->psSipCATSubjectInfo: keep
TrustFreeDecode(WVT_MODID_WINTRUST, (BYTE **)&pProvData->pPDSip->psIndirectData);
// pProvData->pPDSip: keep
}
// pProvData->hMsg: keep
// signer structure: keep
// pProvData->pahStores: keep
// pProvData->padwTrustStepErrors: keep
// pProvData->pasProvPrivData: keep
// pProvData->psPfns: keep
}
BOOL _WVTSipFreeSubjectInfo(SIP_SUBJECTINFO *pSubj)
{
if (!(pSubj))
{
return(FALSE);
}
DELETE_OBJECT(pSubj->pgSubjectType);
switch(pSubj->dwUnionChoice)
{
case MSSIP_ADDINFO_BLOB:
DELETE_OBJECT(pSubj->psBlob);
break;
case MSSIP_ADDINFO_CATMEMBER:
if (pSubj->psCatMember)
{
// The following APIs are in DELAYLOAD'ed mscat32.dll. If the
// DELAYLOAD fails an exception is raised.
__try {
CryptCATClose(
CryptCATHandleFromStore(pSubj->psCatMember->pStore));
} __except(EXCEPTION_EXECUTE_HANDLER) {
DWORD dwExceptionCode = GetExceptionCode();
}
DELETE_OBJECT(pSubj->psCatMember);
}
break;
}
return(TRUE);
}
BOOL _WVTSipFreeSubjectInfoKeepState(SIP_SUBJECTINFO *pSubj)
{
if (!(pSubj))
{
return(FALSE);
}
DELETE_OBJECT(pSubj->pgSubjectType);
switch(pSubj->dwUnionChoice)
{
case MSSIP_ADDINFO_BLOB:
DELETE_OBJECT(pSubj->psBlob);
break;
case MSSIP_ADDINFO_CATMEMBER:
break;
}
return(TRUE);
}
BOOL _WVTSetupProviderData(CRYPT_PROVIDER_DATA *psProvData, CRYPT_PROVIDER_DATA *psState)
{
if (psState)
{
memcpy(psProvData, psState, sizeof(CRYPT_PROVIDER_DATA));
if (_ISINSTRUCT(CRYPT_PROVIDER_DATA, psProvData->cbStruct, fRecallWithState))
{
psProvData->fRecallWithState = TRUE;
}
return(TRUE);
}
memset(psProvData, 0x00, sizeof(CRYPT_PROVIDER_DATA));
psProvData->cbStruct = sizeof(CRYPT_PROVIDER_DATA);
if (!(psProvData->psPfns = (CRYPT_PROVIDER_FUNCTIONS *)WVTNew(sizeof(CRYPT_PROVIDER_FUNCTIONS))))
{
return(FALSE);
}
memset(psProvData->psPfns, 0x00, sizeof(CRYPT_PROVIDER_FUNCTIONS));
psProvData->psPfns->cbStruct = sizeof(CRYPT_PROVIDER_FUNCTIONS);
if (!(psProvData->psPfns->psUIpfns = (CRYPT_PROVUI_FUNCS *)WVTNew(sizeof(CRYPT_PROVUI_FUNCS))))
{
return(FALSE);
}
memset(psProvData->psPfns->psUIpfns, 0x00, sizeof(CRYPT_PROVUI_FUNCS));
psProvData->psPfns->psUIpfns->cbStruct = sizeof(CRYPT_PROVUI_FUNCS);
if (!(psProvData->psPfns->psUIpfns->psUIData = (CRYPT_PROVUI_DATA *)WVTNew(sizeof(CRYPT_PROVUI_DATA))))
{
return(FALSE);
}
memset(psProvData->psPfns->psUIpfns->psUIData, 0x00, sizeof(CRYPT_PROVUI_DATA));
psProvData->psPfns->psUIpfns->psUIData->cbStruct = sizeof(CRYPT_PROVUI_DATA);
GetSystemTimeAsFileTime(&psProvData->sftSystemTime);
return(TRUE);
}
VOID FreeWintrustStateData (WINTRUST_DATA* pWintrustData)
{
PCRYPT_PROVIDER_DATA pStateProvData;
pStateProvData = WTHelperProvDataFromStateData(
pWintrustData->hWVTStateData
);
if ( pStateProvData != NULL )
{
_CleanupProviderData( pStateProvData );
DELETE_OBJECT( pWintrustData->hWVTStateData );
}
}