Skip to content

Feature Request: send entire certificate chain (including root ca) #6776

@hanjo

Description

@hanjo

Hi,

I noticed that caddy will present the intermediate ca certificate and the host certificate when accessing it. This can be checked with openssl, for example:

echo "" | openssl s_client -showcerts -servername example.com -connect example.com:443

Here is an example with an internal pki:

[...]
---
Certificate chain
 0 s:
   i:CN = Caddy - ECC Intermediate
   a:PKEY: id-ecPublicKey, 256 (bit); sigalg: ecdsa-with-SHA256
   v:NotBefore: Jan  8 06:37:14 2025 GMT; NotAfter: Jan  8 18:37:14 2025 GMT
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
 1 s:CN = Caddy - ECC Intermediate
   i:CN = Caddy - 2025 ECC Root
   a:PKEY: id-ecPublicKey, 256 (bit); sigalg: ecdsa-with-SHA256
   v:NotBefore: Jan  6 22:07:41 2025 GMT; NotAfter: Jan 13 22:07:41 2025 GMT
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
---
[...]

In this example "1" is the intermediate ca certificate and "0" is the host certificate.

This is usually working fine, as long as the client (i.e. browser) knows and trusts the root ca certificate. However, if the certificate chain is more complex (i.e. longer), this can cause trouble, because the browser wouldn't be able to fill any gaps in the certificate chain presented by caddy.

To fix this, caddy would need to present the entire certificate chain - including the root ca certificate - to the client. I checked the documentation, but I could not find an option to enable this.

So far, I've been under the impression that it is good practice to include the entire certificate chain, which is also done by many (though not all) popular public websites, for example GitHub:

$ echo "" | openssl s_client -showcerts -servername github.com -connect github.com:443
CONNECTED(00000003)
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust ECC Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo ECC Domain Validation Secure Server CA
verify return:1
depth=0 CN = github.com
verify return:1
---
Certificate chain
 0 s:CN = github.com
   i:C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo ECC Domain Validation Secure Server CA
   a:PKEY: id-ecPublicKey, 256 (bit); sigalg: ecdsa-with-SHA256
   v:NotBefore: Mar  7 00:00:00 2024 GMT; NotAfter: Mar  7 23:59:59 2025 GMT
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
 1 s:C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo ECC Domain Validation Secure Server CA
   i:C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust ECC Certification Authority
   a:PKEY: id-ecPublicKey, 256 (bit); sigalg: ecdsa-with-SHA384
   v:NotBefore: Nov  2 00:00:00 2018 GMT; NotAfter: Dec 31 23:59:59 2030 GMT
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
 2 s:C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust ECC Certification Authority
   i:C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services
   a:PKEY: id-ecPublicKey, 384 (bit); sigalg: RSA-SHA384
   v:NotBefore: Mar 12 00:00:00 2019 GMT; NotAfter: Dec 31 23:59:59 2028 GMT
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
---
[...]

As you can see, "2" is the root ca certificate, "1" is the intermediate ca certificate and "0" is the host certificate.

Therefore, I'd like to request a configuration switch to enable sending the root ca certificate in the certificate chain.

Let me know what you think.
Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    discussion 💬The right solution needs to be found

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions