If exists, use TLS CA File (if it exists) also when loading account configuration
This commit is contained in:
@@ -73,6 +73,7 @@ import kotlinx.coroutines.Job
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.xmlpull.v1.XmlPullParser
|
import org.xmlpull.v1.XmlPullParser
|
||||||
import org.xmlpull.v1.XmlPullParserFactory
|
import org.xmlpull.v1.XmlPullParserFactory
|
||||||
|
import java.io.File
|
||||||
import java.io.StringReader
|
import java.io.StringReader
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@@ -1538,8 +1539,12 @@ private fun initAccountFromConfig(acc: Account, onConfigLoaded: () -> Unit) {
|
|||||||
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||||
scope.launch(Dispatchers.IO) {
|
scope.launch(Dispatchers.IO) {
|
||||||
val url = "https://${Utils.uriHostPart(acc.aor)}/baresip/account_config.xml"
|
val url = "https://${Utils.uriHostPart(acc.aor)}/baresip/account_config.xml"
|
||||||
|
val caFile = File(BaresipService.filesPath + "/ca_certs.crt")
|
||||||
val config = try {
|
val config = try {
|
||||||
URL(url).readText()
|
if (caFile.exists())
|
||||||
|
Utils.readUrlWithCustomCas(URL(url), caFile)
|
||||||
|
else
|
||||||
|
URL(url).readText()
|
||||||
} catch (e: java.lang.Exception) {
|
} catch (e: java.lang.Exception) {
|
||||||
Log.d(TAG, "Failed to get account configuration from network: ${e.message}")
|
Log.d(TAG, "Failed to get account configuration from network: ${e.message}")
|
||||||
null
|
null
|
||||||
|
|||||||
@@ -45,7 +45,10 @@ import java.lang.reflect.Method
|
|||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
import java.net.NetworkInterface
|
import java.net.NetworkInterface
|
||||||
import java.net.SocketException
|
import java.net.SocketException
|
||||||
|
import java.net.URL
|
||||||
|
import java.security.KeyStore
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
|
import java.security.cert.CertificateFactory
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Enumeration
|
import java.util.Enumeration
|
||||||
@@ -61,6 +64,9 @@ import javax.crypto.SecretKeyFactory
|
|||||||
import javax.crypto.spec.IvParameterSpec
|
import javax.crypto.spec.IvParameterSpec
|
||||||
import javax.crypto.spec.PBEKeySpec
|
import javax.crypto.spec.PBEKeySpec
|
||||||
import javax.crypto.spec.SecretKeySpec
|
import javax.crypto.spec.SecretKeySpec
|
||||||
|
import javax.net.ssl.HttpsURLConnection
|
||||||
|
import javax.net.ssl.SSLContext
|
||||||
|
import javax.net.ssl.TrustManagerFactory
|
||||||
import kotlin.text.replaceFirstChar
|
import kotlin.text.replaceFirstChar
|
||||||
|
|
||||||
object Utils {
|
object Utils {
|
||||||
@@ -961,7 +967,6 @@ object Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun aecAgcCheck() {
|
fun aecAgcCheck() {
|
||||||
|
|
||||||
val sessionId = Api.AAudio_open_stream()
|
val sessionId = Api.AAudio_open_stream()
|
||||||
if (sessionId == -1) {
|
if (sessionId == -1) {
|
||||||
Log.e(TAG, "Failed to open AAudio stream")
|
Log.e(TAG, "Failed to open AAudio stream")
|
||||||
@@ -995,7 +1000,45 @@ object Utils {
|
|||||||
Log.i(TAG, "Hardware AGC is NOT available")
|
Log.i(TAG, "Hardware AGC is NOT available")
|
||||||
|
|
||||||
Api.AAudio_close_stream()
|
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> {
|
/*fun listFilesInDirectory(directoryPath: String): List<File> {
|
||||||
|
|||||||
Reference in New Issue
Block a user