Friday, 19 December 2025

Code Signing fun and games for pgAdmin

For years now pgAdmin builds on Windows have been code signed using a certificate installed on a build machine in AWS. That certificate is expiring, so I had to look for a new one (I no longer work at a company that supports Windows that can provide one), and much to my annoyance I found that requirements have changed and a secure physical device is required for key storage. Keys are now generally much more expensive, and whilst there are options to have them installed in virtual keystores at AWS or similar, that adds thousands of dollars to the cost(!) for a supervised installation. Thankfully, Certum offer an Open Source Developer option, which is much more reasonably priced, albeit only valid for a year and only offering basic levels of assurance.

The card and reader arrived this week, and once I was approved, a certificate issued. The first problem I hit was that you cannot run the card manager application via Remote Desktop - you have to do it on the machine's console, or via VNC or similar. I'm running on Proxmox (having passed through the card reader device to the VM), so that meant using the console in the Proxmox UI.

Once the card manager was running, I was able to install the key through the Certum website. So far, so good - until I tried to sign a test binary. That's when the fun began. After a morning of back-and-forth, working with Claude Desktop, we finally got it working with a test binary. In the hope that it will help others in the future (including myself and the rest of the pgAdmin team when the certificate expires in a year, the Claude-generated notes on what we did are below.

My next steps are to figure out how to automate PIN entry, and then incorporate all the changes into the pgAdmin CI/CD pipelines so I don't have to enter a PIN multiple times every day when the team commit changes. Fun times!

Certum Open Source Code Signing Certificate - Windows Setup Reference

Date: December 2025
Hardware: Certum cryptographic card with ACS ACR40T ICC Reader


Overview

This document covers the setup of a Certum-issued Open Source code signing certificate on Windows using a hardware token. The standard "simple" registration via proCertum Card Manager does not correctly link the certificate to the private key, requiring manual repair via an INF file.

Important: Proper certificate-to-key linking (via the INF repair step) is essential. Without it, signing may fail or be limited to SHA1. With proper linking, SHA256 works correctly.


Prerequisites

  • proCertum Card Manager installed (with CSP driver mode selected)
  • Windows SDK (for signtool.exe)
  • Certum cryptographic card with code signing certificate installed

One-Time Setup

Step 1: Configure proCertum Card Manager for CSP Mode

  1. Open proCertum Card Manager
  2. Go to Options
  3. Select CSP driver (not Minidriver)
  4. Apply and restart Windows

Step 2: Import Certificate to Machine Store

  1. Open proCertum Card Manager
  2. Click Read Card
  3. Go to Common Profile tab
  4. Select the code signing certificate from the list
  5. Click Show certificate details
  6. Use the option to Install in Windows (or similar)
  7. Select Machine store -> Personal as the destination

Step 3: Verify Certificate is in Store (But Missing Key Link)

certutil -store My

Look for your certificate. You'll likely see: No key provider information — this is expected and will be fixed in the next step.

Step 4: Create Key Provider INF File

Create a file named keyprov.inf with the following content:

[Properties]
2 = "{text}"
    _continue_ = "Container=YOUR_KEY_CONTAINER_ID&"
    _continue_ = "Provider=crypto3 CSP&"
    _continue_ = "ProviderType=1&"
    _continue_ = "Flags=0&"
    _continue_ = "KeySpec=2"

Note: The trailing & characters on each line are intentional — they are required INF file syntax for multi-line values. Do not remove them.

Note: The Container value is the key container ID specific to your certificate/card. To find it:

certutil -key -csp "crypto3 CSP"

Step 5: Repair the Certificate Store Link

Run as Administrator:

certutil -repairstore My "YOUR_CERT_THUMBPRINT" keyprov.inf

Note: To find your certificate's SHA1 thumbprint, run certutil -store My and look for the Cert Hash(sha1) value.

Step 6: Verify the Link is Established

certutil -store My

You should now see your certificate with:

  • Provider = crypto3 CSP
  • Key Container = ...

Signing Commands

Basic Signing (Recommended)

signtool sign /sm /n "YOUR_CERTIFICATE_NAME" ^
 /tr http://timestamp.digicert.com ^
 /td sha256 /fd sha256 /v myfile.exe
(remember in Windows cmd.exe ^ is the line continuation character)

Batch Signing (Multiple Files)

signtool sign /sm /n "YOUR_CERTIFICATE_NAME" ^
 /tr http://timestamp.digicert.com ^
 /td sha256 /fd sha256 /v file1.exe file2.exe file3.exe

Verify a Signature

signtool verify /pa /v myfile.exe

Key Parameters Explained

ParameterValueNotes
/sm
Use Machine store (required since cert is in machine store)
/n"Your Certificate CN"Certificate subject name (as shown in certificate details)
/fdsha256File digest algorithm (recommended)
/trhttp://timestamp.digicert.comRFC 3161 timestamp server
/tdsha256Timestamp digest algorithm

Alternative Timestamp Servers

If the primary timestamp server is unavailable:

  • http://timestamp.digicert.com (recommended)
  • http://timestamp.sectigo.com
  • http://ts.ssl.com
  • http://time.certum.pl (Certum's own, but was unreliable during setup)

Important Notes

  1. PIN prompt: The first signing operation after card insertion will prompt for the PIN. Subsequent operations in the same session may be cached depending on proCertum settings.
  2. Machine store: The certificate is installed in the machine store, so always use the /sm flag when signing.

Troubleshooting

"No certificates were found that met all the given criteria"

  • Ensure you're using /sm flag (machine store)
  • Verify the certificate is in the correct store: certutil -store My
  • Check the key provider link exists (should show Provider = crypto3 CSP)

"SignerSign() failed" errors

  • Ensure the card is inserted and proCertum Card Manager can read it
  • Check if PIN prompt appeared (may be behind other windows)
  • Verify the certificate-to-key link exists: certutil -store My should show the Provider for your certificate

Timestamp server errors

  • Try a different timestamp server
  • Check internet connectivity
  • Use /tr (RFC 3161) rather than /t (legacy) format

Reference Information

To find your specific values, use these commands:

ItemCommand to Find It
Certificate Thumbprint (SHA1)certutil -store My - look for Cert Hash(sha1)
Key Containercertutil -key -csp "crypto3 CSP"
Certificate Namecertutil -store My - look for Subject: CN=...

Fixed values:

ItemValue
CSP Namecrypto3 CSP
KSP NamecryptoCertum3 KSP

Automation Notes

For CI/CD automation, PIN entry remains a challenge. Options to explore:

  1. PIN caching in proCertum: Enable in Card Manager settings; keeps token unlocked for session
  2. Environment variables: Some CSPs respect CRYPTOAPI_PIN or similar (did not work in testing)
  3. Dedicated signing machine : Self-hosted build agent with token attached, unlocked once per boot

Full unattended signing may require contacting Certum support for their recommended automation approach.