9

In my application I need to verify whether it's signed or not. If it's signed continue the execution and exit the application if not. The signtool will be used to sign the application. Is there any C# code to do that?

Robaticus
  • 22,857
  • 5
  • 54
  • 63
Anas EL HAJJAJI
  • 1,048
  • 2
  • 10
  • 22

4 Answers4

6

Here is a utility method that does it:

var signed = IsSigned(@"c:\windows\explorer.exe");
...
public static bool IsSigned(string filePath)
{
    if (filePath == null)
        throw new ArgumentNullException(nameof(filePath));

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

    var data = new WINTRUST_DATA();
    data.cbStruct = Marshal.SizeOf(typeof(WINTRUST_DATA));
    data.dwUIChoice = WTD_UI_NONE;
    data.dwUnionChoice = WTD_CHOICE_FILE;
    data.fdwRevocationChecks = WTD_REVOKE_NONE;
    data.pFile = Marshal.AllocHGlobal(file.cbStruct);
    Marshal.StructureToPtr(file, data.pFile, false);

    int hr;
    try
    {
        hr = WinVerifyTrust(INVALID_HANDLE_VALUE, WINTRUST_ACTION_GENERIC_VERIFY_V2, ref data);
    }
    finally
    {
        Marshal.FreeHGlobal(data.pFile);
    }
    return hr == 0;
}

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct WINTRUST_FILE_INFO
{
    public int cbStruct;
    public string pcwszFilePath;
    public IntPtr hFile;
    public IntPtr pgKnownSubject;
}

[StructLayoutAttribute(LayoutKind.Sequential)]
private struct WINTRUST_DATA
{
    public int cbStruct;
    public IntPtr pPolicyCallbackData;
    public IntPtr pSIPClientData;
    public int dwUIChoice;
    public int fdwRevocationChecks;
    public int dwUnionChoice;
    public IntPtr pFile;
    public int dwStateAction;
    public IntPtr hWVTStateData;
    public IntPtr pwszURLReference;
    public int dwProvFlags;
    public int dwUIContext;
    public IntPtr pSignatureSettings;
}

private const int WTD_UI_NONE = 2;
private const int WTD_REVOKE_NONE = 0;
private const int WTD_CHOICE_FILE = 1;
private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
private static readonly Guid WINTRUST_ACTION_GENERIC_VERIFY_V2 = new Guid("{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}");

[DllImport("wintrust.dll")]
private static extern int WinVerifyTrust(IntPtr hwnd, [MarshalAs(UnmanagedType.LPStruct)] Guid pgActionID, ref WINTRUST_DATA pWVTData);
Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • 1
    It's very complicated as a solution, I need just a true or false : exe signed, exe not signed – Anas EL HAJJAJI Dec 03 '10 at 13:51
  • 1
    I don't think you have much choice. Authenticode check is not that easy. Just copy paste the code and call the last function: internal static uint WinVerifyTrust(string fileName). A returned 0 means it's signed. – Simon Mourier Dec 03 '10 at 13:55
  • 1
    @Anaseh as Simon pointed, signature validation is more than just true or false. You need to determine presence of signature, it's validity, then validity of the certificate used to make a signature, validity of the timestamp and certificate used to sign a timestamp. – Eugene Mayevski 'Callback Dec 03 '10 at 14:26
2
    Try
        Dim objCertificate As New Security.Cryptography.X509Certificates.X509Certificate2(Security.Cryptography.X509Certificates.X509Certificate.CreateFromSignedFile(strFile))
        Return True

    Catch ex As Exception
        Return False
    End Try
bmolsbeck
  • 51
  • 5
0
   private bool IsAssemblySigned()
    {
        var assembly = Assembly.GetAssembly(GetType());

        var assemblyName = assembly.GetName();
        var key = assemblyName.GetPublicKey();
        return key.Length > 0;
    }
jvanrhyn
  • 2,804
  • 19
  • 14
  • Beat me to it, I was going to suggest AssemblyName.GetPublicKey() http://msdn.microsoft.com/en-us/library/system.reflection.assemblyname.getpublickey%28VS.80%29.aspx – pstrjds Dec 03 '10 at 13:39
  • Thank you for your answer, but this solution won't work because I'm not using Assembly signature, I'm using signtool to sign the application – Anas EL HAJJAJI Dec 03 '10 at 13:40
  • 1
    yeas, signtool creates Authenticode signature, not to be confused with .NET strong name key signature. See my answer below. – Simon Mourier Dec 03 '10 at 13:56
0

I would suggest you use the 'CryptUIWizDigitalSign' API. This link can be used as a reference.

Prasanna K Rao
  • 1,086
  • 2
  • 8
  • 18