public WinVerifyTrustResult GetSign(string filePath)
        {
            var result = new WinVerifyTrustResult();

            var file = new WINTRUST_FILE_INFO
            {
                cbStruct      = Marshal.SizeOf(typeof(WINTRUST_FILE_INFO)),
                pcwszFilePath = filePath
            };

            var data = new WINTRUST_DATA
            {
                cbStruct            = Marshal.SizeOf(typeof(WINTRUST_DATA)),
                dwUIChoice          = NativeMethods.WTD_UI_NONE,
                dwUnionChoice       = NativeMethods.WTD_CHOICE_FILE,
                fdwRevocationChecks = NativeMethods.WTD_REVOKE_NONE,
                dwStateAction       = NativeMethods.WTD_STATEACTION_VERIFY,
                pFile = Marshal.AllocHGlobal(file.cbStruct)
            };

            Marshal.StructureToPtr(file, data.pFile, false);

            try
            {
                var hr = NativeMethods.WinVerifyTrust(NativeMethods.INVALID_HANDLE_VALUE, NativeMethods.WINTRUST_ACTION_GENERIC_VERIFY_V2, ref data);

                result.HasSign     = (hr == NativeMethods.TRUST_SUCCESS || hr == NativeMethods.TRUST_E_BAD_DIGEST);
                result.IsSignValid = hr == NativeMethods.TRUST_SUCCESS;

                if (result.HasSign)
                {
                    IntPtr ptrProvData = NativeMethods.WTHelperProvDataFromStateData(data.hWVTStateData);
                    var    lastError   = Marshal.GetLastWin32Error();

                    if (ptrProvData == IntPtr.Zero && result.IsSignValid)
                    {
                        throw new Win32Exception(lastError);
                    }

                    IntPtr ptrProvSigner = NativeMethods.WTHelperGetProvSignerFromChain(ptrProvData, 0, false, 0);
                    lastError = Marshal.GetLastWin32Error();

                    if (ptrProvSigner == IntPtr.Zero)
                    {
                        throw new Win32Exception(lastError);
                    }

                    IntPtr ptrCert = NativeMethods.WTHelperGetProvCertFromChain(ptrProvSigner, 0);
                    lastError = Marshal.GetLastWin32Error();

                    if (ptrCert == IntPtr.Zero)
                    {
                        throw new Win32Exception(lastError);
                    }

                    CRYPT_PROVIDER_CERT cert = (CRYPT_PROVIDER_CERT)Marshal.PtrToStructure(ptrCert, typeof(CRYPT_PROVIDER_CERT));

                    using (X509Certificate2 certificate = new X509Certificate2(cert.pCert))
                    {
                        result.Publisher = GetPublisherName(certificate.Subject);
                    }
                }
            }
            finally
            {
                data.dwStateAction = NativeMethods.WTD_STATEACTION_CLOSE;

                NativeMethods.WinVerifyTrust(NativeMethods.INVALID_HANDLE_VALUE, NativeMethods.WINTRUST_ACTION_GENERIC_VERIFY_V2, ref data);

                Marshal.FreeHGlobal(data.pFile);
            }
            return(result);
        }
Beispiel #2
0
        internal static void Main(string[] args)
        {
            string fileName = args[0];
            IntPtr hWind    = IntPtr.Zero;
            Guid   WINTRUST_ACTION_GENERIC_VERIFY_V2 = new Guid("{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}");

            byte[] actionIdBytes = WINTRUST_ACTION_GENERIC_VERIFY_V2.ToByteArray();
            IntPtr pcwszFilePath = Marshal.StringToHGlobalAuto(fileName);

            try
            {
                WINTRUST_FILE_INFO File = new WINTRUST_FILE_INFO()
                {
                    cbStruct       = Marshal.SizeOf(typeof(WINTRUST_FILE_INFO)),
                    pcwszFilePath  = pcwszFilePath,
                    hFile          = IntPtr.Zero,
                    pgKnownSubject = IntPtr.Zero,
                };
                IntPtr ptrFile = Marshal.AllocHGlobal(File.cbStruct);
                try
                {
                    Marshal.StructureToPtr(File, ptrFile, false);
                    WINTRUST_DATA WVTData = new WINTRUST_DATA()
                    {
                        cbStruct            = Marshal.SizeOf(typeof(WINTRUST_DATA)),
                        pPolicyCallbackData = IntPtr.Zero,
                        pSIPClientData      = IntPtr.Zero,
                        dwUIChoice          = WTD_UI_NONE,
                        fdwRevocationChecks = WTD_REVOKE_NONE,
                        dwUnionChoice       = WTD_CHOICE_FILE,
                        pFile              = ptrFile,
                        dwStateAction      = WTD_STATEACTION_IGNORE,
                        hWVTStateData      = IntPtr.Zero,
                        pwszURLReference   = IntPtr.Zero,
                        dwProvFlags        = WTD_REVOCATION_CHECK_NONE,
                        dwUIContext        = WTD_UICONTEXT_EXECUTE,
                        pSignatureSettings = IntPtr.Zero,
                    };
                    // N.B. Use of this member is only supported on Windows 8 and Windows Server 2012 (and later)
                    WINTRUST_SIGNATURE_SETTINGS signatureSettings = default(WINTRUST_SIGNATURE_SETTINGS);
                    bool   canUseSignatureSettings = Environment.OSVersion.Version > new Version(6, 2, 0, 0);
                    IntPtr pSignatureSettings      = IntPtr.Zero;
                    if (canUseSignatureSettings)
                    {
                        // Setup WINTRUST_SIGNATURE_SETTINGS to get the number of signatures in the file
                        signatureSettings = new WINTRUST_SIGNATURE_SETTINGS()
                        {
                            cbStruct           = Marshal.SizeOf(typeof(WINTRUST_SIGNATURE_SETTINGS)),
                            dwIndex            = 0,
                            dwFlags            = WSS_GET_SECONDARY_SIG_COUNT,
                            cSecondarySigs     = 0,
                            dwVerifiedSigIndex = 0,
                            pCryptoPolicy      = IntPtr.Zero,
                        };
                        pSignatureSettings = Marshal.AllocHGlobal(signatureSettings.cbStruct);
                    }
                    try
                    {
                        if (pSignatureSettings != IntPtr.Zero)
                        {
                            Marshal.StructureToPtr(signatureSettings, pSignatureSettings, false);
                            WVTData.pSignatureSettings = pSignatureSettings;
                        }
                        IntPtr pgActionID = Marshal.AllocHGlobal(actionIdBytes.Length);
                        try
                        {
                            Marshal.Copy(actionIdBytes, 0, pgActionID, actionIdBytes.Length);
                            IntPtr pWVTData = Marshal.AllocHGlobal(WVTData.cbStruct);
                            try
                            {
                                Marshal.StructureToPtr(WVTData, pWVTData, false);
                                int hRESULT = WinVerifyTrust(hWind, pgActionID, pWVTData);
                                if (hRESULT == 0)
                                {
                                    if (pSignatureSettings != IntPtr.Zero)
                                    {
                                        // Read back the signature settings
                                        signatureSettings = (WINTRUST_SIGNATURE_SETTINGS)Marshal.PtrToStructure(pSignatureSettings, typeof(WINTRUST_SIGNATURE_SETTINGS));
                                    }
                                    int signatureCount = signatureSettings.cSecondarySigs + 1;
                                    Console.WriteLine("File: {0}", fileName);
                                    Console.WriteLine("Authenticode signatures: {0}", signatureCount);
                                    Console.WriteLine();
                                    for (int dwIndex = 0; dwIndex < signatureCount; dwIndex++)
                                    {
                                        if (pSignatureSettings != IntPtr.Zero)
                                        {
                                            signatureSettings.dwIndex = dwIndex;
                                            signatureSettings.dwFlags = WSS_VERIFY_SPECIFIC;
                                            Marshal.StructureToPtr(signatureSettings, pSignatureSettings, false);
                                        }
                                        WVTData.dwStateAction = WTD_STATEACTION_VERIFY;
                                        WVTData.hWVTStateData = IntPtr.Zero;
                                        Marshal.StructureToPtr(WVTData, pWVTData, false);
                                        hRESULT = WinVerifyTrust(hWind, pgActionID, pWVTData);
                                        try
                                        {
                                            if (hRESULT == 0)
                                            {
                                                WVTData = (WINTRUST_DATA)Marshal.PtrToStructure(pWVTData, typeof(WINTRUST_DATA));
                                                IntPtr ptrProvData           = WTHelperProvDataFromStateData(WVTData.hWVTStateData);
                                                CRYPT_PROVIDER_DATA provData = (CRYPT_PROVIDER_DATA)Marshal.PtrToStructure(ptrProvData, typeof(CRYPT_PROVIDER_DATA));
                                                for (int idxSigner = 0; idxSigner < provData.csSigners; idxSigner++)
                                                {
                                                    IntPtr ptrProvSigner           = WTHelperGetProvSignerFromChain(ptrProvData, idxSigner, false, 0);
                                                    CRYPT_PROVIDER_SGNR ProvSigner = (CRYPT_PROVIDER_SGNR)Marshal.PtrToStructure(ptrProvSigner, typeof(CRYPT_PROVIDER_SGNR));
                                                    CMSG_SIGNER_INFO    Signer     = (CMSG_SIGNER_INFO)Marshal.PtrToStructure(ProvSigner.psSigner, typeof(CMSG_SIGNER_INFO));
                                                    if (Signer.HashAlgorithm.pszObjId != IntPtr.Zero)
                                                    {
                                                        string objId = Marshal.PtrToStringAnsi(Signer.HashAlgorithm.pszObjId);
                                                        if (objId != null)
                                                        {
                                                            Oid hashOid = Oid.FromOidValue(objId, OidGroup.All);
                                                            if (hashOid != null)
                                                            {
                                                                Console.WriteLine("Hash algorithm of signature {0}: {1}.", dwIndex + 1, hashOid.FriendlyName);
                                                            }
                                                        }
                                                    }
                                                    IntPtr ptrCert           = WTHelperGetProvCertFromChain(ptrProvSigner, idxSigner);
                                                    CRYPT_PROVIDER_CERT cert = (CRYPT_PROVIDER_CERT)Marshal.PtrToStructure(ptrCert, typeof(CRYPT_PROVIDER_CERT));
                                                    if (cert.cbStruct > 0)
                                                    {
                                                        X509Certificate2 certificate = new X509Certificate2(cert.pCert);
                                                        Console.WriteLine("Certificate thumbprint of signature {0}: {1}", dwIndex + 1, certificate.Thumbprint);
                                                    }
                                                    if (ProvSigner.sftVerifyAsOf.dwHighDateTime != provData.sftSystemTime.dwHighDateTime &&
                                                        ProvSigner.sftVerifyAsOf.dwLowDateTime != provData.sftSystemTime.dwLowDateTime)
                                                    {
                                                        DateTime timestamp = DateTime.FromFileTimeUtc(((long)ProvSigner.sftVerifyAsOf.dwHighDateTime << 32) | (uint)ProvSigner.sftVerifyAsOf.dwLowDateTime);
                                                        Console.WriteLine("Timestamp of signature {0}: {1}", dwIndex + 1, timestamp);
                                                    }
                                                }
                                            }
                                        }
                                        finally
                                        {
                                            WVTData.dwStateAction = WTD_STATEACTION_CLOSE;
                                            Marshal.StructureToPtr(WVTData, pWVTData, false);
                                            hRESULT = WinVerifyTrust(hWind, pgActionID, pWVTData);
                                        }
                                        Console.WriteLine();
                                    }
                                }
                                else if ((uint)hRESULT == 0x800b0100)
                                {
                                    Console.WriteLine("{0} has no Authenticode signatures.", fileName);
                                }
                            }
                            finally
                            {
                                Marshal.FreeHGlobal(pWVTData);
                            }
                        }
                        finally
                        {
                            Marshal.FreeHGlobal(pgActionID);
                        }
                    }
                    finally
                    {
                        if (pSignatureSettings != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(pSignatureSettings);
                        }
                    }
                }
                finally
                {
                    Marshal.FreeHGlobal(ptrFile);
                }
            }
            finally
            {
                Marshal.FreeHGlobal(pcwszFilePath);
            }
            Console.WriteLine("Press enter to exit.");
            Console.ReadLine();
        }