wiki:windows-signing

Version 3 (modified by Greg Couch, 3 days ago) ( diff )

--

Windows Code Signing

This is how we do automated code signing of Windows binaries using a YubiKey. We started with:

Protocol:

  • Use YubiKey Authenticator application to set PIN, PUK, and Management Key (could use yubio-piv-tool instead)
  • Install YubiKey Smart Card Minidriver
  • Install yubio-piv-tool
  • Get email invitation to submit code signing CSR to Sectigo initiated by corporate IT
  • Submit CSR and YubiKey attestation
  • Get email from Sectigo with link to certificate
  • Install certificate on YubiKey
  • Sign code

Submit CSR

The code signing slot is the Authentication slot 9A.

Create key in slot

yubico-piv-tool --slot=$SLOT --action=generate --touch-policy=never --algorithm=$ALGORITHM --key --output=public.key

Use public key to create CSR

yubico-piv-tool --slot=$SLOT --action=verify-pin --action=request-certificate --subject='/CN=Sectigo/' --input=public.key --output=csr.txt

Upload csr.txt for the CSR

YubiKey attestation

Get attestation

yubico-piv-tool --slot=$SLOT --action=attest --output=attest.crt

Get YubiKey's intermediate certificates

yubico-piv-tool --action=read-certificate --slot=f9 --output=intermediateCA.crt

Combine and encode in base64

cat attest.crt intermediateCA.crt > attestation.pem
base64 < attestation.pem > attestation.pem.b64

Attestation is in attestation.pem.b64. Copy the contents and paste in the Key Attestation field. Make sure YubiKey is the HSM type.

Install Certificate

Use "Certificate only, PEM encoded" certificate. Downloads as $CERT_BASE_cert.cer.

Install in Windows User Certificate manager

Open $CERT_BASE_cert.cer in file explorer, then click on Install Certificate.... Choose Current User. Place in Personal Certificate Store.

Install on YubiKey

yubico-piv-tool --action=import-certificate --slot=$SLOT --key --pin-policy=once --touch-policy=never --input=$CERT_BASE_cert.cer

Install intermediate certificates onto YubiKey

Use "Root/Intermediate(s) only, PEM encoded" certificates. Downloads as CERT_BASE_interm.cer.

interm=$CERT_BASE_interm.cer
let slot=$((0x82))
let max_slot=$((0x95))
while openssl x509 -out cert.pem
do
        if [ $slot -ge $max_slot ]
        then
                echo "too many intermediate certificates"
                exit 1
        fi
        hex_slot=$(printf "%x" $slot)
        echo "Import slot $hex_slot: $(openssl x509 -in cert.pem -noout -subject | sed 's/.*CN = //')"
        yubico-piv-tool --action=import-certificate --slot=$hex_slot --key --input=cert.pem
        slot=$((slot + 1))
done < $interm

Sign Code

Microsoft's signtool doesn't have a way to provide the PIN needed utilize the private key. So use MGTEK's scsigntool to wrap signtool. ScSignTool.exe and ScSignTool.dll are placed in the directory where signtool is used.

For example:

scsigntool.exe -pin CODESIGN sign /v /a /sha1 CERT_SHA /fd sha256 /t http://timestamp.sectigo.com/authenticode /d "Application Name" app-installer.exe
Note: See TracWiki for help on using the wiki.