Windows Installer InstallAware for Windows Installer Header Image Windows Installer without Rocket Science

  InstallAware Blog

   

How to Comply With Microsoft’s New Code Signing Policy Using InstallAware X3’s New Build Events

In this tutorial we are going to show you how to make your installer packages conform with Microsoft’s new code signing policy. The “Windows Enforcement of Authenticode Code Signing and Timestamping” is effective as of January 1, 2016. This new policy basically mandates the deprecation of SHA-1 code signing certificates, time stamps, and file hashes for Code Signing. The new Microsoft Policy involves SHA-2 code signing certificates, time stamps, and file hashes as part of the updated policy:

http://social.technet.microsoft.com/wiki/contents/articles/32288.windows-enforcement-of-authenticode-code-signing-and-timestamping.aspx

Fortunately this can be easily achieved following the few steps described with this tutorial. This is entirely based on the use of the new “Build Events” feature available with InstallAware X3.

The “Build Events” feature makes it possible to run any third party process as an integral part of a build process. A “Process” is any executable and may be invoked during the various stages of a build that InstallAware follows while packaging your apps.

In this tutorial, we will not be boring you with the details of the new Code Signing Policy. If you are interested in resolving the overt contradictions in the Microsoft documentation and fancy that sort of a wild goose chase, please enjoy the official Microsoft documentation linked above. Having suffered through the nitty gritty details at InstallAware HQ on your behalf, we will be sparing you this pain; and focus on just the steps necessary to comply with the new Code Signing Policy in order to let you to build trusted setup packages.

Let us start with an overview of the setup binaries produced by a build which need code signing. These are of course, the MSI and/or EXE binaries that comprise your setup files. Please note that if you are setting the NO_MSI compiler variable to TRUE – meaning that you are opting to build a pure Native Engine installation, without any Windows Installer (MSI) bloat – in that case, you may omit the steps for the MSI files below. Similarly, when you are building a pure Windows Installer target (no final EXE output), you may omit the steps for EXE files.

These are in summary the targets that need to comply with the new Code Signing Policy. We may now proceed to the implementation using InstallAware X3.

 

Requirements for This Tutorial

•     InstallAware version X3,

•     An SHA-2 code signing certificate,

•     A recent version of the Microsoft SignTool.exe that supports double signing. This tool is included with the Windows 8 SDK, Windows 8.1 SDK and Windows 10 SDK.

Once the SDK is installed, the SignTool.exe binary is generally found inside one of the following directories:

  • C:\Program Files (x86)\Windows Kits\8.0\bin\x86
  • C:\Program Files (x86)\Windows Kits\8.1\bin\x86
  • C:\Program Files (x86)\Windows Kits\10\bin\x86

 

Getting Started

Make sure the “Sign the package with Authenticode” checkbox in the Build | Authenticode page of your Project Options window is UNCHECKED. This step is necessary since we are replacing the default code signing process in InstallAware X3.

 

Defining Build Events to Sign an Uncompressed Build Layout

With this kind of build its necessary to apply the digital signature to the following files which are part of an uncompressed build layout for a setup package (such as, for a DVD/Blu-Ray distribution target). These are stored at build time under your project’s “uncompressed” output folder.

•     <PackageName>.exe

•     <PackageName>.msi

•     \data\<PackageName>.msi

1. In the Project Options dialog (“CTRL+SHIFT+F11”) select the “Post-Build” event node listed within the left tree pane control. Then in the Commands field enter the following command line sequence.

- “#IADIR#\authenticode\SignTool.exe” sign /f <SHA2_cert> /t <SHA1_timestamp_url> /p <cert_password> “#PROJDIR#\Release\Uncompressed\#TITLE#.msi”

- “#IADIR#\authenticode\SignTool.exe” sign /f <SHA2_cert> /t <SHA1_timestamp_url> /p <cert_password> “#PROJDIR#\Release\Uncompressed\Data\#TITLE#.msi”

- “C:\Program Files (x86)\Windows Kits\10\bin\x86\SignTool.exe” sign /f <SHA2_cert> /t <SHA1_timestamp_url> /p <cert_password> “#PROJDIR#\Release\Uncompressed\#TITLE#.exe”

- “C:\Program Files (x86)\Windows Kits\10\bin\x86\SignTool.exe” sign /f <SHA2_cert> /as /fd sha256 /tr <SHA256_timestamp_url> /td sha256 /p <cert_password> “#PROJDIR#\Release\Uncompressed\#TITLE#.exe”

*Notes:

a) Press CTRL+ENTER to start a new command line. Each new line above represents a new command line and a new process invocation.

b) Ensure to update paths to the folder where the SignTool.exe binary is actually located on your system. In the above example, a typical path for the Windows 10 SDK on a 64-bit operating system has been used.

c) You will need to replace these tokens with your actual desired targets:

<SHA256_timestamp_url>: Replace with the actual time stamp server URL to use, for example http://timestamp.comodoca.com/rfc3161.

<cert_password>: Replace with your code signing certificate password (we better not know what that is, right?)

<SHA2_cert>: Enter the full path to your code signing certificate file here. Ensure to enclose the entire path string inside double quotes (“”) if the path to your code signing certificate contains spaces. Those adventurous among you may also opt to use the short path name for the certificate, if you are averse to using paths with spaces in them (even when they have been double-quoted).

Notice how, in the above command line sequence, we have refrained from hard-coding any folder paths and file names, insofar as your project folder and setup name is concerned. The examples above make use of the pre-defined compiler variables #PROJECTDIR#, #IADIR# and #TITLE#, instead of hard-coding folder paths and file names. These compiler variables are automatically resolved to their final values during the build process. This helps you use the exact same commands across all of your setup projects; without having to engage in the laborious task of updating paths and file names across projects, and/or having to update them when you actually move project folders around/change setup names.

2. In the Post-Build event settings, you may want to check the “Abort build on error (if any command returns non-zero result)” checkbox. Checking this box fails the setup build process when any invoked application returns a non-zero error code as its exit code, which is typically how an error condition is indicated on the command line. You may also want to keep this box unchecked, if you don’t care to break your build process when an intermittent failure occurs with a code signing time stamp server (or if it is not otherwise critical for your code signing to succeed).

3. Finally in the Project Options dialog, select the OK button to confirm the Post-Build event settings. Then rebuild the project. You’re done!


Defining Build Events to Sign a Compressed, Web, or Patch Build Layout

With all other build targets, including a Single Compressed File (monolithic) installer, a Web Build (main setup file plus optional web media block files), or a Patch Build; we need to define either a Post-Compress Event (if your final build target is an EXE file) or a Post-Wrap event (if your final build target is an MSI file).

Note that you could also “nest” your signatures all the way in, if you wanted to. Since any compressed setup is ultimately composed of files found in an uncompressed layout (which are then packaged into a single [or a few, in the case of a web build’s web media block files] file), there’s no harm in signing all those source materials as well.

While Windows will obviously not display any additional elevation requests once you have already elevated the main entry point of your setup package, you may want to use this trick of nested package signing for reasons of improving your chances of preventing false positives with anti-virus software. Anti-viruses have indeed become a cure worse from the disease, often hindering legitimate setups from installation. It may help your installation success rates to sign your packages from top to bottom (although, to set your expectations right; some anti-virus vendors have gotten so aggressive, that your mileage may vary even with everything signed inside out).

So if you want to do the nesting, copy over/retain the Post-Build event instructions for Uncompressed Builds to your compressed build types as well. Of course, remember to replace the string “uncompressed” with the string “single”, “web”, or “patch” based on your new distribution target.

Again while nesting, when building a single MSI file target, retain the Post-Compress event instructions (normally, you would only need to implement the Post-Wrap event instructions).

 

So here are the Post-Compress build events for a Single File Compressed Build:

- “C:\Program Files (x86)\Windows Kits\10\bin\x86\SignTool.exe” sign /f <SHA2_cert> /t <SHA1_timestamp_url> /p <cert_password> “#PROJDIR#\Release\Single\#TITLE#.exe”

- “C:\Program Files (x86)\Windows Kits\10\bin\x86\SignTool.exe” sign /f <SHA2_cert> /as /fd sha256 /tr <SHA256_timestamp_url> /td sha256 /p <cert_password> “#PROJDIR#\Release\Single\#TITLE#.exe”

Here are the Post-Compress build events for a Web Compressed Build:

- “C:\Program Files (x86)\Windows Kits\10\bin\x86\SignTool.exe” sign /f <SHA2_cert> /t <SHA1_timestamp_url> /p <cert_password> “#PROJDIR#\Release\Web\#TITLE#.exe”

- “C:\Program Files (x86)\Windows Kits\10\bin\x86\SignTool.exe” sign /f <SHA2_cert> /as /fd sha256 /tr <SHA256_timestamp_url> /td sha256 /p <cert_password> “#PROJDIR#\Release\Web\#TITLE#.exe”

And finally, the Post-Compress build events for a Patch:

- “C:\Program Files (x86)\Windows Kits\10\bin\x86\SignTool.exe” sign /f <SHA2_cert> /t <SHA1_timestamp_url> /p <cert_password> “#PROJDIR#\Release\Patch\#TITLE#.exe”

- “C:\Program Files (x86)\Windows Kits\10\bin\x86\SignTool.exe” sign /f <SHA2_cert> /as /fd sha256 /tr <SHA256_timestamp_url> /td sha256 /p <cert_password> “#PROJDIR#\Release\Patch\#TITLE#.exe”

 

Now, if you are producing an MSI output instead of an EXE output, use the following build events instead. Of course, if you will be doing nested signing, then remember to retain the above Post-Compress build events as well.

For a Single File MSI Build, use these Post-Wrap build events:

- “#IADIR#\authenticode\SignTool.exe” sign /f <SHA2_cert> /t <SHA1_timestamp_url> /p <cert_password> “#PROJDIR#\Release\Single\#TITLE#.msi”

For a Web MSI Build, use these Post-Wrap build events:

- “#IADIR#\authenticode\SignTool.exe” sign /f <SHA2_cert> /t <SHA1_timestamp_url> /p <cert_password> “#PROJDIR#\Release\Web\#TITLE#.msi”

For a Patch MSI Build, use these Post-Wrap build events:

- “#IADIR#\authenticode\SignTool.exe” sign /f <SHA2_cert> /t <SHA1_timestamp_url> /p <cert_password> “#PROJDIR#\Release\Patch\#TITLE#.msi”

 

Conclusion

 

That’s it!

You’ve seen how easy and versatile it can be to use InstallAware X3’s new Build Events to extend the default build process in the IDE and across the entire InstallAware build toolchain.

Please feel free to use this mechanism to do anything special you like when building your own installers. Have fun!

 

Francesco Toscano
Your InstallAware™ Support Team.

2 Responses to “How to Comply With Microsoft’s New Code Signing Policy Using InstallAware X3’s New Build Events”

  1. Obliterator Says:

    Interesting article – first I’d heard about the changes – thanks.

    We use an EV cert with a hardware dongle – so it would be great if IA allowed us to refer to this by short name (rather than a pfx file) and had the option to prompt for password (once on first build) and pass it through to sign tool (we don’t like saving the password in our config).

    But much appreciate the custom build steps workaround – any plans to integrate this into your signing process to handle all this automatically? :)

  2. Brian Says:

    After following your steps for single file the Build Progress locks up here…


    Created Windows Installer database
    Built installation executable
    Injected setup languages
    Injected runtime files
    Storing support files: componentstree.dfm (0%)

Leave a Reply