All we need is an easy explanation of the problem, so here it is.
I’m teaching a class about certificate chains, so I download the chain from
www.google.com which has 4 certs. I want to demonstrate how the dependencies work from issuer to subject by showing that each entity signs the cert of the one below it.
Call the certs
g3 is a self-signed root,
g1 are intermediate CAs and
g0 is a leaf cert. I try this:
$ openssl verify g0 error 20 at 0 depth lookup:unable to get local issuer certificate
This makes sense: the verify fails because this is a leaf cert with no CA given. So next I try this:
$ openssl verify -CAfile g1 g0 g0: OK
Great! With the intermediate, it now works! Continuing up the chain:
$ openssl verify -CAfile g2 g1 g1: OK
Awesome! Looks like
g1 is properly signed by
g2. But this is actually not what’s being verified. Because
g1 is also apparently signed by
$ openssl verify -CAfile g3 g1 g1: OK
And in fact,
g1 doesn’t even need a CA:
$ openssl verify g1 OK
So it would appear that any cert with CA set to True in Basic Constraints will always pass verification!
Question: How do I verify that
g2 actually signed
g1 using OpenSSL from the CLI? And is this yet another OpenSSL bug? Or just counterintuitive behavior?
How to solve :
I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.
I believe certs g2 and g3 are already present in the default trusted directory (/etc/ssl/certs/) which openssl uses to build the chain of trust and find the ‘trust anchor’.
In my setup:
g2 = GeoTrust Global CA
g3 = Equifax Secure Certificate Authority
Both of these certs are present in the /etc/ssl/certs/ directory.
If you try out the same experiment with a self-generated chain of certs, you will find the behaviour that you expect.
Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂