Closed carlhoerberg closed 8 years ago
Her is a write-up for running CFSSL against softHSM (not better than using file based secrets security wise, but it exercises the pkcs11 code) in ten wonky steps. This is a proof-of-concept, do not use in production!
You follow this outline at your own risk! If your HSM catches fire, it's on you. This write-up describes what worked once for me. It's not official. Horrible hacks abound. Not tested, only ran once on ubuntu 14.04.
# 1. Install pre-requisites
aptitude install libldtl-dev # to build github.com/miekg/pkcs11
aptitude install gnutls-bin # for p11tool
aptitide install opensc # for pkcs11-tool
aptitude install softhsm libsofthsm
# 2. Build CFSSL with pkcs11 support
go get -u -a -tags pkcs11 github.com/cloudflare/cfssl/cmd/...
# 3. If you haven't yet, create key and cert for CA
# (see notes on how this part of the instructions are conceptually broken)
# (requires csrjson as config for cert).
cfssl genkey -initca csrjson | cfssljson -bare ca
# 4. Convert ca-key to DER format
openssl rsa -in ca-key.pem -outform DER -out ca-key.der
# 5. Set shortcut for pkcs#11 implementation of softhsm
export HSMLIB=/usr/lib/softhsm/libsofthsm.so
# 6. Initialize a new token (asks you to set an SO pin)
pkcs11-tool --module ${HSMLIB} --init-token --label cfssl_token
# 7. Set user pin (assume 1234 for the example, but see below)
pkcs11-tool --module ${HSMLIB} --init-pin --label cfssl_token --login
# 8. Import private key into soft token.
# Ugly, but trying to import with pkcs11-tool breaks badly.
HSM_TOKEN_URI=$(\
p11tool --provider ${HSMLIB} --list-tokens --no-detailed-url |\
awk '/URL:.*SoftHSM/{print $2}')
p11tool --provider ${HSMLIB} --login --write ${HSM_TOKEN_URI} \
--load-privkey ca-key.der --inder --label 'cfssl_privkey'
# 9. Remove on-disk key.
# If your HSM breaks after this, you need to create a new signing cert.
rm -f ca-key.pem ca-key.der
# 10. Run CFSSL with pkcs11 flags
$GOPATH/bin/cfssl -loglevel 0 serve \
-config=/etc/cfssl/config.json -ca=/etc/cfssl/ca.pem \
-pkcs11-module=${HSMLIB} -pkcs11-label="cfssl_privkey" \
-pkcs11-token="SoftHSM" -pkcs11-pin=1234 # https://youtu.be/a6iW-8xPw3k?t=33
-pkcs11-module
is as expected, the .so library implementing the pkcs11 interface to your HSM
-pkcs11-label
is the label of the imported key as set in step 8 above
-pkcs11-token
is the name of the HSM Model / Manufacturer (crypto/pkcs11key
actually looks up a SlotDescription which is neither a token nor unique if you have multiple slots in one HSM; I only figured this one out with some strategic debug statements).
-pkcs11-pin
is the pin as a command line arg (sic). Everyone on your machine will be able to see this, so running CFSSL in this configuration is not secure. That said, there is helpers/pkcs11uri
which mentions that pins can only come from a file pin-source. I expect future changes here.
It bears repeating that the above write-up is how I did it, not how it should be done. In a production environment you want to create the key on the HSM (i.e., using pkcs11-tool --keypairgen --keytype rsa:1024 --token-label cfssl_token --label cfssl_privkey --login
) and then sign with that.
cfssl genkey
doesn't support pkcs11, but it should. I filed issue https://github.com/cloudflare/cfssl/issues/254 as a feature request.
It's also worth noting that certificate signing in go 1.4.2 (the latest stable) with an HSM won't work because the x509 library expects a crypto.PrivateKey
, while a PKCS11 token can only provide crypto.Signer
. The latest master branch of Go accepts crypto.Signer
in the x509 library. With the release of go 1.5 in ~August, this should just work out of the box.
https://github.com/golang/go/commit/fe40cdd756763982db6815ee87318f418218fcf5
I've produced a script to help with this: https://github.com/jcjones/cfssl-pkcs11-ca
@jcjones Thanks for this; I'll include a link in the documentation.
This will be handled in a separate repo.
Hi,
I recently attempted to follow these directions however the latest build doesn't seem to support pkcs#11. Any latest updates on how the PKCS#11 integration?
I work for Thales (we manufacturer the nShield/nCipher HSMs) and trying to perform interop testing.
Regards, Ivan
The PKCS#11 code has been moved into a separate package, https://github.com/letsencrypt/pkcs11key.
Hi,
I tried to find documentation how to use cfssl with a HSM, but found the few bits of documentation rather unhelpful.
What steps are needed to integrate the pcks#11 functionality in the letsencrypt repository with cfssl (via multirootca possibly)?
Could this be configured or have the respesctive tools in cfssl to be patched to support pcks#11?
Regards, Jens
@jsha , am I understand this well, the latest stable cfssl release does not have HSM support?
@silveraid I believe that the cfssl
binary does not have HSM support, but if you are compiling your own binaries using the cfssl libraries, you can provide HSM support using the pkcs11key
module. See also https://github.com/cloudflare/cfssl/issues/563.
How do you use a pkcs#11 module with cfssl?