10
votes

How can i include the entire certification path when signing code using signtool?

Older versions of signtool would include the entire certification path in a digital signature. As it is now if i sign an executable with signtool:

signtool.exe" sign /v /f avatar.pfx -t "http://timestamp.verisign.com/scripts/timstamp.dll" app.exe

the signature is not valid:

enter image description here

This is because there is no certification path:

enter image description here

Binaries signed with the older version of signtool worked fine:

enter image description here

How do i tell signcode to include the entire certification path when signing?

What is the proper way to sign a binary?


Update: SignTool version 6.1.7600.16385:

enter image description here

See also

3

3 Answers

9
votes

Use /ac and pass the filename of the .cer in which your certificate is rooted (for Verisign it was called MSCV-VSClass3.cer last time I checked when signing kernel code or other special code).

signtool.exe sign /v /f "Avatar.pfx" 
      /ac "Thawte Code Signing CA - G2.cer" 
      -t "http://timestamp.verisign.com/scripts/timstamp.dll" app.exe

This should be given by your CA. Usually MS offers bundles for the various CAs it accepts within Windows.

See:

Either way, to my knowledge this is only required for kernel code and very specific other things (e.g. Windows Security Center).

2
votes

If you use Thawte then download their primaryca.cer.

Download to file primaryca.cer and sign your file with:

signtool sign /f certificate.pfx /p PASSWORD /ac primaryca.cer APP.exe.

Should work.

0
votes

The documentation for authenticode signing

  • Windows Authenticode Portable Executable Signature Format (.docx đź•—)

says that the PKCS #7 SignedData structure...

...contains the signer certificate and any intermediate certificates, but typically does not contain the root certificate.

However, as I discovered in a bit of a 'DOH!' moment, signtool.exe must be able to find the certificates to include them.

The leaf certificate is provided on the command line. But the identification of the remaining certificates up the chain does not include where to find the certificates. signtool does check the system certificate store, so if they are found there, they are added to the binary. If they are not found, signtool only puts the leaf certificate into the signed binary.

Note that if the intermediate certificates are not in the signed binary, but are in the system certificate store of the system checking the signature, the binary will still pass verification, because the chain can be resolved.

Also note that the exclusion of the root from the signed binary makes sense, given that the root must independently be on the system checking the signature for it to be trusted, so it would be ignored anyway. (The only real benefit to including the root in the binary would be if someone wanted to import the root cert manually, which is almost always a very bad idea.)