VERIFY_RESULT PhpVerifyFile( _In_ PPH_VERIFY_FILE_INFO Information, _In_ HANDLE FileHandle, _In_ ULONG UnionChoice, _In_ PVOID UnionData, _In_ PGUID ActionId, _In_opt_ PVOID PolicyCallbackData, _Out_ PCERT_CONTEXT **Signatures, _Out_ PULONG NumberOfSignatures ) { LONG status; WINTRUST_DATA trustData = { 0 }; trustData.cbStruct = sizeof(WINTRUST_DATA); trustData.pPolicyCallbackData = PolicyCallbackData; trustData.dwUIChoice = WTD_UI_NONE; trustData.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN; trustData.dwUnionChoice = UnionChoice; trustData.dwStateAction = WTD_STATEACTION_VERIFY; trustData.dwProvFlags = WTD_SAFER_FLAG; trustData.pFile = UnionData; if (UnionChoice == WTD_CHOICE_CATALOG) trustData.pCatalog = UnionData; if (Information->Flags & PH_VERIFY_PREVENT_NETWORK_ACCESS) { trustData.fdwRevocationChecks = WTD_REVOKE_NONE; if (WindowsVersion >= WINDOWS_VISTA) trustData.dwProvFlags |= WTD_CACHE_ONLY_URL_RETRIEVAL; else trustData.dwProvFlags |= WTD_REVOCATION_CHECK_NONE; } status = WinVerifyTrust_I(NULL, ActionId, &trustData); PhpGetSignaturesFromStateData(trustData.hWVTStateData, Signatures, NumberOfSignatures); if (status == 0 && (Information->Flags & PH_VERIFY_VIEW_PROPERTIES)) PhpViewSignerInfo(Information, trustData.hWVTStateData); // Close the state data. trustData.dwStateAction = WTD_STATEACTION_CLOSE; WinVerifyTrust_I(NULL, ActionId, &trustData); return PhpStatusToVerifyResult(status); }
VERIFY_RESULT PhpVerifyFileBasic( __in PWSTR FileName, __out_opt PPH_STRING *SignerName ) { LONG status; WINTRUST_DATA trustData = { 0 }; WINTRUST_FILE_INFO fileInfo = { 0 }; GUID actionGenericVerifyV2 = WINTRUST_ACTION_GENERIC_VERIFY_V2; fileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO); fileInfo.pcwszFilePath = FileName; trustData.cbStruct = sizeof(WINTRUST_DATA); trustData.dwUIChoice = WTD_UI_NONE; trustData.dwProvFlags = WTD_SAFER_FLAG; trustData.dwUnionChoice = WTD_CHOICE_FILE; trustData.dwStateAction = WTD_STATEACTION_VERIFY; trustData.pFile = &fileInfo; if (WindowsVersion >= WINDOWS_VISTA) trustData.dwProvFlags |= WTD_CACHE_ONLY_URL_RETRIEVAL; else trustData.dwProvFlags |= WTD_REVOCATION_CHECK_NONE; status = WinVerifyTrust_I(NULL, &actionGenericVerifyV2, &trustData); if (SignerName) { if (status != TRUST_E_NOSIGNATURE) *SignerName = PhpGetSignerNameFromStateData(trustData.hWVTStateData); else *SignerName = NULL; } // Close the state data. trustData.dwStateAction = WTD_STATEACTION_CLOSE; WinVerifyTrust_I(NULL, &actionGenericVerifyV2, &trustData); return PhpStatusToVerifyResult(status); }
VERIFY_RESULT PhpVerifyFileFromCatalog( __in PWSTR FileName, __out_opt PPH_STRING *SignerName ) { LONG status = TRUST_E_NOSIGNATURE; WINTRUST_DATA trustData = { 0 }; WINTRUST_CATALOG_INFO catalogInfo = { 0 }; GUID driverActionVerify = DRIVER_ACTION_VERIFY; HANDLE fileHandle; LARGE_INTEGER fileSize; PUCHAR fileHash = NULL; ULONG fileHashLength; PWSTR fileHashTag = NULL; HANDLE catAdminHandle = NULL; HANDLE catInfoHandle = NULL; ULONG i; if (!NT_SUCCESS(PhCreateFileWin32( &fileHandle, FileName, FILE_GENERIC_READ, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) return VrNoSignature; // Don't try to hash files over 32 MB in size. if (!NT_SUCCESS(PhGetFileSize(fileHandle, &fileSize)) || (fileSize.QuadPart > 32 * 1024 * 1024)) { NtClose(fileHandle); return VrNoSignature; } fileHashLength = 256; fileHash = PhAllocate(fileHashLength); if (!CryptCATAdminCalcHashFromFileHandle(fileHandle, &fileHashLength, fileHash, 0)) { PhFree(fileHash); fileHash = PhAllocate(fileHashLength); if (!CryptCATAdminCalcHashFromFileHandle(fileHandle, &fileHashLength, fileHash, 0)) { NtClose(fileHandle); PhFree(fileHash); return VrNoSignature; } } NtClose(fileHandle); if (!CryptCATAdminAcquireContext(&catAdminHandle, &driverActionVerify, 0)) { PhFree(fileHash); return VrNoSignature; } fileHashTag = PhAllocate((fileHashLength * 2 + 1) * sizeof(WCHAR)); for (i = 0; i < fileHashLength; i++) { fileHashTag[i * 2] = PhIntegerToCharUpper[fileHash[i] >> 4]; fileHashTag[i * 2 + 1] = PhIntegerToCharUpper[fileHash[i] & 0xf]; } fileHashTag[fileHashLength * 2] = 0; catInfoHandle = CryptCATAdminEnumCatalogFromHash( catAdminHandle, fileHash, fileHashLength, 0, NULL ); PhFree(fileHash); if (catInfoHandle) { CATALOG_INFO ci = { 0 }; if (CryptCATCatalogInfoFromContext(catInfoHandle, &ci, 0)) { catalogInfo.cbStruct = sizeof(catalogInfo); catalogInfo.pcwszCatalogFilePath = ci.wszCatalogFile; catalogInfo.pcwszMemberFilePath = FileName; catalogInfo.pcwszMemberTag = fileHashTag; trustData.cbStruct = sizeof(trustData); trustData.dwUIChoice = WTD_UI_NONE; trustData.fdwRevocationChecks = WTD_STATEACTION_VERIFY; trustData.dwUnionChoice = WTD_CHOICE_CATALOG; trustData.dwStateAction = WTD_STATEACTION_VERIFY; trustData.pCatalog = &catalogInfo; if (WindowsVersion >= WINDOWS_VISTA) trustData.dwProvFlags |= WTD_CACHE_ONLY_URL_RETRIEVAL; else trustData.dwProvFlags |= WTD_REVOCATION_CHECK_NONE; status = WinVerifyTrust_I(NULL, &driverActionVerify, &trustData); if (SignerName) { if (status != TRUST_E_NOSIGNATURE) *SignerName = PhpGetSignerNameFromStateData(trustData.hWVTStateData); else *SignerName = NULL; } // Close the state data. trustData.dwStateAction = WTD_STATEACTION_CLOSE; WinVerifyTrust_I(NULL, &driverActionVerify, &trustData); } CryptCATAdminReleaseCatalogContext(catAdminHandle, catInfoHandle, 0); } PhFree(fileHashTag); CryptCATAdminReleaseContext(catAdminHandle, 0); return PhpStatusToVerifyResult(status); }