Code signing mini-FAQ

What really is code signing?
At a high level, code signing allows you to generate a digital signature for the application binary and then provides a mechanism to carry the signature right to the end user. When the end user invokes the application, the digital signature is verified by the user and the user is able to make an informed decision whether the executable must be executed on his/her machine. Code signing uses digital signatures to provide identity and integrity for the code of software applications. It is important to understand that code signing merely asserts the identity of the software publisher and confirms that the software has not changed since it was signed. Code signing does not make a judgement of the quality of the software or its performance.

How does code signing work?
Let us now try and see how code signing works – Let us first understand the different entities involved in the code signing and verification process. The Software publisher obtains a code-signing certificate from the CA and uses the private key corresponding to the certificate to sign the code. The digital signature obtained is either embedded in the code or sent separately from the code (more on this later.) The software consumer who is typically the end user verifies the digital signature on the code before using the software. If the digital signature is verified successfully and the user trusts the signer of the software, he or she may go ahead and use the software. On the other hand, if the digital signature is not verifiable or the user does not trust the signer then he or she may choose to stop the application in its tracks. The bottom line is that code signing offers application designers a robust method of attaching their identity with the code that they write thereby providing greater user accountability and assurance.

What are some of the code signing technologies?
Microsoft offers two technology options for code signing – these are Authenticode and Strong Names.

Authenticode
Authenticode identifies the software publisher and confirms that the software has not changed since the signature was generated on it. It uses digital certificates as opposed to strong names which uses public keys. Therefore, authenticode allows software users to verify the identity of the software publisher up to a trusted root certificate or up to any certificate that the user trusts.  Authenticode does not alter the executable portion of the application. Instead it supports embedded signatures wherein the digital signature is embedded in the non-execution portion of the executable. Examples where embedded signatures are used are in File Download box, the UAC prompt in Vista and the Windows loader. Authenticode also supports detached signatures in which signed catalog files are used to store the hashes of all files that require to be signed. The principal advantage of using detached signatures is when the file format does not support embedded signatures. Another advantage is performance as you have to sign (and verify) a group of files only once if you use detached signatures since the catalog files can reference several files at the same time. Authenticode is more prolific in terms of the number of the file formats that it supports viz. PE (.dll, exe, sys, ocx), Cabinet files and Windows installer files (.msi and .msp)

Strong Names
Strong name signing is used exclusively with .NET assemblies. Although digital signatures are used to generate strong names, it is important to understand that strong naming does not use digital certificate, instead it uses and supports public keys only. This means that it is not really possible to establish a chain of trust for the public key; and therefore there is no way to bind the identity of the software publisher to the private key being used to sign the assembly. Since strong names do not support digital certificates, they do not support expiration or revocation of key material either. This means that extra precautions must be taken by the software publisher to keep the private key private and to securely distribute the publisher’s public key to those assemblies that reference the signed assembly. In order to tide over these limitations, it is recommended that strong names be used along with authenticode, where possible.

What are the best practices for code signing?
Having now discussed the various options available for code signing let us now take a look at the best practices for code signing.

The first one is that you should use code-signing where you can. Code signing puts your product (and your organization) in the league of those organizations who are ready to run the extra mile in reassuring their customers about the reliability of their software. Code signing also tends to create a strong brand recall in the mind of your users when they are using their software. Its like having the About box of your software automatically pop up everytime the user runs your software!

We move on to the second one. Microsoft recommends that commercial software publishers use a different code-signing infrastructure to test sign pre-lease builds of their software. As part of this infrastructure, test publisher certificates must chain to completely different certificates than the root certificate this is used to sign the publicly released version of the software. Also it is much more efficient to use test signing rather than use signing for daily use during development. This helps in the configuration management space too as the using test certificates for signing ensure that pre-release code is not accidentally released to the public.

This point particularly applies to code that will be released to the public. As mentioned earlier, the keys used to generate and verify the signature on code are confidential items and therefore unless if the provided keys are not strongly authenticated, they must not be used for automatic code signing.

Strong naming does not use digital certificates and therefore does not support revocation and expiration. It is therefore imperative that the keys used for strong naming be protected in a failsafe manner.

To take care of the strong name shortcoming mentioned in the previous point, it is always a good idea to couple strong name signatures with authenticode signatures.

What are some of the tools for code signing?
Having seen some of the best practices when using strong naming let us now see some tools that you can use for code signing.

MakeCat – This tool creates an unsigned catalog file that contains the hashes of a specialised set of files and their associated attributes. This allows an organization to sign a single file – the catalog – instead of signing numerous individual files. This tool relies on a catalog definition file (.cdf) that the user must create  which contains the list of files to be cataloged and their attributes. The tool scans this file, verifies the attributes, adds the attributes to the catalog files and hashes and stores the hash values in the catalog file.

SignTool – This is a command line tool that signs, verifies and timestamps all formats supported by Authenticode. This tool is a well-endowed tool in that it can sign and verify signatures, check if certificates are revoked and also wheter a signing certificate is valid for a specific policy.

Strong Name Tool (sn.exe) – This tool is used to sign .NET assemblies. It also allows for key management, signature generate and signature verificateion and supports strong name test signing , delay signing and release signing.

That's it folks.