"DST Root CA X3" expiry workaround for OpenSSL 1.0.1, 1.0.0 and 0.9.8 client applications

Rob Stradling rob at sectigo.com
Sun Oct 3 23:09:21 UTC 2021

The "Old Let’s Encrypt Root Certificate Expiration and OpenSSL 1.0.2" blog article [1] doesn't cover OpenSSL versions prior to 1.0.2, presumably because they've been unsupported for a long time.  However, no doubt there are still some users and applications that are stuck using even older versions of OpenSSL.  Here are some solutions...

Firstly, it's worth noting that Workaround 1 (see [1]) also works with OpenSSL 1.0.1n and above, which seems to be because the 1.0.2 "alternative chains" behaviour was backported (see [2]).

Secondly, I've come up with a variant of Workaround 1 (see "Workaround 0" below) that also works for even older OpenSSL releases.  I thought I'd share it here in case it helps anyone out...

Workaround 0 (on clients with OpenSSL >=0.9.8m)

Modify the "notAfter" date in the expired root certificate (DST Root CA X3) from "Sep 30 14:01:15 2021 GMT" to "Sep 30 18:14:03 2024 GMT" (which is when the new DST->ISRG cross-certificate is due to expire - see [3] and [4]); then, in the OpenSSL-based client application's trust store, replace the expired root certificate with the modified version.  Here's one way to create the modified certificate:

wget -O DSTRootCAX3_Extended.crt "https://crt.sh/?d=8395"
sed -i "s/xMDkzMDE0MDExNVow/0MDkzMDE4MTQwM1ow/g" DSTRootCAX3_Extended.crt

You should find that "openssl s_client" with "-CAfile DSTRootCAX3_Extended.crt" will return "Verify return code: 0 (ok)" when connecting to any server that serves Let's Encrypt's preferred certificate chain (i.e., the chain that includes [4]).  For example:

openssl s_client -connect letsencrypt.org:443 -CAfile ../DSTRootCAX3_Extended.crt

Why does this work?
Modifying the expired root certificate obviously invalidates its self-signed signature.  However, OpenSSL 0.9.8m and above don't check self-signed signatures by default (due to [5]), which is one factor in why this workaround works (whereas 0.9.8l and below do check self-signed signatures).  The other factor is that OpenSSL treats the modified certificate as a root certificate, because the Issuer and Subject Names are identical; since it's not treated as an intermediate certificate, older versions of OpenSSL are able to treat it as a trust anchor even though they lack the "partial chains" functionality that was added in 1.0.2 (see [6]).

It is not necessary to add the new ISRG Root X1 self-signed certificate to the client's trust store for Workaround 0 to work.  Note however that Workaround 0 won't work beyond Sep 30 18:14:03 2024 GMT.

[1] https://www.openssl.org/blog/blog/2021/09/13/LetsEncryptRootCertExpire/<https://www.openssl.org/blog/blog/2021/09/13/LetsEncryptRootCertExpire/)>

[2] https://github.com/openssl/openssl/commit/f7bf8e02dfcb2c02bc12a59276d0a3ba43e6c204

[3] https://letsencrypt.org/2020/12/21/extending-android-compatibility.html

[4] https://crt.sh/?id=3958242236

[5] https://github.com/openssl/openssl/commit/1e53b797f65ef6d3c2eb1052797683fec27a9ff5

[6] https://github.com/openssl/openssl/commit/9a1f59cd3128ddac73d3e0721ecd55935f53ba8b

Rob Stradling
Senior Research & Development Scientist
Sectigo Limited

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mta.openssl.org/pipermail/openssl-users/attachments/20211003/f88389a3/attachment-0001.html>

More information about the openssl-users mailing list