Hi Rob,
I was trying to set up a configuration where certmonger would generate
and track a key in an NSS database with an HSM token. I used SoftHSMv2
for the token.
The script roughly describing what I did is attached. You need to put
SELinux in permissive as it would be messing up on certmonger's access.
On Rawhide it creates a private key in the HSM but unable to store a
public key of the certificate there. Rawhide has p11-kit proxy active
and that complicates things because any NSS db gets p11-kit-proxy.so
PKCS11 module injected via crypto-policy:
# cat /etc/crypto-policies/back-ends/nss.config
library=
name=Policy
NSS=flags=policyOnly,moduleDB
config="disallow=ALL allow=HMAC-SHA256:HMAC-SHA1:HMAC-SHA384:HMAC-SHA512:SECP256R1:SECP384R1:SECP521R1:aes256-gcm:chacha20-poly1305:aes256-cbc:camellia256-cbc:aes128-gcm:aes128-cbc:camellia128-cbc:SHA256:SHA384:SHA512:SHA1:ECDHE-RSA:ECDHE-ECDSA:RSA:DHE-RSA:tls-version-min=tls1.0:dtls-version-min=dtls1.0:DH-MIN=1023:DSA-MIN=2048:RSA-MIN=2048"
name=p11-kit-proxy
library=p11-kit-proxy.so
when p11-kit-proxy.so is injected, it makes all configured PKCS11
modules available in all NSS databases. Even if my script tries to
insert an explicit PKCS11 module into the database used for a
certificate generation, I can skip that on Rawhide as p11-kit-proxy does
it for me:
# certutil -d sql:my-token -U
slot: NSS User Private Key and Certificate Services
token: NSS Certificate DB
uri: pkcs11:token=NSS%20Certificate%20DB;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203
slot: NSS Internal Cryptographic Services
token: NSS Generic Crypto Services
uri: pkcs11:token=NSS%20Generic%20Crypto%20Services;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203
slot: SoftHSM slot ID 0x5489b984
token: HSM
uri: pkcs11:token=HSM;manufacturer=SoftHSM%20project;serial=396d3e3c5489b984;model=SoftHSM%20v2
slot: SoftHSM slot ID 0x1cf72acc
token: my-token
uri: pkcs11:token=my-token;manufacturer=SoftHSM%20project;serial=77cb41421cf72acc;model=SoftHSM%20v2
Anyway, even if I disable this injection with
NSS_IGNORE_SYSTEM_POLICY=1, it doesn't help because the environment
variable has to be specified for certmonger process too. I tried that as
well and it doesn't help, so there seems to be a bug with certmonger's
processing of PKCS11 modules in nss and p11-kit proxying is not really
changing that.
Certmonger is confused when it doesn't succeed in unlocking a token even
if it is a wrong token:
# certmonger -S -p /var/run/certmonger.pid -n -d 2
2018-08-21 17:42:15 [26673] Changing to root directory.
2018-08-21 17:42:15 [26673] Obtaining system lock.
2018-08-21 17:42:15 [26677] Token is named "NSS Generic Crypto Services", not "NSS Certificate DB", skipping.
2018-08-21 17:42:15 [26677] Token is named "HSM", not "NSS Certificate DB", skipping.
2018-08-21 17:42:15 [26677] Token is named "my-token", not "NSS Certificate DB", skipping.
2018-08-21 17:42:15 [26678] Error authenticating to token "HSM".
2018-08-21 17:42:15 [26679] Error authenticating to cert db.
2018-08-21 17:42:15 [26679] Error authenticating to cert db.
2018-08-21 17:42:15 [26679] Error locating certificate.
2018-08-21 17:42:15 [26680] Token is named "NSS Certificate DB", not "my-token", skipping.
2018-08-21 17:42:15 [26680] Token is named "HSM", not "my-token", skipping.
2018-08-21 17:42:15 [26681] Token is named "NSS Certificate DB", not "my-token", skipping.
2018-08-21 17:42:15 [26681] Token is named "NSS Generic Crypto Services", not "my-token", skipping.
2018-08-21 17:42:15 [26681] Token is named "HSM", not "my-token", skipping.
2018-08-21 17:42:15 [26681] Error locating certificate.
2018-08-21 17:42:17 [26733] Certificate "Local Signing Authority" valid for 29682906s.
2018-08-21 17:42:17 [26731] Error authenticating to token "HSM".
2018-08-21 17:42:20 [26673] No hooks set for pre-save command.
2018-08-21 17:42:21 [26750] PIN was not needed to auth to key store, though one was provided. Treating this as an error.
2018-08-21 17:42:21 [26750] Error shutting down NSS.
Somehow, it doesn't see my token at all but still manages to store the
private key there. It then leaves the request in a state
NEED_CERTSAVE_PIN:
# getcert list -i 20180821173352
Number of certificates and requests being tracked: 4.
Request ID '20180821173352':
status: NEED_CERTSAVE_PIN
stuck: yes
key pair storage: type=NSSDB,location='sql:/root/test-token/my-token',nickname='my-cert',token='my-token',pin set
certificate: type=NSSDB,location='sql:/root/test-token/my-token',nickname='my-cert',token='my-token'
CA: SelfSign
issuer:
subject:
expires: unknown
pre-save command:
post-save command:
track: yes
auto-renew: yes
If I look at the SoftHSMv2 token directly (via pkcs11-tool), I can see
that the key and the cert are both there:
# pkcs11-tool --module /usr/lib64/pkcs11/libsofthsm2.so --token-label my-token -l -p Test1234 -O
Public Key Object; RSA 2048 bits
label:
ID: f9119ce98a883f7f75a72fb32faed0125b1b31a3
Usage: encrypt, verify, wrap
Private Key Object; RSA
label: my-cert
ID: f9119ce98a883f7f75a72fb32faed0125b1b31a3
Usage: decrypt, sign, unwrap
Using certutil I can also see the private key but not the public one there:
# certutil -d sql:my-token -L -h my-token
Certificate Nickname Trust Attributes
SSL,S/MIME,JAR/XPI
Enter Password or Pin for "my-token":
[root@ho-2 test-token]# certutil -d sql:my-token -K -h my-token
certutil: Checking token "my-token" in slot "SoftHSM slot ID 0x1cf72acc"
Enter Password or Pin for "my-token":
< 0> rsa f9119ce98a883f7f75a72fb32faed0125b1b31a3 my-cert
--
/ Alexander Bokovoy
Sr. Principal Software Engineer
Security / Identity Management Engineering
Red Hat Limited, Finland