Available for Code Signing Gateway.
Overview
The SignPath Crypto Providers allow signing tools such as SignTool.exe, OpenSSL or jarsigner to sign files locally using keys or certificates stored and managed by SignPath.
Crypto Providers are generally used to provide a device-independent API for using secure key storage devices such as USB key tokens or Hardware Security Modules (HSMs). You may think of them as device drivers for crypto hardware. Most software tools used for code signing support one Crypto Provider technology, such as Microsoft KSP/CSP or PKCS #11 Cryptoki.
The SignPath Crypto Providers do not access the crypto hardware directly. Instead, they implement these interfaces to provide access to SignPath Projects and Signing Policies. During the entire operation, the private key will remain on the HSM.
Version info
This documentation contains information about the latest version of the CryptoProviders. See the CryptoProvider changelog or the macOS CryptoTokenKit changelog for updates.
Crypto Providers
The following Crypto Providers are available for SignPath:
Crypto Provider | Technology | Supported platforms | Description |
---|---|---|---|
Cryptoki (Cryptographic Token Interface) | PKCS #11 version 2.40 | Windows, Linux | |
KSP (Key Storage Provider) | CNG (Cryptographic API: Next Generation) | Windows | |
CSP (Cryptographic Service Provider) | CAPI (CryptoAPI) | Windows | This API is deprecated, most tools now use KSP/CNG |
CTK (CryptoTokenKit) | CTK extension | macOS |
Signing flow
This diagram describes how the various components work together to create a signature.
With small platform-specific variations, the general flow of a signing operations is as follows:
- The user invokes the signing tool.
- The command line usually specifies a key reference. In SignPath this is the Project and Signing Policy.
- The credentials are passed using the command line or environment variables.
- The signing tool reads the file and calculates a hash digest.
- Depending on the tool, this might be the hash digest of the entire file, or just a of a specific part of the file.
- For Authenticode, this step is performed by a Windows API using a format-specific SIP (Subject Interface Package).
- The signing tool calls a System API (Windows) or an engine (PKCS #11) to get a signature block.
- This API or engine calls the SignPath Crypto Provider.
- The SignPath Crypto Provider calls the SignPath REST API over HTTPS/REST.
- SignPath
- verifies the user’s credentials and permissions for the specified Project and Signing Policy,
- selects the key pair or certificate for this operation,
- uses the HSM to sign the digest using the specified algorithm,
- and writes the entire operation to the audit log.
- The resulting signature block is returned up the entire call chain.
- The signing tool writes the signature
- by inserting it into the signed file,
- by wrapping the file into a signed envelope,
- or by creating a detached signature file that must be shipped along the original file. Again, for Authenticode this is actually performed by the SIP.
As always, the private key does not leave the boundaries of the HSM.
Linux Docker container samples
The Crypto Provider package contains Linux sample scripts that demonstrate the different signing tool scenarios, their configuration, and the required dependencies in the Scenarios
directory. See the README.md
for the full list.
For supported Linux distributions, you can execute the samples using the provided Docker container configurations. See the Linux/samples
directory in the Crypto Provider package. See README.md
for further information and details how to use the run_scenario.sh
and RunScenario.ps1
entry point scripts to invoke samples.
All scripts can also be executed without containers. We recommend using containers when possible to easily manage dependencies, especially for GPG based signing tools.
Timestamps
When using SignTool.exe (or any other signing tool) directly, you are responsible for correct time stamping. Here are a few hints:
- You may use the timestamp authority (TSA) provided by the certificate authority that issued your code signing certificate or any other CA that provides a free public TSA.
- TSAs may impose quota limits, and free TSAs usually don’t provide any SLA level.
- TSAs may ignore the parameters you provide, e.g. the hashing algorithm. This may result in invalid timestamps. Depending on the platform, that might only lead to problems after the certificate becomes invalid.
- TSAs may use certificates with a short lifetime. Some platforms, such as Authenticode, accept expired TSA certificates. For other platforms, your signatures might become invalid after the TSA certificate has expired. A good TSA certificate should have a remaining lifetime of about 10 years or more.
Always check your signatures and timestamps to ensure that they will be valid after your certificate expires or gets revoked. Otherwise, your signatures may become invalid. Another problem is that revocation for compromised certificates becomes a much harder decision if you cannot rely on timestamps.
If you use the file-based signing method of SignPath, timestamps will be managed automatically.
Installation and usage
Depending on the signing tool you’re using, the corresponding Crypto Provider needs to be installed (on all build nodes). See the respective pages:
- SignPath KSP and CSP for SignTool.exe and most native Windows tools
- SignPath Cryptoki for OpenSSL, jarsigner, and many other Open Source tools
- GPG-based tools, such as gpg, rpm, or dkpg-sig use the SignPath Cryptoki Crypto Provider but require additional configuration steps
- SignPath CryptoTokenKit for macOS codesign
- Instead of using a CryptoProvider, it is also possible to sign hashes directly using the REST API
Configuration
Values
This section describes how to specify configuration values for all Crypto Providers.
Configuration options:
- Provide individual environment variables per setting
- Specify the path to a JSON configuration file via the
SIGNPATH_CONFIG_FILE
environment variable - Combine both approaches (individual environment variables take precedence over the corresponding JSON file values)
In case you used the MSI installer, a SIGNPATH_CONFIG_FILE
system env variable is created and set to %ProgramFiles%\SignPath\CryptoProviders\CryptoProvidersConfig.json
which points to a skeleton JSON file you can use to provide your own (default) values.
JSON setting | Environment variable | Default Value | Description |
---|---|---|---|
OrganizationId |
SIGNPATH_ORGANIZATION_ID |
(mandatory) | ID of your organization |
ApiToken |
SIGNPATH_API_TOKEN |
(mandatory) | API token for a CI or Interactive User (see below for options) |
TlsClientCertificate |
SIGNPATH_TLS_CLIENT_CERTIFICATE |
(optional) | Reference to a TLS/SSL client authentication certificate in the format thumbprint:$HexThumbprint (Windows only) |
ApiUrl |
SIGNPATH_API_URL |
https://app.signpath.io/Api |
SignPath API endpoint to use. Needs to be set if for self-hosted SignPath installations |
HttpProxy |
http_proxy |
(optional) | Address of an HTTP (web) proxy (not available on macOS) |
Cryptoki.DoNotFailOnReadWriteSessions |
SIGNPATH_CRYPTOKI_DO_NOT_FAIL_ON_READ_WRITE_SESSIONS |
false |
Enables compatibility with Cryptoki/PKCS #11 clients that open sessions with read/write option |
IncludeDummyX509CertificateForGpgKeys |
SIGNPATH_INCLUDE_DUMMY_X509CERTIFICATE_FOR_GPG_KEYS |
false |
Enables compatibility with clients that require X.509 objects (required for GPG hash signing due to gnupg-pkcs11-scd X.509-based key discovery) |
Logging settings:
JSON setting | Environment variable | Default Value | Description |
---|---|---|---|
Log.Console.Level |
SIGNPATH_LOG_CONSOLE_LEVEL |
none |
Log level used for console logging (not available on macOS) |
Log.Console.OutputStream |
SIGNPATH_LOG_CONSOLE_OUTPUT_STREAM |
stderr |
Console stream to use (either stderr or stdout ) (not available on macOS) |
Log.File.Level |
SIGNPATH_LOG_FILE_LEVEL |
info |
Log level used for file logging |
Log.File.Directory |
SIGNPATH_LOG_FILE_DIRECTORY |
Windows: %TEMP%\SignPathLogs , Linux: /tmp/SignPathLogs |
Path to the folder to store log files |
Supported log levels: none
, fatal
, error
, warning
, info
, debug
, verbose
.
Timeout settings:
JSON setting | Environment variable | Default Value | Description |
---|---|---|---|
Timeouts.HttpRequest |
SIGNPATH_TIMEOUTS_HTTP_REQUEST |
30 |
Timeout for HTTP calls in seconds per attempt |
Timeouts.FirstRetryDelay |
SIGNPATH_TIMEOUTS_FIRST_RETRY_DELAY |
1.16 |
Initial delay in seconds in case of failed API HTTP requests |
Timeouts.RetryCount |
SIGNPATH_TIMEOUTS_RETRY_COUNT |
10 |
Maximum number of retries in case of failed API HTTP requests |
HTTP timeouts and 5xx server erros (e.g. 503 Service Unavailable errors) are treated as failed requests.
The delay between retries increases exponentially. For the default values this sums up to a total delay time of 10 minuntes.
Sample configuration file:
{
"ApiUrl": "https://app.signpath.io/Api",
"OrganizationId": "$OrganizationId",
"ApiToken": "$ApiToken",
"Log": {
"Console": {
"Level": "warning"
},
"File": {
"Level": "info",
"Directory": "C:\\SignPath\\Logs"
}
}
}
API token options
The ApiToken
value can contain the API token in one of the following variants:
Value | Example |
---|---|
Unencrpyted token | AIk/65sl23lA1nVV/pgSqk96SvHFsSw3xitmp5Qhr+F/ |
DPAPI-encrypted token (Windows only) | encrypted:AQAAANCMnd8BFdERjHoAwE/Cl+sBAAA... |
Registry path to DPAPI-encrypted token (Windows only) | registry:HKEY_CURRENT_USER\\SOFTWARE\\SignPath\\MyEncryptedApiToken |
In order to encrypt the token, you can use the following PowerShell snippet:
$ApiToken = "..."
# Encrypt ApiToken with DPAPI and encode it in Base64 format
Add-Type -AssemblyName System.Security
$ApiTokenBytes = [System.Text.Encoding]::UTF8.GetBytes($ApiToken)
$EncryptedApiToken = [Security.Cryptography.ProtectedData]::Protect($ApiTokenBytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
$EncryptedBase64EncodedApiToken = [System.Convert]::ToBase64String($EncryptedApiToken)
To store the encrypted token in the Windows registry, you can use the following snippet:
$ApiTokenRegistryValueName = "MyEncryptedApiToken"
# Write encrypted & encoded ApiToken to registry
New-Item -Path "HKCU:\SOFTWARE\" -Name SignPath
New-ItemProperty -Path "HKCU:\SOFTWARE\SignPath" -Name "$ApiTokenRegistryValueName" -Value "$EncryptedBase64EncodedApiToken" -PropertyType "String"
HTTP Proxy
Optionally an HTTP web proxy can be used for the outgoing API requests.
On Windows by default the WinINet (“Internet Options”) proxy settings are respected.
Alternatively, a proxy server can be specified in the configuration (Windows and Linux) using the following value formats:
$ProxyHost:$ProxyPort
http://$ProxyHost:$ProxyPort
In case this configuration value is set, it overrides the system’s proxy settings on Windows.
SignPath Project
In order to perform hash-based signing with the Crypto Providers, perform the following steps in the SignPath UI:
- Create or open a Project
- Add an Artifact Configuration of type Hash signing data
- Set this Artifact Configuration as Default
- Remember the Project slug
- Create an dedicated CI User (recommended) or generate an API Token for your own Interactive User
- Remember the API token
- Create or open a Signing Policy for the Project
- Add the CI User or Interactive User as a Submitter
- Remember the Signing Policy slug