Old Let’s Encrypt Root Certificate Expiration and OpenSSL 1.0.2

The currently recommended certificate chain as presented to Let’s Encrypt ACME
clients when new certificates are issued contains an intermediate certificate
(ISRG Root X1) that is signed by an old DST Root CA X3 certificate that expires
on 2021-09-30. In some cases the OpenSSL 1.0.2 version will regard the
certificates issued by the Let’s Encrypt CA as having an expired trust chain.

See more information about the currently issued trust chains at
Let’s Encrypt.

Most up-to-date CA cert trusted bundles, as provided by operating systems,
contain this soon-to-be-expired certificate. The current CA cert bundles also
contain an ISRG Root X1 self-signed certificate. This means that clients
verifying certificate chains can find the alternative non-expired path to the
ISRG Root X1 self-signed certificate in their trust store.

Unfortunately this does not apply to OpenSSL 1.0.2 which always prefers the
untrusted chain and if that chain contains a path that leads to an expired
trusted root certificate (DST Root CA X3), it will be selected for the
certificate verification and the expiration will be reported.

These are some possible workarounds to resolve the problem:

Workaround 1 (on clients with OpenSSL 1.0.2)

Just remove the expired root certificate (DST Root CA X3) from the trust store
used by the OpenSSL 1.0.2 TLS client to verify the identity of TLS servers. If
the new ISRG Root X1 self-signed certificate isn’t already in the trust store,
add it.

There is no downside to this workaround apart from the need to modify all the
potential OpenSSL 1.0.2 TLS client hosts trust stores.

The removal and addition of certificates from/into the system certificate trust
stores is a highly specific operation depending on the operation system. For
example, on Linux based systems which manage system certificate trust stores
with the ca-certificates tool, a CA certificate can be removed by first copying
the certificate into /etc/pki/ca-trust/source/blacklist directory and added by
copying into the /etc/pki/ca-trust/source/anchors directory. The trust store
is then updated by running the update-ca-trust command.

Workaround 2 (on clients with OpenSSL 1.0.2)

The -trusted_first option support in openssl verify, openssl s_client,
and other similar openssl commands when applied, overrides the certificate
chain building so it prefers the trust store certificates over the
untrusted certificates in the chain provided by the peer. That effectively
means that with the option enabled the problem does not happen.

However the option is not enabled by default and third party applications do
not usually provide a way to enable this option. The applications would have
to call X509_VERIFY_PARAM_set_flags() function with the
X509_V_FLAG_TRUSTED_FIRST flag to enable this option.

The next release of OpenSSL 1.0.2 (1.0.2zb – available to premium support
customers only) will make it possible to build the release with added
-DOPENSSL_TRUSTED_FIRST_DEFAULT on the build configuration command line.
That will make the -trusted_first option enabled by default by the
OpenSSL library.

Workaround 3 (on the servers that 1.0.2 clients connect to)

Configure the server to use the alternative certificate chain which can be
requested from Let’s Encrypt with most up-to-date ACME protocol clients.
This chain does not contain the ISRG Root X1 cross-signed by the soon to be
expired DST Root CA X3 and thus any OpenSSL 1.0.2 clients will not be misled
by this expired path.

The downside is that the servers will be seen as using an untrusted root
certificate by some older Android clients because these clients do not contain
the self-signed ISRG Root X1 certificate in their trust stores.OpenSSL BlogRead More