Five Essential OpenSSL Troubleshooting Commands

OpenSSL LogoTroubleshooting SSL certificates and connections? Here are five handy openssl commands that every network engineer should be able to use. Bookmark this – you never know when it will come in handy!

1. Check the Connection

This command opens an SSL connection to the specified site and displays the entire certificate chain as well. Here’s an abridged version of the sample output:

I’ve reformatted the lines to make things a little clearer, and be grateful that I removed the blocks of Base64-encoded text that represent the certificates or it would be even more painful to read. There are a couple of things to note, however.

I Only Want to See the Server Certificate

Fine then; remove the -showcerts argument, and your wish will be fulfilled.

error:num=20:unable to get local issuer certificate

There’s an error here. Depth 2 means which certificate in the chain; in this case the third one as they are numbered 0, 1 and 2, and this error means that openssl was unable to find a certificate for the issuer of certificate 2 whose Common Name(CN) is “VeriSign Class 3 Public Primary Certification Authority – G5”. That’s because the issuer is a root certificate and openssl does not know where the root certificates are. This can be fixed by adding the -CAfile option pointing to a file containing all the trusted root certificates, but where to get those? That’s coming soon in another post. For now what we need to know is that we have three certificates in a chain and at least up to certificate 2, things are verifying correctly.

Certificate Subject and Issuer

Each certificate is presented as a Subject and an Issuer. The Subject is the thing the certificate is supposed to represent, and the Issuer is the issuing Certificate Authority. For example here’s certificate 0 (the server certificate) from this chain:

You can see the certificate number (zero) then s: meaning Subject: and i: meaning Issuer. It follows then that the Issuer of certificate 0 should be the Subject of certificate 1, as we want to verify if the Issuer is valid; and so it is:

This of course continues up the chain.

error:num=21:unable to verify the first certificate

If you see this when you run this command, it means exactly what it says … that chain of trust is broken right from the start. Typically it might happen if you fail to include intermediate certificates, or if you supply the wrong intermediate certificate.

This Opens a Connection

Really. It might look like the openssl command has hung, but actually it did exactly what we asked it to and opened a connection. It’s waiting for you to send something now. To quit, either Ctrl-C, or hit Enter a couple of times or – if you’re testing for a response – try typing some basic HTTP commands, e.g.:

You’ll still have to break out after that using Ctrl-C, but meanwhile, what fun! Don’t forget that for most sites (particularly HTTP but usually HTTPS as well) you have to use the Host: directive so that the web server knows which site you were trying to contact. When you think about it, most hosting companies have tens or hundreds of web sites served by a single server and IP. Supplying a Host: is essential.

2. Decoding a Base64 Certificate (e.g. PEM)

The output from the previous command will display the raw certificate data between the “—–BEGIN CERTIFICATE—–” and “—–END CERTIFICATE—–” tags. I removed it from the output above so that I could hit you with one now as an example:

Certificates can be in a variety of formats (yay for standardization), but the output from OpenSSL (like above) will be Base64 encoded and basically unreadable. Thankfully, the openssl command can help you view those in a format that is human readable and formatted nicely. Take the Base64 text (including the BEGIN and END lines) of the certificate you are interested in, and save it to a file. Then run this command (in my case with a file called cert-microsoft.pem):

This tells openssl to read the file cert-microsoft.pem , display it in a textual format, and not to create any kind of output certificate. The result is exactly what you asked for:

And, since we have the other certificates in the chain, I could check them too.

Does This Work With Binary Certificate Files?

DER is a binary certificate format, but the content is basically the same underneath it all. When discussing the AIA field in a previous post, I casually skipped over the fact that this file in my experience seems to be supplied in DER format rather than PEM (I don’t know if this is a standard, just that it’s what I’ve seen. Maybe it’s to keep the transfer shorter and thus faster?). All openssl asks is that you tell if you want to supply it with a DER instead of a PEM (Base64) certificate. Personally I would have thought that the absence of “—–BEGIN CERTIFICATE” was sufficient clue for openssl to make an educated guess, but apparently that’s not the case. Instead, you have to use the command line option -inform der. For example, to view a binary certificate as text you’d do this:

By the way, -inform is short for “input format”; you’re not really “informing” openssl about anything. If you were wondering, yes, there is an -outform command as well, and on that note:

3. Convert Certificate From DER to PEM Format

In the examples above, we asked openssl not to create an output certificate using the -nout command line argument. However, openssl is very helpful at converting certificates between formats, so let’s try converting DER to PEM:

This command specifies that the input format is DER, the input file is cert_symantec.der and that we want an output format of PEM saved to an output file called cert_symantec.pem. The observant will have noted that the command actually did not specify the output format of PEM. PEM is the default input and output format, so it does not need to be specified. However, if you like to remove ambiguity in a totally harmless and logical fashion, the full command would be:

Easy peasy. The added benefit of understanding how to do this is that you now don’t have to use somebody else’s website to convert you internal certificates between formats.

4. Checking Your Own Chain of Trust

You’re ready to deploy a certificate for a website, and you have been given a ZIP file containing the public server cert and a file purporting to contain the necessary intermediate certificate(s). How can you check that you have the correct certificates without actually installing them? Why, openssl, of course!

What happened here? Error 20 was mentioned above; it means that the intermediate certificate (or at least, the certificate for the Issuer of the server certificate) is missing. Well of course it is; we didn’t supply it! The site uses a certificate from Symantec, so let’s use that and tell openssl about it:

That’s progress; we still have an error 20, but now it has moved to “1 depth” – that is, the error is no longer on the server certificate (0 depth) but now we can’t find the issuer certificate for the Symantec cert. In a previous post, we discovered that the Symantec cert was issued by a Verisign entity that is in our trusted root store. So now I’ll add a link to the root store as well to complete the chain:

That’s it! We have confirmed that we have a full chain of trust from a trusted root cert all the way down to the server certificate. Even for a Mac user, this is a good thing.

What About Multiple Intermediate Certificates?

If you have more than a single Intermediate Certificate between the server and a trusted root certificate, you need to make them all available to the client. That’s easily done by creating a certificate bundle, which is a fancy way of saying “add all the certificates together in a single file.” Really. If you have two files each containing an intemediate certificate and need to bundle them, in *nix / OS X you do this:

It’s that easy. In any GUI environment you can just paste them one after another in Notepad and save them out. Remember to include the BEGIN and END lines. Now in your command line just change the argument to -untrusted intermediatebundle.pem and you’re good.

5. Testing for SSLv3 Using OpenSSL

This one is pretty easy. Using the s_client function again, we can ask openssl to try to connect using SSLv3. A site that supports SSLv3 (naughty naughty) will look like this:

A site that does NOT support SSLv3 will look like this:

There are other error codes you may see, but generally speaking if you get dumped back to a prompt with an error, chances are this means that SSLv3 is not allowed.

I thought it was interesting, by the way, that allowed an SSLv3 connection, but did not. The former uses a different certificate chain and redirects to the latter, so perhaps it all comes out in the wash. It’s actually a missed opportunity in some ways for Microsoft not to detect SSLv3 in some way, then pop up a web page saying “Hello IE6 user – why not upgrade now?”, but they don’t do that.

My 10 Bits

I have had to use all of these commands recently in order to troubleshoot a few different issues that were popping up with some web sites. I confess to being terrible at remembering commands in detail, so I’m going to bookmark my own page for reference even if you don’t! Openssl does plenty more that can be useful, but this is a great start when it comes to certificates and ciphers.

2 Comments on Five Essential OpenSSL Troubleshooting Commands

  1. Thank you so much for taking the time to write this article. It was invaluable to me in resolving some coding issues with OpenSSL. Using the command line tools was a much easier way of determining and resolving the issues. By the way, I hit another basic problem that I thought was worth mentioning – when passing PEM files to OpenSSL, it is very fussy about the character encoding. Cut & pasting your Microsoft example did not work at first, as my text editor saved (by default) with the wrong character encoding – resaving as ASCII instead of UTF-8 resolved the problem. Just FYI.

Leave a Reply

Your email address will not be published.