Skip to main content

Key Management via PKCS#11

This tutorial shows how to do basic key management (listing keys, generating keys, creating certificates) with PKCS#11 command line tools, namely pkcs11-tool, p11tool, and certtool.

Installation

Make sure that the Primus PKCS#11 Provider is installed in /usr/local/primus and is fully configured as per the docs.

The pkcs11-tool comes from the OpenSC project; p11tool and certtool come from GnuTLS. To get these tools, install the following packages:

CLI toolDebian packageRHEL package
pkcs11-toolopensc-pkcs11opensc
p11tool, certtoolgnutls-bingnutls-utils

Environment

Define the variables to be used later:

export P11_PIN=<YOUR_PKCS11_PASSWORD>
export P11_TOKEN=<YOUR_HSM_PARTITION_NAME>
export P11_LABEL=<YOUR_PKCS11_KEY_LABEL>
export P11_LIB=/usr/local/primus/lib/libprimusP11.so

The P11_PIN is the PKCS#11 Password that you have configured.

If you omit the --pin (pkcs11-tool) or the --set-pin (p11tool) option you will be prompted to enter the PIN interactively.

On Windows, the module path would be C:\Program Files\Securosys\Primus P11\primusP11.dll.

pkcs11-tool (from OpenSC)

The pkcs11-tool test function (--test) is not recommended and may fail due to incompatibilities.

List objects

pkcs11-tool --module ${P11_LIB} \
--login --pin ${P11_PIN} \
--list-objects --type privkey

Available types are cert, privkey, pubkey, secrkey, data.

Generate a key pair

pkcs11-tool --module ${P11_LIB} \
--login --pin ${P11_PIN} \
--keypairgen --key-type RSA:2048 \
--slot 0 --label ${P11_LABEL} --sensitive

Other available key types include RSA:4096, EC:secp256r1, and EC:secp384r1.

To show all available elliptic curves, provide an invalid curve:

pkcs11-tool --module ${P11_LIB} --keypairgen --key-type EC:
Using slot 0 with a present token (0x0)
EC key parameters may be specified by their canonic name or object identifier. Possible values are:
secp192r1 (1.2.840.10045.3.1.1)
prime192v1 (1.2.840.10045.3.1.1)
prime192v2 (1.2.840.10045.3.1.2)
prime192v3 (1.2.840.10045.3.1.3)
<more curves>

You can also find the list of curves on GitHub. However, note that the upstream source code may have newer curves that are not yet included in the version of pkcs11-tool that you installed from your distribution's repository.

Generate a symmetric key

pkcs11-tool --module ${P11_LIB} \
--login --pin ${P11_PIN} \
--keygen --key-type AES:32 \
--slot 0 --label ${P11_LABEL}

Export a public key

pkcs11-tool --module ${P11_LIB} \
--login --pin ${P11_PIN} \
--read-object --type pubkey \
--label ${P11_LABEL} \
--output-file ${P11_LABEL}.pub.der \
--slot 0

To view the ASN1:

openssl asn1parse -in ${P11_LABEL}.pub.der -inform DER -i

dumpasn1 ${P11_LABEL}.pub.der

To convert to PEM (with OpenSSL 3.x):

openssl rsa -in ${P11_LABEL}.pub.der -pubin -inform DER -outform PEM -out ${P11_LABEL}.pub.pem

Use openssl ec with the same options for an EC key.

Import a certificate

See below for how to use certtool to create a certificate.

pkcs11-tool --module ${P11_LIB} \
--login --pin ${P11_PIN} \
--write-object ${P11_LABEL}.crt.pem --type cert \
--slot 0 --label ${P11_LABEL}

Delete an object

pkcs11-tool --module ${P11_LIB} \
--login --pin ${P11_PIN} \
--delete-object --type pubkey \
--label ${P11_LABEL}

p11tool (from GnuTLS)

p11tool is aware of p11-kit. If you configure p11-kit you don't need to specify the --provider option every time. (Instead, you may need to specify the token URL.)

List tokens

Every HSM partition will show as a token.

p11tool --provider ${P11_LIB} --list-tokens

List objects

p11tool --provider ${P11_LIB} \
--login --set-pin ${P11_PIN} \
--list-all
"pkcs11:token=${P11_TOKEN}"

Generate a key pair

Generate an RSA key:

p11tool --provider ${P11_LIB} \
--login --set-pin ${P11_PIN} \
--generate-privkey RSA --bits 2048 \
--label ${P11_LABEL} \
"pkcs11:token=${P11_TOKEN}"

Generate an EC key:

p11tool --provider ${P11_LIB} \
--login --set-pin ${P11_PIN} \
--generate-privkey ECC --curve secp256r1 \
--label ${P11_LABEL} \
"pkcs11:token=${P11_TOKEN}"

See man p11tool for the list of available parameters.

Export a public key

p11tool --provider ${P11_LIB} \
--login --set-pin ${P11_PIN} \
--export-pubkey --outfile ${P11_LABEL}.pub.pem \
"pkcs11:token=${P11_TOKEN};object=${P11_LABEL}"

Import a certificate

See below for how to use certtool to create a certificate.

p11tool --provider ${P11_LIB} \
--login --set-pin ${P11_PIN} \
--write --load-certificate ${P11_LABEL}.crt.pem \
--label ${P11_LABEL} \
"pkcs11:token=${P11_TOKEN}"

Delete an object

p11tool --provider ${P11_LIB} \
--login --set-pin ${P11_PIN} \
--delete \
"pkcs11:token=${P11_TOKEN};object=${P11_LABEL}"

You will be shown the objects to be deleted and will be prompted to interactively confirm their deletion.

certtool (from GnuTLS)

Usually, certificates cannot be directly created on the HSM via PKCS#11 commands. Instead, you have to use helper tools to create a Certificate Signing Request (CSR). The CSR is then signed by a private key on the HSM to create a certificate. On the PKCS#11-level, this is just signing an opaque bitstring; thus you need helper tools that handle building the X.509 structures. Finally, you can import the certificate into the HSM (if desired).

In this example, we use certtool from the GnuTLS utils to create certificates.

We assume that you have created two key pairs on the HSM, with labels root and leaf. We will create a self-signed certificate for the root key pair, and then create a certificate for the leaf key pair signed by root. Finally, we will verify the certificate chain.

Like p11tool, certtool is aware of p11-kit. Therefore, you can drop the --provider option if you have p11-kit configured.

Create a self-signed certificate

certtool --provider ${P11_LIB} \
--password ${P11_PIN} \
--generate-self-signed \
--load-privkey "pkcs11:token=${P11_TOKEN};type=private;object=root" \
--outfile root.crt.pem

Create a certificate signed by a CA

Create a CSR:

certtool --provider ${P11_LIB} \
--password ${P11_PIN} \
--generate-request \
--load-privkey "pkcs11:token=${P11_TOKEN};type=private;object=leaf" \
--outfile leaf.csr.pem

Create a certificate from the CSR:

certtool --provider ${P11_LIB} \
--password ${P11_PIN} \
--generate-certificate \
--load-request leaf.csr.pem \
--load-ca-certificate root.crt.pem \
--load-ca-privkey "pkcs11:token=${P11_TOKEN};type=private;object=root" \
--outfile leaf.crt.pem

View certificate info

certtool --certificate-info --infile root.crt.pem

Verify a certificate

certtool \
--verify \
--load-ca-certificate root.crt.pem \
--infile leaf.crt.pem

References

Get started withCloudHSM for free.
Other questions?Ask Sales.
Feedback
Need help?