| 1 | /* |
|---|
| 2 | * $Id$ |
|---|
| 3 | * Copyright 2008 The Eraser Project |
|---|
| 4 | * Original Author: Joel Low <lowjoel@users.sourceforge.net> |
|---|
| 5 | * Modified By: |
|---|
| 6 | * |
|---|
| 7 | * This file is part of Eraser. |
|---|
| 8 | * |
|---|
| 9 | * Eraser is free software: you can redistribute it and/or modify it under the |
|---|
| 10 | * terms of the GNU General Public License as published by the Free Software |
|---|
| 11 | * Foundation, either version 3 of the License, or (at your option) any later |
|---|
| 12 | * version. |
|---|
| 13 | * |
|---|
| 14 | * Eraser is distributed in the hope that it will be useful, but WITHOUT ANY |
|---|
| 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR |
|---|
| 16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
|---|
| 17 | * |
|---|
| 18 | * A copy of the GNU General Public License can be found at |
|---|
| 19 | * <http://www.gnu.org/licenses/>. |
|---|
| 20 | */ |
|---|
| 21 | |
|---|
| 22 | using System; |
|---|
| 23 | using System.Collections.Generic; |
|---|
| 24 | using System.Text; |
|---|
| 25 | using System.Runtime.InteropServices; |
|---|
| 26 | using System.Windows.Forms; |
|---|
| 27 | |
|---|
| 28 | namespace Eraser.Util |
|---|
| 29 | { |
|---|
| 30 | public static class WintrustApi |
|---|
| 31 | { |
|---|
| 32 | /// <summary> |
|---|
| 33 | /// Verifies the Authenticode signature in a file. |
|---|
| 34 | /// </summary> |
|---|
| 35 | /// <param name="pathToFile">The file to verify.</param> |
|---|
| 36 | /// <returns>True if the file contains a valid Authenticode certificate.</returns> |
|---|
| 37 | public static bool VerifyAuthenticode(string pathToFile) |
|---|
| 38 | { |
|---|
| 39 | NativeMethods.WINTRUST_FILE_INFO fileinfo = new NativeMethods.WINTRUST_FILE_INFO(); |
|---|
| 40 | fileinfo.cbStruct = (uint)Marshal.SizeOf(typeof(NativeMethods.WINTRUST_FILE_INFO)); |
|---|
| 41 | fileinfo.pcwszFilePath = pathToFile; |
|---|
| 42 | |
|---|
| 43 | NativeMethods.WINTRUST_DATA data = new NativeMethods.WINTRUST_DATA(); |
|---|
| 44 | data.cbStruct = (uint)Marshal.SizeOf(typeof(NativeMethods.WINTRUST_DATA)); |
|---|
| 45 | data.dwUIChoice = NativeMethods.WINTRUST_DATA.UIChoices.WTD_UI_NONE; |
|---|
| 46 | data.fdwRevocationChecks = NativeMethods.WINTRUST_DATA.RevocationChecks.WTD_REVOKE_NONE; |
|---|
| 47 | data.dwUnionChoice = NativeMethods.WINTRUST_DATA.UnionChoices.WTD_CHOICE_FILE; |
|---|
| 48 | data.pUnion = Marshal.AllocHGlobal((int)fileinfo.cbStruct); |
|---|
| 49 | Marshal.StructureToPtr(fileinfo, data.pUnion, false); |
|---|
| 50 | |
|---|
| 51 | Guid guid = NativeMethods.WINTRUST_ACTION_GENERIC_VERIFY_V2; |
|---|
| 52 | int result = NativeMethods.WinVerifyTrust(IntPtr.Zero, ref guid, ref data); |
|---|
| 53 | Marshal.FreeHGlobal(data.pUnion); |
|---|
| 54 | return result == 0; |
|---|
| 55 | } |
|---|
| 56 | |
|---|
| 57 | internal static class NativeMethods |
|---|
| 58 | { |
|---|
| 59 | /// <summary> |
|---|
| 60 | /// The WinVerifyTrust function performs a trust verification action on a |
|---|
| 61 | /// specified object. The function passes the inquiry to a trust provider |
|---|
| 62 | /// that supports the action identifier, if one exists. |
|---|
| 63 | /// |
|---|
| 64 | /// For certificate verification, use the CertGetCertificateChain and |
|---|
| 65 | /// CertVerifyCertificateChainPolicy functions. |
|---|
| 66 | /// </summary> |
|---|
| 67 | /// <param name="hWnd">Handle to a caller window. A trust provider can use |
|---|
| 68 | /// this value to determine whether it can interact with the user. However, |
|---|
| 69 | /// trust providers typically perform verification actions with input from |
|---|
| 70 | /// the user. |
|---|
| 71 | /// |
|---|
| 72 | /// This parameter can be one of the following values. |
|---|
| 73 | /// Value Meaning |
|---|
| 74 | /// INVALID_HANDLE_VALUE There is no interactive user. The trust provider |
|---|
| 75 | /// performs the verification action without the |
|---|
| 76 | /// user's assistance. |
|---|
| 77 | /// Zero The trust provider can use the interactive desktop |
|---|
| 78 | /// to display its user interface. |
|---|
| 79 | /// A valid window handle A trust provider can treat any value other than |
|---|
| 80 | /// INVALID_HANDLE_VALUE or zero as a valid window |
|---|
| 81 | /// handle that it can use to interact with the user.</param> |
|---|
| 82 | /// <param name="pgActionID">A pointer to a GUID structure that identifies an |
|---|
| 83 | /// action and the trust provider that supports that action. This value indicates |
|---|
| 84 | /// the type of verification action to be performed on the structure pointed to |
|---|
| 85 | /// by pWinTrustData. |
|---|
| 86 | /// |
|---|
| 87 | /// The WinTrust service is designed to work with trust providers implemented |
|---|
| 88 | /// by third parties. Each trust provider provides its own unique set of action |
|---|
| 89 | /// identifiers. For information about the action identifiers supported by a |
|---|
| 90 | /// trust provider, see the documentation for that trust provider. |
|---|
| 91 | /// |
|---|
| 92 | /// or example, Microsoft provides a Software Publisher Trust Provider that can |
|---|
| 93 | /// establish the trustworthiness of software being downloaded from the Internet |
|---|
| 94 | /// or some other public network. The Software Publisher Trust Provider supports |
|---|
| 95 | /// the following action identifiers. These constants are defined in Softpub.h.</param> |
|---|
| 96 | /// <param name="pWVTData">A pointer that, when cast as a WINTRUST_DATA structure, |
|---|
| 97 | /// contains information that the trust provider needs to process the specified |
|---|
| 98 | /// action identifier. Typically, the structure includes information that |
|---|
| 99 | /// identifies the object that the trust provider must evaluate. |
|---|
| 100 | /// |
|---|
| 101 | /// The format of the structure depends on the action identifier. For information |
|---|
| 102 | /// about the data required for a specific action identifier, see the documentation |
|---|
| 103 | /// for the trust provider that supports that action.</param> |
|---|
| 104 | /// <returns>If the trust provider verifies that the subject is trusted for the |
|---|
| 105 | /// specified action, the return value is zero. No other value besides zero |
|---|
| 106 | /// should be considered a successful return. |
|---|
| 107 | /// |
|---|
| 108 | /// If the trust provider does not verify that the subject is trusted for the |
|---|
| 109 | /// specified action, the function returns a status code from the trust provider. |
|---|
| 110 | /// |
|---|
| 111 | /// For example, a trust provider might indicate that the subject is not trusted, |
|---|
| 112 | /// or is trusted but with limitations or warnings. The return value can be a |
|---|
| 113 | /// trust-provider-specific value described in the documentation for an individual |
|---|
| 114 | /// trust provider, or it can be one of the following error codes. |
|---|
| 115 | /// |
|---|
| 116 | /// Return code Description |
|---|
| 117 | /// TRUST_E_SUBJECT_NOT_TRUSTED The subject failed the specified verification |
|---|
| 118 | /// action. Most trust providers return a more |
|---|
| 119 | /// detailed error code that describes the reason |
|---|
| 120 | /// for the failure. |
|---|
| 121 | /// TRUST_E_PROVIDER_UNKNOWN The trust provider is not recognized on this |
|---|
| 122 | /// system. |
|---|
| 123 | /// TRUST_E_ACTION_UNKNOWN The trust provider does not support the |
|---|
| 124 | /// specified action. |
|---|
| 125 | /// TRUST_E_SUBJECT_FORM_UNKNOWN The trust provider does not support the form |
|---|
| 126 | /// specified for the subject.</returns> |
|---|
| 127 | [DllImport("Wintrust.dll", CharSet = CharSet.Unicode)] |
|---|
| 128 | public static extern int WinVerifyTrust(IntPtr hWnd, ref Guid pgActionID, |
|---|
| 129 | ref WINTRUST_DATA pWVTData); |
|---|
| 130 | |
|---|
| 131 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] |
|---|
| 132 | public struct WINTRUST_FILE_INFO |
|---|
| 133 | { |
|---|
| 134 | public uint cbStruct; // = sizeof(WINTRUST_FILE_INFO) |
|---|
| 135 | public string pcwszFilePath; // required, file name to be verified |
|---|
| 136 | public IntPtr hFile; // optional, open handle to pcwszFilePath |
|---|
| 137 | public IntPtr pgKnownSubject; // optional: fill if the subject type is known. |
|---|
| 138 | } |
|---|
| 139 | |
|---|
| 140 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] |
|---|
| 141 | public struct WINTRUST_DATA |
|---|
| 142 | { |
|---|
| 143 | public uint cbStruct; // = sizeof(WINTRUST_DATA) |
|---|
| 144 | |
|---|
| 145 | public IntPtr pPolicyCallbackData; // optional: used to pass data between the app and policy |
|---|
| 146 | public IntPtr pSIPClientData; // optional: used to pass data between the app and SIP. |
|---|
| 147 | public UIChoices dwUIChoice; // required: UI choice. One of the following. |
|---|
| 148 | public RevocationChecks fdwRevocationChecks;// required: certificate revocation check options |
|---|
| 149 | public UnionChoices dwUnionChoice; // required: which structure is being passed in? |
|---|
| 150 | |
|---|
| 151 | public IntPtr pUnion; |
|---|
| 152 | |
|---|
| 153 | public StateActions dwStateAction; // optional (Catalog File Processing) |
|---|
| 154 | public IntPtr hWVTStateData; // optional (Catalog File Processing) |
|---|
| 155 | private string pwszURLReference; // optional: (future) used to determine zone. |
|---|
| 156 | public ProviderFlags dwProvFlags; |
|---|
| 157 | public UIContexts dwUIContext; |
|---|
| 158 | |
|---|
| 159 | public enum UIChoices : uint |
|---|
| 160 | { |
|---|
| 161 | WTD_UI_ALL = 1, |
|---|
| 162 | WTD_UI_NONE = 2, |
|---|
| 163 | WTD_UI_NOBAD = 3, |
|---|
| 164 | WTD_UI_NOGOOD = 4, |
|---|
| 165 | } |
|---|
| 166 | public enum RevocationChecks : uint |
|---|
| 167 | { |
|---|
| 168 | WTD_REVOKE_NONE = 0x00000000, |
|---|
| 169 | WTD_REVOKE_WHOLECHAIN = 0x00000001 |
|---|
| 170 | } |
|---|
| 171 | public enum UnionChoices : uint |
|---|
| 172 | { |
|---|
| 173 | WTD_CHOICE_FILE = 1, |
|---|
| 174 | WTD_CHOICE_CATALOG = 2, |
|---|
| 175 | WTD_CHOICE_BLOB = 3, |
|---|
| 176 | WTD_CHOICE_SIGNER = 4, |
|---|
| 177 | WTD_CHOICE_CERT = 5 |
|---|
| 178 | } |
|---|
| 179 | |
|---|
| 180 | public enum StateActions : uint |
|---|
| 181 | { |
|---|
| 182 | WTD_STATEACTION_IGNORE = 0x00000000, |
|---|
| 183 | WTD_STATEACTION_VERIFY = 0x00000001, |
|---|
| 184 | WTD_STATEACTION_CLOSE = 0x00000002, |
|---|
| 185 | WTD_STATEACTION_AUTO_CACHE = 0x00000003, |
|---|
| 186 | WTD_STATEACTION_AUTO_CACHE_FLUSH = 0x00000004 |
|---|
| 187 | } |
|---|
| 188 | public enum ProviderFlags : uint |
|---|
| 189 | { |
|---|
| 190 | WTD_PROV_FLAGS_MASK = 0x0000FFFF, |
|---|
| 191 | WTD_USE_IE4_TRUST_FLAG = 0x00000001, |
|---|
| 192 | WTD_NO_IE4_CHAIN_FLAG = 0x00000002, |
|---|
| 193 | WTD_NO_POLICY_USAGE_FLAG = 0x00000004, |
|---|
| 194 | WTD_REVOCATION_CHECK_NONE = 0x00000010, |
|---|
| 195 | WTD_REVOCATION_CHECK_END_CERT = 0x00000020, |
|---|
| 196 | WTD_REVOCATION_CHECK_CHAIN = 0x00000040, |
|---|
| 197 | WTD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x00000080, |
|---|
| 198 | WTD_SAFER_FLAG = 0x00000100, |
|---|
| 199 | WTD_HASH_ONLY_FLAG = 0x00000200, |
|---|
| 200 | WTD_USE_DEFAULT_OSVER_CHECK = 0x00000400, |
|---|
| 201 | WTD_LIFETIME_SIGNING_FLAG = 0x00000800, |
|---|
| 202 | WTD_CACHE_ONLY_URL_RETRIEVAL = 0x00001000 |
|---|
| 203 | } |
|---|
| 204 | public enum UIContexts |
|---|
| 205 | { |
|---|
| 206 | WTD_UICONTEXT_EXECUTE = 0, |
|---|
| 207 | WTD_UICONTEXT_INSTALL = 1 |
|---|
| 208 | } |
|---|
| 209 | } |
|---|
| 210 | |
|---|
| 211 | public static readonly Guid WINTRUST_ACTION_GENERIC_VERIFY_V2 = new Guid(0xaac56b, |
|---|
| 212 | unchecked((short)0xcd44), 0x11d0, new byte[] { 0x8c, 0xc2, 0x0, 0xc0, 0x4f, 0xc2, 0x95, 0xee }); |
|---|
| 213 | } |
|---|
| 214 | } |
|---|
| 215 | } |
|---|