12

In my C#/.NET application I have to check if a given executable is digitally signed (preferably without Exception testing.)

Then I need to check if its certificate is valid (based on installed root certificates) and if the files content is valid for the signature.

There are so many classes in the BCL, I don't know where to start & what to use, and anything I've found so far doesn't eliminate my confusion...

I'd like to do something like this, without P/Invoke if possible:

bool IsSignedFile(string path);  
Cert GetCertificateFromSignedFile(string path);
bool IsValidCertificate(Cert cert)
Sig GetSignatureFromSignedFile(string path);
bool IsValidSignature(string path, Sig sig, Cert cert);  

Added clarification:

The big problem I currently have is that I don't find a way to obtain the signature of such a file in an easy way. Still hope there is a provided, managed, BCL solution as I would be surprised if exactly that part is missing. (For the certificate this can be done with just X509Certificate.CreateFromSignedFile, validating that is possible, too)
I'd prefer not mixing that 50% work done with P/Invoke code or a big different library.

I've found a AuthenticodeSignatureInformation class, no information about using that for a given executable though.

ordag
  • 2,497
  • 5
  • 26
  • 35
  • Possible duplicate of http://stackoverflow.com/questions/7622732/c-how-to-detect-tampering-of-authenticode-signed-file – DeCaf Oct 15 '11 at 20:13
  • I hope this won't be a duplicate of a not answered question ;) – ordag Oct 15 '11 at 20:17
  • The question linked to has three answers from what I can see. (None of them were accepted, but that's not to say they aren't relevant). There is another similar one at http://stackoverflow.com/questions/301024/validate-authenticode-signature-on-exe-c-without-capicom but everything points to the use of p/invoke being required unfortunately. – DeCaf Oct 15 '11 at 20:20
  • These answers are _"parse the output of some other tool"_ and _"use platform invoke"_. There is a huge [namespace](http://msdn.microsoft.com/library/system.security.cryptography.x509certificates.aspx) for that topic, worst case to not use something of it. – ordag Oct 15 '11 at 20:23
  • @ordag: Most solutions I've found use P/Invoke. May I ask why you don't want to? – Rob Oct 15 '11 at 20:24
  • @robjb It seems false to use it when there is so much about this topic available, just missing the guide how to use it. Also I may not be allowed to use P/Invoke in the developed application. – ordag Oct 15 '11 at 20:31

2 Answers2

8

You can do this using only managed code. The mono project has it's own signcode and chktrust tools that allows you to sign and verify Authenticode(tm) signatures.

Both use the Mono.Security.dll assembly, which works fine under Windows, and all the code is licensed under the MIT.X11 license (so you can pretty much do what you want with it).

However you'll need a bit of extra logic to check the root certificate, since Mono uses it's own stores - not the one on Windows. That should not be a big issue since .NET (since v2) provides classes that query/access the user/machine certificate stores.

Disclaimer: I wrote most of the code above ;-)

poupou
  • 43,413
  • 6
  • 77
  • 174
  • @poupou Can't figure out how to get anything but reason 6 using Mono.Security.dll. Even looking at the code, it should only get reason 6 if you call IsTrusted() or if there wasn't already a reason from verifying the signature after setting the FileName. Problem is, I know a file I'm testing has an invalid signature, yet it somehow passes all the first set of checks in CheckSignature() and ends up with a trusted root error anyway. Is this a bug in the signature checks? – BrutalDev May 03 '16 at 21:49
4

Determining if a file has a valid digital signature using PInvoke in case you don't find the managed solution

Haris Hasan
  • 29,856
  • 10
  • 92
  • 122