Signing launchers and installers

Wednesday, April 22, 2009 | Posted by

  Since the release of Vista, code signing has been of growing interest for our users, mainly because a signed installer or launcher produces nicer and less UAC dialogs when it wants to elevate its privileges.

install4j provides a signing hook for all generated windows executables. On step 5 of the Windows Media Wizard, you can specify any external tool with the executable files as parameter. The signing tool will be called with the working directory set to the project file parent directory so you can specify keys and certificates relatively. You can use the $EXECTUABLE variable to refer to the launcher or installer and an $OUTFILE variable if the tool you use requires different in and out files.

I will explain below what tools you can use to sign your executables, but first, you would need a Microsoft Authenticode Certificate from a certificate authority like Thawte:

https://www.thawte.com/code-signing/index.html

In their order process, they will generate a private key (PVK) file and a certificate request. After Thawte verified your identify, they will provide you a SPC file that contains your certificate. There are a bunch of other certificate authorities, most notably verisign where the process is quite similar.

Code signing on Windows

On Windows, you can quite easily use Microsoft's tools like signcode or signtool which are contained in the freely available Platform and .Net SDKs. You can find the documentation in the MSDN:

http://msdn.microsoft.com/de-de/library/9sh96ycy%28VS.80%29.aspx

Below is a good summary of how to use signtool:

http://www.curlybrace.com/words/2008/09/12/using-certificates-and-signtool/

It also explains how to convert different file formats that other certificate authorities might issue.

Code signing on other platforms with Mono's signcode

It is also possible to sign executables on other platforms. The $INSTALL4J_HOME/resource/signcode.exe executable is a mono executable modified by ej-technologies to support signing of 64-bit executables. This executable can only be executed if mono is installed. Mono is available for a number of platforms and can be downloaded free of charge.
The tool has the same syntax as the one from Microsoft. A typical entry would be mono /opt/install4j/resource/signcode.exe -spc mycert.spc -v mykey.pvk -vp password -t http://timestamp.verisign.com/scripts/timstamp.dll $EXECUTABLE
Some SPC files cannot be read directly by this tool. If this is the case for your certificate, you can export all CER files from the SPC file and generate a new SPC file with the cert2spc tool included with mono. You have to add the CER files in the order of the certificate chain (your own certificate is the last one on the command line).
Code signing on other platforms with openssl and osslsigncode
If you want to avoid installing mono or have problems with your SPC file, you can also use a different tool called osslsigncode in conjunction with openssl. Here is a download with a patch for signing PE32+ (Windows x64) executables. A short ./configure && make should be sufficient when you have curl and openssl installed.
This tool requires the private key in a different form, though. First, you would have to convert your PVK file to a PEM file with this tool on Windows. A typical command line would be simply pvk -in mykey.pvk -out mykey.pem. The upcoming openssl 1.0 will also be able to do this conversion.
The PEM file is still encrypted, but osslsigncode needs an unencrypted DER file. You might want to generate this DER file directly before your build process and delete it afterwards to avoid having your private key hanging around unencrypted longer than necessary. The conversion to a DER file is done with openssl rsa -passin pass:XXXXX -outform der -in mykey.pem -out mykey.der.
A typcial command line in install4j would then be osslsigncode -spc mycert.spc -key mykey.der -t http://timestamp.verisign.com/scripts/timstamp.dll -in $EXECUTABLE -out $OUTFILE. Remember that the spc and key files can be specified relatively to your install4j project file.
-------
Update: As of install4j 5.1, code signing is implemented directly and the above mentioned tools are no longer required.

12 comments

  1. Is it possible to use osslsigncode with a cross-certificate from Microsoft (.cer) in addition to a 3rd party cert (.spc & .pvk) ?

    ReplyDelete
  2. I assume that works, too. Actually, cer and spc are both X.509 certificates. You can for example convert the cer to the spc format on a Windows machine. Just import it into your certificate store and export it as as p7b file (which is identical to a spc file).

    The problem is rather that you definitely need the private key (the pvk file). Sometimes it is not possible to export that from a Windows machine.

    If you did not save your private key during the certification process, you could ask your CA to reissue your certificate. Thawte for example does this for free. (rather don't do this if you already have signed stuff with this certificate deployed, though).

    ReplyDelete
  3. I tried osslsigncode and signcode (from Mono) with same certificates and keys (except for converted pvk into der for osslsigncode) on the same exe. And then I looked the properties of the files in Windows XP. And it turned out that ossl-signed file didn't contain valid signature yet in the properties it did have certificate info, but the summary in the properties said (next to the file icon on additional properties tab) that the file didn't have a signature. The product of signcode was ok though. So, the file properties looked identical except for this summary... However I tried to find the solution, there was no even a hint of my problem in search results. So, I cannot figure out what is the problem of such a difference? Both tools use Authenticode format and I used the latest versions of them, etc. Please light my search path :)

    ReplyDelete
  4. Unfortunately, we don't know that either. We are also only users of these tools.

    It might be a bug that is triggered by your specific certificate. I would suggest to just use signcode if that works for you.

    ReplyDelete
  5. The point is that I need a signing library or source code of an utility to use in my C++ program on Linux. The only source I've found is osslsigncode and it doesn't work... As for signcode - its sources are only in C# and use .NET assemblies. May be you could kindly suggest something suitable for my needs?

    ReplyDelete
  6. BTW, could you try my scenario described above (testing these tools with identical certificate-key) and in case you get valid (windows-accepted) signature from osslsigncode send me the certificates that have been tested so I could try them?
    Thanks in advance.

    ReplyDelete
  7. As far as I know, the openSSL library itself should support all formats needed, at least in the newly released 1.0 version. That might be the best way for you to go.

    We ourselves are using osslsigncode with our Thwate certificate for all our executables. You will probably understand that I cannot send out our private key.

    If you have problems with these libraries or tools, I would suggest to contact the respective authors. They can be much better of help as we are also only users of these tools.

    ReplyDelete
  8. Of course, I meant sharing some test (self-issued, for instance) ceritficate, not production one :) But thanks anyway, I'll try your suggestions.
    BTW, do you use your signed files with Windows, and if yes does it report that signature is OK?

    ReplyDelete
  9. You need more than just openssl and curl to get osslsigncode to work, you also need a C compiler. That might be there by default on Linux, but not on the Mac.

    ReplyDelete
  10. Yes, you are of course right. Thanks for pointing that out. You have to install Apple's developer tools on the Mac.

    ReplyDelete
  11. The solution to denisaruis problem can be found here:

    https://developer.mozilla.org/en/Signing_an_executable_with_Authenticode

    ReplyDelete