Internal Network CA: “Invalid Common Name” or Invalid Cert on everything (except Internet Explorer and Windows’ Certificates mmc snapin)

certificatecertificate-authorityopensslssl-certificate

We run an internal Certificate Authority powered by an Ubuntu 16.04 server and an OpenSSL backend for internal resources, on a mixed Windows / Linux environment.

This CA is used with some internal websites in an attempt to provide valid, trusted site certificates for internal websites, software deployments, etc. We have one problem.

The CA Root certificate is pushed to all our Windows systems by GPO, or were manually installed. However, every certificate signed by that CA ends up giving some problems – Chrome and Firefox both indicate that the certificate has an invalid common name, while other utilities such as an XMPP server here can't validate the certificate even if the CA cert is in the trust stores.

Only Internet Explorer respects the certificate. Unfortunately, we are a Chrome and Firefox house, so using IE for everything is going to be a problem.

Has anyone figured out a solution to make an OpenSSL CA cert and its signed certificates for issued certs not have an "Invalid Common Name" error on Chrome and Firefox, and thus permit internal certificates to be seen as 'valid'?

Best Answer

I actually figured out the core problem, and it took a ton of searching. Finally found an answer over on StackOverflow, which combined with my investigation into the actual data on the certificate itself with openssl req -text -noout -verify -in CSR.csr to read the data in the CSR, and openssl x509 -in certificate.crt -text -noout to dissect the generated certificate and comparing these two, pointed at the core problem.

Apparently, OpenSSL was ignoring the section of our conrfiguration file relating to the V3 extensions, and doesn't do the v3 extensions unless you tell it to properly in the actual CA signature step...

This was the configuration file data being passed into the openssl req command:

[ req ]
default_bits = 4096
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = v3_req

[ dn ]
C=US
ST=Pennsylvania
L=Somewhere
O=No Man's Land
OU=Internal
CN = chat.foo.bar.baz

[ v3_req ]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage=serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1   = chat.foo.bar.baz
DNS.2   = chat
DNS.3   = 10.1.2.151

A standard call of the following did not respect the v3 extensions somehow:

openssl req -new -sha256 -out cert.csr -key cert.key -config csrgen.cnf

... however, this one did work:

openssl req -new -sha256 -out cert.csr -key cert.key -config csrgen.cnf -extensions v3_req

... and when signing the certificate with the CA, we had to use something like this, executing this from where we had all the site certs stored (including the CSR and key, for generating the cert in the first place - the CA certificates and keys are in a separate /certauthority/... section on our system):

openssl x509 -req -days 3650 -in ./cert.csr -CA /certauthority/certs/cacert.pem -CAkey /certauthority/private/cakey.pem -CAserial /certauthority/CA/serial -CAcreateserial -out certificate.crt -extfile csrgen.cnf -extensions v3_req

This command properly put the v3 extensions into the certificate, and somehow ignored the actual extensions in the file otherwise. This in turn solved the CN and SAN issues, and now the system returns the certificate as "valid" for internal sites and (most) internal services.