Okhttp: Review impact of let's encrypt CA change

Created on 8 Nov 2020  路  13Comments  路  Source: square/okhttp

Effective: As of January 11, 2021

https://letsencrypt.org/2020/11/06/own-two-feet.html

However, this does introduce some compatibility woes. Some software that hasn鈥檛 been updated since 2016 (approximately when our root was accepted to many root programs) still doesn鈥檛 trust our root certificate, ISRG Root X1. Most notably, this includes versions of Android prior to 7.1.1. That means those older versions of Android will no longer trust certificates issued by Let鈥檚 Encrypt.

Potentially we could promote adoption of Conscrypt for older clients and confirm they are shipping updated CA certs outside of the App?

bug

All 13 comments

We should also check that our cert pinning code does something reasonable for cross-signed certs. I suspect that might be a common mitigation?

My current suggestion is a stackoverflow Question and self answer with sample code like the following (with correct certificate of course)

  val cert: X509Certificate = """
   -----BEGIN CERTIFICATE-----
   MIIBFzCBwgIJAIVAqagcVN7/MA0GCSqGSIb3DQEBBAUAMBMxETAPBgNVBAMMCGNh
   c2guYXBwMB4XDTE5MDkwNzAyMjg0NFoXDTE5MDkwODAyMjg0NFowEzERMA8GA1UE
   AwwIY2FzaC5hcHAwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA8qAeoubm4mBTD9/J
   ujLQkfk/fuJt/T5pVQ1vUEqxfcMw0zYgszQ5C2MiIl7M6JkTRKU01q9hVFCR83wX
   zIdrLQIDAQABMA0GCSqGSIb3DQEBBAUAA0EAO1UpwhrkW3Ho1nZK/taoUQOoqz/n
   HFVMtyEkm5gBDgz8nJXwb3zbegclQyH+kVou02S8zC5WWzEtd0R8S0LsTA==
   -----END CERTIFICATE----- 
  """.trimIndent().parsePemCertificate().toX509Certificate()

  val handshakeCertificates = HandshakeCertificates.Builder()
      .addPlatformTrustedCertificates()
      .addTrustedCertificate(cert)
      .build()

  val client = OkHttpClient.Builder()
      .sslSocketFactory(handshakeCertificates.sslSocketFactory(), handshakeCertificates.trustManager)
      .build()

I like that!

Should we post this in our changelog? Or on our website?

Should we post this in our changelog? Or on our website?

I'm working on a confirmed fix now. Then yes, but stackoverflow is the right forum for the canonical answer.

The fix works, but is complicated by Junit5 requirements on Android...

Closing this out. Think the two test cases and stackoverflow + forum post are better than the samples.

@yschimke Is there advice on how to port this solution with enforcing TLS 1.2 on Android 4.x devices. More specifically how can I provide a particular TLS protocol to the SSLContext of the handshakeCertificates.

Not really you could copy https://github.com/square/okhttp/blob/parent-3.12.12/okhttp-tls/src/main/java/okhttp3/tls/HandshakeCertificates.java and adjust to what you need.

Also do you really need to change the call to SSLContext.getInstance? AndroidPlatform tries to do the optimal thing here and 3.12.12 should support these older devices. I think I always get mixed up at whether you are trying to conditionally enable TLSv1.2 or the opposite and keep TLSv1.1 which was dropped later in 3.13. Sorry for the confusion.

https://github.com/square/okhttp/blob/parent-3.12.12/okhttp/src/main/java/okhttp3/internal/platform/AndroidPlatform.java#L442-L465

@yschimke Thanks, My issue turned out to be something else. I was adding the call to .sslSocketFactory(handshakeCertificates.sslSocketFactory(), handshakeCertificates.trustManager) before adding TLSv1.2 (using conscrypt) which resulted into HTTP calls not using TLSv1.2 on Android 4.

Was this page helpful?
0 / 5 - 0 ratings