I am trying to write some code to verify that a digitally signed file came from my company.
I was horrified to stumble across this deeply buried answer on Stack Overflow, an out-of-left-field possibility I had not considered and had certainly not coded for: https://stackoverflow.com/a/46770722
[I]t's possible for Authenticode to have multiple signatures. ...
WinVerifyTrust will tell you the file is valid if any of the signatures are valid and come from a trusted certificate chain. However it won't tell you which of the signatures was valid. ...
If you're using the details of the primary signature to validate that the certificate is one your software trusts, you're vulnerable to a situation where WinVerifyTrust is trusting a secondary signature, but your code is checking the primary signature's certificate is what you expected, and you haven't noticed that the signature from the primary certificate is nonsense. An attacker could use your public certificate without owning its private key, combined with some other code-signing certificate issued to someone else, to bypass a publisher check this way.
I really could not believe how poorly documented (and designed) this is.
So, what are all the possibilities people need to consider and should test their apps against (or even better, an equivalent of BadSSL.com for Authenticode would be amazing). So far I have:
Trusted (Standard Validation) Trusted (Extended Validation) Trusted (Unicode characters in certificate e.g. company name) Trusted (Expired certificate with external timestamp made within validity of certificate) Trusted (Self-signed certificate manually added to Trusted list) Trusted (Weak hash) Trusted (WHQL verified) Untrusted (No certificate) Untrusted (Certificate revoked) Untrusted (Certificate expired and not timestamped) Untrusted (Certificate expired and timestamped outside of validity period of certificate) Untrusted (Certificate expired and timestamped by a non-trusted authority) Untrusted (File Contents tampered with) Untrusted (Self-signed, not trusted) Untrusted (Insufficiently long key) Untrusted (Certificate is issued in the same company name, by a Trusted CA, but company is registered in another country and is not your real company) Untrusted (Malicious use of multiple certificates, some of which are invalid) Other (Computer clock is wrong)
Are there any more possibilities to consider?