I maintain/enhance a product that uses a browser-based admin interface. We're late to the party and are only now looking to support HTTPS between the browser and our backend (Apache httpd in front of Tomcat, all running on Linux).

So... I'm fumbling my way thru new (to me) areas, and one of them is dealing with certificates as obtained from a certificate authority.

For testing/education purposes I obtained my own certificate from a CA - I provided them a CSR, and what I got in return were two things:

  1. server.crt and
  2. intermediates.crt (a file containing at least one - maybe more? - intermediate certificates)

IIUC both of these files need to be installed into our Apache. But since the Apache we ship with our product is of the newer variety (read: httpd.conf directive 'SSLCertificateChainFile' has been removed after version 2.4.8), the two files from the CA must be combined into a single file like this (with Apache 'SSLCertificateFile' pointing to that one file):

cat server.crt intermediates.crt > combined.crt

OK fine. Apache's happy.

Where I'm running into problems is how to verify the 'combined.crt' file for correctness. Since it'll be user-generated - and users screw up - I'll want to do some validation on the file. FWIW... our product completely hides Linux from the user - the user does not have access to a Linux command prompt, root, etc. EVERYTHING the user does in the way of admin'ing our product is done thru our product's front-end interface. So any answer that involves the user going to a Linux prompt is a non-starter.

I cannot figure out any way to use 'openssl' to validate that the input 'combined.crt' the user would have created from the CA-provided files

  1. really contains certificates and not just some random garbage from a confused user, and then
  2. verify that the certificates the file contains actually constitute a valid certificate chain - i.e. the order of certificates in the file is correct

I understand that openssl verify ... can do what I want but the only way I've found to make it work is to specify the two CA-provided files separately...

openssl verify -CAfile intermediates.crt server.crt

I guess I could design my interface so that the user provides both files separately. And I may end up just doing that vs. expecting the user to use a text editor to combine the two files into the proper order (more work for me but easier for our user - and safer). But at this point -- dang it -- it's now become more of a learning exercise for me. Seems like there MUST be some way for 'openssl' to verify the single certificate file as required by Apache.......?

Thanks for any guidance.

  • 2
    You don't explain the capabilities of your product's front-end. Can you not split the single input file into one that contains the 1st PEM block, and another that contains the rest of the input file? You can then use those two with openssl verify. You'll need to provide the correct trust-anchor of course. Commented Jan 13, 2022 at 18:22
  • The front end capabilities are whatever I want since I'm the one who will be creating the screens. As I said, I may go the route you suggested (user uploads both files), so my 'problem' has now entered into the realm of "There must be a way" - i.e. there must be a way to use openssl to verify a .crt file containing a chain - right?
    – John Lamb
    Commented Jan 13, 2022 at 19:32
  • I've just tried with a chain as the target and it seems to work for me - would need further testing though. openssl verify -CAFile root.pem chain.pem returned chain.pem: OK. Commented Jan 13, 2022 at 20:19
  • hmmm. Would love to hear more about what's in your chain.pem file b/c I can't get it to work. In my chain.pem I have two certificates 'back to back' (sorry comments here don't seem to support line breaks): -----BEGIN CERTIFICATE----- server certificate gobbledgook -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- intermediate certificate gobbledgook -----END CERTIFICATE----- Instead of -CAFile <file> I use -CApath /etc/ssl/certs/ It complains error 20 at 0 depth lookup: unable to get local issuer certificate
    – John Lamb
    Commented Jan 13, 2022 at 21:26
  • Hmmm. I think I had magic in it, as I've just re-created the chain and it's now failing as yours did. I can't explain that. However, I've just used the same file (the chain) for -untrusted as for the target and it seems to work. Sort of makes sense as OpenSSL only picks the certs it needs from -untrusted and picks the first certificate in the chain from the target. Again, would need further testing. Commented Jan 13, 2022 at 21:32

1 Answer 1


When openssl (or at least the sub-command openssl x509) read its input, if there is more input left, it doesn't touch it, allowing to chain multiple openssl commands to process multiple combined certificates and making splitting them back easy without having to use text processing commands.

An intermediate certificate is not trusted: only root certificates usually in the OS store (the list usually provided by Mozilla, Google Microsoft & co.) are trusted. So -CAfile shouldn't be used with an intermediate certificate (even if it accepts such certificate) or it won't validate the complete chain. -trusted is to be used for real (self-signed) root certificates but is usually needed only for an internal (non-public) root CA that wasn't added to the OS store.

All intermediate certificates should be provided through the -untrusted parameter.

Using a bash shell for its convenient <() construct, turning pipe-like output into file-like parameters, which openssl supports well. I made below some repetition (combined.crt is read twice) that could probably be avoided with a better script or language, but it stayed simple.

The command becomes (requiring a bash shell):

openssl verify -untrusted <( { openssl x509 >/dev/null; cat; } < combined.crt ) <(openssl x509 < combined.crt)

First read of combined.crt discards the server certificate by a dummy use of openssl x509 and provides back (all) following intermediate certificate(s), second read of combined.crt takes the first (server) certificate and discards everything else.

  • 1
    This could be simpler, couldn't it? openssl verify -untrusted <( { openssl x509 >/dev/null; cat; } < combined.crt ) combined.crt. Since as you said, everything after the first cert is "discarded", and openssl verify can take a PEM file on the command line, you don't need to use "file-like" input redirection, just pass the filename. Commented Feb 26 at 15:20
  • 1
    @fourpastmidnight Yes, most certainly!
    – A.B
    Commented Feb 26 at 16:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .