Skip to content

Code Signing

NeySlim edited this page Jun 13, 2026 · 1 revision

Code Signing

UCM issues and manages code-signing certificates — for Windows Authenticode, Java JARs and macOS. UCM is the CA/lifecycle side: it issues the certificate (with the right key usages and EKUs), exports it as PKCS#12, and can timestamp signatures via its built-in RFC 3161 TSA. The actual artifact signing is done by the standard platform tools (osslsigncode, jarsigner, codesign), which consume the certificate UCM issues.

1. Issue a code-signing certificate

Option A — built-in template. Certificates → Issue → template type Code Signing. This sets:

  • Key Usage: digitalSignature
  • Extended Key Usage: codeSigning (1.3.6.1.5.5.7.3.3)

Option B — add platform-specific EKUs. On the issue form (or CSR signing), use Extra EKUs (RFC 5280 §4.2.1.12) to add purpose OIDs on top of codeSigning. UCM ships these well-known code-signing EKUs in the picker:

Name OID Use
codeSigning 1.3.6.1.5.5.7.3.3 Base — Authenticode, JAR, generic
msIndividualCodeSigning 1.3.6.1.4.1.311.2.1.21 Authenticode (individual)
msCommercialCodeSigning 1.3.6.1.4.1.311.2.1.22 Authenticode (commercial)
msLifetimeSigning 1.3.6.1.4.1.311.10.3.13 Binds signature validity to the cert lifetime
msKernelModeCodeSigning 1.3.6.1.4.1.311.61.1.1 Windows kernel-mode drivers
appleCodeSigning 1.2.840.113635.100.4.1 macOS code signing
appleDeveloperIDApplication 1.2.840.113635.100.4.13 macOS Developer ID Application

Up to 16 EKUs per certificate. anyExtendedKeyUsage (2.5.29.37.0) is rejected.

Export the issued certificate as PKCS#12 (.p12/.pfx) — it bundles the leaf, private key and chain, which all three signing tools accept.

2. Sign with it

Windows — Authenticode (osslsigncode)

osslsigncode sign \
  -pkcs12 codesign.p12 -pass '<p12-password>' \
  -n "My App" -i https://example.com \
  -ts http://your-ucm-host:8080/tsa \
  -in app.exe -out app-signed.exe

-ts points at UCM's RFC 3161 timestamp authority so the signature stays valid after the certificate expires.

Java — JAR (jarsigner)

jarsigner needs a keystore. Convert the PKCS#12 (it is a PKCS#12 keystore) and sign:

jarsigner -keystore codesign.p12 -storetype PKCS12 \
  -storepass '<p12-password>' \
  -tsa http://your-ucm-host:8080/tsa \
  app.jar 1   # 1 = the key alias inside the .p12
# verify
jarsigner -verify -verbose -certs app.jar

macOS (codesign)

Import the PKCS#12 into the login keychain, then sign:

security import codesign.p12 -k ~/Library/Keychains/login.keychain-db -P '<p12-password>'
codesign --sign "<common-name>" --timestamp app.bundle
codesign --verify --verbose app.bundle

macOS Gatekeeper only trusts certificates chaining to Apple's roots. A UCM-issued certificate works for internal distribution (enterprise machines that trust your CA) — not for public notarized distribution.

3. Timestamping (TSA)

All three flows above use UCM's own RFC 3161 Time-Stamp Authority (/tsa on the HTTP protocol port). Timestamping is what keeps a signature valid after the signing certificate expires. See TSA — Timestamp Authority.

Scope

UCM issues, tracks, renews and revokes code-signing certificates and timestamps signatures. It does not itself run osslsigncode/jarsigner/codesign against your artifacts — that stays in your build pipeline, consuming the certificate UCM provides.

Clone this wiki locally