-
Notifications
You must be signed in to change notification settings - Fork 145
Creating a CA with a Pkcs11 Module
The following example sets up a local CA using a pkcs11 module as the (root) CA. The setup is done under a user's account.
We use softhsm2 as an example pkcs11 module since it is commonly available. certtool
is part of the gnutls package.
First we setup softhsm2:
#> sudo apt-get install -y softhsm gnutls-bin # Debian/Ubuntu
#> sudo dnf install -y softhsm gnutls-utils # Fedora/RedHat
#> mkdir -p ~/.config/softhsm2/tokens
#> cat <<_EOF_ > ~/.config/softhsm2/softhsm2.conf
directories.tokendir = ${HOME}/.config/softhsm2/tokens
objectstore.backend = file
log.level = DEBUG
slots.removable = false
_EOF_
#> export SOFTHSM2_CONF=${HOME}/.config/softhsm2/softhsm2.conf
#> softhsm2-util --init-token --label mytoken --free --so-pin my-so-pin --pin my-pin
Slot 0 has a free/uninitialized token.
The token has been initialized and is reassigned to slot 353319736
We set SOFTHSM2_CONF
to the location of our softhsm2 configuration file. In this particular case it would not have been necessary since the file at ${HOME}/.config/softhsm2/softhsm2.conf
is being searched automatically by softhsm2, but it makes clear where the file is located at.
Now we use certtool to create the private key for our root CA. We then create a self-signed certificate.
In every step involving pkcs11 URIs, one has to use the pkcs11 URIs shown in the local output, so do not just copy all the command lines here. All URIs used on the command line have to be surrounded by single quotes (').
#> p11tool --list-tokens
[...]
Token 2:
URL: pkcs11:model=SoftHSM%20v2;manufacturer=SoftHSM%20project;serial=b5187422150f3b38;token=mytoken
Label: mytoken
Type: Generic token
Flags: RNG, Requires login
Manufacturer: SoftHSM project
Model: SoftHSM v2
Serial: b5187422150f3b38
Module: /usr/lib64/pkcs11/libsofthsm2.so
[...]
#> p11tool --generate-privkey=rsa --login --set-pin my-pin --label cakey \
'pkcs11:model=SoftHSM%20v2;manufacturer=SoftHSM%20project;serial=b5187422150f3b38;token=mytoken'
Generating an RSA key...
-----BEGIN PUBLIC KEY-----
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA4P9KeEDe5iy8FmKg1FGM
BzCFdyUlCkW/evMr0s8Rr2kMcheZfNdI8/AIG99Ih3hAzs1Q5wiqXpM68L+IcRce
pzO1DRYW6nlzdXSJUgGEoWehhFme3sltYegh57kPti30C3qHPIrpXLNkCLXt4fOt
arY/r+D7W7WR/XAnUKgWGBPkUKYo9uOabkQC9c7vdJ2IBengg+gGCo1V6QMHOSlt
HtIDC7vjNXcnWAZymdD+AWnPgIv4aHhGad6cIAQmiTnEiVP85QlY2lxkOaVgQK4w
lcjlwXEuQi1oamIg+o10ZC4JFozCt9amEGGnhJjKurzj6qKfYwm/Lxd3FZt4SWWR
lU9pjz/PrR2Z4KOG2xzwsgd+9GVKR91FfMkiIc6eNZz9gGB0rnnzlKDYlIsLFNY3
0pp6ksPRkeutnVK6Ct+mcysI1gLwfhfr1FJ4LFLkVO/np6JmYMuZlj5rNdBZIRaC
qEdZvaScFMTkwJI9uoyHC0Y4nJMo0xt0HAz2jIHj2n3lAgMBAAE=
-----END PUBLIC KEY-----
#> p11tool --list-privkeys --login --set-pin my-pin \
'pkcs11:model=SoftHSM%20v2;manufacturer=SoftHSM%20project;serial=b5187422150f3b38;token=mytoken'
URL: pkcs11:model=SoftHSM%20v2;manufacturer=SoftHSM%20project;serial=b5187422150f3b38;token=mytoken;id=%DE%75%15%CF%BD%C4%70%51%89%F4%68%10%1B%01%4E%1D%0E%B9%F0%E9;object=cakey;type=private
Type: Private key (RSA-3072)
Label: cakey
Flags: CKA_WRAP/UNWRAP; CKA_PRIVATE; CKA_NEVER_EXTRACTABLE; CKA_SENSITIVE;
ID: de:75:15:cf:bd:c4:70:51:89:f4:68:10:1b:01:4e:1d:0e:b9:f0:e9
#> export SIGNINGKEY='pkcs11:model=SoftHSM%20v2;manufacturer=SoftHSM%20project;serial=b5187422150f3b38;token=mytoken;id=%DE%75%15%CF%BD%C4%70%51%89%F4%68%10%1B%01%4E%1D%0E%B9%F0%E9;object=cakey;type=private'
#> cat <<_EOF_ > template
cn=swtpm-localca-rootca
ca
cert_signing_key
expiration_days = 3650
_EOF_
#> GNUTLS_PIN=my-pin certtool --generate-self-signed --template template --outfile issuercert.pem --load-privkey ${SIGNINGKEY}
Generating a self signed certificate...
[...]
Signing certificate...
We now have our root CA's certificate in issuercert.pem. Let's set up a local CA and create an EK certificate. The signing key is the pkcs11 URI of the private key. We can pass the PIN either using SWTPM_PKCS11_PIN
or signingkey_password
(since swtpm 0.5.0) or append ?pin-value=my-pin
to the URI. We also write the softhsm2 environment variable into this file so that the softhsm2 pkcs11 module will find its configuration file.
#> XDG_CONFIG_HOME=${HOME}/.config /usr/share/swtpm/swtpm-create-user-config-files
Writing /home/stefanb/.config/swtpm_setup.conf.
Writing /home/stefanb/.config/swtpm-localca.conf.
Writing /home/stefanb/.config/swtpm-localca.options.
#> cat <<_EOF_ > ${HOME}/.config/swtpm-localca.conf
statedir = ${HOME}/.config/var/lib/swtpm-localca
signingkey = ${SIGNINGKEY}
signingkey_password = my-pin
issuercert = ${HOME}/.config/var/lib/swtpm-localca/issuercert.pem
certserial = ${HOME}/.config/var/lib/swtpm-localca/certserial
env:SOFTHSM2_CONF=${HOME}/.config/softhsm2/softhsm2.conf
_EOF_
#> mv issuercert.pem ~/.config/var/lib/swtpm-localca/issuercert.pem
#> /usr/share/swtpm/swtpm-localca --type ek --ek da625739e699ac82d1f76ea42f368d8870a33a6a062ef6c7beb9545e1d11d23652544a47f36b3c33cb054671e4db0497624a451da4b6314aba9fb11bf1feac6d6960a600633987f90613413a3f0e3b6680445ce7d30e1d9d0edcb48349717fbe1c66cf51e1e6750d229d290ebba423e5b966c15f5e4a13b6bf51d10cb023c60fd8a086d3897efbb11b136580aeac9646abf38fb9ba67f6109d6fb644df6b343d3604031efcad11f58c1ce8de1ebe85ded71339573b319ba60805e80c298c64dd2b44160537bf9a96309e5b64ac5df76784f133c09d79755588eacf1a7d2a1067725b8e3d03467d46df3e390d1cc98372df5d4ffd7f68401d53404f54485ebf55 \
--dir ./ --tpm-spec-family 2.0 --tpm-spec-level 0 --tpm-spec-revision 162 --tpm-manufacturer id:00001014 \
--tpm-model swtpm --tpm-version id:20191023 --tpm2 --configfile ${HOME}/.config/swtpm-localca.conf \
--optsfile ${HOME}/.config/swtpm-localca.options --vmid test
CA uses a PKCS#11 key; using password from 'signingkey_password'
Successfully created EK certificate locally.
#> ls -l ek.cert
-rw-rw-r--. 1 stefanb stefanb 1015 Sep 18 14:05 ek.cert
Finally, we verify the certificate chain.
#> certtool -i --inder --infile ek.cert --outfile ekcert.pem
#> certtool --verify --load-ca-certificate ${HOME}/.config/var/lib/swtpm-localca/issuercert.pem \
--infile ekcert.pem --verify-profile medium
Loaded CAs (1 available)
Subject: CN=test
Issuer: CN=swtpm-localca-rootca
Checked against: CN=swtpm-localca-rootca
Signature algorithm: RSA-SHA256
Output: Verified. The certificate is trusted.
Chain verification output: Verified. The certificate is trusted.
If libvirt is used in user mode, then this local CA will create the TPM certificates. To use a similar CA in libvirt's 'system mode', the configuration file /etc/swtpm-localca.conf
would have to be adapted accordingly.