I've been playing with x509 certificates to better understand them and I've hit a strange issue which makes me think I have a misunderstanding. Initially I tested everything with libressl 2.8.3 and things work as expected, however when testing against openssl 1.1.1d things fall apart.
First I've created a root key and certificate with
libressl ecparam -out root.pem -name secp384r1 -genkey libressl req -new -key root.pem -out root.csr libressl x509 -in root.csr -out root.crt -req -signkey root.pem -days 30
then the intermediate
libressl ecparam -out inter.pem -name secp384r1 -genkey libressl req -new -key inter.pem -out inter.csr libressl x509 -in inter.csr -out inter.crt -req -signkey root.pem -days 30
and a leaf
libressl ecparam -out leaf.pem -name secp384r1 -genkey libressl req -new -key leaf.pem -out leaf.csr libressl x509 -in leaf.csr -out leaf.crt -req -signkey inter.pem -days 30
The issue I'm hitting is that libressl will verify the intermediate cert while openssl will not
>>> libressl verify -CAfile root.crt inter.crt inter.crt: C = US, ST = CA, L = SF, O = Inter error 18 at 0 depth lookup:self signed certificate OK >>> openssl verify -CAfile root.crt inter.crt C = US, ST = CA, L = SF, O = Inter error 18 at 0 depth lookup: self signed certificate error inter.crt: verification failed
Am I missing something or is openssl exposing that I have a misunderstanding of x509 certs and libre/openssl? Similarly validating the leaf cert with a bundle of the root and intermediate succeeds with libressl and fails with openssl.
Thanks to Mike Ounsworth pointing out the issue. My intermediate cert was being generated as a self signed cert using the
openssl x509 -req -signkey root.pem -days 30 -in inter.csr -out inter.crt
command. Which resulted in a certificate which read
Certificate: Data: Version: 1 (0x0) Serial Number: 14260606495133371304 (0xc5e7da0d280d8ba8) Signature Algorithm: ecdsa-with-SHA1 Issuer: C=US, ST=CA, L=SF, O=Test, OU=Test, CN=Intermediate Validity Not Before: Jan 21 20:45:34 2020 GMT Not After : Feb 20 20:45:34 2020 GMT Subject: C=US, ST=CA, L=SF, O=Test, OU=Test, CN=Intermediate
Swapping the command above to
openssl x509 -req -days 30 -in inter.csr -CA root.crt -CAkey root.pem -CAcreateserial -out inter.crt
Resulted in a certificate with the issuer set to root.
Certificate: Data: Version: 1 (0x0) Serial Number: 14926915319265390371 (0xcf270e658d266f23) Signature Algorithm: ecdsa-with-SHA1 Issuer: C=US, ST=CA, L=SF, O=Test, OU=Test, CN=Root Validity Not Before: Jan 21 20:51:07 2020 GMT Not After : Feb 20 20:51:07 2020 GMT Subject: C=US, ST=CA, L=SF, O=Test, OU=Test, CN=Intermediate
The intermediate cert now passes verification
However on verification the leaf certificate I get an error with
❯❯❯ libressl verify -verbose -CAfile root.crt -untrusted inter.crt leaf.crt leaf.crt: C = CA, ST = CA, L = SF, O = Test, OU = Test, CN = Intermediate error 24 at 1 depth lookup:invalid CA certificate OK
To Answer my own question. I had to add the CA:true x509v3 extension to my intermediate certificate. This gave me the cert generation line
openssl x509 -req -sha256 -days 30 -in inter.csr -CA root.crt -CAkey root.pem -extfile extensions.txt -out inter.crt
basicConstraints=critical,@bs_section [bs_section] CA=true pathlen=1
copied directly from https://www.openssl.org/docs/manmaster/man5/x509v3_config.html
I'm unclear about what
critical means as openssl simply states
If critical is present then the extension will be critical. on their man page, but whatever.