Can't verify CA certificate unless CApath or C

2019-01-23 08:53发布

问题:

Im having trouble with having OpenSSL connect to a server because of trust issues. I placed the CA certificate on /etc/ssl/certs/ and have run sudo c_rehash and can see that the correct file has been made. I can see that CA certificate is in the ca-certificates.crt. However if I run:

openssl s_client -connect servername.domain.com:636

The command fails with Verify return code: 21 (unable to verify the first certificate)

If I do:

openssl s_client -connect servername.domain.com:636 -CApath /etc/ssl/certs/

I get Verify return code: 0 (ok)

What can I do so I dont have to specify the CApath?

I'm using Ubuntu 13.04.

回答1:

OpenSSL connect to a server because of trust issues.

Unlike browsers, which trust nearly everything from anybody, OpenSSL trusts nothing by default.

Its up to you to determine what should be trusted. You will have to specify something when using OpenSSL and s_client.

If you are working programmatically with the OpenSSL API, you have more options. But this appears to be related to using the OpenSSL commands.


What can I do so I don't have to specify the CApath?

You can use the CAfile. It avoids the rehash, and it creates a 1:1 mapping for trust of the domain. That is, you only trust one issuer for the domain in question. If any other issuer claims to be the issuer, you won't trust the issuer or the server.

You can see how to extract the needed info from OpenSSL's s_client and use CAfile at How to Grab SSL Certificate in OpenSSL.

When using all the certificates present in CAPath, you trust any issuer, even if its not the real issuer. This has happened in the past and its bad.

The corner case is where a bad guy compromises the CA you trust and issues phony certifcates for the domain. This has happened in the past too, and its bad.

In the two negative cases above, you can forgo conferring trust to DNS and CAs and use a security diversification technique like certificate or public key pinning. If there's a pre-existing relationship between you and the site, then you know the expected public key of the server. In this case, there's no need to trust a CA.



回答2:

You can also set and export the environment variables SSL_CERT_FILE or SSL_CERT_DIR...

export SSL_CERT_FILE=/path/to/ca_bundle.crt

export SSL_CERT_DIR=/path/to/ca/dir

Then you do not have to specify CAfile or CApath in every openssl command.



回答3:

If I understood correctly the question, you have to assign at your domain the certificate.

You could do that (on apache) into /etc/httpd/vhost.d/servername.domain.com (if you use vhosts)

SSLEngine On
SSLProtocol all -SSLv2
SSLCipherSuite HIGH:MEDIUM
SSLCertificateFile /etc/httpd/ssl/yourcert.crt
SSLCertificateKeyFile /etc/httpd/ssl/yourcert.key
SSLCertificateChainFile /etc/httpd/ssl/yourcert.ca-bundle