SSL Root CA certificate is not recognized, although present in the trust store. Why?
Background:
- Ubuntu Server 14.10 64-bit on aws.amazon.com/ec2
- Cheap PositiveSSL server certificate from COMODO
- 1 server certificate, 2 intermediate CA certificates and 1 Root CA certificate as ZIP archive from COMODO
- Citadel's WebCit httpsd
Problem:
The concatenated certificate chain seems to be correct but verification fails.
openssl s_client myhost:port
shows the certificate chain and the issuer-subject pairs line up correctly through the chain, but:
verify error:num=19:self signed certificate in certificate chain
The root CA certificate is not accepted by openssl, although it is found per default in the Ubuntu server trust store.
Specifically:
AddTrustExternalCARoot.crt
received per email from COMODO and
/etc/ssl/certs/AddTrust_External_Root.pem
which links to
/usr/share/ca-certificates/mozilla/AddTrust_External_Root.crt
are indentical.
What is wrong here?
OpenSSL at least through current (1.0.2a) has a bug where s_client
with NO -CA{path,file}
argument doesn't actually use the default truststore as it should, and thus fails to verify certs that are valid according to that truststore. (Also s_server
and s_time
, but caring about verification in those is rare.) See https://serverfault.com/questions/607233/how-to-make-openssl-s-client-using-default-ca . A fix is announced in dev, but may take some time to be released and distributed. In the meantime you need to explicitly specify the -CA*
argument(s). Note that openssl verify
does not have this bug, and therefore correctly reported the cert/chain as valid.
UPDATES 2015/08/26: fix was released 2015/06/12 in 1.0.1o and 1.0.2c. Also, while investigating something else I found that RedHat packages may have been okay. More specifically the CentOS source RPM for openssl-1.0.1e-30.el6.11
which I understand is a copy of the RedHat one (but can't easily confirm) contains openssl-1.0.1c-default-paths.patch
which contains changes to s_client.c s_server.c s_time.c
dated 2012/12/06 that appear equivalent to (though not textually the same as) the 2015/06/12 upstream fixes. Assuming this patch was applied in RedHat and CentOS packages, which I can't easily go back and check, they would (have) work(ed) as expected.
I faced a similar issue with Comodo certificates recently when developing a script using Ruby. In the end it was that OpenSSL did not have it in the store, even though it looked like it did.
To test this, download all of the Comodo intermediate certs and create a cert bundle something like this (you'll need to use different cert names depending on what you downloaded):
cat EssentialSSLCA_2.crt ComodoUTNSGCCA.crt UTNAddTrustSGCCA.crt AddTrustExternalCARoot.crt > yourDomain.ca-bundle
Comodo has an article on how to do this.
Once done, try verifying the certificate again using OpenSSL and specifying the cert store on the command line:
openssl verify -untrusted yourDomain.ca-bundle cert.pem
That example was adapted from this Unix and Linux StackExchange article.
Once you've determined which certificate it is, it should be possible to add the certificate to the local cert store, which is detailed here for Ubuntu, and is something like:
Create a directory for extra CA certificates in /usr/share/ca-certificates
sudo mkdir /usr/share/ca-certificates/extra
Copy the '.crt' file to the directory
sudo cp foo.crt /usr/share/ca-certificates/extra/foo.crt
Let Ubuntu add the '.crt' file's path relative to /usr/share/ca-certificates to /etc/ca-certificates.conf
sudo dpkg-reconfigure ca-certificates