This is a quick cheatsheet for using Smallstep CA. It is not meant to be a comprehensive guide, but rather a quick reference for myself. It starts with the common tasks, but contains install and setup information as the end of the document.

Overview

This setup creates a Certificate Authority using the Smallstep CA, and a Nitrokey HSM 2 to protect the keying material.

I do this so that I can login to things like Opengear terminal servers, Dell iDRAC interfaces, Proxmox machines and similar without getting the annoying NET::ERR_CERT_AUTHORITY_INVALID error message from Chrome.

This really is not intended to replace more secure solutions, but instead as a convenience.

Note that the Smallstep support for PKCS #11 is still a beta, and requires adding the step-kms-plugin as well as building a local copy of step-ca

My Certificates

  1. Kumari Root EC CA
  2. Kumari Intermediate EC CA

Common tasks

Signing a CSR

This will take a Certificate Signing Request and generate a certificate. In order to keep these organized I store them in ~/src/code/CA/certificates.

Because I am using the PKCS11 interface, I cannot use “offline” mode, and instead use the (locally compiled, with PKCS#11 support) step-ca program.

This means that I need to start Step CA, and then use step to actually sign the certificates. Don’t forget to stop step-ca after this. It is configured to only listen on 127.0.0.1:8100, so it’s not really the end of the world if I do forget, but…

  1. Start step-ca
  2. In another window: step ca sign test.example.com.csr test.example.com.crt NOTE: This will prompt for a provisioner password. As this is only available locally, it is “password”.
  3. Inspect the new certificate: step certificate inspect --short test.example.com.crt
  4. Stop step-ca

Creating a certificate without a CSR

Sometimes devices don’t have an easy way to make a CSR, and instead expect you to make a key and certificate for them. If this is the case, step can create a key and CSR, and then use the above to sign it.

$ step certificate create --csr --san localhost --san example.com 192.0.2.1 test.example.com.csr test.kumari.net.key

Please enter the password to encrypt the private key:

Inspecting a certificate

To inspect a certificate, you can use the step certificate inspect CLI tool. The basic command:

step certificate inspect --short test.example.com.crt                                                      ✔
X.509v3 TLS Certificate (ECDSA P-256) [Serial: 2898...4074]
  Subject:     127.0.0.1
               localhost
               macbook
  Issuer:      My Intermediate CA
  Provisioner: [email protected] [ID: Odw5...Aisg]
  Valid from:  2026-03-08T08:43:38Z
          to:  2036-03-05T08:44:38Z

List issued certificates

To list issued certificates, you can use the step-badger CLI tool. This is a third party tool, from step-badger

The basic command:

step-badger x509Certs ~/.step/db
Serial number                            Subject             Start                 Finish                Validity
302993289828619663782218509723082042948  CN=test.example.com  2026-03-08T04:05:50Z  2026-03-09T04:06:50Z  Valid
288747816944534935195190911414687768787  CN=test.example.com  2026-03-08T04:06:41Z  2026-03-09T04:07:41Z  Valid

Note: Because this uses the database, step-ca must be stopped.

Troubleshooting

Forgot to plug in the HSM

This bit me once - I fetched the HSM and connected the adapter - but forgot to actually connect the HSM to the adapter. The error message is clear though: error initializing PKCS#11: could not find PKCS#11 token

$ step-ca
badger 2026/03/29 20:04:08 INFO: All 1 tables opened in 0s
badger 2026/03/29 20:04:08 INFO: Replaying file id: 0 at offset: 20127
badger 2026/03/29 20:04:08 INFO: Replay took: 1µs
error initializing PKCS#11: could not find PKCS#11 token

OS X Update breaks PKCS#11

This is a known issue with OS X updates - see Nitrokey HSM Getting Started for more information.

Symptoms

$ step-ca
error initializing PKCS#11: could not find PKCS#11 token
$ pkcs15-tool -D
Using reader with a card: Nitrokey Nitrokey HSM
Failed to connect to card: Unresponsive card (correctly inserted?)

Solution

The problem can be fixed by either copying /usr/libexec/SmartCardServices to /usr/local/libexec/SmartCardServices

sudo mkdir -p /usr/local/libexec/SmartCardServices/drivers
sudo cp -a /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle /usr/local/libexec/SmartCardServices/drivers

Note: This is a known issue with OS X updates - see Nitrokey HSM Getting Started for more information.

Note: Ignore the errors from chown / permissions…

Setup and installation

Initializing the Nitrokey HSM

sc-hsm-tool --initialize --so-pin <16 char hex> --pin <6 char pin>

Printing the key info

$ pkcs15-tool -D
Using reader with a card: Nitrokey Nitrokey HSM
PKCS#15 Card [SmartCard-HSM]:
 Version        : 0
 Serial number  : DENKxxx
 Manufacturer ID: www.CardContact.de
 Flags          :

PIN [UserPIN]
 Object Flags   : [0x03], private, modifiable
 Auth ID        : 02
  [...]
 Tries left     : 3

PIN [SOPIN]
 Object Flags   : [0x01], private
 ID             : 02
 [...]
 Tries left     : 15

Make things simpler - save

export PKCS_URI='pkcs11:module-path=/usr/local/lib/opensc-pkcs11.so;token=SmartCard-HSM;pin-value=<PIN>;id=1;object=root-ca-ec'

Creating the CA key

step kms create 'pkcs11:module-path=/usr/local/lib/opensc-pkcs11.so;token=SmartCard-HSM;pin-value=<KEY>;id=1;object=root-ca-ec'
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoKX9OFloafydMUzgJJkvE1iN7DQr
IPAE6BBgdXuWERsGWkpKx+79mPO8NwBs3Yjv+fRL2/RATvIOoaBthaX42g==
-----END PUBLIC KEY-----

Creating the Root Certificate

step certificate create --profile root-ca --not-after 219000h \
--kms
'pkcs11:module-path=/usr/local/lib/opensc-pkcs11.so;token=SmartCard-HSM;pin-value=<6 char key>;id=1;object=root-ca-ec'\
--key 'pkcs11:id=1;object=root-ca-ec'  "Kumari Root EC CA" root_ca_ec.crt

This creates a root certificate with a 25 year validity (219000h)

Create the Intermediate Certificate

$ step kms create --kms "$PKCS_URI" "pkcs11:id=2;object=intermediate-ca-ec"
# And the certificate (also with 25 year life):
$ step certificate create --profile intermediate-ca --not-after 219000h \\                                              1   15s 
   --kms "$PKCS_URI" \\
   --ca-kms "$PKCS_URI" \\
   --ca root_ca_ec.crt \\
   --ca-key "pkcs11:id=1;object=root-ca-ec" \\
   --key "pkcs11:id=2;object=intermediate-ca-ec" \\
   "Kumari Intermediate EC CA" intermediate_ca_ec.crt

Setting defaults

# Defaults - 5year, max 10 year.
step ca provisioner update "[email protected]" --x509-default-dur=43800h --x509-min-dur=5m --x509-max-dur=87600h