Use "openssl ca" as Intermediate CA

This section provides a tutorial example on how to use the 'openssl ca' command as Intermediate CA to sign a CSR (Certificate Signing Request) into a certificate using a given section in openssl.cnf.

Today, most end entity certificates are signed by an intermediate CA, not a root CA. The main feature of an intermediate CA certificate is that it must be signed by a root CA or another intermediate CA, not self-signed.

Here is what I did to use the "openssl ca" command as an intermediate CA to sign end user certificate.

1. Prepare directories and files required by the intermediate CA.

# Create the base directory for the intermediate CA 
herong$ mkdir intermediate

# Create the sub-directory for newly signed certificates 
herong$ mkdir intermediate/certs

# Create an empty database index file
herong$ touch intermediate/index.txt

# Initialize a serial number file
herong$ echo 1000 > intermediate/serial

2. Add a "ca_intermediate" section in the openssl.cnf file for the "openssl ca -name ca_intermediate" command for intermediate CA to invoke.

herong$ vi openssl.cnf 

#- openssl.cnf
#- #- Copyright (c) 2017 HerongYang.com. All Rights Reserved.

# Default section
default_md     = sha256         # default hash algorithm
default_days   = 365            # how long to certify for
email_in_dn    = no             # don't add the email into cert DN
policy         = ca_policy_default # default policy section

...

# "-name" section of "openssl ca" for intermediate CA
[ca_intermediate]
dir            = ./intermediate # where everything is kept
serial         = $dir/serial    # serial number file
database       = $dir/index.txt # database index file
new_certs_dir  = $dir/certs     # new certs are kept
private_key    = $dir/key.pem   # CA private/public key file
certificate    = $dir/cert.pem  # CA certificate file

...

3. Also add a "ca_extensions_intermediate" section for the "openssl ca -extensions ca_extensions_intermediate" command for root CA to invoke to sign the intermediate CA certificate.

# "-extensions" section for "openssl ca" to sign intermediate CA
[ca_extensions_intermediate]
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

...

4. Create a CSR for the intermediate CA.

herong$ openssl req -new -out intermediate/csr.pem \
  -newkey ec -pkeyopt ec_paramgen_curve:P-384 \
  -keyout intermediate/key.pem -passout pass:TopSecret

Generating an EC private key
writing new private key to 'intermediate/key.pem'

-----
Country Name (2 letter code) [AU]:ZZ
State or Province Name (full name) [Some-State]:.
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:.
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:ZZ Intermediate CA
Email Address []:

# For older OpenSSL releases, do this in 3 steps
openssl ecparam -genkey -name secp384r1 -noout \
  -out intermediate/key.pem

openssl ec -in intermediate/key.pem -out intermediate/key.pem \
  -aes128 -passout pass:TopSecret

openssl req -new -out intermediate/csr.pem \
  -key intermediate/key.pem -passin pass:TopSecret

5. Sign the intermediate CA's CSR as root CA.

herong$ openssl ca -config openssl.cnf -name ca_root -key TopSecret \
  -in intermediate/csr.pem -out intermediate/cert.pem \
  -extensions ca_extensions_intermediate

Using configuration from openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'ZZ'
commonName            :ASN.1 12:'ZZ Intermediate CA'
Certificate is to be certified until Nov 20 14:52:00 2025 GMT
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

6. Look at the intermediate CA certificate. X509v3 extensions seem to be good.

herong$ openssl x509 -in intermediate/cert.pem -text -noout 

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 4097 (0x1001)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = ZZ, CN = ZZ Root CA
        Validity
            Not Before: Nov 20 14:52:00 2024 GMT
            Not After : Nov 20 14:52:00 2025 GMT
        Subject: C = ZZ, CN = ZZ Intermediate CA
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (384 bit)
                pub:
                    04:5b:ea:f2:9e:d6:34:c4:3d:9b:4d:a5:e3:73:d4:
                    ae:77:fd:6c:df:4e:0e:48:01:93:05:82:68:0f:30:
                    ...
                    56:89:b9:47:e6:b0:76
                ASN1 OID: secp384r1
                NIST CURVE: P-384
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:0
            X509v3 Key Usage: critical
                Digital Signature, Certificate Sign, CRL Sign
    Signature Algorithm: ecdsa-with-SHA256
         30:65:02:30:6e:61:95:1b:f3:99:07:e7:6a:4d:b5:13:8c:07:
         ca:0a:84:b9:5d:a3:5d:30:dd:cc:88:4a:a1:a7:2b:de:22:6c:
         ...
         c6:1f:8e:fa:24:0b:7d:4c:e5:5d:17:b8:07

7. Sign the Herong's CSR created from the last tutorial as intermediate CA.

herong$ openssl ca -config openssl.cnf -name ca_intermediate \
  -key TopSecret -in herong/hy-csr.pem -out herong/hy-cert-2.pem

Using configuration from openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'ZZ'
commonName            :ASN.1 12:'Herong Yang'
Certificate is to be certified until Nov 20 15:02:45 2025 GMT
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

8. Look at my second certificate signed by the intermediate CA. Everything seems to be good.

herong$ openssl x509 -in herong/hy-cert-2.pem -text -noout 

Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 4096 (0x1000)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = ZZ, CN = ZZ Intermediate CA
        Validity
            Not Before: Nov 20 15:02:45 2024 GMT
            Not After : Nov 20 15:02:45 2025 GMT
        Subject: C = ZZ, CN = Herong Yang
...

Table of Contents

 About This Book

 Introduction of PKI (Public Key Infrastructure)

 Introduction of PKI Certificate

 PKI Certificate File Formats

 OpenSSL - Cryptography Toolkit

"openssl ca" - CA (Certificate Authority) Tool

 "openssl ca" - CA Signing Certificate

 openssl.cnf - OpenSSL Configuration File

 Use "openssl ca" as Root CA

 Add "keyUsage" into Root CA

Use "openssl ca" as Intermediate CA

 Create Web Server Certificate

 OpenSSL CA Database Files

 "openssl.cnf" Example and Usages

 Java "keytool" Commands and KeyStore Files

 PKI Certificate Store

 PKCS12 Certificate Bundle File

 PKCS7 Certificate Chain File

 PKI Certificate Related Terminology

 References

 Full Version in PDF/EPUB