I just got a Nitrokey HSM 2, and I’m trying to use it to build an internal PKI infrastructure. I have generated a root CA certificate on the HSM, and generated the intermediate CA on the HSM, I also generated a CSR from the intermediate certificate onto my computer. My next objective is to sign the intermediate CA with the root certificate. I’ve tried running variations on the following commands:
In both cases, and in other variations of the above, I get the following error:
engine "pkcs11" set.
Using configuration from ../ca.ini
Format not recognized!
The key ID is not a valid PKCS#11 URI
The PKCS#11 URI format is defined by RFC7512
The legacy ENGINE_pkcs11 ID format is also still accepted for now
Format not recognized!
The key ID is not a valid PKCS#11 URI
The PKCS#11 URI format is defined by RFC7512
The legacy ENGINE_pkcs11 ID format is also still accepted for now
PKCS11_get_private_key returned NULL
cannot load CA private key from engine
139786102428992:error:80065064:pkcs11 engine:ctx_load_key:invalid id:eng_back.c:659:
139786102428992:error:26096080:engine routines:ENGINE_load_private_key:failed loading private key:crypto/engine/eng_pkey.c:77:
unable to load CA private key
I’m not sure why I’m getting that error, except that when I run the following command, I get a message that reading the private key is not supported.
$ pkcs11-tool -l --read-object --type privkey --label rootUsing slot 0 with a present token (0x0)
Logging in to "SmartCard-HSM (UserPIN)".
Please enter User PIN:
sorry, reading private keys not (yet) supported
Is signing from HSM generated private keys supported on the Nitrokey HSM 2?
The cited error says, that OpenSC cannot get the proper key handle to the key.
Have you tried specifying the slot ID, under which the key was stored instead of the URI? E.g. a number from range 1-15? As far as I see you do not use any label for the key to identify in the URI as well - maybe that’s the cause. Something like:
ca -engine pkcs11 -keyfile "15" -keyform engine -config ./openssl-rootca.conf
(edit by @szszszsz: difference in the --key switch parameter).
I found this page to have the best description for a PCKS11 URI format. Therefore, I tried several permutations on the PKCS11 URI scheme. Here are some that I’ve tried:
I found out that ‘p11tool’ will show you the proper format for the PKCS11 URI, so I copied that, and it’s still not working. I’m still getting the following error message:
PKCS11_get_private_key returned NULL
cannot load CA private key from engine
Is that because I can’t get the private key?
$ pkcs11-tool -l --read-object --type privkey --label root
Using slot 0 with a present token (0x0)
Logging in to "SmartCard-HSM (UserPIN)".
Please enter User PIN:
sorry, reading private keys not (yet) supported
The message is about reading the private key in a raw format from the device. Nitrokey HSM does not allow to do so, unless in encrypted form using DKEK, hence the error (this is expected).
Could you run signing using OpenSC (e.g. with pkcs11-tool) to confirm the key is correctly written to the device and usable?
I saw in the micro-ca-tool, that they use OpenSSL shell/REPL instead of command switch to set the environment. Could you do the same?
I see you are using -key switch in the OpenSSL call. Should not that be -keyfile (as in micro-ca-tool#L507)?
Then, you are correctly prompted to enter your pin and have your certificate signed.
engine "pkcs11" set.
Using configuration from create_root.ini
Enter PKCS#11 token PIN for SmartCard-HSM (UserPIN):
Check that the request matches the signature
Signature ok
Certificate Details:
...
I ran through the tutorial again this morning to make sure that I couldn’t find any problems, and everything works exactly as expected. So, feel free to use and change it in any way that you want!
Originally, I was using openssl ca -config myconfig.cnf -engine pkcs11 -keyform engine -key 00 -gencrl -out crl/mycrl.crl and it was generating the errors:
Format not recognized!
The key ID is not a valid PKCS#11 URI
It strange because specifying -key {id} works perfectly fine when generating an x509 certificate but doesn’t seem to work when you want to sign. However, using -keyfile {id} worked like a charm!
Maybe it will help someone in the future: I had identical problem to the one in the original post. In the end I discovered that it wasn’t the problem with private_key value: I was able to sign certificates with private_key=label_root-ca.
The real problem was output from OpenSSL - it kept telling me that it cannot load private key - maybe, but it wasn’t the root of the problem. This was caused by my mistake and it was really simple in the end:
I used this PKI Tutorial to create PKI - it works pretty well. What I did wrong was that I created self-signed certificate WITHOUT SPECIFYING -extensions root_ca_ext - I ended up with root certificate that had CA set to true, but with pathlen: 0 - this means that no subordinate CA can be created using this certificate. After passing -extensions root_ca_ext while creating self-signed certificate I had no problems with signing intermediate CA’s certificate, even with private_key = label_root-ca.
I really miss these few hours that I lost on this…