Use liblinphone rootCA.pem file for SSO connection

This commit is contained in:
Sylvain Berfini 2026-03-20 10:10:12 +01:00
parent 10b3801bca
commit daad2f6a2e
2 changed files with 63 additions and 3 deletions

View file

@ -491,6 +491,10 @@ class CorePreferences
val messageReceivedInVisibleConversationNotificationSound: String
get() = context.filesDir.absolutePath + "/share/sounds/linphone/incoming_chat.wav"
@get:AnyThread
val rootCaPem: String
get() = context.filesDir.absolutePath + "/share/linphone/rootca.pem"
@UiThread
fun copyAssetsFromPackage() {
copy("linphonerc_default", configPath)

View file

@ -21,10 +21,12 @@ package org.linphone.ui.main.sso.viewmodel
import android.content.Intent
import androidx.annotation.UiThread
import androidx.annotation.WorkerThread
import androidx.core.net.toUri
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import java.io.File
import kotlinx.coroutines.launch
import net.openid.appauth.AppAuthConfiguration
import net.openid.appauth.AuthState
import net.openid.appauth.AuthorizationException
import net.openid.appauth.AuthorizationRequest
@ -42,7 +44,19 @@ import org.linphone.ui.GenericViewModel
import org.linphone.utils.Event
import org.linphone.utils.FileUtils
import org.linphone.utils.TimestampUtils
import androidx.core.net.toUri
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.net.HttpURLConnection
import java.net.URL
import java.security.KeyStore
import java.security.SecureRandom
import java.security.cert.Certificate
import java.security.cert.CertificateFactory
import javax.net.ssl.HttpsURLConnection
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManagerFactory
class SingleSignOnViewModel
@UiThread
@ -134,6 +148,7 @@ class SingleSignOnViewModel
private fun singleSignOn() {
Log.i("$TAG Fetch from issuer [$singleSignOnUrl]")
operationInProgress.postValue(true)
AuthorizationServiceConfiguration.fetchFromIssuer(
singleSignOnUrl.toUri(),
AuthorizationServiceConfiguration.RetrieveConfigurationCallback { serviceConfiguration, ex ->
@ -177,14 +192,55 @@ class SingleSignOnViewModel
authRequestBuilder.setLoginHint(username)
}
val appAuthConfig = AppAuthConfiguration.Builder()
.build()
val authRequest = authRequestBuilder.build()
authService = AuthorizationService(coreContext.context)
authService = AuthorizationService(coreContext.context, appAuthConfig)
val authIntent = authService.getAuthorizationRequestIntent(authRequest)
startAuthIntentEvent.postValue(Event(authIntent))
},
{ uri ->
val url = URL(uri.toString())
val connection = url.openConnection() as HttpURLConnection
if (connection is HttpsURLConnection) {
val socketFactory = getSocketFactory()
if (socketFactory != null) {
Log.i("$TAG Using custom SSL Socket Factory")
connection.setSSLSocketFactory(socketFactory)
}
}
connection
}
)
}
@WorkerThread
private fun getSocketFactory(): SSLSocketFactory? {
val caPath = corePreferences.rootCaPem
val caInput: InputStream = FileInputStream(caPath)
try {
val ca: Certificate? =
CertificateFactory.getInstance("X.509").generateCertificate(caInput)
val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())
keyStore.load(null, null)
keyStore.setCertificateEntry("ca", ca)
val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
tmf.init(keyStore)
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, tmf.trustManagers, SecureRandom())
Log.i("$TAG Created custom SSL Socket Factory using rootCa file at [$caPath]")
return sslContext.socketFactory
} catch (ex: Exception) {
Log.e("$TAG Failed to created custom SSL Socket Factory: $ex")
}
return null
}
@UiThread
private fun performRefreshToken() {
operationInProgress.postValue(true)