Using a Cloud HSM key with OpenSSL

This guide provides instructions for setting up OpenSSL to use a Cloud HSM key on Debian 11 (Bullseye). These instructions are generally applicable even if you're using another OS or environment, but be aware that there may be slight differences.

Requirements

Download a release of the library to get started. A user guide is available for consultation.

Before starting, install the libengine-pkcs11-openssl package.

sudo apt-get update
sudo apt-get install libengine-pkcs11-openssl

Configuration

Setting the PKCS11_MODULE_PATH environment variable.

In order for openssl to use our PKCS #11 library, set the PKCS11_MODULE_PATH environment variable:

export PKCS11_MODULE_PATH="/path/to/libkmsp11.so"
echo 'export PKCS11_MODULE_PATH="/path/to/libkmsp11.so"' | sudo tee /etc/profile

PKCS #11 library configuration

The PKCS #11 library requires a YAML configuration file to locate Cloud KMS resources. The YAML must at a minimum configure a single PKCS #11 token.

If you are using OpenSSL with another process that may end up forking (for example, Apache or Nginx), you must also ensure that the refresh_interval_secs field remains unset, or is set to 0.

Sample configuration file:

---
tokens:
  - key_ring: "projects/my-project/locations/us-central1/keyRings/my-keyring"

With this configuration, all asymmetric signing and decryption keys in my-keyring will be available in the library.

You must set the permissions on the configuration file so that it is writable only by the file owner. Point KMS_PKCS11_CONFIG to your config file:

export KMS_PKCS11_CONFIG="/path/to/pkcs11-config.yaml"

Again, you can make this setting permanent by adding it to /etc/profile.

echo 'export KMS_PKCS11_CONFIG="/path/to/pkcs11-config.yaml"' | sudo tee /etc/profile

Running OpenSSL commands

With the engine and library properly configured, you may now use the engine in OpenSSL commands.

When creating asymmetric signatures, keep in mind that Cloud KMS keys are constrained to use a single digest. As an example, a CryptoKeyVersion with the algorithm EC_SIGN_P256_SHA256 must always be used in conjunction with a SHA-256 digest. That corresponds to the -sha256 flag in OpenSSL. Keys that require SHA-384 or SHA-512 digests should be used with the -sha384 or -sha512 flags.

Create a new signature

Assuming there's a key named foo in your configured key ring, use the following command to create a signature over bar.txt:

openssl dgst -sha256 -engine pkcs11 -keyform engine -sign pkcs11:object=foo bar.txt

The output of this command is unformatted binary.

That command assumes you are using a key that takes a SHA-256 digest, so the -sha256 argument was used. The -sha384 or -sha512 options would be appropriate for Cloud HSM keys that use those digest types.

For an RSA-PSS key, remember to use the -sigopt options discussed previously.

Create a new certificate signing request

You may also generate a certificate signing request (CSR) for a Cloud HSM signing key. This is useful if your certificate authority requires a CSR in order to generate a new certificate for code signing, or to protect TLS web sessions.

openssl req -new -subj '/CN=test/' -sha256 -engine pkcs11 \
  -keyform engine -key pkcs11:object=foo > my-request.csr

Generate a new self-signed certificate

For local development and testing, you can use a self-signed certificate for a Cloud HSM signing key. Self-signed certificates are also useful for SAML token signing.

openssl req -new -x509 -days 3650 -subj '/CN=test/' -sha256 -engine pkcs11 \
  -keyform engine -key pkcs11:object=foo > my-request.crt