0

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.

Edit:

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

With extensions.txt reading

 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.

  • It looks to me like both are throwing a error 18 at 0 depth lookup, and for some reason openssl considers that a fatal error while libressl does not. If you posted a text dump / pretty print of the root and inter certs, that might help us spot the problem. – Mike Ounsworth Jan 21 at 20:10
  • You've omitted to show us the interactive part of the req command. This SO answer suggests that you might get this error if the root and intermediate have the same DN / CN, which is not allowed. (x509 is full of pesky little rules, and it often takes me a few tries to generate valid certs with openssl) – Mike Ounsworth Jan 21 at 20:13
1

Pending more info in the question, I would guess that when you invoke the req command, you are using the same Distinguished Name (DN) for all certs. If so, the error that you're seeing on both openssl and libressl

error 18 at 0 depth lookup:self signed certificate

is because the SubjectDN and IssuerDN are the same, so openssl expects the cert to be self-signed (ie signed with its own key). As suggested by this SO answer.

RFC 5280 (the X.509 spec) says:

Name chaining is performed by matching the issuer distinguished name in one certificate with the subject name in a CA certificate.

| improve this answer | |
  • X.509 is a complicated spec and it often takes me several tries to generate a valid cert chain in openssl. – Mike Ounsworth Jan 21 at 20:26
  • 1
    This does seem to be the case. I am putting CNs in as Root Intermediate and Leaf, but looking at the intermediate cert I'm seeing a match in subject and issuer. Issuer: C=US, ST=CA, L=SF, O=Test, OU=Test, CN=Intermediate and Subject: C=US, ST=CA, L=SF, O=Test, OU=Test, CN=Intermediate – Darakian Jan 21 at 20:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.