WinVerifyTrust
C# Signature:
[DllImport("wintrust.dll", ExactSpelling = true, SetLastError = false, CharSet = CharSet.Unicode)]
static extern WinVerifyTrustResult WinVerifyTrust(
[In] IntPtr hwnd,
[In] [MarshalAs(UnmanagedType.LPStruct)] Guid pgActionID,
[In] WinTrustData pWVTData
);
VB Signature:
Declare Function WinVerifyTrust Lib "wintrust.dll" (TODO) As TODO
User-Defined Types:
namespace Security.WinTrust
{
using System;
using System.Runtime.InteropServices;
#region WinTrustData struct field enums
enum WinTrustDataUIChoice : uint
{
All = 1,
None = 2,
NoBad = 3,
NoGood = 4
}
enum WinTrustDataRevocationChecks : uint
{
None = 0x00000000,
WholeChain = 0x00000001
}
enum WinTrustDataChoice : uint
{
File = 1,
Catalog = 2,
Blob = 3,
Signer = 4,
Certificate = 5
}
enum WinTrustDataStateAction : uint
{
Ignore = 0x00000000,
Verify = 0x00000001,
Close = 0x00000002,
AutoCache = 0x00000003,
AutoCacheFlush = 0x00000004
}
[FlagsAttribute]
enum WinTrustDataProvFlags : uint
{
UseIe4TrustFlag = 0x00000001,
NoIe4ChainFlag = 0x00000002,
NoPolicyUsageFlag = 0x00000004,
RevocationCheckNone = 0x00000010,
RevocationCheckEndCert = 0x00000020,
RevocationCheckChain = 0x00000040,
RevocationCheckChainExcludeRoot = 0x00000080,
SaferFlag = 0x00000100, // Used by software restriction policies. Should not be used.
HashOnlyFlag = 0x00000200,
UseDefaultOsverCheck = 0x00000400,
LifetimeSigningFlag = 0x00000800,
CacheOnlyUrlRetrieval = 0x00001000, // affects CRL retrieval and AIA retrieval
DisableMD2andMD4 = 0x00002000 // Win7 SP1+: Disallows use of MD2 or MD4 in the chain except for the root
}
enum WinTrustDataUIContext : uint
{
Execute = 0,
Install = 1
}
#endregion
#region WinTrust structures
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
class WinTrustFileInfo
{
UInt32 StructSize = (UInt32)Marshal.SizeOf(typeof(WinTrustFileInfo));
IntPtr pszFilePath; // required, file name to be verified
IntPtr hFile = IntPtr.Zero; // optional, open handle to FilePath
IntPtr pgKnownSubject = IntPtr.Zero; // optional, subject type if it is known
public WinTrustFileInfo(String _filePath)
{
pszFilePath = Marshal.StringToCoTaskMemAuto(_filePath);
}
public void Dispose()
{
if(pszFilePath != IntPtr.Zero) {
Marshal.FreeCoTaskMem(pszFilePath);
pszFilePath = IntPtr.Zero;
}
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
class WinTrustData
{
UInt32 StructSize = (UInt32)Marshal.SizeOf(typeof(WinTrustData));
IntPtr PolicyCallbackData = IntPtr.Zero;
IntPtr SIPClientData = IntPtr.Zero;
// required: UI choice
WinTrustDataUIChoice UIChoice = WinTrustDataUIChoice.None;
// required: certificate revocation check options
WinTrustDataRevocationChecks RevocationChecks = WinTrustDataRevocationChecks.None;
// required: which structure is being passed in?
WinTrustDataChoice UnionChoice = WinTrustDataChoice.File;
// individual file
IntPtr FileInfoPtr;
WinTrustDataStateAction StateAction = WinTrustDataStateAction.Ignore;
IntPtr StateData = IntPtr.Zero;
String URLReference = null;
WinTrustDataProvFlags ProvFlags = WinTrustDataProvFlags.RevocationCheckChainExcludeRoot;
WinTrustDataUIContext UIContext = WinTrustDataUIContext.Execute;
// constructor for silent WinTrustDataChoice.File check
public WinTrustData(WinTrustFileInfo _fileInfo)
{
// On Win7SP1+, don't allow MD2 or MD4 signatures
if ((Environment.OSVersion.Version.Major > 6) ||
((Environment.OSVersion.Version.Major == 6) && (Environment.OSVersion.Version.Minor > 1)) ||
((Environment.OSVersion.Version.Major == 6) && (Environment.OSVersion.Version.Minor == 1) && !String.IsNullOrEmpty(Environment.OSVersion.ServicePack)))
{
ProvFlags |= WinTrustDataProvFlags.DisableMD2andMD4;
}
WinTrustFileInfo wtfiData = _fileInfo;
FileInfoPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(WinTrustFileInfo)));
Marshal.StructureToPtr(wtfiData, FileInfoPtr, false);
}
public void Dispose()
{
if(FileInfoPtr != IntPtr.Zero) {
Marshal.FreeCoTaskMem(FileInfoPtr);
FileInfoPtr = IntPtr.Zero;
}
}
}
#endregion
enum WinVerifyTrustResult : uint
{
Success = 0,
ProviderUnknown = 0x800b0001, // Trust provider is not recognized on this system
ActionUnknown = 0x800b0002, // Trust provider does not support the specified action
SubjectFormUnknown = 0x800b0003, // Trust provider does not support the form specified for the subject
SubjectNotTrusted = 0x800b0004, // Subject failed the specified verification action
FileNotSigned = 0x800B0100, // TRUST_E_NOSIGNATURE - File was not signed
SubjectExplicitlyDistrusted = 0x800B0111, // Signer's certificate is in the Untrusted Publishers store
SignatureOrFileCorrupt = 0x80096010, // TRUST_E_BAD_DIGEST - file was probably corrupt
SubjectCertExpired = 0x800B0101, // CERT_E_EXPIRED - Signer's certificate was expired
SubjectCertificateRevoked = 0x800B010C, // CERT_E_REVOKED Subject's certificate was revoked
UntrustedRoot = 0x800B0109 // CERT_E_UNTRUSTEDROOT - A certification chain processed correctly but terminated in a root certificate that is not trusted by the trust provider.
}
sealed class WinTrust
{
private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
// GUID of the action to perform
private const string WINTRUST_ACTION_GENERIC_VERIFY_V2 = "{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}";
[DllImport("wintrust.dll", ExactSpelling = true, SetLastError = false, CharSet = CharSet.Unicode)]
static extern WinVerifyTrustResult WinVerifyTrust(
[In] IntPtr hwnd,
[In] [MarshalAs(UnmanagedType.LPStruct)] Guid pgActionID,
[In] WinTrustData pWVTData
);
// call WinTrust.WinVerifyTrust() to check embedded file signature
public static bool VerifyEmbeddedSignature(string fileName)
{
WinTrustFileInfo wtfi = new WinTrustFileInfo(fileName);
WinTrustData wtd = new WinTrustData(wtfi);
Guid guidAction = new Guid(WINTRUST_ACTION_GENERIC_VERIFY_V2);
WinVerifyTrustResult result = WinVerifyTrust(INVALID_HANDLE_VALUE, guidAction, wtd);
bool ret = (result == WinVerifyTrustResult.Success);
wtfi.Dispose();
wtd.Dispose();
return ret;
}
private WinTrust() { }
}
}
Notes:
WinTrustFileInfo winTrustFileInfo = null;
WinTrustData winTrustData = null;
try
{
// specify the WinVerifyTrust function/action that we want
Guid action = new Guid(WINTRUST_ACTION_GENERIC_VERIFY_V2);
// instantiate our WinTrustFileInfo and WinTrustData data structures
winTrustFileInfo = new WinTrustFileInfo(filename);
winTrustData = new WinTrustData(filename, winTrustFileInfo);
// call into WinVerifyTrust
return WinVerifyTrust(INVALID_HANDLE_VALUE, action, winTrustData);
}
finally
{
// free the locally-held unmanaged memory in the data structures
if (winTrustFileInfo != null) winTrustFileInfo.Dispose();
if (winTrustData != null) winTrustData.Dispose();
}
Tips & Tricks:
static public bool CheckFile(string filename)
{
// check digital signature
bool ret = WinTrust.VerifyEmbeddedSignature(filename);
// do some other checks - for example verify the subject
X509Certificate2 cert = new X509Certificate2(filename);
return ret && cert.Verify() && cert.Subject == <CN=you, O=you,....>;
}
Sample Code:
System.Console.WriteLine("Signature is OK: {0}", WinTrust.VerifyEmbeddedSignature(fileName));
Última actualización