|
@@ -0,0 +1,168 @@
|
|
|
+using NLog;
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
+using System.Runtime.InteropServices;
|
|
|
+using System.Text;
|
|
|
+using System.Threading.Tasks;
|
|
|
+
|
|
|
+namespace SyncTrayzor.Utils
|
|
|
+{
|
|
|
+ // From http://www.pinvoke.net/default.aspx/wintrust.winverifytrust
|
|
|
+ public static class AuthenticodeTools
|
|
|
+ {
|
|
|
+ private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
|
|
+
|
|
|
+ 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)]
|
|
|
+ private 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, bool allowInvalidRoot)
|
|
|
+ {
|
|
|
+ WinTrustData wtd = new WinTrustData(fileName);
|
|
|
+ Guid guidAction = new Guid(WINTRUST_ACTION_GENERIC_VERIFY_V2);
|
|
|
+ WinVerifyTrustResult result = WinVerifyTrust(INVALID_HANDLE_VALUE, guidAction, wtd);
|
|
|
+ logger.Info("Result: {0}", result);
|
|
|
+ bool ret = (result == WinVerifyTrustResult.Success || (allowInvalidRoot && result == WinVerifyTrustResult.UntrustedRoot));
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ private enum WinTrustDataUIChoice : uint
|
|
|
+ {
|
|
|
+ All = 1,
|
|
|
+ None = 2,
|
|
|
+ NoBad = 3,
|
|
|
+ NoGood = 4
|
|
|
+ }
|
|
|
+
|
|
|
+ private enum WinTrustDataRevocationChecks : uint
|
|
|
+ {
|
|
|
+ None = 0x00000000,
|
|
|
+ WholeChain = 0x00000001
|
|
|
+ }
|
|
|
+
|
|
|
+ private enum WinTrustDataChoice : uint
|
|
|
+ {
|
|
|
+ File = 1,
|
|
|
+ Catalog = 2,
|
|
|
+ Blob = 3,
|
|
|
+ Signer = 4,
|
|
|
+ Certificate = 5
|
|
|
+ }
|
|
|
+
|
|
|
+ private enum WinTrustDataStateAction : uint
|
|
|
+ {
|
|
|
+ Ignore = 0x00000000,
|
|
|
+ Verify = 0x00000001,
|
|
|
+ Close = 0x00000002,
|
|
|
+ AutoCache = 0x00000003,
|
|
|
+ AutoCacheFlush = 0x00000004
|
|
|
+ }
|
|
|
+
|
|
|
+ [Flags]
|
|
|
+ private 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
|
|
|
+ }
|
|
|
+
|
|
|
+ private enum WinTrustDataUIContext : uint
|
|
|
+ {
|
|
|
+ Execute = 0,
|
|
|
+ Install = 1
|
|
|
+ }
|
|
|
+
|
|
|
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
|
+ private 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);
|
|
|
+ }
|
|
|
+ ~WinTrustFileInfo()
|
|
|
+ {
|
|
|
+ Marshal.FreeCoTaskMem(pszFilePath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
|
+ private 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(String _fileName)
|
|
|
+ {
|
|
|
+ // 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 = new WinTrustFileInfo(_fileName);
|
|
|
+ FileInfoPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(WinTrustFileInfo)));
|
|
|
+ Marshal.StructureToPtr(wtfiData, FileInfoPtr, false);
|
|
|
+ }
|
|
|
+ ~WinTrustData()
|
|
|
+ {
|
|
|
+ Marshal.FreeCoTaskMem(FileInfoPtr);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private 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.
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|