Generating a CSR using OpenSSL PKCS#11 Provider and the YubiHSM2


 

 

Introduction:

A common use case for the YubiHSM2 is Code Signing. Code Signing requires a Private Key stored on the HSM, together with a Certificate holding the corresponding Public Key located in an adequate place. In the case of PKCS#11, the Code Signing Private Key and its corresponding certificate needs to be stored in the same "slot", or rather under the same Object ID on the YubiHSM2. For Windows CSP the Code Signing Certificate should be placed in the current user's personal certificate store.

 

One of the hurdles to getting a Code Signing Certificate is that this requires a Certificate Signing Request (CSR) to first be generated. This CSR is then sent to a CA, who in turn signs the request and returns the finished Code Signing Certificate. This Certificate can then be imported to the YubiHSM.

 

This guide will specifically look at how the Latchset PKCS#11 Provider for OpenSSL can be leveraged to generate a CSR for a Private Key that has been generated on the YubiHSM.

 

 

Prerequisites:

 

  1. Download and install the pkcs11-provider
  2. Install the yubihsm-connector and yubihsm-shell from the YubiHSM2-SDK
  3. Install OpenSC pkcs11-tool (optional)
  4. Start the yubihsm-connector
manual-icon.svg Note:  FIPS mode needs to be enabled before any objects, besides the default authentication key (0x0001), are stored or generated on the YubiHSM2 FIPS module.

 

 

Configuration:

 

  1. Generate the yubihsm_pkcs11.conf configuration file.
  2. Generate the openssl.conf configuration file.
  3. Set the Environment variables
    • YUBIHSM_PKCS11_CONF; pointing to the configuration file from step 1.
    • OPENSSL_CONF; Pointing to the configuration file from step 2.
  4. Verify that the pkcs11-provider has been loaded by openssl and is active

    Command:

    openssl list -providers

    Example: 
    $ openssl list -providers              
    Providers:
      default
        name: OpenSSL Default Provider
        version: 3.4.1
        status: active
      pkcs11
        name: PKCS#11 Provider
        version: 3.4.0
        status: active

 

 

Procedure:

 

1. Generate Private key:

The Private key can be generated on the YubiHSM either through PKCS#11 or the YubiHSM-Shell. The examples below will display how to generate an RSA4096 key on the YubiHSM2 using OpenSC's pkcs11-tool and how to perform a similar action with the YubiHSM-shell action. The private key object will be assigned a random Object ID in the case of pkcs11-tool, and we will specify the Object ID to 0x0002 when creating the key through the yubihsm-shell.

  • pkcs11-tool
  • yubihsm-shell
 

 

info-circle-line-icon.svg Info: When interacting with the YubiHSM2 using pkcs#11, the "PIN" is a concatenation of the object ID and the Password of the authentication key you want to use when connecting to the YubiHSM. In these examples we will use the default key, with Object ID 0x0001, and default password "password", this means that the PIN will become "0001password".

 

 

 

2. Verify Object ID

In the case that you want to verify the Object Label of an object that is stored on the YubiHSM2, you can easily list the available objects on the YubiHSM2 with pkcs11-tool or with a yubihsm-shell action command.

  • pkcs11-tool
  • yubihsm-shell
 

3. Generate a CSR based on the Private Key

In this step we will leverage the pkcs11 provider in OpenSSL in order to generate a CSR based on the private key that was generated in the previous step.

Make sure that the configuration files are set up correctly in order to get a good result from this step.


Command:

openssl req -new -key pkcs11:object=[pkcs#11_label]  -subj [certificate_subject] --passin pass:[PKCS11_PIN]

 

Example:

$ openssl req -new -key pkcs11:object=my_key -subj "/CN=my_key" --passin pass:0001password
-----BEGIN CERTIFICATE REQUEST----- MIIEVjCCAj4CAQAwETEPMA0GA1UEAwwGbXlfa2V5MIICIjANBgkqhkiG9w0BAQEF AAOCAg8AMIICCgKCAgEAqgGhcREME4cmiHxnj3Y8ZlPRc+ZM89VBoacP8bc78sX8 LUG78/jEU7ASDy+aOXYI9cTNuiuVPDh0wlivn9U4SRfzs/D3AErWp0NXsrKWxoFC VSyyvvK4RXSWh5G36mT/QIrS/JoQcxH9c7R9ud7bXTSDzKC34bMVyo7eMjGstQfE Ts+uSV70JHx31Qp/LzO9FxM6CtqmR5spozKYOy1jP+mM5u23kwm1mo67j903iPNg hwckPUAdY23wofhr+AnDvUEhjl5BjO6N86L0xET8pxdSefuc8LrpcN3t7BU5ZtZu ehfhh+B9fhG3Peit9TxYtcVY2fbPPRNiVUzdCcWqc4SIYUcZySmQ6/3MMMSWYptP svhost1BttFGYT1Haz9xf7Pd9fYvb8jT0u59313X70Zoa+8EXdhFJFtDcgyaXGP5 d7lgSgNx4rauM6Ao6LbzvqorVkwIMpPrLGc/cVv7VCGWsTy6vk7Ze/AFEL2edX69 In7GrSaPKWxce6EZSioGCj6oqCzt5+eJlrCqJd8AXVFwSAlCGNbPuRFvaKg7dJGC YL+fZkya6sXUhFEDthyn2WwEjes4Z8RSId8jLF3oP+8G1/G3xMETVRwhOX/OMvTm tCBmrgYrntYR4tM6EiC6Mc9gSkm38uy4fTT7uqIo9jEoEBeRmLqMjM4wQ5D9DM0C AwEAAaAAMA0GCSqGSIb3DQEBCwUAA4ICAQAvdtSZ2HKlAqn77VL8kdCGH7GZ7bo5 nXR5APn3oPb30ILOJtsOEWdBb8ch7mrqBDBLTHyewAM/T6ZDhqVX2usBJs+Zwx9n tlSizBUxd9aEuDt45sOdauJ28aaLbb0FWSH9S4I54HRz9xjcfgJoQzTLFHfsceLN SV8979OSlAPiBcGdyKheXRltQG+2ow4b5UUsqcpAIsGjHz0D1kHd0arK8VlVe4dw O2mtPtuluUjG1MbSr2B+6nTxFGw83ekxdNi/HeRdigb9UKoeQ5FcVy43BjlEKG/5 gDtBia5tnYwZXsmZPGAcjAvVssgRXgykPtXJG7YvPOkyEVoQB6VQ9XHRdOIul4jw 2y0AZUvvHIpjulNJVnZFWg3JhZ6n7jv+kDxVHomf+YKYW4pRyHLhWpfEIK38HLtU sPBZ33apwvOph/UyI90nuGSJTc+M0pepn+1295rRUIu0KwcL6fxnpUFJRnguu2Ps LOWw6vA0l/ZP2z8jklQd1I8a5KwSSNkPia9PyBOH0+iJi7ybukGS/C9Jd3Wk8zJL FXMGNjLYTkJtg4+54Kh0mNP/U4nS0HlSabI3ymKM1RuED38QorU4EqOvpXesENTl OAgOShkLzi3ScaFfKUcbjtVoxyPJzGA+vyTEhPah1zd8d3FRe+TSMPPXBX/ZNloZ 9SzVxR1HV4f2Zg== -----END CERTIFICATE REQUEST-----
bulb-light-icon.svg Tip: 
Add the parameter -out [path_to_csr_output_file] in order to save the CSR to a file in the target directory instead.

 

 

4. Import the Signed Certificate back to the YubiHSM2:

Once the CSR is signed and the Certificate has been issued you can import it back unto the YubiHSM2. It is important to note that the PKCS#11 specification requires that the Certificate is stored in the same slot as the corresponding private Key. Objects are separated by a combination of Object ID and Object type, which means that the YubiHSM can store multiple objects in the same Object ID, as long as their Object Types are different.

 

Command:

yubihsm-shell -a put-opaque -i [Object_ID] -l [object_label] -d [domains] -c [capabilities] -A [object_algorithm] --in [input_file] --informat [input_format]  --authkey [authentication_key_ID] -p [password]

 

Example:

yubihsm-shell -a put-opaque -i 0xa1a3 -l my_key -d all -c sign-pkcs,exportable-under-wrap -A opaque-x509-certificate --in req.pem --informat PEM --authkey 0x0001 -p password
Using default connector URL: http://localhost:12345
Session keepalive set up to run every 15 seconds
Created session 0
Stored 725 bytes to Opaque object 0xd596