3

I am trying to understand how to sign stuff using an intermediate CA certificate. I have developed a rather simple example (using https://gist.github.com/jadbaz/9350f4df4e4ef4c5d256889aa3d5a5ed as the basis, though I removed the configuration file and adjusted some of the commands accordingly)... I would expect the final certificate to be verifiable using either of the 2 CAs that I create during the execuion, but verification fails.... what am I missing:

# root ca
openssl genrsa -out rootca.key 4096
openssl req -sha256 -new -x509 -days 3650 -key rootca.key -out rootca.crt -subj /CN=rootca

# intermediate ca
openssl genrsa -out interca1.key 4096
openssl req -sha256 -new -key interca1.key -out interca1.csr -subj /CN=intermediateca -addext "basicConstraints=critical,CA:true" -addext "keyUsage=critical,keyCertSign,cRLSign"
openssl x509 -copy_extensions copyall -req -days 365 -in interca1.csr -CA rootca.crt -CAkey rootca.key -CAcreateserial -out interca1.crt

# verify chain so far
openssl verify -CAfile rootca.crt rootca.crt interca1.crt # both certificates are ok

# generating an example certificate
openssl genrsa -out example1.key 2048
openssl req -new -sha256 -key example1.key -out example1.csr -subj /CN=example1
openssl x509 -copy_extensions copyall -req -days 365 -in example1.csr -CA interca1.crt -CAkey interca1.key -CAcreateserial -out example1.crt

# verify results
openssl verify -CAfile rootca.crt rootca.crt interca1.crt example1.crt
openssl verify -CAfile interca1.crt interca1.crt example1.crt

Here's the output of the last verify runs:

# openssl verify -CAfile rootca.crt rootca.crt interca1.crt example1.crt
rootca.crt: OK
interca1.crt: OK
CN=example1
error 20 at 0 depth lookup: unable to get local issuer certificate
error example1.crt: verification failed
# openssl verify -CAfile interca1.crt interca1.crt example1.crt
CN=intermediateca
error 20 at 0 depth lookup: unable to get local issuer certificate
error interca1.crt: verification failed
CN=intermediateca
error 2 at 1 depth lookup: unable to get issuer certificate
error example1.crt: verification failed

What am I missing?

Also, why can't interca1 verify itself the same way that rootca did?

I am using openssl 3.2.2.

Update

It is not explained in the accepted answer but let me add a command that should work in case you want to try:

$ openssl verify -CAfile <( cat rootca.crt interca1.crt ) rootca.crt interca1.crt example1.crt
rootca.crt: OK
interca1.crt: OK
example1.crt: OK
4
  • Have you try to concatenate in one file all the root and intermediate certificates? Commented Feb 26 at 18:04
  • That works to let me verify the certificates... but that still does not help me understand why verifications fail if using a single certificate. Is it always mandatory to have access to the full certificate chain to be able to verify? It's not possible to verify if you have, say, only the certificate that was used to sing the final certificate? Commented Feb 26 at 18:11
  • In the certificate is mentioned entire chain. So to verify you need all of them. Commented Feb 26 at 18:19
  • 1
    Ok.... Thanks for the clarification. If it's not a duplicate, please, move that to an answer so I can accept it. Thanks! Commented Feb 26 at 18:28

1 Answer 1

4

In your case the issued certificate contain reference to all root and intermediate CA. When you check issued certificate you should provide (if in file) all root and intermediate certificates in one file. If you use CAdir instead of CAfile you can add all the root, intermediate certificates in this dir.

P.S. And you use verify command which require all the certificates in chain to be verified. And to quote comment:

One more bit I temporarily forgot: verify requires everything above the to-be-verified to be either in the truststore OR supplied by the -untrusted option, but that is rarely used. The root, or other anchor with partial_chain, must be specifically in the truststore

3
  • 1
    Actually each cert only links one level -- EE links to inter and inter links to root, or it could link to a higher intermediate that in turn links to root -- but it is true that by default openssl verify requires all certs above the one being verified to be in the truststore (CAfile, CAdir, or in 3.0 up CAstore) so inter<root works but EE<inter or EE<root doesn't. Since 1.0.2 (documented since 1.1.0) there is an option -partial_chain and with that EE<inter works but EE<root still doesn't Commented Feb 27 at 4:11
  • Compare security.stackexchange.com/questions/118062/… and cross serverfault.com/questions/582438/… Commented Feb 27 at 4:21
  • 1
    One more bit I temporarily forgot: verify requires everything above the to-be-verified to be either in the truststore OR supplied by the -untrusted option, but that is rarely used. The root, or other anchor with partial_chain, must be specifically in the truststore. Commented Feb 27 at 4:51

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.