I have got three certificates that should make up a valid chain:
I am trying to use OpenSSL to verify that the Client Certificate was in-fact signed by the Intermediate CA/Root CA.
From looking online I was able to find the following command:
openssl verify -CAfile root-ca.pem -untrusted Intermediate.pem ClientCert.pem
Running this command returns:
ClientCert.pem: OK
From reading the docs about the verify command, it says:
If a certificate is found which is its own issuer it is assumed to be the root CA.
The way this appears to work is that it sees my Intermediate as the root CA and tries to validate the Client certificate using the Intermediate as the Root certificate and verifies that the Intermediate did in-fact sign the Client Certificate. This effectively makes the inclusion of the -CAfile root-ca.pem
useless as it is never used in the validation. (I tested this by replacing the root-ca.pem
in the OpenSSL command with a random, unrelated root-ca and it still returned that the chain was valid, which seems a bit mad to me as that means that chain is in fact not being validated)
Next I tried to verify my certificate by removing the -untrusted
option and omitting the Intermediate.pem
. This resulted in the following error:
error 20 at 0 depth lookup: unable to get local issuer certificate
error ClientCert.pem: verification failed
I also attempted to bundle the Client and Intermediate certificate together, but my understanding is that OpenSSL only looks at the first certificate in a file.
The following command also returns OK, even if the CA provided has no connection to the Intermediate:
openssl verify -CAfile some-random-ca.pem Intermediate.pem
If a Client certificate is signed by an intermediate, is it not possible to verify that certificate using only the root ca and the client certificate and if there no way to verify that a root-ca created an Intermediate that then signed a Client certificate?
EDIT
From further investigation the -trusted
flag can be used to provide the root-ca to have OpenSSL verify the entire chain:
openssl verify -trusted root-ca.pem -untrusted Intermediate.pem ClientCert.pem
-trusted file
A file of trusted certificates, which must be self-signed, unless the -partial_chain option is specified. The file contains one or more certificates in PEM format. With this option, no additional (e.g., default) certificate lists are consulted. That is, the only trust-anchors are those listed in file. This option can be specified more than once to include trusted certificates from multiple files. This option implies the -no-CAfile and -no-CApath options. This option cannot be used in combination with either of the -CAfile or -CApath options.
Using the -trusted
option, if I now provide an incorrect CA (that did not create the Intermediate) then OpenSSL correctly reports:
error 20 at 1 depth lookup: unable to get local issuer certificate
The behavior you describe happens if the Root CA is already trusted, i.e. is in the trust store directory openssl uses by default (i.e. something like /usr/lib/ssl/certs
). While -CAfile
will add the given certificate(s) as trusted it will still consider the default trust store directory. This explains why you can skip this argument or provide some other CA and everything behaves the same - the Root CA in the default trust store directory is still used as trust anchor.
Contrary to this -trusted
not only adds trust into the given certificate but also removes trust into all other certificates. This means the default trust store which includes the Root CA will not be used (contrary to when using -CAfile
) and therefore giving a wrong CA here will cause the verification to fail. You can get a similar behavior with -CAfile
if you explicitly forbid to use the default trust store directory with -no-CApath
.