Skip to content

Commit

Permalink
feat: Include Mozilla's CA cert bundle inside the app
Browse files Browse the repository at this point in the history
  • Loading branch information
feelfreelinux committed May 16, 2024
1 parent ea4ef7c commit 0953dbd
Show file tree
Hide file tree
Showing 5 changed files with 3,605 additions and 13 deletions.
2 changes: 1 addition & 1 deletion app/app/src/main/java/com/octo4a/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ val appModule = module {
}
engine {
sslManager = {
it.sslSocketFactory = TLSSocketFactory()
it.sslSocketFactory = TLSSocketFactory(androidContext())
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/app/src/main/java/com/octo4a/Octo4aApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Octo4aApplication : MultiDexApplication() {
}

fun initializeSSLContext() {
val noSSLv3Factory: TLSSocketFactory = TLSSocketFactory()
val noSSLv3Factory: TLSSocketFactory = TLSSocketFactory(applicationContext)

HttpsURLConnection.setDefaultSSLSocketFactory(noSSLv3Factory)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ class BootstrapRepositoryImpl(

val sslcontext = SSLContext.getInstance("TLSv1")
sslcontext.init(null, null, null)
val noSSLv3Factory: SSLSocketFactory = TLSSocketFactory()

val noSSLv3Factory: SSLSocketFactory = TLSSocketFactory(context)

HttpsURLConnection.setDefaultSSLSocketFactory(noSSLv3Factory)
val connection: HttpsURLConnection =
Expand Down
50 changes: 40 additions & 10 deletions app/app/src/main/java/com/octo4a/utils/NoSSLv3SocketFactory.kt
Original file line number Diff line number Diff line change
@@ -1,30 +1,60 @@
package com.octo4a.utils

import android.content.Context
import com.octo4a.R
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import java.net.InetAddress
import java.net.Socket
import java.net.UnknownHostException
import java.security.KeyStore
import java.security.KeyStoreException
import java.security.NoSuchAlgorithmException
import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate
import java.util.*
import javax.net.ssl.*

class TLSSocketFactory() : SSLSocketFactory() {
class TLSSocketFactory(val context: Context) : SSLSocketFactory() {
private val delegate: SSLSocketFactory
private var trustManagers: Array<TrustManager>? = emptyArray()
@Throws(KeyStoreException::class, NoSuchAlgorithmException::class)
private fun generateTrustManagers() {
val trustManagerFactory: TrustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
trustManagerFactory.init(null as KeyStore?)
val trustManagers: Array<TrustManager> = trustManagerFactory.getTrustManagers()
if (trustManagers.size != 1 || trustManagers.get(0) !is X509TrustManager) {
throw IllegalStateException(
"Unexpected default trust managers:"
+ Arrays.toString(trustManagers)
)
val inputStream: InputStream = context.resources.openRawResource(R.raw.cacert)

// Load PEM-encoded certificate bundle
val pemCertificates = mutableListOf<X509Certificate>()
var certBuffer = StringBuilder()
BufferedReader(InputStreamReader(inputStream)).use { reader ->
var line: String?
while (reader.readLine().also { line = it } != null) {
if (line!!.startsWith("-----BEGIN CERTIFICATE-----")) {
certBuffer = StringBuilder()
}
certBuffer.append(line).append("\n")
if (line!!.startsWith("-----END CERTIFICATE-----")) {
val certBytes = certBuffer.toString().toByteArray()
val certificateFactory = CertificateFactory.getInstance("X.509")
val certificate = certificateFactory.generateCertificate(certBytes.inputStream()) as X509Certificate
pemCertificates.add(certificate)
}
}
}

val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())
keyStore.load(null)
for ((index, certificate) in pemCertificates.withIndex()) {
keyStore.setCertificateEntry("ca$index", certificate)
}

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

val trustManagers = trustManagerFactory.trustManagers
val trustManager = trustManagers.firstOrNull { it is X509TrustManager } as? X509TrustManager
?: throw IllegalStateException("No X509TrustManager found")
this.trustManagers = trustManagers
}

Expand Down
Loading

0 comments on commit 0953dbd

Please sign in to comment.