From 571349953bf5c482c6f17d66342b2f89dd66d9da Mon Sep 17 00:00:00 2001 From: Christophe Deschamps Date: Wed, 7 Apr 2021 14:46:24 +0200 Subject: [PATCH] Move VFS Activation at earlier stage --- .../java/org/linphone/LinphoneApplication.kt | 4 + .../viewmodels/AdvancedSettingsViewModel.kt | 3 +- .../java/org/linphone/core/CoreContext.kt | 197 +++++++++--------- 3 files changed, 102 insertions(+), 102 deletions(-) diff --git a/app/src/main/java/org/linphone/LinphoneApplication.kt b/app/src/main/java/org/linphone/LinphoneApplication.kt index 8a59d4d96..187a374a0 100644 --- a/app/src/main/java/org/linphone/LinphoneApplication.kt +++ b/app/src/main/java/org/linphone/LinphoneApplication.kt @@ -44,6 +44,10 @@ class LinphoneApplication : Application() { corePreferences = CorePreferences(context) corePreferences.copyAssetsFromPackage() + if (corePreferences.vfsEnabled) { + CoreContext.activateVFS() + } + val config = Factory.instance().createConfigWithFactory(corePreferences.configPath, corePreferences.factoryConfigPath) corePreferences.config = config diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AdvancedSettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AdvancedSettingsViewModel.kt index d0bc6b529..f273c0fba 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AdvancedSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AdvancedSettingsViewModel.kt @@ -23,6 +23,7 @@ import androidx.lifecycle.MutableLiveData import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R import org.linphone.activities.main.settings.SettingListenerStub +import org.linphone.core.CoreContext import org.linphone.core.Factory import org.linphone.mediastream.Version import org.linphone.utils.AppUtils @@ -107,7 +108,7 @@ class AdvancedSettingsViewModel : GenericSettingsViewModel() { val vfsListener = object : SettingListenerStub() { override fun onBoolValueChanged(newValue: Boolean) { prefs.vfsEnabled = newValue - if (newValue) coreContext.activateVFS() + if (newValue) CoreContext.activateVFS() } } val vfs = MutableLiveData() diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt index 7f4285a4c..54acb41e6 100644 --- a/app/src/main/java/org/linphone/core/CoreContext.kt +++ b/app/src/main/java/org/linphone/core/CoreContext.kt @@ -291,9 +291,6 @@ class CoreContext(val context: Context, coreConfig: Config) { Log.i("[Context] Crashlytics enabled, register logging service listener") } - if (corePreferences.vfsEnabled) { - activateVFS() - } core = Factory.instance().createCoreWithConfig(coreConfig, context) stopped = false @@ -685,111 +682,109 @@ class CoreContext(val context: Context, coreConfig: Config) { private const val LINPHONE_VFS_ENCRYPTION_AES256GCM128_SHA256 = 2 private const val VFS_IV = "vfsiv" private const val VFS_KEY = "vfskey" - } - - @Throws(java.lang.Exception::class) - private fun generateSecretKey() { - val keyGenerator = - KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE) - keyGenerator.init( - KeyGenParameterSpec.Builder( - ALIAS, - KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT + @Throws(java.lang.Exception::class) + private fun generateSecretKey() { + val keyGenerator = + KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE) + keyGenerator.init( + KeyGenParameterSpec.Builder( + ALIAS, + KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT + ) + .setBlockModes(KeyProperties.BLOCK_MODE_GCM) + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) + .build() ) - .setBlockModes(KeyProperties.BLOCK_MODE_GCM) - .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) - .build() - ) - keyGenerator.generateKey() - } - - @Throws(java.lang.Exception::class) - private fun getSecretKey(): SecretKey? { - val ks = KeyStore.getInstance(ANDROID_KEY_STORE) - ks.load(null) - val entry = ks.getEntry(ALIAS, null) as KeyStore.SecretKeyEntry - return entry.secretKey - } - - @Throws(java.lang.Exception::class) - fun generateToken(): String? { - return sha512(UUID.randomUUID().toString()) - } - - @Throws(java.lang.Exception::class) - private fun encryptData(textToEncrypt: String): Pair { - val cipher = Cipher.getInstance(TRANSFORMATION) - cipher.init(Cipher.ENCRYPT_MODE, getSecretKey()) - val iv = cipher.iv - return Pair( - iv, - cipher.doFinal(textToEncrypt.toByteArray(StandardCharsets.UTF_8)) - ) - } - - @Throws(java.lang.Exception::class) - private fun decryptData(encrypted: String?, encryptionIv: ByteArray): String { - val cipher = Cipher.getInstance(TRANSFORMATION) - val spec = GCMParameterSpec(128, encryptionIv) - cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), spec) - val encryptedData = Base64.decode(encrypted, Base64.DEFAULT) - return String(cipher.doFinal(encryptedData), StandardCharsets.UTF_8) - } - - @Throws(java.lang.Exception::class) - fun encryptToken(string_to_encrypt: String): Pair { - val encryptedData = encryptData(string_to_encrypt) - return Pair( - Base64.encodeToString(encryptedData.first, Base64.DEFAULT), - Base64.encodeToString(encryptedData.second, Base64.DEFAULT) - ) - } - - @Throws(java.lang.Exception::class) - fun sha512(input: String): String { - val md = MessageDigest.getInstance("SHA-512") - val messageDigest = md.digest(input.toByteArray()) - val no = BigInteger(1, messageDigest) - var hashtext = no.toString(16) - while (hashtext.length < 32) { - hashtext = "0$hashtext" + keyGenerator.generateKey() } - return hashtext - } - @Throws(java.lang.Exception::class) - fun getVfsKey(sharedPreferences: SharedPreferences): String { - val keyStore = KeyStore.getInstance(ANDROID_KEY_STORE) - keyStore.load(null) - return decryptData( - sharedPreferences.getString(VFS_KEY, null), - Base64.decode(sharedPreferences.getString(VFS_IV, null), Base64.DEFAULT) - ) - } + @Throws(java.lang.Exception::class) + private fun getSecretKey(): SecretKey? { + val ks = KeyStore.getInstance(ANDROID_KEY_STORE) + ks.load(null) + val entry = ks.getEntry(ALIAS, null) as KeyStore.SecretKeyEntry + return entry.secretKey + } - fun activateVFS() { - try { - Log.i("[Context] Activating VFS") + @Throws(java.lang.Exception::class) + fun generateToken(): String? { + return sha512(UUID.randomUUID().toString()) + } - if (corePreferences.encryptedSharedPreferences.getString(VFS_IV, null) == null) { - generateSecretKey() - generateToken()?.let { encryptToken(it) }?.let { data -> - corePreferences.encryptedSharedPreferences - .edit() - .putString(VFS_IV, data.first) - .putString(VFS_KEY, data.second) - .commit() - } - } - Factory.instance().setVfsEncryption( - LINPHONE_VFS_ENCRYPTION_AES256GCM128_SHA256, - getVfsKey(corePreferences.encryptedSharedPreferences).toByteArray().copyOfRange(0, 32), - 32 + @Throws(java.lang.Exception::class) + private fun encryptData(textToEncrypt: String): Pair { + val cipher = Cipher.getInstance(TRANSFORMATION) + cipher.init(Cipher.ENCRYPT_MODE, getSecretKey()) + val iv = cipher.iv + return Pair( + iv, + cipher.doFinal(textToEncrypt.toByteArray(StandardCharsets.UTF_8)) ) + } - Log.i("[Context] VFS activated.") - } catch (e: Exception) { - Log.f("[Context] Unable to activate VFS encryption: $e") + @Throws(java.lang.Exception::class) + private fun decryptData(encrypted: String?, encryptionIv: ByteArray): String { + val cipher = Cipher.getInstance(TRANSFORMATION) + val spec = GCMParameterSpec(128, encryptionIv) + cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), spec) + val encryptedData = Base64.decode(encrypted, Base64.DEFAULT) + return String(cipher.doFinal(encryptedData), StandardCharsets.UTF_8) + } + + @Throws(java.lang.Exception::class) + fun encryptToken(string_to_encrypt: String): Pair { + val encryptedData = encryptData(string_to_encrypt) + return Pair( + Base64.encodeToString(encryptedData.first, Base64.DEFAULT), + Base64.encodeToString(encryptedData.second, Base64.DEFAULT) + ) + } + + @Throws(java.lang.Exception::class) + fun sha512(input: String): String { + val md = MessageDigest.getInstance("SHA-512") + val messageDigest = md.digest(input.toByteArray()) + val no = BigInteger(1, messageDigest) + var hashtext = no.toString(16) + while (hashtext.length < 32) { + hashtext = "0$hashtext" + } + return hashtext + } + + @Throws(java.lang.Exception::class) + fun getVfsKey(sharedPreferences: SharedPreferences): String { + val keyStore = KeyStore.getInstance(ANDROID_KEY_STORE) + keyStore.load(null) + return decryptData( + sharedPreferences.getString(VFS_KEY, null), + Base64.decode(sharedPreferences.getString(VFS_IV, null), Base64.DEFAULT) + ) + } + fun activateVFS() { + try { + Log.i("[Context] Activating VFS") + + if (corePreferences.encryptedSharedPreferences.getString(VFS_IV, null) == null) { + generateSecretKey() + generateToken()?.let { encryptToken(it) }?.let { data -> + corePreferences.encryptedSharedPreferences + .edit() + .putString(VFS_IV, data.first) + .putString(VFS_KEY, data.second) + .commit() + } + } + Factory.instance().setVfsEncryption( + LINPHONE_VFS_ENCRYPTION_AES256GCM128_SHA256, + getVfsKey(corePreferences.encryptedSharedPreferences).toByteArray().copyOfRange(0, 32), + 32 + ) + + Log.i("[Context] VFS activated.") + } catch (e: Exception) { + Log.f("[Context] Unable to activate VFS encryption: $e") + } } } }