Code signing How-To¶
What is code signing and why is it required?¶
Windows¶
Code signing provides benefits to application security features like Windows Defender Application Control (WDAC). It allows the system to cryptographically verify that a file hasn’t been tampered with before any code is to run.
Windows doesn’t require software developers to digitally sign their code. Users can install applications from sites other than the Microsoft Store if they allow such applications to run. When code sign is provided, Windows reduces the number of warnings when running.
macOS¶
App code signing process in macOS
“On devices with macOS 10.15, all apps distributed outside the App Store must be signed by the developer using an Apple-issued Developer ID certificate (combined with a private key) and notarized by Apple to run under the default Gatekeeper settings. Apps developed in-house should also be signed with an Apple-issued Developer ID so that users can validate their integrity.”
Starting with OmegaT 6.0.2, OmegaT is distributed as a notarized application for both the old Intel CPU machines and the new Apple CPU machines (starting with M1).
How to obtain a certificate?¶
A certificate can be obtained from certification authority companies. Both Microsoft and Apple specify which companies are compatible with their respective platforms.
Windows¶
Many certification authority companies provide a certification for code signing for Windows.
Certum Open Source developer certificate program¶
Certum® is one of the certification authority services provided by Asseco Ltd.
They provide discounted a code signing certificate to FOSS projects. They not only check developer individual identities but also check the project itself.
Comodo certificate for individuals¶
Comodo provides a certification with affordable prices for individuals.
macOS¶
Apple is the only authority that provides a certification for code signing and notarization. The certification comes with an Apple Developper account.
Certificate issued by Apple¶
A developper account comes with an Apple verified developper ID.
Application notarized by Apple¶
Apple provides the notarization service based on the Apple verified developper ID.
Tools¶
Windows¶
signtool.exe¶
signtool.exe is a utility bundled with Windows SDK.
SignTool is a command-line tool that digitally signs files,
verifies the signatures in files, and time stamps files.
For more information, see SignTool documentation.
Installation¶
Option 1: Windows SDK
Download the latest Windows SDK
(minimum version: 10.0.22621.0).
After installation, signtool.exe is located at:
C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\signtool.exe
Option 2: NuGet package (PowerShell)
Download nuget.exe:
Invoke-WebRequest -Uri https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile .\nuget.exe
Download and extract the Windows SDK Build Tools:
.\nuget.exe install Microsoft.Windows.SDK.BuildTools -x
signtool.exe will be found under the extracted package directory.
Signing an installer executable¶
signtool sign /fd sha256 /n "Open Source Developer: Your Name" /t http://time.certum.pl/ /v OmegaT_6.2.0_Beta_Windows_64.exe
The command will ask you password on the terminal.
Key options:
Option |
Description |
|---|---|
|
File digest algorithm (SHA256 required for modern SDK versions) |
|
Subject name of the signing certificate |
|
Timestamp server URL |
|
RFC 3161 timestamp server URL (alternative to |
|
Digest algorithm for RFC 3161 timestamping (required with |
|
Verbose output |
To sign multiple files in a single session (avoids re-entering the PIN for each file), pass them as consecutive arguments:
signtool sign /fd sha256 /n "Open Source Developer: Your Name" /t http://time.certum.pl/ /v OmegaT_6.2.0_Beta_Windows_64.exe OmegaT_6.2.0_Beta_Windows_64_Without_JRE.exe
To verify a signed file:
signtool verify /pa OmegaT_6.2.0_Beta_Windows_64.exe
Linux¶
osslsigncode¶
osslsigncode is a small tool that implements part of the functionality of
the Microsoft tool signtool.exe — specifically Authenticode signing and timestamping.
It is based on OpenSSL and cURL, and compiles on most platforms where those exist.
See osslsigncode on SourceForge for more information.
Note: Starting from November 2022, certification providers require private keys to be stored on a Hardware Security Module (HSM). Since June 1, 2023, industry standards mandate that private keys for standard code signing certificates be stored on hardware certified as FIPS 140 Level 2, Common Criteria EAL 4+, or equivalent. (See bug #1179.) For PKCS#11 HSM-based signing, osslsigncode version 2.5 or later is required.
Installation¶
On Debian/Ubuntu:
sudo apt install osslsigncode
For PKCS#11 HSM signing with OpenSSL 3, use an up-to-date osslsigncode
version. osslsigncode 2.10 and later support OpenSSL 3 PKCS#11 providers;
osslsigncode 2.13 has been tested successfully with Certum common-profile
tokens.
If the distribution package is older, build a recent version from source:
sudo apt install git build-essential cmake pkg-config libssl-dev libcurl4-openssl-dev
git clone https://github.com/mtrojnar/osslsigncode.git
cd osslsigncode
git checkout 2.13
mkdir build
cmake -S . -B build
cmake --build build
./build/osslsigncode --version
Install the OpenSSL 3 PKCS#11 provider package:
sudo apt install pkcs11-provider
Check where the provider module was installed:
ls -l /usr/lib/x86_64-linux-gnu/ossl-modules/
On Debian/Ubuntu, the provider module is typically:
/usr/lib/x86_64-linux-gnu/ossl-modules/pkcs11.so
Finding the certificate label and PKCS#11 module¶
When you obtain a certificate from Certum stored on a USB hardware token,
use the proCertum Card Manager application to find the certificate label
(used as the -pkcs11cert argument):
Open proCertum Card Manager.
Select your USB card reader.
Go to the Common Profile tab.
The certificate label appears in the table shown there.
When proCertum Card Manager is installed on Linux, the PKCS#11 module for the common profile is:
/opt/proCertumCardManager/sc30pkcs11-3.0.6.72-MS.so
The exact filename depends on the installed version.
Certum may provide multiple PKCS#11 modules. Make sure to use the module matching the profile where the certificate/private key is stored. For example, the common/standard profile may appear as:
token label : profil standardowy
token manufacturer : Certum common profile v.1
The secure profile may appear as:
token label : profil bezpieczny
token manufacturer : Certum secure profile v.1
If the certificate is in the common profile, use the common-profile module
such as sc30pkcs11-...so, not the secure-profile module.
Alternatively, use p11-kit to list all available PKCS#11 modules on your system:
p11-kit list-modules
This shows the path of each module, for example the OpenSC module at
/usr/lib/x86_64-linux-gnu/pkcs11/opensc-pkcs11.so.
To inspect the token slots exposed by a PKCS#11 module:
pkcs11-tool \
--module /opt/proCertumCardManager/sc30pkcs11-3.0.6.72-MS.so \
--list-slots
To list certificate and key objects on the token:
pkcs11-tool \
--module /opt/proCertumCardManager/sc30pkcs11-3.0.6.72-MS.so \
--login \
--list-objects
Look for matching certificate and private-key objects. They should have the
same ID, for example:
Private Key Object; RSA
label:
ID: a3f8c2e701b45d9682f3a07c14e8d53b2c916f74
Certificate Object; type = X.509 cert
serial: 3F8A2D174C956B0E8912A4F7E63B5D29
ID: a3f8c2e701b45d9682f3a07c14e8d53b2c916f74
The PKCS#11 ID is not the certificate serial number. It is binary object
identifier data. In a PKCS#11 URI it must be percent-encoded byte by byte:
a3f8c2e701b45d9682f3a07c14e8d53b2c916f74
becomes:
%A3%F8%C2%E7%01%B4%5D%96%82%F3%A0%7C%14%E8%D5%3B%2C%91%6F%74
Signing an installer executable¶
For OpenSSL 3 provider-based signing, create a local OpenSSL configuration file that loads both the default provider and the PKCS#11 provider, and points the PKCS#11 provider to the Certum common-profile module:
openssl-pkcs11.cnf:
openssl_conf = openssl_init
[openssl_init]
providers = provider_sect
[provider_sect]
default = default_sect
pkcs11 = pkcs11_sect
[default_sect]
activate = 1
[pkcs11_sect]
module = /usr/lib/x86_64-linux-gnu/ossl-modules/pkcs11.so
pkcs11-module-path = /opt/proCertumCardManager/sc30pkcs11-3.0.6.72-MS.so
pkcs11-module-load-behavior = early
activate = 1
Then sign the Windows installer. The certificate can be supplied as a PEM file, while the private key is used from the token through a PKCS#11 URI:
OPENSSL_CONF=$PWD/openssl-pkcs11.cnf \
osslsigncode sign \
-provider default \
-provider /usr/lib/x86_64-linux-gnu/ossl-modules/pkcs11.so \
-certs 3f8a2d174c956b0e8912a4f7e63b5d29.pem \
-key 'pkcs11:token=profil%20standardowy;id=%A3%F8%C2%E7%01%B4%5D%96%82%F3%A0%7C%14%E8%D5%3B%2C%91%6F%74;type=private' \
-pass 'token-password' \
-t http://time.certum.pl/ \
-n "OmegaT" \
-i https://omegat.org/ \
-h sha256 \
-in OmegaT_6.2.0_Beta_Windows_64.exe \
-out OmegaT_6.2.0_Beta_Windows_64_signed.exe
Key options:
Option |
Description |
|---|---|
|
OpenSSL configuration file that enables the PKCS#11 provider |
|
Loads OpenSSL’s default provider; required for normal file handling |
|
Loads the OpenSSL 3 PKCS#11 provider |
|
Path to the signing certificate file (PEM format) |
|
PKCS#11 URI identifying the private key on the token |
|
PIN/password for the token |
|
Timestamp server URL |
|
Description/name displayed in Windows security dialogs |
|
URL of the application’s website |
|
Hash algorithm for signing |
|
Input unsigned executable |
|
Output signed executable |
Avoid the older -pkcs11module engine-based flow for this setup. With some
OpenSSL 3, engine_pkcs11, and Certum module combinations, the engine-based
flow may fail or crash. The OpenSSL 3 provider-based flow shown above has been
tested successfully.
To verify a signed file:
osslsigncode verify OmegaT_6.2.0_Beta_Windows_64_signed.exe
Troubleshooting PKCS#11 signing¶
If osslsigncode reports that the pkcs11 engine cannot be loaded, the older
engine-based flow is being used. For OpenSSL 3 provider-based signing, use
osslsigncode 2.10 or later and pass the -provider options shown above.
If OpenSSL reports an error such as unregistered scheme: scheme=file, make
sure the default provider is loaded:
-provider default
If OpenSSL reports that the token is not recognized, check that the OpenSSL PKCS#11 provider is configured to use the Certum module, not OpenSC or another default module:
pkcs11-module-path = /opt/proCertumCardManager/sc30pkcs11-3.0.6.72-MS.so
If the token exposes multiple profiles, verify the selected module with:
pkcs11-tool \
--module /opt/proCertumCardManager/sc30pkcs11-3.0.6.72-MS.so \
--list-slots
If the certificate label is empty or differs from the certificate subject, use
the PKCS#11 object ID instead of the label. The object ID must match between
the certificate and private key.
If needed, test raw token signing independently of osslsigncode:
printf test > test.bin
pkcs11-tool \
--module /opt/proCertumCardManager/sc30pkcs11-3.0.6.72-MS.so \
--login \
--id a3f8c2e701b45d9682f3a07c14e8d53b2c916f74 \
--sign \
--mechanism SHA256-RSA-PKCS \
--input-file test.bin \
--output-file test.sig
If this succeeds, the token, PIN, private key, and PKCS#11 module are working;
remaining problems are likely in the OpenSSL/osslsigncode configuration.
batch signing¶
Here is a sample shell script to accept multiple *.exe and write *_signed.exe
#!/usr/bin/bash
set -euo pipefail
OPENSSL_CONF=openssl-pkcs11.cnf
export OPENSSL_CONF
if [[ $# -eq 0 ]]; then
echo "Usage: $0 <file.exe> [file2.exe ...]" >&2
exit 1
fi
read -rsp "PIN: " PIN
echo
for infile in "$@"; do
outfile="${infile%.exe}_signed.exe"
echo "Signing: $infile -> $outfile"
osslsigncode sign \
-provider default \
-provider /usr/lib/x86_64-linux-gnu/ossl-modules/pkcs11.so \
-certs 3f8a2d174c956b0e8912a4f7e63b5d29.pem \
-key 'pkcs11:token=profil%20standardowy;id=%A3%F8%C2%E7%01%B4%5D%96%82%F3%A0%7C%14%E8%D5%3B%2C%91%6F%74;type=private' \
-pass "$PIN" \
-t http://time.certum.pl/ \
-n OmegaT \
-i https://omegat.org \
-h sha256 \
-in "$infile" \
-out "$outfile"
done
OpenSC¶
OpenSC is an open source smart card tools and middleware. It supports PKCS#11/MiniDriver/Tokend.
The list of supported hardware is at OpenSC Wiki.
openssl-pkcs11¶
macOS¶
The tools and processes are described here: