Lessons Learned Code Signing a Visual Studio 2008 .MSI Setup Project

I thought my mission was an easy one:

Code sign an existing MFC application (Metafile Companion) setup installer

I should have known better. 🙂 I was successful and it really isn’t that hard once you find out what to do. But there’s the rub – the web is full of options that end up being dead ends. Below are some of the lessons I learned.

Lesson 1: You really can pay $99 for a one-year signing certificate from K Software.

There are other more expensive Certificate Authorities (e.g. VeriSign and Comodo) that charge more than this. But the K Software certificate (issued by Comodo) seems to work just fine. I would recommend using either Firefox or Internet Explorer to place your order and later downloading your certificate so it is added “automagically” to the system certificate store. Also, follow their export instructions so you have a backup of your certificate.

Lesson 2: To see what certificates are on your system, run “certmgr.msc”. 

This is how you can be assured that your certificate was properly stored on your system.

Lesson 3: The MSDN article “How to: Sign Application and Deployment Manifests” doesn’t apply to older MFC / VC++ projects.

While this might work for newer C# projects, for my older MFC / VC++ application in Visual Studio 2008, it doesn’t. So don’t try to hard to find options that aren’t there.

Lesson 4: The SignCode utility is “obsolete”; use SignTool instead.

SignCode has a nice wizard mode, but it doesn’t show you a corresponding command line for the options you choose. SignTool is command line only, but is the current tool.

Lesson 5: Add a call to SignTool as the PostBuildEvent property for the Setup project.

Once you figure out all the options you need, adding the event is easy. Here’s what I used for my project:

signtool sign /a /v /d “Metafile Companion” /du http://www.CompanionSoftware.com/ /t http://timestamp.comodoca.com/authenticode “$(BuiltOuputPath)”

You can read the documentation for what the various options are. One time-saving thing is the “/a” option which automatically uses the “best” signing certificate it finds in the store. If you only have one, there this works like a charm. A while back, I had added a “self-signed” certificate to play with. I had to remove this (using CertMgr.msc) to get my purchased certificate to be the “best” one.

I hope these lessons help anyone else that might be trying to do something similar!