Should clients care about when a Root Certificate expires? That's a bit of an odd question, and the first time I asked myself this question, the answer was a resounding 'yes, of course'! On further inspection though, it seems like there could be a case to make about clients using Root Certificates long after their expiration date.

The Let's Encrypt Root Certificate Expiration

This question came around because of the recent expiration of the Let's Encrypt Root Certificate. You can read that blog for the full details, but the Root Certificate expired 30 Sep 2021 and there was concern that clients in the wider ecosystem would not have received updates containing the replacement Root Certificate, which would cause major outages. I did a Post-Mortem on the event and whilst I feel it went quite well, we did see a lot of stuff break and we saw a lot of problems in places we didn't expect to see problems. This basically boiled down to either misconfigured servers or outdated clients, both things that required updates that sometimes weren't even available or easy to apply.

Legacy Devices

Old Android devices were of particular concern in this event because they don't have to be very old in order for them to not receive updates any more and indeed they did feature quite prominently in the discussions before the expiration happened. One thing that ultimately allowed the impact of this event to be greatly reduced is that Android devices do not check the expiration date of the Root CA Certificate when establishing trust in the certificate chain... This means that it is still possible to anchor on the expired IdenTrust Root CA, and those Android devices would work, but other clients would still fail because it's expired and they will check the expiry date. That's why the quirky cross-signed chain ended up happening.

source

The 'New Default Chain' still ultimately anchors on the IdenTrust Root CA, meaning compatibility with Android devices that won't check the expiration date, but it passes through the new Let's Encrypt ISRG Root X1 CA which more modern clients will have in their trust store. This means those modern clients will stop the chain there and accept it as trusted too. Win-win.

Signature validation on Root Certificates

Those who have dealt with certificates know about expiration dates, many websites have been rendered unavailable by an expired certificate that someone forgot to renew! This, I guess, is why this behaviour in Android seemed odd, but I wrote it off as 'something that Android does' and moved on. I was then even more surprised though to hear about an interesting idea that would have helped work around this problem of an expiring Root CA on a wide selection of devices using OpenSSL.

Since OpenSSL 0.9.8m, signature validation has not been taking place on the Root CA Certificate in the chain. This is something I've known about and covered in our TLS/PKI training for some time and it makes absolute sense. The Root Certificate in the trust store is self-signed and checking the signature on something that is self-signed is kind of pointless, with the change dating back to 2009. "Don't check self signed certificate signatures in X509_verify_cert(): it just wastes time without adding any security". To understand why, you have to imagine that doing a signature validation on a self-signed certificate is a bit like asking someone if what they say about themselves is true, whilst having no other source of information to verify that against, it's pointless as you'd just have to take them at their word anyway. One interesting side effect of this though is that you can then modify the Root Certificates in the trust store and because no signature validation is taking place, meaning no integrity check is taking place, the modified Root Certificate will be treated as perfectly valid. This is the part that I'd never thought about.

Fudging the expiration date

The proposal from Rob in the linked email was to change the expiration date of the IdenTrust DST Root CA X3 certificate in the trust store so that it would be valid for another 3 years.

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

The wget command is fetching the certificate and the sed command is replacing a substring inside the certificate. To understand what's happening here, we can take a look at the certificate file we downloaded.

-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----

This is typically what a certificate will look like and is a PEM encoded certificate, which is the base64 encoded binary (DER) data of the certificate itself. If I parse the certificate using OpenSSL X509, we get the following.

[email protected]:~$ openssl x509 -in DSTRootCAX3_Extended.crt -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            44:af:b0:80:d6:a3:27:ba:89:30:39:86:2e:f8:40:6b
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: O = Digital Signature Trust Co., CN = DST Root CA X3
        Validity
            Not Before: Sep 30 21:12:19 2000 GMT
            Not After : Sep 30 14:01:15 2021 GMT
        Subject: O = Digital Signature Trust Co., CN = DST Root CA X3
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:df:af:e9:97:50:08:83:57:b4:cc:62:65:f6:90:
                    82:ec:c7:d3:2c:6b:30:ca:5b:ec:d9:c3:7d:c7:40:
                    c1:18:14:8b:e0:e8:33:76:49:2a:e3:3f:21:49:93:
                    ac:4e:0e:af:3e:48:cb:65:ee:fc:d3:21:0f:65:d2:
                    2a:d9:32:8f:8c:e5:f7:77:b0:12:7b:b5:95:c0:89:
                    a3:a9:ba:ed:73:2e:7a:0c:06:32:83:a2:7e:8a:14:
                    30:cd:11:a0:e1:2a:38:b9:79:0a:31:fd:50:bd:80:
                    65:df:b7:51:63:83:c8:e2:88:61:ea:4b:61:81:ec:
                    52:6b:b9:a2:e2:4b:1a:28:9f:48:a3:9e:0c:da:09:
                    8e:3e:17:2e:1e:dd:20:df:5b:c6:2a:8a:ab:2e:bd:
                    70:ad:c5:0b:1a:25:90:74:72:c5:7b:6a:ab:34:d6:
                    30:89:ff:e5:68:13:7b:54:0b:c8:d6:ae:ec:5a:9c:
                    92:1e:3d:64:b3:8c:c6:df:bf:c9:41:70:ec:16:72:
                    d5:26:ec:38:55:39:43:d0:fc:fd:18:5c:40:f1:97:
                    eb:d5:9a:9b:8d:1d:ba:da:25:b9:c6:d8:df:c1:15:
                    02:3a:ab:da:6e:f1:3e:2e:f5:5c:08:9c:3c:d6:83:
                    69:e4:10:9b:19:2a:b6:29:57:e3:e5:3d:9b:9f:f0:
                    02:5d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Subject Key Identifier:
                C4:A7:B1:A4:7B:2C:71:FA:DB:E1:4B:90:75:FF:C4:15:60:85:89:10
    Signature Algorithm: sha1WithRSAEncryption
         a3:1a:2c:9b:17:00:5c:a9:1e:ee:28:66:37:3a:bf:83:c7:3f:
         4b:c3:09:a0:95:20:5d:e3:d9:59:44:d2:3e:0d:3e:bd:8a:4b:
         a0:74:1f:ce:10:82:9c:74:1a:1d:7e:98:1a:dd:cb:13:4b:b3:
         20:44:e4:91:e9:cc:fc:7d:a5:db:6a:e5:fe:e6:fd:e0:4e:dd:
         b7:00:3a:b5:70:49:af:f2:e5:eb:02:f1:d1:02:8b:19:cb:94:
         3a:5e:48:c4:18:1e:58:19:5f:1e:02:5a:f0:0c:f1:b1:ad:a9:
         dc:59:86:8b:6e:e9:91:f5:86:ca:fa:b9:66:33:aa:59:5b:ce:
         e2:a7:16:73:47:cb:2b:cc:99:b0:37:48:cf:e3:56:4b:f5:cf:
         0f:0c:72:32:87:c6:f0:44:bb:53:72:6d:43:f5:26:48:9a:52:
         67:b7:58:ab:fe:67:76:71:78:db:0d:a2:56:14:13:39:24:31:
         85:a2:a8:02:5a:30:47:e1:dd:50:07:bc:02:09:90:00:eb:64:
         63:60:9b:16:bc:88:c9:12:e6:d2:7d:91:8b:f9:3d:32:8d:65:
         b4:e9:7c:b1:57:76:ea:c5:b6:28:39:bf:15:65:1c:c8:f6:77:
         96:6a:0a:8d:77:0b:d8:91:0b:04:8e:07:db:29:b6:0a:ee:9d:
         82:35:35:10

As you can see, right near the start of that output, is the Not After date, when the certificate expires. This is the part of the certificate we need to change and the substring replacement is targeting the 3rd line of base64 date.

DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow

If we base64 decode that, of course we will have some issues displaying the binary data, but the strings will do just fine.

DST Root CA X30
000930211219Z
210930140115Z0

The second string there is the raw Not After date and what the sed command will replace.

sed -i "s/xMDkzMDE0MDExNVow/0MDkzMDE4MTQwM1ow/g" DSTRootCAX3_Extended.crt

If we take a look at the certificate file, the change can be seen in the base64 encoded data.

-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTI0MDkzMDE4MTQwM1ow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----

But now, if we parse it with OpenSSL X509 again, we can see the new Not After date is present.

[email protected]:~$ openssl x509 -in DSTRootCAX3_Extended.crt -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            44:af:b0:80:d6:a3:27:ba:89:30:39:86:2e:f8:40:6b
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: O = Digital Signature Trust Co., CN = DST Root CA X3
        Validity
            Not Before: Sep 30 21:12:19 2000 GMT
            Not After : Sep 30 18:14:03 2024 GMT
        Subject: O = Digital Signature Trust Co., CN = DST Root CA X3
...

Testing the new certificate

Of course, the final step is to prove that this works and all you need is a website serving a Let's Encrypt certificate chain, s_client and the new Root Certificate.

[email protected]:~$ openssl s_client -connect letsencrypt.org:443 -CAfile DSTRootCAX3_Extended.crt
CONNECTED(00000003)
depth=3 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = lencr.org
verify return:1
---
Certificate chain
 0 s:CN = lencr.org
   i:C = US, O = Let's Encrypt, CN = R3
 1 s:C = US, O = Let's Encrypt, CN = R3
   i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
 2 s:C = US, O = Internet Security Research Group, CN = ISRG Root X1
   i:O = Digital Signature Trust Co., CN = DST Root CA X3
---
*snip*
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok) <-- LOOK IT WORKED!
---

That shows that s_client is able to connect to the server and properly validate the certificate chain using only the new, modified, IdenTrust Root Certificate and will be able to do so until Sep 2024. The Sep 2024 date is important, and we can't just keep extending the expiration date beyond that, because that's when the ISRG Root X1 certificate in the chain expires, so it's the furthest out this can be pushed. Still though, it would have given us another 3 years.

Trying another expiry date

Just because I found this idea so interesting, I wanted to see how easy it would be to do and how little a change would be required to the certificate itself. Turns out it's quite easy and you can get away with a single character being changed in the PEM encoded certificate!

wget -O DSTRootCAX3_Extended_1_Year.crt "https://crt.sh/?d=8395"
sed -i "s/DTIxMDk/DTIyMDk/g" DSTRootCAX3_Extended_1_Year.crt

That gives us the following certificate:

[email protected]:~$ openssl x509 -in DSTRootCAX3_Extended_1_Year.crt -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            44:af:b0:80:d6:a3:27:ba:89:30:39:86:2e:f8:40:6b
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: O = Digital Signature Trust Co., CN = DST Root CA X3
        Validity
            Not Before: Sep 30 21:12:19 2000 GMT
            Not After : Sep 30 14:01:15 2022 GMT
        Subject: O = Digital Signature Trust Co., CN = DST Root CA X3
...

Which also works fine in s_client!

[email protected]:~$ openssl s_client -connect letsencrypt.org:443 -CAfile DSTRootCAX3_Extended_1_Year.crt
CONNECTED(00000003)
depth=3 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = lencr.org
verify return:1
---
Certificate chain
 0 s:CN = lencr.org
   i:C = US, O = Let's Encrypt, CN = R3
 1 s:C = US, O = Let's Encrypt, CN = R3
   i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
 2 s:C = US, O = Internet Security Research Group, CN = ISRG Root X1
   i:O = Digital Signature Trust Co., CN = DST Root CA X3
---
*snip*
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok) <-- STILL WORKS!
---

Making the change is relatively easy, requiring you to base64 decode the PEM certificate into hex for editing and then changing the expiry date in the certificate data. Here are the original Base64 and Hex versions followed by the modified versions.

Original:
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
30 82 03 4a 30 82 02 32 a0 03 02 01 02 02 10 44 af b0 80 d6 a3 27 ba 89 30 39 86 2e f8 40 6b 30 0d 06 09 2a 86 48 86 f7 0d 01 01 05 05 00 30 3f 31 24 30 22 06 03 55 04 0a 13 1b 44 69 67 69 74 61 6c 20 53 69 67 6e 61 74 75 72 65 20 54 72 75 73 74 20 43 6f 2e 31 17 30 15 06 03 55 04 03 13 0e 44 53 54 20 52 6f 6f 74 20 43 41 20 58 33 30 1e 17 0d 30 30 30 39 33 30 32 31 31 32 31 39 5a 17 0d 32 31 30 39 33 30 31 34 30 31 31 35 5a 30 3f 31 24 30 22 06 03 55 04 0a 13 1b 44 69 67 69 74 61 6c 20 53 69 67 6e 61 74 75 72 65 20 54 72 75 73 74 20 43 6f 2e 31 17 30 15 06 03 55 04 03 13 0e 44 53 54 20 52 6f 6f 74 20 43 41 20 58 33 30 82 01 22 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 82 01 0f 00 30 82 01 0a 02 82 01 01 00 df af e9 97 50 08 83 57 b4 cc 62 65 f6 90 82 ec c7 d3 2c 6b 30 ca 5b ec d9 c3 7d c7 40 c1 18 14 8b e0 e8 33 76 49 2a e3 3f 21 49 93 ac 4e 0e af 3e 48 cb 65 ee fc d3 21 0f 65 d2 2a d9 32 8f 8c e5 f7 77 b0 12 7b b5 95 c0 89 a3 a9 ba ed 73 2e 7a 0c 06 32 83 a2 7e 8a 14 30 cd 11 a0 e1 2a 38 b9 79 0a 31 fd 50 bd 80 65 df b7 51 63 83 c8 e2 88 61 ea 4b 61 81 ec 52 6b b9 a2 e2 4b 1a 28 9f 48 a3 9e 0c da 09 8e 3e 17 2e 1e dd 20 df 5b c6 2a 8a ab 2e bd 70 ad c5 0b 1a 25 90 74 72 c5 7b 6a ab 34 d6 30 89 ff e5 68 13 7b 54 0b c8 d6 ae ec 5a 9c 92 1e 3d 64 b3 8c c6 df bf c9 41 70 ec 16 72 d5 26 ec 38 55 39 43 d0 fc fd 18 5c 40 f1 97 eb d5 9a 9b 8d 1d ba da 25 b9 c6 d8 df c1 15 02 3a ab da 6e f1 3e 2e f5 5c 08 9c 3c d6 83 69 e4 10 9b 19 2a b6 29 57 e3 e5 3d 9b 9f f0 02 5d 02 03 01 00 01 a3 42 30 40 30 0f 06 03 55 1d 13 01 01 ff 04 05 30 03 01 01 ff 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 01 06 30 1d 06 03 55 1d 0e 04 16 04 14 c4 a7 b1 a4 7b 2c 71 fa db e1 4b 90 75 ff c4 15 60 85 89 10 30 0d 06 09 2a 86 48 86 f7 0d 01 01 05 05 00 03 82 01 01 00 a3 1a 2c 9b 17 00 5c a9 1e ee 28 66 37 3a bf 83 c7 3f 4b c3 09 a0 95 20 5d e3 d9 59 44 d2 3e 0d 3e bd 8a 4b a0 74 1f ce 10 82 9c 74 1a 1d 7e 98 1a dd cb 13 4b b3 20 44 e4 91 e9 cc fc 7d a5 db 6a e5 fe e6 fd e0 4e dd b7 00 3a b5 70 49 af f2 e5 eb 02 f1 d1 02 8b 19 cb 94 3a 5e 48 c4 18 1e 58 19 5f 1e 02 5a f0 0c f1 b1 ad a9 dc 59 86 8b 6e e9 91 f5 86 ca fa b9 66 33 aa 59 5b ce e2 a7 16 73 47 cb 2b cc 99 b0 37 48 cf e3 56 4b f5 cf 0f 0c 72 32 87 c6 f0 44 bb 53 72 6d 43 f5 26 48 9a 52 67 b7 58 ab fe 67 76 71 78 db 0d a2 56 14 13 39 24 31 85 a2 a8 02 5a 30 47 e1 dd 50 07 bc 02 09 90 00 eb 64 63 60 9b 16 bc 88 c9 12 e6 d2 7d 91 8b f9 3d 32 8d 65 b4 e9 7c b1 57 76 ea c5 b6 28 39 bf 15 65 1c c8 f6 77 96 6a 0a 8d 77 0b d8 91 0b 04 8e 07 db 29 b6 0a ee 9d 82 35 35 10


Modified:
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIyMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
30 82 03 4a 30 82 02 32 a0 03 02 01 02 02 10 44 af b0 80 d6 a3 27 ba 89 30 39 86 2e f8 40 6b 30 0d 06 09 2a 86 48 86 f7 0d 01 01 05 05 00 30 3f 31 24 30 22 06 03 55 04 0a 13 1b 44 69 67 69 74 61 6c 20 53 69 67 6e 61 74 75 72 65 20 54 72 75 73 74 20 43 6f 2e 31 17 30 15 06 03 55 04 03 13 0e 44 53 54 20 52 6f 6f 74 20 43 41 20 58 33 30 1e 17 0d 30 30 30 39 33 30 32 31 31 32 31 39 5a 17 0d 32 32 30 39 33 30 31 34 30 31 31 35 5a 30 3f 31 24 30 22 06 03 55 04 0a 13 1b 44 69 67 69 74 61 6c 20 53 69 67 6e 61 74 75 72 65 20 54 72 75 73 74 20 43 6f 2e 31 17 30 15 06 03 55 04 03 13 0e 44 53 54 20 52 6f 6f 74 20 43 41 20 58 33 30 82 01 22 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 82 01 0f 00 30 82 01 0a 02 82 01 01 00 df af e9 97 50 08 83 57 b4 cc 62 65 f6 90 82 ec c7 d3 2c 6b 30 ca 5b ec d9 c3 7d c7 40 c1 18 14 8b e0 e8 33 76 49 2a e3 3f 21 49 93 ac 4e 0e af 3e 48 cb 65 ee fc d3 21 0f 65 d2 2a d9 32 8f 8c e5 f7 77 b0 12 7b b5 95 c0 89 a3 a9 ba ed 73 2e 7a 0c 06 32 83 a2 7e 8a 14 30 cd 11 a0 e1 2a 38 b9 79 0a 31 fd 50 bd 80 65 df b7 51 63 83 c8 e2 88 61 ea 4b 61 81 ec 52 6b b9 a2 e2 4b 1a 28 9f 48 a3 9e 0c da 09 8e 3e 17 2e 1e dd 20 df 5b c6 2a 8a ab 2e bd 70 ad c5 0b 1a 25 90 74 72 c5 7b 6a ab 34 d6 30 89 ff e5 68 13 7b 54 0b c8 d6 ae ec 5a 9c 92 1e 3d 64 b3 8c c6 df bf c9 41 70 ec 16 72 d5 26 ec 38 55 39 43 d0 fc fd 18 5c 40 f1 97 eb d5 9a 9b 8d 1d ba da 25 b9 c6 d8 df c1 15 02 3a ab da 6e f1 3e 2e f5 5c 08 9c 3c d6 83 69 e4 10 9b 19 2a b6 29 57 e3 e5 3d 9b 9f f0 02 5d 02 03 01 00 01 a3 42 30 40 30 0f 06 03 55 1d 13 01 01 ff 04 05 30 03 01 01 ff 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 01 06 30 1d 06 03 55 1d 0e 04 16 04 14 c4 a7 b1 a4 7b 2c 71 fa db e1 4b 90 75 ff c4 15 60 85 89 10 30 0d 06 09 2a 86 48 86 f7 0d 01 01 05 05 00 03 82 01 01 00 a3 1a 2c 9b 17 00 5c a9 1e ee 28 66 37 3a bf 83 c7 3f 4b c3 09 a0 95 20 5d e3 d9 59 44 d2 3e 0d 3e bd 8a 4b a0 74 1f ce 10 82 9c 74 1a 1d 7e 98 1a dd cb 13 4b b3 20 44 e4 91 e9 cc fc 7d a5 db 6a e5 fe e6 fd e0 4e dd b7 00 3a b5 70 49 af f2 e5 eb 02 f1 d1 02 8b 19 cb 94 3a 5e 48 c4 18 1e 58 19 5f 1e 02 5a f0 0c f1 b1 ad a9 dc 59 86 8b 6e e9 91 f5 86 ca fa b9 66 33 aa 59 5b ce e2 a7 16 73 47 cb 2b cc 99 b0 37 48 cf e3 56 4b f5 cf 0f 0c 72 32 87 c6 f0 44 bb 53 72 6d 43 f5 26 48 9a 52 67 b7 58 ab fe 67 76 71 78 db 0d a2 56 14 13 39 24 31 85 a2 a8 02 5a 30 47 e1 dd 50 07 bc 02 09 90 00 eb 64 63 60 9b 16 bc 88 c9 12 e6 d2 7d 91 8b f9 3d 32 8d 65 b4 e9 7c b1 57 76 ea c5 b6 28 39 bf 15 65 1c c8 f6 77 96 6a 0a 8d 77 0b d8 91 0b 04 8e 07 db 29 b6 0a ee 9d 82 35 35 10

The only changes in the Base64/Hex data were:

DTIxMDk - 2021 expiry
DTIyMDk - 2022 expiry

32 31 30 39 33 30 31 34 30 31 31 35 - 2021 expiry
32 32 30 39 33 30 31 34 30 31 31 35 - 2022 expiry

Of course, as I said before, you can only modify the certificate in this way because the signature is not being validated by the client and as a result, the integrity check that would catch these modifications is not being performed.

Is there a risk to this?

When first thinking about this issue, I felt a little bit like I did when I first found out, all those years ago, about signatures not being validated on roots and how that seemed ridiculous. Once you think about this more though, you realise that it does make sense and that it just doesn't seem logical upon first thought. In order to make this change and it actually have an effect on the client, you need to have access to that client with administrative privileges to change the root store. If your concern is that an attacker might do something like this, well, I'd suggest you have far bigger issues to concern yourself with given that the attacker has admin/root and is on your device!

As the administrator of the system, I get to say what it trusts and doesn't trust, and I could achieve exactly the same scenario by installing my own Root CA onto the client and having it trust an upstream proxy that terminates TLS. In these regards then, what we've done here is no different to what could already be done, it's just that this way is a lot more convenient.

This could well have been very useful for the Let's Encrypt Root Certificate expiration and may well be helpful in the future when other Root CAs are approaching expiration too. Hopefully we might not need such workarounds in the coming years, but it never hurts to have options!