OpenSSL Client Compatibility Changes for Let’s Encrypt Certificates

Last month, we announced that we've developed a way for Let's Encrypt subscribers to keep supporting older Android devices after our cross-signature from DST Root CA X3 expires this September.

There is one notable exception: OpenSSL versions 1.0.0 through 1.0.2 will reject the Android-compatible chain, regardless of whether they have ISRG Root X1 in their trust store. If you do nothing, your ACME client will choose the Android-compatible chain by default, which we think is the right choice for most sites. If you know your site or API has to support devices running OpenSSL 1.0.x, you'll want to choose the alternate (shorter) chain that supports OpenSSL instead of Android (and then update to the latest OpenSSL). We think the OpenSSL issue is most likely to affect IoT devices that aren't getting updates from their manufacturer.

Compatibility - Now Compatibility - After June 2021
Android >= 7.1.1 :heavy_check_mark: :heavy_check_mark:
Android < 7.1.1 and >= 4.0 :heavy_check_mark: :heavy_check_mark: (by default)
OpenSSL >= 1.1 with ISRG Root X1 in trust store :heavy_check_mark: :heavy_check_mark:
OpenSSL 1.0.x with ISRG Root X1 in trust store :heavy_check_mark: :x: (by default)
OpenSSL (any version) without ISRG Root X1 in trust store :heavy_check_mark: :x:
Android < 4.0 :heavy_check_mark: :x:

For compatibility with older Android devices, we'll be relying on a signature from an expired root, which is supported by Android. However, as Ryan Sleevi points out in “Path Building vs Path Verifying,” older versions of OpenSSL will reject a certificate chain that includes a signature by an expired root, even if OpenSSL could validate the chain by ignoring that certificate.

Let’s Encrypt is not the first CA to be impacted by this problem, nor will we be the last as long as old versions of OpenSSL are in use. Last year, the expiration of a long-lived Sectigo root certificate led to disruption of service for IoT devices and software that depended on these same versions of OpenSSL. Prompted by that event, the PKI community has done some excellent research focused on understanding the problem, exploring solutions, and evaluating implementations of other popular TLS clients.

Impacted versions of OpenSSL

The behavior that causes this incompatibility was fixed over 4 years ago with the release of OpenSSL 1.1.0.

If your software depends on OpenSSL version 1.1.0 or newer and ISRG Root X1 is present in your “trust store," Let’s Encrypt certificates will continue to validate without interruption. This will remain the case, even after the expiration of DST Root CA X3 in September of this year.

If you use or maintain software that relies on versions of OpenSSL released before 1.1.0 you should seriously consider updating. In the last 4 years the OpenSSL team has shipped patches for over 60 vulnerabilities. These range from “Denial of Service” to “Remote Code Execution”.

How to support older OpenSSL versions

If you need to support affected OpenSSL versions and don't need compatibility with devices running Android versions older than 7.1.1, you'll be able to configure your ACME client to use a short chain that works for OpenSSL.

When you request a certificate with ACME, our servers provide your ACME client with a recommended certificate chain to go with it. Right now, that default chain is short and consists of one certificate:

R3 (signed by ISRG Root X1) -> Subscriber certificate

Soon, our servers will start recommending a slightly longer default chain that will maintain Android compatibility through 2024:

ISRG Root X1 (signed by DST Root CA X3) -> R3 (signed by ISRG Root X1) -> Subscriber certificate

However, we will continue to provide the shorter chain as an alternate, which can be selected by ACME clients that have alternate chain support. To support OpenSSL versions older than 1.1.0, you should configure this shorter chain.This functionality is officially supported by ACME and is already implemented by clients like uacme, Caddy, and more recently Certbot.

ISRG Root X1 is already trusted by most modern browsers and smartphones, however, devices running Android older than 7.1.1 will consider the certificate presented by your server to be invalid and will reject it.

Regardless of the certificate chain being used, ISRG Root X1 will need to be present in the “trust store” of clients using any version of OpenSSL. If not, the certificate will be rejected as untrusted.

Other Libraries

We've focussed on OpenSSL since it's one of the most popular TLS libraries, but other libraries have similar issues. LibreSSL < 3.2.0 has the same issue. GnuTLS < 3.6.14 also has the same issue. The platform verifiers on Windows and macOS (CryptoAPI and SecureTransport) don't have this problem. Browsers in general don't have this problem.

Serving the Most Users By Default

The premise of Let's Encrypt from the beginning has been making HTTPS as accessible as possible to as many people browsing the Web as possible. We also want to make it as simple as possible for the subscribers who get certificates from us. Fortunately, the ACME protocol lets us do that. By default, we'll recommend the certificate chain that does the most good for the most people -- the longer, Android-compatibility chain. We encourage you to update your OpenSSL, and if that is not possible, to follow this alternative configuration.

For updates on this change, please select “watching” under the bell in API Announcements - we will continue to update this thread as needed.

If you have questions about this change, please post on this thread: here