1

I am developing a library distributed as a Windows DLL to be called by 3rd party executables. I expect the calling EXE to be digitally signed and need to verify that.

I have no control over the computer on which my code will run. How do I validate if the calling executable is signed by a trusted, well-known CA such as Verisign or Symantec at the top of the certificate chain? I need to do this offline.

I have considered the following:

  1. Look for the strings "Verisign" and "Symantec" in the certificate subject.
  2. Compare certificate serial nos. against a list of serial nos. known to be valid.
  3. Compare certificate thumbprint against a list of known thumbprints.

However, I know that 1 and 2 can be spoofed. About 3, I am not sure about spoofing but how reliable is it when considering expiry and revocation?

2

First, you need to ask Windows to validate the signature on the EXE. Your DLL can do this using the WinVerifyTrust() API, and Microsoft provide example code for doing this here.

That will tell you that the Windows you're running on is happy with the signature on the EXE. A maliciously configured machine could have an EXE signed with a self-issued certificate that had been installed on the machine, so this doesn't fulfil all your requirements, but it does it least force the opponent to do his job thoroughly.

Then, to check on the certificates, use CertGetCertificateChain(), followed by CertVerifyCertificateChainPolicy(). You can ask these functions to check for revocation, and do several other kinds of check: it's worth reading their documentation closely. There's an example program here.

Through these APIs, you can get the CERT_INFO structures for the certificates in the appropriate chain, and can check those however you like.

If you know which certificates could have been used to make valid signatures, the strongest check is to get the public keys from the certificates in the chain and check them against the public keys of the known certificates.

There is a counter to this check, if the opponent is smart, which is to edit your DLL to change the public keys stored in it to the ones the opponent is using. So you have to hide those public keys, by encrypting them, spreading their bits out over a larger piece of data, or similar tricks. Most software copy-protection comes down to trying to hide data from an opponent while still making use of it, and this is no exception. A sufficiently persistent opponent will always win this battle; your task is to make it sufficiently difficult that they give up before solving the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.