unit TrustCheck;
interface
uses
Windows,SysUtils,jwaWinTrust,JwaWinCrypt;
function CheckFileTrust(const FileName: WideString; var Signner: WideString): Boolean;
implementation
const
WINTRUST_ACTION_GENERIC_VERIFY_V2: TGUID = '{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}';
function CryptCATAdminAcquireContext(var HCatAdmin: THandle; pgSubsystem: PGUID; dwFlags: DWORD): BOOL; stdcall; external 'wintrust.dll' ;
function CryptCATAdminReleaseContext(hAdmin: THANDLE; dwFlags: DWORD): BOOL; stdcall; external 'wintrust.dll' ;
function CryptCATAdminCalcHashFromFileHandle(hFile: THANDLE; var dwSize: DWORD; buf: PByte; dwFlags: DWORD): BOOL; stdcall; external 'wintrust.dll' ;
function CryptCATAdminEnumCatalogFromHash(hAdmin: THANDLE; pbHash: PByte; pHashSize: DWORD; dwFlags: DWORD; phPrevCatInfo: PHandle): THANDLE; stdcall;external 'wintrust.dll' ;
function CryptCATCatalogInfoFromContext(hCatInfo: THANDLE; psCatInfo: PWintrustCatalogInfo; dwFlags: DWORD): BOOL; stdcall; external 'wintrust.dll' ;
function CryptCATAdminReleaseCatalogContext(hAdmin: THANDLE; hCatInfo: THANDLE; dwFlags: DWORD): BOOL; stdcall; external 'wintrust.dll' ;
function WinVerifyTrust(hwnd: THANDLE; pgActionID: PGUID; pWintrustData: PWINTRUST_DATA): Longint; stdcall; external 'wintrust.dll' ;
function bf2s(bf: PByte; len: Integer): WideString;
begin
Result := '';
while len > 0 do
begin
Result := Result + IntToHex(bf^,2);
Inc(bf);
Dec(len);
end;
end;
function GetSignner(hWVTStateData: THANDLE): WideString;
var
provider: PCRYPT_PROVIDER_DATA;
signner: PCRYPT_PROVIDER_SGNR;
cert: PCRYPT_PROVIDER_CERT;
S: string;
i: Integer;
begin
provider := WTHelperProvDataFromStateData(hWVTStateData);
if provider = nil then
Exit;
signner := WTHelperGetProvSignerFromChain(provider,0,False,0);
if signner = nil then
Exit;
cert := WTHelperGetProvCertFromChain(signner, 0);
if cert = nil then
Exit;
i := CertGetNameString(cert.pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, nil, nil, 0);
SetLength(S,i);
CertGetNameString(cert.pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, nil, @s[1], Length(s));
Result := S;
end;
function CheckFileTrust(const FileName: WideString; var Signner: WideString): Boolean;
var
buf: array[0..255]of Byte;
cb: DWORD;
hAdmin: THandle;
hCtx: THandle;
hFile: THandle;
I,Ret: Integer;
S: WideString;
WTrustData: WINTRUST_DATA;
WTDFileInfo: TWintrustFileInfo;
CatalogInfo: TWintrustCatalogInfo;
WTDCatalogInfo: WINTRUST_CATALOG_INFO;
begin
Result := False;
Signner := '';
if not FileExists(FileName) then
Exit;
hAdmin := 0;
hCtx := 0;
hFile := INVALID_HANDLE_VALUE;
try
if not CryptCATAdminAcquireContext(hAdmin,nil,0) then
Exit;
hFile := CreateFileW(PWideChar(FileName),GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if hFile = INVALID_HANDLE_VALUE then
begin
I := GetLastError;
sleep(I * 0);
Exit;
end;
cb := SizeOf(buf);
if not CryptCATAdminCalcHashFromFileHandle(hFile,cb,@buf[0],0) then
Exit;
S := bf2s(@buf[0],cb);
hCtx := CryptCATAdminEnumCatalogFromHash(hAdmin,@buf[0],cb,0,nil);
FillChar(WTrustData,SizeOf(WTrustData),0);
WTrustData.dwUIChoice := WTD_UI_NONE;
WTrustData.fdwRevocationChecks := WTD_REVOKE_NONE;
WTrustData.dwStateAction := WTD_STATEACTION_VERIFY;
WTrustData.dwProvFlags := WTD_REVOCATION_CHECK_NONE;
if hCtx = 0 then
begin
FillChar(WTDFileInfo,SizeOf(WTDFileInfo),0);
WTDFileInfo.cbStruct := SizeOf(WTDFileInfo);
WTDFileInfo.pcwszFilePath := PWideChar(FileName);
WTrustData.cbStruct := SizeOf(WTrustData);
WTrustData.dwUnionChoice := WTD_CHOICE_FILE;
WTrustData.InfoUnion.pFile := @WTDFileInfo;
end
else
begin
CryptCATCatalogInfoFromContext(hCtx, @CatalogInfo, 0);
FillChar(WTDCatalogInfo,SizeOf(WTDCatalogInfo),0);
WTDCatalogInfo.cbStruct := SizeOf(WTDCatalogInfo);
WTDCatalogInfo.pcwszCatalogFilePath := CatalogInfo.pcwszCatalogFilePath;
WTDCatalogInfo.pcwszMemberFilePath := PWideChar(Filename);
WTDCatalogInfo.pcwszMemberTag := PWideChar(S);
WTrustData.cbStruct := SizeOf(WTrustData);
WTrustData.dwUnionChoice := WTD_CHOICE_CATALOG;
WTrustData.InfoUnion.pCatalog := @WTDCatalogInfo;
end;
Ret := WinVerifyTrust(INVALID_HANDLE_VALUE,@WINTRUST_ACTION_GENERIC_VERIFY_V2,@WTrustData);
Result := Ret = 0;
if Result and (WTrustData.hWVTStateData > 0) then
Signner := GetSignner(WTrustData.hWVTStateData);
WTrustData.dwStateAction := WTD_STATEACTION_CLOSE;
WinVerifyTrust(INVALID_HANDLE_VALUE,@WINTRUST_ACTION_GENERIC_VERIFY_V2,@WTrustData);
finally
if hCtx > 0 then
CryptCATAdminReleaseCatalogContext(hAdmin,hCtx, 0);
if hAdmin <> 0 then
CryptCATAdminReleaseContext(hAdmin,0);
if hFile <> INVALID_HANDLE_VALUE then
CloseHandle(hFile);
end;
end;
end.