Setup Intermediate CA

The Intermediate CA is the workhorse for certificate authorities. This will be the main CA used for issuing and revoking server / client certificates.

Create Intermediate CA Openssl Configuration

A good default is here. This configuration should only contain relevant sections for the required Intermediate CA actions. Configuration file must be specified when issuing Intermediate CA operations otherwise the systemwide openssl.conf default configuration will be used.

0600 root root /root/ca/inter/inter.ca
# OpenSSL intermediate CA configuration file.
# Stripped down to just Intermediate CA functionality.
# https://jamielinux.com/docs/openssl-certificate-authority/create-the-intermediate-pair.html

[ ca ]
default_ca                     = CA_default

[ CA_default ]
# Directory and file locations.
dir                            = /root/ca/inter
certs                          = $dir/certs
crl_dir                        = $dir/crl
new_certs_dir                  = $dir/newcerts
database                       = $dir/index.txt
serial                         = $dir/serial
RANDFILE                       = $dir/private/.rand

# The root key and root certificate.
private_key                    = $dir/private/inter.key.pem
certificate                    = $dir/certs/inter.cert.pem

# For certificate revocation lists.
crlnumber                      = $dir/crlnumber
crl                            = $dir/crl/inter.crl.pem
crl_extensions                 = crl_ext
default_crl_days               = 375

default_md                     = sha512
name_opt                       = ca_default
cert_opt                       = ca_default
default_days                   = 375
preserve                       = no
policy                         = policy_loose

[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
countryName                    = optional
stateOrProvinceName            = optional
localityName                   = optional
organizationName               = optional
organizationalUnitName         = optional
commonName                     = supplied
emailAddress                   = optional

[ req ]
# Options for the 'openssl req' tool: man req
default_bits                   = 4096
distinguished_name             = req_distinguished_name
string_mask                    = utf8only
default_md                     = sha512
x509_extensions                = machine_cert

[ req_distinguished_name ]
# CSR information required, prompts and defaults.
countryName                    = Country Name (2 letter code)
stateOrProvinceName            = State or Province Name
localityName                   = Locality Name
0.organizationName             = Organization Name
organizationalUnitName         = Organizational Unit Name
commonName                     = Common Name
emailAddress                   = Email Address

# Default values for certification generation.
countryName_default            = XX
stateOrProvinceName_default    = XX
localityName_default           = XX
0.organizationName_default     = {CA NAME}
organizationalUnitName_default = {CA NAME} Certificate Authority
commonName_default             = {CA NAME} Intermediate CA
emailAddress_default           = XX

[ user_cert ]
# User certificate extensions: man x509v3_config '-extensions user_cert'
basicConstraints               = CA:FALSE
nsCertType                     = client, email
nsComment                      = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier           = hash
authorityKeyIdentifier         = keyid,issuer
keyUsage                       = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage               = clientAuth, emailProtection

[ machine_cert ]
# Machine certificate extensions: man x509v3_config '-extensions machine_cert'
basicConstraints               = CA:FALSE
nsCertType                     = client
nsComment                      = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier           = hash
authorityKeyIdentifier         = keyid,issuer
keyUsage                       = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage               = clientAuth

[ server_cert ]
# Server certificate extensions: man x509v3_config '-extensions server_cert'
basicConstraints               = CA:FALSE
nsCertType                     = server
nsComment                      = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier           = hash
authorityKeyIdentifier         = keyid,issuer:always
keyUsage                       = critical, digitalSignature, keyEncipherment
extendedKeyUsage               = serverAuth

[ crl_ext ]
# Certificate revocation list extensions: man x509v3_config
authorityKeyIdentifier         = keyid:always

[ ocsp ]
# Extension for OCSP signing certificates: man ocsp
basicConstraints               = CA:FALSE
subjectKeyIdentifier           = hash
authorityKeyIdentifier         = keyid,issuer
keyUsage                       = critical, digitalSignature
extendedKeyUsage               = critical, OCSPSigning

Create Intermediate CA Private Key and Certificate

Private key should be kept offline of live services, but accessible to enable changes. Lifetimes for Intermediate CAs should be shorter than Root CAs.

Create the private key.
openssl genrsa -aes256 -out /root/ca/inter/private/inter.key.pem 4096
chmod 0400 /root/ca/inter/private/inter.key.pem
Create the Intermediate CA Certficate.
openssl req -config /root/ca/inter/inter.ca -new -sha512 -key /root/ca/inter/private/inter.key.pem -out /root/ca/inter/csr/inter.csr.pem
openssl ca -config /root/ca/root/root.ca -extensions v3_intermediate_ca -days 3650 -notext -md sha512 -in /root/ca/inter/csr/inter.csr.pem -out /root/ca/inter/certs/inter.cert.pem
chmod 444 /root/ca/inter/certs/inter.cert.pem
openssl x509 -noout -text -in /root/ca/inter/certs/inter.cert.pem
openssl verify -CAfile /root/ca/root/certs/root.cert.pem /root/ca/inter/certs/inter.cert.pem
  • Defaults from inter.ca will autofill Intermediate CA certificate fields.

  • The Root CA is used to sign the Intermediate CA. This creates a chain of trust.

  • Lifetime is half (3650 days, 10 years) for an Intermediate CA. When the Intermediate CA expires, all child certificates become invalid.

  • The verify command should return OK. This means that the Intermediate certificate is currently valid.

Create Intermediate Chain of Trust

The chain of trust is used to validate all certificates up to the Root CA. This is usually deployed with server/client certificates if the Root CA is not added to each machine’s Trusted CA store.

Create Intermediate Chain of Trust.
cat /root/ca/inter/certs/inter.cert.pem /root/ca/root/certs/root.cert.pem > /root/ca/inter/certs/ca-chain.cert.pem
chmod 444 /root/ca/inter/certs/ca-chain.cert.pem