If exists, use TLS CA File (if it exists) also when loading account configuration

This commit is contained in:
Juha Heinanen
2025-10-17 08:47:52 +03:00
parent 82f0a669e0
commit 3b7f45844a
2 changed files with 50 additions and 2 deletions

View File

@ -73,6 +73,7 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserFactory
import java.io.File
import java.io.StringReader
import java.net.URL
import java.util.Locale
@ -1538,8 +1539,12 @@ private fun initAccountFromConfig(acc: Account, onConfigLoaded: () -> Unit) {
val scope = CoroutineScope(Job() + Dispatchers.Main)
scope.launch(Dispatchers.IO) {
val url = "https://${Utils.uriHostPart(acc.aor)}/baresip/account_config.xml"
val caFile = File(BaresipService.filesPath + "/ca_certs.crt")
val config = try {
URL(url).readText()
if (caFile.exists())
Utils.readUrlWithCustomCas(URL(url), caFile)
else
URL(url).readText()
} catch (e: java.lang.Exception) {
Log.d(TAG, "Failed to get account configuration from network: ${e.message}")
null

View File

@ -45,7 +45,10 @@ import java.lang.reflect.Method
import java.net.InetAddress
import java.net.NetworkInterface
import java.net.SocketException
import java.net.URL
import java.security.KeyStore
import java.security.SecureRandom
import java.security.cert.CertificateFactory
import java.text.DateFormat
import java.util.Calendar
import java.util.Enumeration
@ -61,6 +64,9 @@ import javax.crypto.SecretKeyFactory
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.PBEKeySpec
import javax.crypto.spec.SecretKeySpec
import javax.net.ssl.HttpsURLConnection
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManagerFactory
import kotlin.text.replaceFirstChar
object Utils {
@ -961,7 +967,6 @@ object Utils {
}
fun aecAgcCheck() {
val sessionId = Api.AAudio_open_stream()
if (sessionId == -1) {
Log.e(TAG, "Failed to open AAudio stream")
@ -995,7 +1000,45 @@ object Utils {
Log.i(TAG, "Hardware AGC is NOT available")
Api.AAudio_close_stream()
}
fun readUrlWithCustomCas(url: URL, caFile: File): String? {
if (!caFile.exists()) {
Log.d("Utils", "Custom CA file not found at ${caFile.path}")
return null
}
// 1. Create a CertificateFactory and load the user's certificate
val certificateFactory = CertificateFactory.getInstance("X.509")
val certificateInputStream = caFile.inputStream()
val userCertificate = certificateFactory.generateCertificate(certificateInputStream)
certificateInputStream.close()
// 2. Create a KeyStore containing our trusted CAs
val keyStoreType = KeyStore.getDefaultType()
val keyStore = KeyStore.getInstance(keyStoreType)
keyStore.load(null, null)
keyStore.setCertificateEntry("user_ca", userCertificate)
// 3. Create a TrustManager that trusts the CAs in our KeyStore
val tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm()
val tmf = TrustManagerFactory.getInstance(tmfAlgorithm)
tmf.init(keyStore)
// 4. Create an SSLContext that uses our TrustManager
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, tmf.trustManagers, null)
// 5. Tell HttpsURLConnection to use our custom SSLContext
val urlConnection = url.openConnection() as HttpsURLConnection
urlConnection.sslSocketFactory = sslContext.socketFactory
// 6. Proceed with the connection
return try {
urlConnection.inputStream.bufferedReader().use { it.readText() }
} finally {
urlConnection.disconnect()
}
}
/*fun listFilesInDirectory(directoryPath: String): List<File> {