Root CA Certificate Expiry and Renewal: Best Practices for OpenSSL-based PKI Management


3 views

When your root CA certificate expires in 2014, all certificates in its chain will become untrusted regardless of their individual expiration dates. This occurs because modern TLS implementations (OpenSSL 1.1.1+, browsers) validate the entire certificate chain's validity period during handshakes.

You'll need to create a new root CA certificate and implement a cross-signing approach:

# Generate new root CA
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \
  -out new_ca.crt -config openssl.cnf

# Cross-sign the new CA with old CA
openssl x509 -req -in new_ca.csr -CA old_ca.crt -CAkey old_ca.key \
  -CAcreateserial -out cross_signed.crt -days 3650 -sha256

Begin the transition 3-6 months before expiration:

  • Month 1-3: Issue new intermediate certificates signed by both old and new roots
  • Month 4-6: Gradually replace end-entity certificates
  • Final Month: Complete root certificate rotation

For clients only accessible via VPN, implement a two-phase rollout:

# Phase 1: Update client configs with additional CA cert
<ca>
-----BEGIN CERTIFICATE-----
(Current CA cert)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(New CA cert)
-----END CERTIFICATE-----
</ca>

# Phase 2: After verification, remove old CA

To simplify future renewals:

  • Use intermediate CAs with shorter lifespans (2-3 years)
  • Implement certificate revocation lists (CRLs) or OCSP
  • Maintain detailed certificate inventory with issuance/expiry dates

Here's a bash script to check certificate validity across your infrastructure:

#!/bin/bash
# Check certificate chain validity
check_cert() {
  enddate=$(openssl x509 -enddate -noout -in "$1" | cut -d= -f2)
  if [ $(date -d "$enddate" +%s) -lt $(date +%s) ]; then
    echo "EXPIRED: $1"
  else
    echo "VALID: $1 (until $enddate)"
  fi
}

# Check all certs in /etc/ssl/certs
find /etc/ssl/certs -name '*.crt' | while read cert; do
  check_cert "$cert"
done

When a root CA certificate expires, all dependent certificates in the chain become technically invalid - even if their own validity periods extend beyond the CA's expiration. This occurs because modern PKI implementations validate the entire certificate chain's temporal validity during verification.

Certificates signed by an expired root CA typically won't validate, regardless of their individual expiration dates. For example:

openssl verify -CAfile expired_root.pem server_cert.pem
# Will return error: "certificate has expired"

Option 1: Root Certificate Reissuance
Generate a new root key pair and certificate, then cross-sign with the old root:

# Generate new root
openssl req -new -x509 -newkey rsa:4096 -keyout new_root.key \
  -out new_root.crt -days 3650 -nodes

# Cross-sign
openssl x509 -req -in new_root.csr -CA old_root.crt \
  -CAkey old_root.key -CAcreateserial -out cross_signed.crt

Option 2: Certificate Migration
Issue new intermediate CAs from the new root and migrate all end-entity certificates.

Begin renewal at least 6-12 months before expiration. This allows for:

  • Client configuration updates
  • Testing of new trust chains
  • Grace period for legacy systems

Here's how to verify certificate chain validity in code:

// Python example using cryptography
from cryptography import x509
from cryptography.hazmat.backends import default_backend

def validate_chain(cert_pem, root_pem):
    cert = x509.load_pem_x509_certificate(cert_pem, default_backend())
    root = x509.load_pem_x509_certificate(root_pem, default_backend())
    
    # Check root validity
    if root.not_valid_after < datetime.datetime.now():
        raise Exception("Root certificate expired")
    
    # Additional validation logic here
    return True

1. Implement certificate transparency logs
2. Automate certificate rotation procedures
3. Maintain detailed certificate inventory
4. Consider shorter validity periods (1-2 years) for end-entity certificates

For OpenVPN tunnels where access depends on the existing certificates:

# Temporary solution: Extend system trust for both roots
cp old_root.crt new_root.crt /etc/ssl/certs/
update-ca-certificates

Remember to monitor CRLs and OCSP responders during the transition period to ensure uninterrupted service.