BetterTLS: Path Building

What is BetterTLS: Path Building?

This test suite exercises the certificate path building capabilities of TLS implementations. Path building refers to the problem of building a valid, trusted chain from an end-entity's leaf certificate to a trust anchor. For background and motivation, we highly recommend you read Ryan Sleevi's blog post on this topic. The problem stated can be succinctly summarized with this excerpt:

Often, when I talk to people who are responsible for configuring certificates on their servers, they often talk about _the_ certificate chain. ... [But] there are many chains, with different chains are needed by different clients, who have different root stores and different behaviors.

Historically the TLS specifications have not required that TLS implementations support particularly robust certificate path building. In practice many of them (such as OpenSSL) don't support verifying anything other than a simple, non-branching sequence of certificates. This has changed in the specification for TLS 1.3 which advises that implementations SHOULD support more robust certificate path building:

Note: Prior to TLS 1.3, "certificate_list" ordering required each certificate to certify the one immediately preceding it; however, some implementations allowed some flexibility. Servers sometimes send both a current and deprecated intermediate for transitional purposes, and others are simply configured incorrectly, but these cases can nonetheless be validated properly. For maximum compatibility, all implementations SHOULD be prepared to handle potentially extraneous certificates and arbitrary orderings from any TLS version, with the exception of the end-entity certificate which MUST be first.

This test suite can be applied to TLS implementations to not only verify whether they satisfy the above provision, but whether they are doing so correctly.

Check out our blog post for a summary of results from common TLS implementations at the time this suite was created.

Why does this matter?

The web PKI ecosystem is a shifting landscape. Features like what certificate authorities are trusted, what algorithms should be used, and what X.509 certificate extensions can (and should) be enforced have been changing every year. Service owners need to keep up with these changes while also ensuring that existing clients are able to reach their service.

For example, the Let's Encrypt R3 CA has two certificates; one signed by `DST Root CA X3` and one signed by `ISRG Root X1`. Older clients only trusted the self-signed DST Root CA X3 certificate, usually since they were built before the ISRG Root X1 CA had made its way into broadly distributed truststores. However, newer clients only trust the ISRG Root X1 CA since the DST Root CA X3 self-signed certificate expired on September 30, 2021. Ideally, service owners would be able to send _both_ the DST Root CA X3 => R3 and ISRG Root X1 => R3 certificate so that any client can verify their trust of the Let's Encrypt R3 CA and ultimately verify their trust in the end entity certificate. In practice, many clients are not able to handle getting muiltple potential paths in a TLS response and this leaves both clients and service operators subject to outages.

In general, having clients with a robust certificate path building allows the community to be more agile and make changes to the web PKI ecosystem over time while reducing risk of breaking older clients. Here are just a few examples of these sorts of changes in the past:

At a minimum, this test suite can help inform service owners about how much path building different TLS client implementations support so that they can determine how clients will be impacted by changes to their service's TLS configuration and certificates.

What's on this website?

The site contains archived test results from the time the test suite was originally created. Check out the project's GitHub page for information on how you can apply the test suite to additional TLS implementations.

This is a collection of save test results. This test suite detects supported features (such as distrusting certificates with a deprecated signature algorithm and whether path building is supported at all) and skips tests that rely on unsupported features. To make sense of results, you should not only consider failed tests but see which were not even run.

Check out our blog post for some discussion of these results.