Jenkins plugin for keypair signing
Code Signing with Software Trust is a Jenkins plugin that streamlines keypair-based signing workflows to improve software security and integrates with DevOps processes to sign binaries.
This plugin accelerates the installation and configuration of clients and signature tools to help developers become signing-ready for Jenkins pipelines on Windows and Linux. It can also be used to set up client tools tasks.
You can download the plugin from the Jenkins Marketplace or by navigating to Jenkins homepage or dashboard > Manage Jenkins > Manage Plugins.
Prerequisites
DigiCert ONE account
DigiCert ONE client authentication certificate
Download Code signing with Software Trust Manager
Jenkins build system
Any agent with OS that supports Java on Jenkins
JDK installed on the agent
DigiCert® Software Trust Manager access setup
Before you begin
When running this plugin on a remote agent, the path environment variable for the installed tools isn't automatically set. The path as an environment variable must be manually configured in your pipeline script.
For example, on a Linux environment, add the following script to your pipeline script:
pipeline { agent any environment { PATH = "/root/smtools-linux-x64:${env.PATH}" } // other pipeline steps... }
For Linux, review the paths that the plugin sets up:
/<Jenkins user directory>/smtools-linux-x64
For Windows, review the paths that the plugin sets up:
C:\Program Files\DigiCert\DigiCert One Signing Manager Tools C:\Users\<Jenkins user directory> <Path to signtool.exe on the machine>
User authentication
Software Trust enforces multi-factor authentication for security. To access keypairs, certificates, and sign code, you need to set up two types of credentials: An API key and an authentication certificate.
Create an API key
The API key is an authentication method used to verify you as a user and your permissions assigned in DigiCert ONE. The API key provides the first factor authentication.
In DigiCert ONE, select the profile (
) icon, and then select Admin Profile.
Under API keys, select Create API key.
For Name, enter a descriptive name for the key.
For End date (optional), enter the date when the key should expire.
Select Create. The API key appears this one time and can't be accessed again. Securely store the API key for future use.
Create an authentication certificate
The client authentication certificate is an authentication method used to verify you as a user and your permissions assigned in DigiCert ONE. The client authentication certificate provides the second factor authentication.
In DigiCert ONE, select the profile (
) icon, and then select Admin Profile.
Under Client authentication certificates, select Create client authentication certificate.
For Nickname, enter a descriptive name for the key.
For End date, enter the date when the certificate should expire.
Select the desired Encryption and Signature hash algorithm.
Select Generate certificate. The password appears this one time and can't be accessed again. Download the certificate and securely store the password for future use.
Best practices for secure Jenkins use
To sign code using Software Trust, use secret text and files to ensure security and accountability among your Jenkins users.
Secrets are encrypted variables in Jenkins where users can input information without knowing the specific value. For example, you may not want your Jenkins collaborators to know your unique API key, but they may need it to access signing tools. As a result, you can set up a variable where "(api_key)" is the name and the value is the API key itself.
To connect with Software Trust, client tools needs environment variables to be configured, which this document explains.
Configure Jenkins secrets
Note
To perform this action, you must be a Jenkins user with the Credentials > Create permission.
Sign in to Jenkins.
Go to Jenkins homepage or dashboard > Manage Jenkins > Manage Credentials > Store > Jenkins > System > Global credentials (unrestricted).
Select Add credentials.
Select the desired Scope:
Scope type
Description
Global
Apply the scope of the credentials to the Pipeline project/item "object" and all its descendant objects.
System
Apply the scope of the credentials to a single object.
Add the following types of credentials:
ID
Credential type
Description
SM_API_KEY
Secret text
Copy and paste your Software Trust API token in Secret.
SM_CLIENT_CERT_FILE
Secret file
Select Choose file, and then upload your Software Trust client authentication certificate.
SM_CLIENT_CERT_PASSWORD
Secret text
Copy and paste your Software Trust client certificate password in Secret.
SM_HOST
Secret text
Copy and paste your Software Trust host environment in Secret.
Integrate with Jenkins
To integrate with environment variables that are part of the pipeline, review the following script:
pipeline { agent any environment { SM_API_KEY = credentials('SM_API_KEY') SM_HOST = credentials('SM_HOST') SM_CLIENT_CERT_PASSWORD = credentials('SM_CLIENT_CERT_PASSWORD') SM_CLIENT_CERT_FILE = credentials('SM_CLIENT_CERT_FILE') }
Note
Alternatively, you can integrate environment variables at an operating system environment level.
To add a stage to the pipeline script and call the plugin to perform Software Trust setup for standard keypairs, review the following script:
stages { stage('Set Up Software Trust Manager') { steps { SoftwareTrustManagerSetup() } } }
Jenkins pipeline for standard keypair signing
To learn about signing a file using a standard keypair, review the following sample Jenkins pipeline scripts:
Windows
pipeline { agent any environment { PATH = "C:\\Program Files\\DigiCert\\DigiCert One Signing Manager Tools;${env.PATH}" SM_API_KEY=credentials('SM_API_KEY') SM_HOST=credentials('SM_HOST') SM_CLIENT_CERT_PASSWORD=credentials('SM_CLIENT_CERT_PASSWORD') SM_CLIENT_CERT_FILE=credentials('SM_CLIENT_CERT_FILE') } stages { stage('Set up Software Trust Manager') { steps { SoftwareTrustManagerSetup() sh''' smctl sign --keypair-alias <keypair alias> --config-file <Software Trust Manager PKCS11 config file> --input path\to\your\unsignedfile ''' } } } }
Linux
pipeline { agent any environment { PATH = "/root/smtools-linux-x64:${env.PATH}" //path to the tools directory SM_API_KEY=credentials('SM_API_KEY') SM_HOST=credentials('SM_HOST') SM_CLIENT_CERT_PASSWORD=credentials('SM_CLIENT_CERT_PASSWORD') SM_CLIENT_CERT_FILE=credentials('SM_CLIENT_CERT_FILE') } stages { stage('Set up Software Trust Manager') { steps { SoftwareTrustManagerSetup() sh''' smctl healthcheck smctl sign --keypair-alias <keypair alias> --config-file /root/smtools-linux-x64/pkcs11properties.cfg --input path/to/your/unsignedfile ''' } } } }
Create keypair and certificate
The following commands may require the following inputs:
Keypair alias
Keypair ID
Certificate alias
Certificate profile ID.
The certificate profile ID used must belong to the correct profile category.
To create a keypair and default certificate, run the following script:
stage('keypair setup') { steps { bat 'smctl keypair generate rsa <keypair alias> --cert-alias=<certificate alias> --cert-profile-id=<certificate profile ID> --generate-cert=true --key-type=<TEST or PRODUCTION>' }
To create a certificate from an existing keypair, run the following script:
stage('keypair setup') { steps { bat 'smctl keypair generate-cert <keypair ID> --cert-alias=<certificate alias> --cert-profile-id=<certificate profile ID> --set-as-default-cert=true --key-type=<TEST or PRODUCTION>' }
Signing
To sign with the default signing tool, run the following script:
Note
The input parameters are the path to the file that needs to be signed, the name/alias of the certificate that needs to be used for signing, and the alias of the keypair used for signing.
stage('sign') { steps{ bat 'smctl sign --keypair-alias <keypair alias> --config-file <Software Trust Manager PKCS11 config file> --input <unsigned file> -v' } }
To sign using signtool.exe, run the following script:
Note
The input parameters are the alias of the keypair used for signing, the name/alias of the certificate that needs to be used for signing, and the path to the file that needs to be signed.
stage('sign') { steps { bat 'signtool.exe sign /csp "DigiCert Signing Manager KSP" /kc "<keypair alias>" /f <certificate> /tr http://timestamp.digicert.com <unsigned file>' }
To sign using nuget.exe, run the following script:
Note
The input parameters are the the path to the file that needs to be signed, the path of the output signed file, and the fingerprint of the certificate that needs to be used for signing.
stage('sign') { steps { bat 'nuget sign <unsigned file> -Timestamper http://timestamp.digicert.com -outputdirectory <output path for signed file> -CertificateFingerprint <certificate fingerprint> -Verbosity detailed -Overwrite' }
To sign using Jarsigner, run the following script:
Note
The input parameters are the path where the signed jar needs to be output, the path to the jar that needs to be signed, and the name/alias of the certificate that needs to be used for signing.
stage('sign') { steps { bat 'jarsigner -keystore NONE -storetype Windows-My -signedjar <output path for signed file> -sigalg SHA256withRSA -digestalg SHA256 <unsigned file> <keypair alias>' }
To sign using Jsign, run the following script:
stage('sign') { steps{ bat 'jsign --keystore pkcs11properties.cfg --storepass NONE --storetype PKCS11 --alias <keypair alias> <unsigned file> jsign –keystore <path to Software Trust Manager PKCS11 config file> –storepass NONE –storetype PKCS11 -alias <keypair alias>' } }
Verify signature
Note
The only input is the path to the signed file that needs to be verified.
To verify using SignTool, run the following script:
stage('verify') { steps { bat 'signtool.exe sign verify /v /pa <signed file>' }
To verify using NuGet, run the following script:
stage('verify') { steps { bat 'nuget verify -all <signed file>' }
To verify using Jarsigner, run the following script:
stage('verify') { steps { bat 'jarsigner -verify <signed file>' }