Centos – OpenSSL keeps telling me ‘unable to get local issuer certificate’

centosopensslssl-certificate

I'm using CentOS, which has OpenSSL 1.0.2k-fips installed, and I've built and installed version 1.1.0g alongside it as part of a HTTP2 install outlined here: https://www.tunetheweb.com/performance/http2/

I've been using the 1.1.0g fine, but lately I renewed the certificates and now it seems lost when trying to verify the CA. The location of the CA file has not changed, the 1.0.2k-fips version seems fine with it, but 1.1.0g does not get past complaining:

Verify return code: 20 (unable to get local issuer certificate)

So, I've verified the certs are good, the location has not changed, I did not manually change any config.

I figured perhaps I should rebuild the 1.1.0g, but that changes nothing. I also tried using the -CApath option for the openssl command, like so (using the same dir as 1.0.2k-fips uses):

echo | /usr/local/ssl/bin/openssl s_client -connect example.com:443 -CApath /etc/pki/tls

I also tried -CAfile, directly pointing to the ca-bundle.crt which I know has the correct certs (1.0.2k-fips uses them without issue), still no change.

I'm clueless as to why it will not pick up my certs, and wonder if this problem might have already existed before I changed the certs (I checked if they worked after changing them, it might be possible 1.1.0g was already broken at that point).

I'm thinking it could be due to updates performed on the system, breaking some link or file, but where to look when the certificate stuff all looks normal? Or is 1.1.0g missing some other/more certs I need to point out to it?

Best Answer

You can get s_client to show you the certificate chain with -showcerts:

openssl s_client -connect example.com:443 -showcerts </dev/null

This will start with the certificate chain, then show other information about the server certificate and TLS connection. All of that should help you to figure out where the trouble is. It might be in an intermediate certificate, not the CA.

You can get a quick summary of the certificate chain by filtering the output:

openssl s_client -connect example.com:443 -showcerts </dev/null 2>/dev/null |
sed -e '1,/Certificate chain/d' -e '/BEGIN CERTIFICATE/,/END CERTIFICATE/d' -e '/---/,$d'