I won't repeat the "Signing your code with Signtool" walkthrough that is already detailed in 50,000 other posts. You can Bing that with Google as easily as I did. What I will share is a little issue that tripped me up for a bit.

I wanted the code signed as part of the TFS automated build. And, while I could run the command line myself, I could not get it to work under TFS builds.

The Scenario

  • I wanted the keys in the certificate store, rather than on disk. This makes it possible to use the certificate without storing the certificate's private key password on disk.
  • The build process is NOT running as local admin.
  • The code signing tasks happen as a "Post-Build" event, specified in the project's properties.
  • The certificate was installed in the Machine Store, not a specific account's store.

The Problem

I could run the Signtool command under my account and it worked. But if I ran under a limited account, it didn't work.

I tried copying the cert into the service account's personal store, but that didn't help.

The Solution - Permissions, of course!

It wasn't immediately obvious because of various error messages such as:

  • "No certificates were found that met all the given criteria"
  • "No provider was specified for the store or object"
  • … and others

I figured that I'd check to see what Signtool was looking for to see if I could isolate the issue. ProcessMonitor did the trick in a matter of minutes. Spinning it up, I found that it was getting access denied on the Machine Store's key files. I've seen this before related to IIS / ASP.NET (I think).

On Windows Server 2003 and earlier, the machine keys are stored under:
C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys

On Windows Server 2008, these are now under:
C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys

I found the file related to the cert that I just installed and inspected permissions. Just "Administrators" and "System". I granted my build service account read access and, VOILA, the Signtool works!

If anyone knows how to manage cert permissions without mucking with the file system directly, please do tell! And if you know why this is the way it is, I'd love to hear it.

Cheers!