CryptoCorner OpenSSL

Generate an OpenSSL X.509 certificate with SoftHSM2

This article shows how to use OpenSSL with an PKCS11 engine to generate and sign an X.509 certificate. This is not an easy task, as we need to use the PKCS11 tools to generate a key pair on the SoftHSM2 first. This tutorial is suitable for any self-signed root CA or issuing CA.

Step1: Generate a modified /etc/ssl/openssl.cnf

#/etc/ssl/openssl.cnf
HOME = .
oid_section = new_oids
openssl_conf = default_conf
[engine_section]
pkcs11 = pkcs11_section

[pkcs11_section]
engine_id = pkcs11
dynamic_path = /home/appuser/n_series_rest/p11modules/engines-1.1/pkcs11.so
MODULE_PATH = /home/appuser/n_series_rest/p11modules/libsofthsm2.so
init = 0

[ new_oids ]
tsa_policy1 = 1.2.3.4.1
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7

[ ca ]

[ CA_default ]
policy = policy_match

[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
string_mask = utf8only

[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = AT
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Some-State
localityName = Locality Name (eg, city)
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Internet Widgits Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64

[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name

[ usr_cert ]
basicConstraints=CA:FALSE
nsComment = „OpenSSL Generated Certificate“
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:true

[ crl_ext ]
authorityKeyIdentifier=keyid:always

[ proxy_cert_ext ]
basicConstraints=CA:FALSE
nsComment = „OpenSSL Generated Certificate“
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo

[ tsa ]

[ tsa_config1 ]

[default_conf]
ssl_conf = ssl_sect
engines = engine_section

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT@SECLEVEL=2

Refer to openssl.cnf

in Linux set OPENSSL_CONF to the location of the edited openssl.cnf

$ set OPENSSL_CONF=/etc/ssl/openssl.cnf

Generate a PKCA11 key pair

Now we need to generate a key pair on SoftHSM2. Please note that you need to initialize the slot first an use the generated token label instead of „tokenemul“

$ pkcs11-tool –module /s.so -l –token-label tokenemul -k –key-type rsa:2048 –id a1b2 –label rsatest –pin secret1

Identify the PKCS11 URI

If you know your PKCS11 uri of the generated private key your are fine, otherwise you easily can use Linux p11tool to list all available uris on a given token:

p11tool –login –list-all „pkcs11:token=tokenemul“

Result:

Enter PIN: *******
Object 1:
URL: pkcs11:model=SoftHSM%20v2;manufacturer=SoftHSM%20project;serial=ab8f2f27a1a10565;token=tokenemul;id=%A1%B2;object=rsatest;type=private
Type: Private key (RSA-2048)
Label: rsatest
Flags: CKA_WRAP/UNWRAP; CKA_PRIVATE; CKA_NEVER_EXTRACTABLE; CKA_SENSITIVE;
ID: a1:b2

Object 1:
URL: pkcs11:model=SoftHSM%20v2;manufacturer=SoftHSM%20project;serial=ab8f2f27a1a10565;token=tokenemul;id=%A1%B2;object=rsatest;type=public
Type: Public key (RSA-2048)
Label: rsatest
Flags: CKA_WRAP/UNWRAP;
ID: a1:b2

Identify the PKCS11 URI

Paste in the PKCS11 uri of your private key into the following OpenSSL command to generate an X.509v3 certificate and sign the certificate with the HSM stored private key:

$ openssl req -new -x509 -days 3652 -sha256 -extensions v3_ca -engine pkcs11 -keyform engine -key „pkcs11:model=SoftHSM%20v2;manufacturer=SoftHSM%20project;serial=ab8f2f27a1a10565;token=tokenemul;id=%00;object=rsatest;type=private“ -out ecroot.pem

After providing a couple of X.509 certificate attributes and the PKCS11 token pin the X.509 root certificate is generated in the current folder.

A more complex CA scenario can be found on https://github.com/mylamour/blog/issues/80

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.