Skip to main content

Creating a Self-Signed Root CA Certificate with OpenSSL

The following example shows how to use OpenSSL to:

  • create a Self-Signed Root Certificate for a Root Certificate Authority (CA)
  • Use the root certificate to create a certificate for an intermediate CA
  • issue a server certificate.
danger

The OpenSSL commands and configurations are examples to demonstrate the possibility of using OpenSSL in combination with a Securosys HSM for PKI applications. Some of the tools are not considered to have "production quality" by OpenSSL itself:

This command was originally meant as an example of how to do things in a CA. Its code does not have production quality. It was not supposed to be used as a full blown CA itself -- openssl-ca man page

Preparation

  1. Create the directories and initial files

    mkdir -p myCA/{rootCA,intermediateCA}/{certs,crl,newcerts,private,csr}

    touch myCA/rootCA/index.txt
    echo 1000 > myCA/rootCA/serial
    echo 1000 > myCA/rootCA/crlnumber

    touch myCA/intermediateCA/index.txt
    echo 1000 > myCA/intermediateCA/serial
    echo 1000 > myCA/intermediateCA/crlnumber
  2. Download the configuration for the root CA openssl_root.cnf, and the intermediate CA openssl_intermediate.cnf. These two configurations specify constraints, policies and extensions that are applied to the certificates they create and sign.

Root CA certificate

  1. Create a key.

    openssl genpkey -propquery "provider=pkcs11" \
    -algorithm rsa -pkeyopt rsa_keygen_bits:4096 \
    -pkeyopt pkcs11_uri:"pkcs11:object=MyRootCA"
    note

    If your pkcs11-provider is configured to access to multiple partitions on the HSM the pkcs11-uris used in these examples are ambiguous. Additionally specify the partition by adding the token attribute to the URI. E.g.: Use pkcs11:object=MyRootCA;token=<USER_PARTITION_NAME> instead of pkcs11:object=MyRootCA.

  2. Create a self-signed certificate. The v3_ca extensions defined in the openssl_root.cnf configuration are applied which enable the "CA:true" property.

    openssl req -config openssl_root.cnf \
    -key "pkcs11:object=MyRootCA" \
    -new -x509 -days 7300 -sha256 -extensions v3_ca \
    -out myCA/rootCA/certs/ca.cert.pem \
    -subj "/C=CH/ST=Zurich/L=Zurich/O=My Example Organisation/OU=IT Department/CN=Root CA"

Intermediate CA certificate

  1. Create a key.

    openssl genpkey -propquery "provider=pkcs11" \
    -algorithm rsa -pkeyopt rsa_keygen_bits:4096 \
    -pkeyopt pkcs11_uri:"pkcs11:object=MyIntermediateCA"
  2. Create a certificate signing request (CSR).

    openssl req -config openssl_intermediate.cnf \
    -key "pkcs11:object=MyIntermediateCA" \
    -new -sha256 \
    -out myCA/intermediateCA/certs/intermediate.csr.pem \
    -subj "/C=CH/ST=Zurich/L=Zurich/O=My Example Organisation/OU=IT Department/CN=Intermediate CA"
  3. As root CA, sign the CSR for the intermediate CA with the root CA key.The v3_intermediate_ca extensions defined in the openssl_root.cnf configuration are applied.

    openssl ca -batch -config openssl_root.cnf \
    -keyfile "pkcs11:object=MyRootCA" \
    -extensions v3_intermediate_ca -days 750 -notext -md sha256 \
    -in myCA/intermediateCA/certs/intermediate.csr.pem \
    -out myCA/intermediateCA/certs/intermediate.cert.pem
  4. Verify the signature on the intermediate certificate

    openssl verify -CAfile myCA/rootCA/certs/ca.cert.pem \
    myCA/intermediateCA/certs/intermediate.cert.pem

Server certificate

  1. Create a key.

    openssl genpkey -propquery "provider=pkcs11" \
    -algorithm rsa -pkeyopt rsa_keygen_bits:4096 \
    -pkeyopt pkcs11_uri:"pkcs11:object=server-www.example.com"
  2. Create a certificate signing request (CSR).

    openssl req -copy_extensions=copyall \
    -key "pkcs11:object=server-www.example.com" \
    -new -sha256 \
    -out server-www.example.com.csr.pem \
    -subj "/C=CH/ST=Bern/L=Bern/O=My Example Organisation/OU=IT Department/CN=www.example.com" \
    -addext "subjectAltName = DNS:www.example.com, DNS:*.www.example.com"
  3. As intermediate CA, sign the server CSR with the intermediate CA key.

    openssl ca -batch -config openssl_intermediate.cnf \
    -extensions v3_server_cert \
    -keyfile "pkcs11:object=MyIntermediateCA" \
    -days 40 -notext -md sha256 \
    -in server-www.example.com.csr.pem \
    -out server-www.example.com.cert.pem
  4. Verify the certificate by checking the signatures using OpenSSL.

    cat myCA/intermediateCA/certs/intermediate.cert.pem \
    myCA/rootCA/certs/ca.cert.pem \
    > chain.pem

    openssl verify -show_chain \
    -trusted myCA/rootCA/certs/ca.cert.pem \
    --untrusted chain.pem \
    server-www.example.com.cert.pem

    Additionally test the certificate by starting a https server

    openssl s_server \
    -cert server-www.example.com.cert.pem \
    -key 'pkcs11:object=server-www.example.com' \
    -chainCAfile chain.pem -naccept +1

    and connecting to it

    curl -v --cacert myCA/rootCA/certs/ca.cert.pem \
    --connect-to www.example.com:443:localhost:4433 \
    https://www.example.com

More resources: