Monday, November 09, 2009

Executable Signing with Inno Setup

As I discussed a couple of years ago, code signing your executables is important for a variety of reasons. Our installation creation tool of choice is Inno Setup and version 5.2.4 released in March 2009 made it easier to sign the setup executable through the new Signtool directive in the [Setup] section.

This directive works like this (assuming you already have a digital certificate):

  • Run the Inno Setup UI and choose Configure Sign Tools in the Tools menu.
  • Create a new “sign tool” by clicking Add and specifying a name and the command line to execute your signing application. For example, I created one called “Standard” with the following command line to call Microsoft’s SIGNTOOL.EXE:

"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\signtool.exe" sign /f CertPath\mycert.pfx /p MyPassword

where CertPath\mycert.pfx is the name and location of the PFX file and MyPassword is the password.

  • In the [Setup] section of your Inno Setup script (ISS) file, add the following:

SignTool=Standard /d $qStonefield Query Installer$q $f

Specify the name of your “sign tool” in place of “Standard” and a descriptive name for your setup program in place of “Stonefield Query Installer.” $q is an Inno Setup constant representing a quote and $f is a constant containing the name and path of the setup EXE created by Inno Setup.

Now, every time you build your setup using the Inno Setup UI, your setup executable is automatically signed.

However, I also like to build setups as part of a build process, so I call the Inno Setup compiler via the command line. Once I added the SignTool directive in my ISS files, my command line builds failed.

Here’s the solution: you need to add the same “sign tool” definition you did to the UI to the command line. For example:

"C:\Program Files\Inno Setup 5\iscc" "/sStandard=C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\signtool.exe sign /f CertPath\mycert.pfx /p MyPassword $p" sfquery.iss

Now, whether I build using the UI or through a build process, my setup executable is always signed.

33 comments:

Michael Blackburn said...

Thank you for the informative post. However, I wonder why we need separate certificates for SSL on a website and for code signing. It's the same technology and the same verification process, just two separate fees.

Doug Hennig said...

Good question, but I don't know the answer.

netsendjoe said...

Where can I get or create my own digital certificate for free?

Doug Hennig said...

You can't create your own digital certificate: if you could, then anyone could do it, which would defeat the purpose of digitally signing an app. I doubt you can find a free one.

David Mail said...

Of course you can get a free certificate creating so called 'self-signed' certificate. Just Google a bit for that. It would not be trusted since it was not issued by a known Certificates Authority, but it is good enough for the testing purpose

Anonymous said...

It is very important to point out, that the current version of ISTool seems to have a bug and cannot interprete the [Server] directive "Signtool". You will always get an error "Invalid paramters".

You need to use the original Inno Compiler to compile your .iss files.

Anonymous said...

I found that I needed to add a $p (for parameters) onto the end of the argument list for the signtool.exe tool for it to work.

Anonymous said...

Thanks Anonymous for the comment to add $p onto the end. That was so, so not obvious. The signing kept failing until I did what you said. Thanks!

Mark R said...

This works just fine when I install it on the computer represented by the directory path. But when I upload it to my CPalen-hosted website for others to download, evaluate, and buy, the certificate notice does not appear. I have a ticket into cPanel to resolve this, but I have not seen a discussion anywhere that discusses executable file certificates. All I see discussed are securing entire domains. I don't need to secure my domain as I am not planning to do financial transactions over it. You have a nice site. Thanks.

Doug Hennig said...

Mark, this blog post was ONLY about executable signing, not securing a domain. Assuming you've correctly signed both the installer executable and the executable being installed, the user should see the publisher name in the UAC dialog.

Alex said...

If the path to certificate has a space in it, your last command won't work. Any solutions?

Doug Hennig said...

Put quotes around it.

Anonymous said...

Thanks for your insightful post! Saved me a bunch of time getting a project signed.

Jason Rutgers said...

This is quite useful if you're having a project that needs to be implemented quickly. I'm just getting started with SSL and this is something this post has some insights on the subject..

Zeet said...

signtool.exe location will vary for x86 & x64 machines. HOw to make it generic ?

Doug Hennig said...

I only have a 64-bit system so I didn't bother.

Brad said...

Thank you for your post! The INNO helpful was woeful in terms of explaining what you made clear. I was able to resolve the issues I was having getting command like compilation done with signing.

Rick Strahl said...

FWIW I like to add my certificate to the Windows certificate store and reference that for the signing. This is nice in that I don't have to specify a path to the cert and I won't accidentally include it in source control :-)

Also, when building my final build I just copy signtool.exe into my build folder so that i don't need to have the SDK installed to build. The SDK path changes with versions and that's a pain when you move to a different machine. Ultimately it's nice to have a repeatable build.

Doug Hennig said...

We like to use a certificate file because we have multiple build machines (we have multiple products) and can all reference the same file. But I agree having it in the cert store makes sense for one machine.

I like the idea of copying Signtool.exe into the build folder -- thanks for the suggestion!

Unknown said...

Supposing I have a .jar file which I wrapped into an .exe installler using innosetup. Which one has to be signed? both or just the final result?

Doug Hennig said...

I don't know anything about .jar files but I assume just the .exe.

Unknown said...

I know I'm coming to this thread pretty late, but I'm just now trying to sign my installation .exe. I just applied for my certificate but haven't received it yet, thus I have a question about the text enclosed between $q. Does that appear during the installation process, and where? Thanks for sharing your knowledge with us.

Doug Hennig said...

Yes, it appears in the security dialog that pops up. If you don't specify this description, the user will see "Unknown application" or something similar.

Unknown said...

Got my certificate but having a hard time getting it to work with inno setup. I think I followed your example to the letter, but I continue to get Sign Tool failed with exit code 0x1. Below are the messages in the Compiler Output window. Just before it aborts, a Command Window flashes open. I sure hope you can shed some light on where I'm going wrong.

Running Sign Tool command: "C:\Program Files\Microsoft.NET\SDK\v2.0 64bit\Bin\signtool.exe" sign f/D:\ABS_3_Code\My_Certificate.pfx /pMyPassword
*** Compile aborted.

Unknown said...

I forgot to show you the commands in the [Setup] section:
SignedUninstaller=No
SignTool=standard /d $qABS Agency Builder Installer$q $f

Doug Hennig said...

Your command line has "f/" instead of "/f" plus I think there should be spaces after "/f" and "/p" before the next parameter.

Unknown said...

Tried that. Still getting :
---------------------------
Compiler Error
---------------------------
Sign Tool failed with exit code 0x1.
---------------------------
OK
---------------------------

I'll keep trying things, but this error message is not really much help.

Doug Hennig said...

Try adding a $p to the end of your "standard" definition. I don't see it in these instructions (not sure why) but I included it in a newer post: http://doughennig.blogspot.com/2016/02/executable-signing-using-sha-256.html

Anonymous said...

Also see https://stackoverflow.com/questions/36640899/inno-script-studio-sign-tool-not-recognised-when-using-compiler-from-command-p for a way to modify the registry rather than using a command line prompt.

Doug Hennig said...

That isn't a replacement for using a command prompt; it make it possible to use a command prompt when you've set the sign tool settings using Inno Setup Studio rather than Inno Setup.

Unknown said...

If anyone can give me some advice about what is wrong with this signtool line I would hugely appreciate it (this is from the Inno Script studio run output). Note some names have been changed to protect the innocent:

Running Sign Tool SignTool: "c:\myproginst\distrib\signtool.exe" sign /f "c:\myproginst\distrib\code_certificate\HJCarls_XXX.PFX" /tr http://timestamp.digicert.com /p NoNotMyPassword "C:\myproginst\distrib\workstation-inno\setup-ds-0403012.exe"
Compiler Error!
Sign Tool command failed with exit code 0x1.

After banging my head against the wall just to get the certificate generated, I had to put this aside for a while, so I'm also not really sure which PFX file I need to be using for this. I included a path to the certificate, but it's also in my certificate store. Thanks!

Unknown said...

WELLLLLL... Never mind re: comment posted 31-May-2022: I got it to work with a simpler command from a newer blog post (and then stumbled on the inactive link to your own discussion of SHA-256 certificates.). I have to say, though, that trying to buy, create and then use a code signing certificate for the first time is easily the most brain-wracking programming task I've ever encountered.

Doug Hennig said...

I hear ya! Buying a certificate for the first time is a huge PITA. Renewal isn't so bad. It took a lot of experimentation to get these instructions correct.