Certificate Chain (Self-signed root CA)

apache-2.4certificate-authorityhttpspkissl-certificate

I am creating a self-signed Root CA for internal usage, I have decided to use an intermediate certificate. However, I am having issues with Chromium and Firefox 54.0 not trusting the certificate chain.

The content is being hosted via Apache 2.4.18 on Ubuntu 16.04 with the following configuration:


<VirtualHost *:443>
DocumentRoot /var/www/html/
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
SSLCertificateChainFile /etc/apache2/ssl/fullchain.crt
</VirtualHost>

Chromium is reporting "There are issues with the sites certificate chain", and Firefox "Error code: SEC_ERROR_CA_CERT_INVALID". Both Chromium and Firefox have the Root CA installed in their trust store, as a trusted certificate for verifying websites.

Below is the setup used to generate, sign and verify the certificates


#Generate and self-sign the Root CA
#===========================================================
openssl genrsa -out ca.key 2048
#openssl genrsa -aes256 -out ca.key 4096
openssl req -new -x509 -days 3650 -key ca.key -subj "/C=UK/ST=London/L=/O=SWS, Inc./CN=X1 SWS Root CA" -out ca.crt

#===Generate and sign the intermediate CA
#============================================================
openssl req -newkey rsa:2048 -nodes -keyout intermediate.key -subj "/C=UK/ST=London/L=/O=SWS Intermediate, Inc./CN=SWS Intermediate CA" -out intermediate.csr
openssl x509 -req -extfile <(printf "subjectAltName=DNS:localhost") -in intermediate.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out intermediate.crt -days 2000 -sha256


#===Generate a certificate and sign with the intermediate CA
#============================================================
openssl req -newkey rsa:2048 -nodes -keyout server.key -subj "/C=UK/ST=London/L=/O=SWS, Inc./CN=*.sws.com" -out server.csr
openssl x509 -req -extfile <(printf "subjectAltName=DNS:sws.com,DNS:*.sws.com") -days 730 -in server.csr -CA intermediate.crt -CAkey intermediate.key -CAcreateserial -out server.crt

#===Generate a certificate chain
#===========================================================
cat intermediate.crt ca.crt > fullchain.crt
#===Verify the certificate (CRT) info
#============================================================
openssl x509 -in server.crt -text -noout
#===Verifies the Chain of Trust
#============================================================
openssl verify -CAfile ca.crt intermediate.crt
openssl verify -verbose -CAfile <(cat intermediate.crt ca.crt) server.crt

This seems quite bizarre as the certificate chain is valid, and performing the same steps without having an intermediate provides a valid certificate chain within Chromium and Firefox.

Please acknowledge that the domain name "sws.com", is a local DNS; it is configured via the hosts file.

Best Answer

As this topic is quite large, I have chosen to attached the URLs below, giving detailed explanations of the configuration procedure.

Using the documents on Jamie Linux, I have created a root and intermediate CA. However, this tutorial did not include the X509v3 Extension for alternative subject names. This was easily resolved by modify the intermediate/openssl.cnf file under module [ server_cert ], by adding the following lines.

[ server_cert ] ... subjectAltName = @alt_names [ alt_names ] DNS.1 = example.com DNS.2 = www.example.com

The modified intermediate configuration file has been added below as "Config ICA".

The problem I made with the initial question, was that the intermediate CA had no basic constraints. Therefore, it was an X509v1 certificate, such that it had no constraint stating whether it was a CA, and as X509v1 is deprecated all browsers will automatically distrust the trust chain.


Jamie Linux: https://jamielinux.com/docs/openssl-certificate-authority/create-the-root-pair.html
Config ICA: https://pastebin.com/gCGcFdiP