Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Let's Encrypt TLS on old API versions #2489

Merged
merged 2 commits into from Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Expand Up @@ -57,6 +57,7 @@ mockito-kotlin = "org.mockito:mockito-android:_"
mpandroidchart = "com.github.PhilJay:MPAndroidChart:_"
nullaway = "com.uber.nullaway:nullaway:_"
okhttp = "com.squareup.okhttp3:okhttp:_"
okhttp-tls = "com.squareup.okhttp3:okhttp-tls:_"
okio = "com.squareup.okio:okio:_"
profileinstaller = "androidx.profileinstaller:profileinstaller:_"
qrcodereaderview = "com.dlazaro66.qrcodereaderview:qrcodereaderview:_"
Expand Down
1 change: 1 addition & 0 deletions snapshot-tests/build.gradle
Expand Up @@ -60,6 +60,7 @@ dependencies {
implementation libs.compose.material

implementation libs.okhttp
implementation libs.okhttp.tls

androidTestImplementation libs.aws.android.sdk.s3
androidTestImplementation(libs.aws.android.sdk.mobile.client) { transitive = true }
Expand Down
Expand Up @@ -6,6 +6,7 @@ import android.os.Build
import android.util.Log
import com.airbnb.lottie.L
import com.airbnb.lottie.snapshots.BuildConfig
import com.airbnb.lottie.snapshots.R
import com.amazonaws.auth.BasicAWSCredentials
import com.amazonaws.mobileconnectors.s3.transferutility.TransferObserver
import com.amazonaws.mobileconnectors.s3.transferutility.TransferUtility
Expand All @@ -14,19 +15,35 @@ import com.amazonaws.services.s3.model.CannedAccessControlList
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import kotlinx.coroutines.*
import okhttp3.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.Call
import okhttp3.Callback
import okhttp3.Credentials
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.math.BigInteger
import java.net.URLEncoder
import java.nio.charset.Charset
import java.security.KeyStore
import java.security.MessageDigest
import java.util.*
import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate
import java.util.UUID
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManagerFactory
import javax.net.ssl.X509TrustManager
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
Expand Down Expand Up @@ -60,7 +77,28 @@ class HappoSnapshotter(
// private val reportNamePrefixes = listOf(System.currentTimeMillis().toString()).filter { it.isNotBlank() }
private val reportNames = reportNamePrefixes.map { "$it-$androidVersion" }

private val okhttp = OkHttpClient()
private val okhttp by lazy {
// https://androiddev.social/@botteaap/112108241212116279
// https://letsencrypt.org/2023/07/10/cross-sign-expiration.html
// https://letsencrypt.org/certs/isrgrootx1.der
val ca: X509Certificate = context.resources.openRawResource(R.raw.isrgrootx1).use {
CertificateFactory.getInstance("X.509").generateCertificate(it) as X509Certificate
}

val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())
keyStore.load(null, null)
keyStore.setCertificateEntry("ca", ca)

val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
trustManagerFactory.init(keyStore)

val sslContext: SSLContext = SSLContext.getInstance("TLS")
sslContext.init(null, trustManagerFactory.trustManagers, null)

OkHttpClient.Builder()
.sslSocketFactory(sslContext.socketFactory, trustManagerFactory.trustManagers[0] as X509TrustManager)
.build()
}

private val transferUtility = TransferUtility.builder()
.context(context)
Expand Down Expand Up @@ -155,4 +193,4 @@ class HappoSnapshotter(
digest.update(this, 0, this.size)
return BigInteger(1, digest.digest()).toString(16)
}
}
}
Binary file added snapshot-tests/src/main/res/raw/isrgrootx1.der
Binary file not shown.