Windows Code Signing with eSigner
3 minute read.
I miss the good old days, when we still were able to use a private key for code signing.
Nowadays, in addition to a highly expensive certificate that requires validation of your company with “reliable third-party websites” that may have a bunch of misinformation on you, we’re also expected to pay a dollar per API request to sign a piece of code. Because it requires specialized hardware to host your private key or something like that. I heard it might be almost as expensive as an Nvidia H100, or maybe not even close, yet somehow is way more expensive to run a REST API request on to justify the price… hmmm.
Thanks to these new requirements, we now have to deal with a beautiful Java-based tool that ships the JDK instead of the JRE and ends up being a 200+ MB download (compressed!).
Installation
Ideally, just have it installed on your runner once. If that’s not an option, here is a script:
# Install eSigner CodeSignTool from SSL.com Invoke-WebRequest -OutFile CodeSignTool.zip "https://www.ssl.com/download/codesigntool-for-windows/" Expand-Archive -Force CodeSignTool.zip Remove-Item CodeSignTool.zip Move-Item -Destination "$Env:USERPROFILE\Desktop\CodeSignTool" -Path "CodeSignTool"
You can use it in your .gitlab-ci.yml directly or save it as a install-esigner-tool.ps1 file and run it.
Code Sign from CMake
We code sign directly from CMake, since we use CPack to package up the signed executables, and then run a POST_PACKAGE
script to sign the installer.
This is our custom target to sign the executable:
set(CODESIGN_TOOL .\\CodeSignTool.bat) set(CODESIGN_TOOL_DIR $ENV{USERPROFILE}\\Desktop\\CodeSignTool\\) if(NOT EXISTS "${CODESIGN_TOOL_DIR}\\${CODESIGN_TOOL}") message(FATAL_ERROR "Missing ${CODESIGN_TOOL}") endif() # Windows code signing add_custom_target(YourExecutableSigned COMMAND ${CODESIGN_TOOL} sign -credential_id="$ENV{CODESIGN_CREDENTIAL_ID}" -username="$ENV{CODESIGN_USER}" -password="$ENV{CODESIGN_PWD}" -input_file_path="$<SHELL_PATH:$<TARGET_FILE:YouExecutableTarget>>" -totp_secret="$ENV{CODESIGN_TOTP}" -override="true" WORKING_DIRECTORY ${CODESIGN_TOOL_DIR} COMMENT "Signing Editor executable")
Run it with cmake --build . --target YourExecutableSigned
.
The WORKING_DIRECTORY
is not optional. Our tool can only run from inside its own directory.
Note that all the credentials are provided via environment variables. Add them as CI secrets:
CODESIGN_CREDENTIAL_ID
: The eSigner credential ID from SSL.com.CODESIGN_USER
: Your SSL.com username.CODESIGN_PWD
: Your SSL.com password.CODESIGN_TOTP
: The seed for the OTPs. This is required, since you can’t input the time-based authenticator codes via CI, so you input the private token instead, that the tool will use to generate a OTP with.
You’ll have to replace YouExecutableTarget
with your target, of course.
Hope this saved you some time.