diff --git a/app/src/main/java/org/linphone/core/CorePreferences.kt b/app/src/main/java/org/linphone/core/CorePreferences.kt index 8d90a0696..db742ba0e 100644 --- a/app/src/main/java/org/linphone/core/CorePreferences.kt +++ b/app/src/main/java/org/linphone/core/CorePreferences.kt @@ -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) diff --git a/app/src/main/java/org/linphone/ui/main/sso/viewmodel/SingleSignOnViewModel.kt b/app/src/main/java/org/linphone/ui/main/sso/viewmodel/SingleSignOnViewModel.kt index 554fb2f7f..1ddd67154 100644 --- a/app/src/main/java/org/linphone/ui/main/sso/viewmodel/SingleSignOnViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/sso/viewmodel/SingleSignOnViewModel.kt @@ -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)