OpenSSL is an SSL library and includes a useful command, "openssl", for dealing with SSL certificates.
# Print out details of a certificate
openssl x509 -in certificatefile.crt -noout -text
# Print out details of a certificate request
openssl req -in certrequest.csr -noout -text
# Convert a PEM certificate (the base64 block of letters format) to DER (a binary format)
# If a cryptic error appears it means the input certificate was not PEM format.
# You can also add the "-inform PEM|DER" flag to the above command to check that it is the format you expect.
openssl x509 -inform PEM -outform DER -in certificatefile.crt -out certificatefile.der
# Check the certificates on a server (the path specified by CApath may vary on your machine)
openssl s_client -CApath /etc/ssl/certs -connect yourserver.warwick.ac.uk:443
# Check the certificates on a server, showing certificates
openssl s_client -CApath /etc/ssl/certs -connect yourserver.warwick.ac.uk:443 -showcerts
Using the showcerts option will print PEM versions of each certificate presented. You can copy-and-paste these certificates (including the "BEGIN CERTIFICATE" and "END CERTIFICATE") into a new file ending .pem, and use these certificates elsewhere, such as importing into a trusted certificates file (like Java's cacerts).
Errors when checking server certificates
While most errors in the OpenSSL server response are bad, a couple are expected so if you see them, it doesn't necessarily mean there's anything wrong.
- verify error:num=19:self signed certificate in certificate chain
- You will get this if you are sending the root certificate as part of the chain. Doing this is usually not a problem, but as root CA certificates are signed by themselves, it will tell you about it. Some apps may have problems consuming these chains, so it's usually best to avoid supplying the root as part of the chain.
- verify error:num=20:unable to get local issuer certificate
- You will see this one if OpenSSL couldn't find a trusted cert in the chain. If you didn't specify -CApath, OpenSSL won't trust any certificates so you will get this error. If you have specified the correct -CApath, then this means there is some problem with your chain that you need to fix. There is also a small chance that you have an outdated set of CA certificates on your machine.
Example certificate setup
Here's what one of Google's servers returns:
~$ openssl s_client -CApath /etc/ssl/certs -connect google.com:443
depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
depth=1 C = US, O = Google Trust Services, CN = Google Internet Authority G3
depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = *.google.com
0 s:/C=US/ST=California/L=Mountain View/O=Google LLC/CN=*.google.com
i:/C=US/O=Google Trust Services/CN=Google Internet Authority G3
1 s:/C=US/O=Google Trust Services/CN=Google Internet Authority G3
i:/OU=GlobalSign Root CA - R2/O=GlobalSign/CN=GlobalSign
This is a good example as it shows the server presenting an intermediate CA certificate as well as its own. The server's certificate is number 0 in the chain, and the intermediate is number 1. The issuer of the intermediate is a root certificate, which all recent browsers and HTTP clients should have a copy of. Since we specified a valid -CApath, it trusts GlobalSign's "GlobalSign Root CA - R2" certificate and thus it trusts the whole chain. At the bottom of the response you should see
Verify return code: 0 (ok)
A return code of 0 is what you want to get from a properly configured server.