0

I am getting two different errors on two different installations of the same server-client micro services. These are Node.js based services running on different hosts. Yes, I am using self-signed certificates. Based on the searches online, I can bypass these errors using rejectUnauthorized: false in https.agent option or set NODE_TLS_REJECT_UNAUTHORIZED=0 as ENVIRONMENT variable of the client. I do not want to do that, primarily because that defeats the whole purpose of TLS and HTTPS. Hence, I passed the signed certificate to the client and things work well now. At least, in one instance of my installation which was giving DEPTH_ZERO_SELF_SIGNED_CERT. I can not test the other instance which is giving SELF_SIGNED_CERT_IN_CHAIN (logistical issues). I wish to know, what is the difference between the two errors? Some online blogs and forums treat these two errors synonymously and provide similar fix for both.

aman_novice
  • 1,027
  • 3
  • 13
  • 31

1 Answers1

2

Both error strings come from OpenSSL.

So if you look at https://www.openssl.org/docs/manmaster/man1/openssl-verify.html you get:

X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN

The certificate chain could be built up using the untrusted certificates but the root could not be found locally.

and

X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT

The passed certificate is self-signed and the same certificate cannot be found in the list of trusted certificates.

So they are technically different, but in both cases it means that in the chain of certificates (either the certificate itself when self signed or something higher in the chain) there is one of them that is not trusted/not found locally as trusted.

Which basically mean you are not using the certificate you expect to use or your trust store is not configured accordingly.

Details with openssl verify

Create a self signed certificate and run openssl verify on it, you get:

$ openssl verify -verbose cert.pem
cert.pem: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd
error 18 at 0 depth lookup:self signed certificate
OK

If you look at its manpage you get:

   18 X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: self signed certificate

So error 18 is DEPTH_ZERO_SELF_SIGNED_CERT

Now create another certificate (cert2.pem) that will be signed by this self-signed certificate.

Without passing the untrusted part:

$ openssl verify -verbose cert2.pem
cert2.pem: C = US, ST = Some-State, O = Internet Widgits Pty Ltd
error 20 at 0 depth lookup:unable to get local issuer certificate

Error 20 is X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY. As expected, openssl is telling you that this certificate is not self signed but signed by an authority it does not know about locally.

But by passing the previous self signed certificate as CA for this second one:

$ openssl verify -verbose -untrusted cert.pem cert2.pem
cert2.pem: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd
error 19 at 1 depth lookup:self signed certificate in certificate chain

Error 19 is indeed X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: openssl is telling you that it can validate the final certificate cert2.pem based on the untrusted (that is typically intermediate) certificate in cert.pem (so there is a valid signature between the two) but then that intermediate certificate is self signed and not known as trusted CA, so based on your current trust store, openssl is unable to fully validate this certificate.

Patrick Mevzek
  • 10,995
  • 16
  • 38
  • 54
  • So how to make the self-signed a trusted one? Thank you – Jeb50 Jun 30 '21 at 22:11
  • @Jeb50 Add it in the relevant truststore and mark it as trusted. This completely depends on how you use it, so you will need to create a new specific question with your details. It might also not be ontopic here as not related to programming, so look instead at SuperUser or Webmasters depending on the content (read their help section to find out what is ontopic on each) – Patrick Mevzek Jun 30 '21 at 22:41