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