Why can’t I verify this certificate chain


I have three certificates in a chain:

  • root.pem
  • intermediate.pem
  • john.pem

When I examine them using openssl x509 -in [filename] -text -noout they look fine, root.pem looks like it is self-signed (Issuer == Subject), and the Subject of each certificate is the Issuer of the next one, as expected.

And indeed I can verify the chain up to the intermediate certificate:

$ openssl verify -CAfile root.pem root.pem
root.pem: OK
$ openssl verify -CAfile root.pem intermediate.pem
intermediate.pem: OK

However, john.pem fails:

$ openssl verify -CAfile root.pem -CAfile intermediate.pem john.pem
john.pem: C = CL, [...redacted data...]
error 2 at 1 depth lookup:unable to get issuer certificate

To the best of my knowledge, this means that openssl is unable to find the issuer for intermediate.pem. Which doesn't make sense since root.pem is indeed the issuer for intermediate.pem.

What am I missing?

Edit: I had originally posted an answer saying that root.pem and intermediate.pem should be concatenated in one file, and then one should use this file as the parameter for -CAfile. This is WRONG, because this implicitly trusts intermediate.pem, as Johannes Pille points out. Read the link he posted in my deleted answer: https://mail.python.org/pipermail/cryptography-dev/2016-August/000676.html

Best Answer

You don't have to cat the two certificates together in order to verify them.

If you have the following three certificates:

  • root.pem - stores a self-signed certificate.
  • intermediate.pem - stores a certificate signed by root.pem
  • john.pem - stores a certificate signed by intermediate.pem

And you trust only root.pem, then you would verify john.pem with the following command:

openssl verify -CAfile root.pem -untrusted intermediate.pem john.pem

It you had many intermediates, you could just chain -untrusted intermediate2.pem -untrusted intermediate3.pem ...