Public Declare Sub RtlFillMemory Lib "kernel32.dll" (Destination As Long, Length As Long, Fill As Byte) Public Declare Function WinVerifyTrust Lib "Wintrust.dll" (hWnd As Long, pgActionID As Long, pWVTData As Long) As Long Public Declare Function GetLastError Lib "kernel32.dll" () As Long
Const WTD_UI_NOBAD = 3& ' Do not display any negative UI.
Const WTD_UI_NOGOOD = 4& ' Do not display any positive UI.
Const WTD_REVOKE_NONE = 0& 'No additional revocation checking will be done.
Const WTD_REVOKE_WHOLECHAIN = 1& ' Revocation checking will be done on the whole chain.
Const WTD_CHOICE_FILE = 1& ' Use the file pointed to by pFile.
Const WTD_CHOICE_CATALOG = 2& ' Use the catalog pointed to by pCatalog.
Const WTD_CHOICE_BLOB = 3& ' Use the BLOB pointed to by pBlob.
Const WTD_CHOICE_SIGNER = 4& ' Use the WINTRUST_SGNR_INFO structure pointed to by pSgnr.
Const WTD_CHOICE_CERT = 5& ' Use the certificate pointed to by pCert.
Const WTD_SAFER_FLAG = 256&
Type GUID D1 As Long D2 As Integer D3 As Integer D4(0 To 7) As Byte End Type
Type WINTRUST_FILE_INFO cbStruct As Long pcwszFilePath As Long hFile As Long pgKnownSubject As Long End Type
Type WINTRUST_DATA cbStruct As Long pPolicyCallbackData As Long pSIPClientData As Long dwUIChoice As Long fdwRevocationChecks As Long dwUnionChoice As Long 'Union pUnionData As Long dwStateAction As Long hWVTStateData As Long pwszURLReference As Long dwProvFlags As Long dwUIContext As Long End Type
Public Function VerifyEmbeddedSignature(pwszSourceFile As String) As Boolean Dim lStatus As Long Dim dwLastError As Long
'// Initialize the WinVerifyTrust input data structure.
'// Default all fields to 0. RtlFillMemory ByVal VarPtr(WinTrustData), ByVal LenB(WinTrustData), ByVal 0 WinTrustData.cbStruct = LenB(WinTrustData) '// Use default code signing EKU. WinTrustData.pPolicyCallbackData = 0 '// No data to pass to SIP. WinTrustData.pSIPClientData = 0 '// Disable WVT UI. WinTrustData.dwUIChoice = WTD_UI_NONE '// No revocation checking. WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE '// Verify an embedded signature on a file. WinTrustData.dwUnionChoice = WTD_CHOICE_FILE '// Default verification. WinTrustData.dwStateAction = 0 '// Not applicable for default verification of embedded signature. WinTrustData.hWVTStateData = 0 '// Not used. WinTrustData.pwszURLReference = 0 '// Default. WinTrustData.dwProvFlags = WTD_SAFER_FLAG
' // This is not applicable if there is no UI because it changes ' // the UI to accommodate running applications instead of ' // installing applications. WinTrustData.dwUIContext = 0
'// Set pFile. WinTrustData.pUnionData = VarPtr(FileData)
'// WinVerifyTrust verifies signatures as specified by the GUID '// and Wintrust_Data. lStatus = WinVerifyTrust(ByVal 0, ByVal VarPtr(WVTPolicyGUID), ByVal VarPtr(WinTrustData))
Select Case (lStatus) Case ERROR_SUCCESS
MsgBox "The file """ & pwszSourceFile & """ is signed and the signature was verified."
Case TRUST_E_NOSIGNATURE
dwLastError = GetLastError() If (TRUST_E_NOSIGNATURE = dwLastError) Or (TRUST_E_SUBJECT_FORM_UNKNOWN = dwLastError) Or (TRUST_E_PROVIDER_UNKNOWN = dwLastError) Then
'// The file was not signed. MsgBox "The file """ & pwszSourceFile & """ is not signed."
Else
' // The signature was not valid or there was an error ' // opening the file. MsgBox "An unknown error occurred trying to verify the signature of the """ & pwszSourceFile & """ file."
End If
Case TRUST_E_EXPLICIT_DISTRUST ' // The hash that represents the subject or the publisher ' // is not allowed by the admin or user. MsgBox "The signature is present, but specifically disallowed."
Case TRUST_E_SUBJECT_NOT_TRUSTED '// The user clicked "No" when asked to install and run. MsgBox "The signature is present, but not trusted."
Case CRYPT_E_SECURITY_SETTINGS
MsgBox "CRYPT_E_SECURITY_SETTINGS - The hash " & _ "representing the subject or the publisher wasn't " & _ "explicitly trusted by the admin and admin policy " & _ "has disabled user trust. No signature, publisher " & _ "or timestamp errors."
Case Else ' // The UI was disabled in dwUIChoice or the admin policy ' // has disabled user trust. lStatus contains the ' // publisher or time stamp chain error. MsgBox "Error is: 0x" & Hex(lStatus) & "." End Select
//------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. // Example of verifying the embedded signature of a PE file by using // the WinVerifyTrust function.
/* WVTPolicyGUID specifies the policy to apply on the file WINTRUST_ACTION_GENERIC_VERIFY_V2 policy checks:
1) The certificate used to sign the file chains up to a root certificate located in the trusted root certificate store. This implies that the identity of the publisher has been verified by a certification authority.
2) In cases where user interface is displayed (which this example does not do), WinVerifyTrust will check for whether the end entity certificate is stored in the trusted publisher store, implying that the user trusts content from this publisher.
3) The end entity certificate has sufficient permission to sign code, as indicated by the presence of a code signing EKU or no EKU. */
// This is not applicable if there is no UI because it changes // the UI to accommodate running applications instead of // installing applications. WinTrustData.dwUIContext = 0;
// Set pFile. WinTrustData.pFile = &FileData;
// WinVerifyTrust verifies signatures as specified by the GUID // and Wintrust_Data. lStatus = WinVerifyTrust( NULL, &WVTPolicyGUID, &WinTrustData);
switch (lStatus) { case ERROR_SUCCESS: /* Signed file: - Hash that represents the subject is trusted.
- Trusted publisher without any verification errors.
- UI was disabled in dwUIChoice. No publisher or time stamp chain errors.
- UI was enabled in dwUIChoice and the user clicked "Yes" when asked to install and run the signed subject. */ wprintf_s(L"The file \"%s\" is signed and the signature " L"was verified.\n", pwszSourceFile); break;
case TRUST_E_NOSIGNATURE: // The file was not signed or had a signature // that was not valid.
// Get the reason for no signature. dwLastError = GetLastError(); if (TRUST_E_NOSIGNATURE == dwLastError || TRUST_E_SUBJECT_FORM_UNKNOWN == dwLastError || TRUST_E_PROVIDER_UNKNOWN == dwLastError) { // The file was not signed. wprintf_s(L"The file \"%s\" is not signed.\n", pwszSourceFile); } else { // The signature was not valid or there was an error // opening the file. wprintf_s(L"An unknown error occurred trying to " L"verify the signature of the \"%s\" file.\n", pwszSourceFile); }
break;
case TRUST_E_EXPLICIT_DISTRUST: // The hash that represents the subject or the publisher // is not allowed by the admin or user. wprintf_s(L"The signature is present, but specifically " L"disallowed.\n"); break;
case TRUST_E_SUBJECT_NOT_TRUSTED: // The user clicked "No" when asked to install and run. wprintf_s(L"The signature is present, but not " L"trusted.\n"); break;
case CRYPT_E_SECURITY_SETTINGS: /* The hash that represents the subject or the publisher was not explicitly trusted by the admin and the admin policy has disabled user trust. No signature, publisher or time stamp errors. */ wprintf_s(L"CRYPT_E_SECURITY_SETTINGS - The hash " L"representing the subject or the publisher wasn't " L"explicitly trusted by the admin and admin policy " L"has disabled user trust. No signature, publisher " L"or timestamp errors.\n"); break;
default: // The UI was disabled in dwUIChoice or the admin policy // has disabled user trust. lStatus contains the // publisher or time stamp chain error. wprintf_s(L"Error is: 0x%x.\n", lStatus); break; }