- jsign, a java implementation
- signcode from the Mono project, as suggested by Mozilla. It's in the mono-devel ubuntu package.
- osslsigncode, an Openssl-based implementation of authenticode signing that uses curl to make the timestamp requests.
The Mozilla instructions are good for getting your keys and certs into a format that will work with these tools. Some minor additions to those below:
openssl pkcs12 -in authenticode.pfx -nocerts -nodes -out key.pem openssl rsa -in key.pem -outform PVK -pvk-strong -out authenticode.pvk openssl pkcs12 -in authenticode.pfx -nokeys -nodes -out cert.pem cat Thawte_Primary_Root_CA_Cross.cer >> cert.pem openssl crl2pkcs7 -nocrl -certfile cert.pem -outform DER -out authenticode.spc shred -u key.pemOnce you're done here you have authenticode.pvk with your encrypted private key, and authenticode.spc with your public certs. Appending the cross cert is necessary to make signature validation work with some tools. The windows GUI "Properties|Digital Signatures|Details" dialog will tell you "This digital signature is OK" but if you check with signtool verify on Windows, you'll find it isn't:
>"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\signtool.exe" verify /v /kp my.exe Verifying: my.exe [snip] SignTool Error: Signing Cert does not chain to a Microsoft Root Cert. Number of files successfully Verified: 0 Number of warnings: 0 Number of errors: 1I suspect the GUI uses the local cert store and/or APIs that automatically fetch the required cross cert, but signtool and 3rd-party signature verifiers do not. With the cross cert added to the spc as above it can be correctly verified and mentions the MS cross cert:
Z:\signing\windows>"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\signtool.exe" verify /v /kp my.exe Verifying: my.exe [snip] Cross Certificate Chain: Issued to: Microsoft Code Verification Root [snip] Successfully verified: my.exeIf you use Bit9 it's also worth checking that it will verify your binary using the dascli.exe tool:
>"C:\Program Files (x86)\Bit9\Parity Agent\DasCLI.exe" certinfo my.exe File[C:my.exe] Elapsed[630ms] CertValidated[Y] Detached[N] Publisher[My Inc] FileVerified[Y] [snip]So, back to signing on Linux. At first I tried installing mono and using "signcode". It claims to succeed:
$ signcode sign -spc authenticode.spc -v authenticode.pvk -a sha1 -$ commercial -n MyApp -t http://timestamp.verisign.com/scripts/timestamp.dll -tr 5 my.exe Mono SignCode - version 184.108.40.206 Sign assemblies and PE files using Authenticode(tm). Copyright 2002, 2003 Motus Technologies. Copyright 2004-2008 Novell. BSD licensed. Enter password for authenticode.pvk: MY_GODDAM_PASSWORD_IN_CLEARTEXT SuccessAnd in the process echoes your password in cleartext!?! This is something I was prepared to fix with a "read -s -p 'Password'" wrapper script like this guy, but the signature was no good. I could see it appended in a hexeditor but Windows didn't give me a Digital Signature tab in the GUI and signtool couldn't find it either:
>"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\signtool.exe" verify /v /kp my.exe Verifying: my.exe SignTool Error: No signature found. Number of files successfully Verified: 0 Number of warnings: 0 Number of errors: 1It's possible that there's something weird about our exe that caused this to fail. Someone else reported a similar problem but then later claimed it was due to a corrupted exe. In any case, not being particularly wedded to, or happy with, mono and signcode at this point I tried osslsigncode, which worked fine and produced a valid signature.
sudo apt-get install libcurl4-openssl-dev ./configure make sudo make install osslsigncode sign -certs authenticode.spc -key authenticode.pvk -n "MyApp" -t http://timestamp.verisign.com/scripts/timstamp.dll -in my.exe -out my_signed.exeUpdate: After coming across this mozilla post, I suspect my problem with mono's signcode was that signcode may not support 64 bit, but I didn't go back to check.