I want to EV Code sign using a private key on a Yubico Yubikey 5 using signtool.exe, However everytime I sign a file, it prompts for the password. I would like the entry of this key to be automated as part of a build pipeline triggered on a secure machine.
I previously used a Safenet token and was able to do this using solutions from
this question, however my understanding is that this functionality was a specific implementation for the eToken Cryptographic Security Provider used by Safenet.
I have exported the public certificate from the Yubikey and used certutil to dump info about the key container (which is a GUID like 0bababab-0000-aaaa-baba-cdcdcdcdcdcd) and the CSP which is Microsoft Smart Card Key Storage Provider but when I use this info I get the following issue:
signtool sign /f <cert file>.crt /csp "Microsoft Smart Card Key Storage Provider" /v /kc <container_id>
Error information: "CryptExportPublicKeyInfoEx failed" (-2146893819/0x80090005)
SignTool Error: An unexpected internal error has occurred.
In addition to
Microsoft Smart Cardsupport the Yubikey also supportsPKCS11. This interface isn't natively supported bysigntool.exebut it is supported by third party tools likeosslsigncodewhich allows the key password to be supplied over the CLI.Here's how I got it working:
OpenSSLi.e. from here Important: make sure to install it toC:\OpenSSL-Win64instead of the default ofC\Program Files\OpenSSL-Win64yubico-piv-tooli.e. from here and note the location of the filelibykcs11.dllwhich should be atC:\Program Files\Yubico\Yubico PIV Tool\binImportant: Add this path to yourPATHvariable orosslsigncodewon't work.libp11libp11usingnmake, more detailed instructions here. Note: The current version of the make file is sensitive toOpenSSLbeing installed to the directory in Step 1pkcs11.dllwhich is produced from Step 4 this will be ourpkcs11engineforosslsigncodeosslsigncodei.e. from here and add its location to yourPATHvariable.crtfile and note its locationosslsigncode sign -pkcs11module <location_of_libykcs11.dll> -pkcs11engine <location_of_pkcs11.dll> -pass <yubikey_passcode> -ts <timestamp_server_url> -key "pkcs11:id=%01" -certs <path_to_public_cert.crt> -in "input_file.exe" -out "output_file.exe"Additional resources:
pkcs11-toolwas extremely useful in getting this running