Move VFS Activation at earlier stage

This commit is contained in:
Christophe Deschamps 2021-04-07 14:46:24 +02:00 committed by Sylvain Berfini
parent 9ccab891ab
commit 571349953b
3 changed files with 102 additions and 102 deletions

View file

@ -44,6 +44,10 @@ class LinphoneApplication : Application() {
corePreferences = CorePreferences(context) corePreferences = CorePreferences(context)
corePreferences.copyAssetsFromPackage() corePreferences.copyAssetsFromPackage()
if (corePreferences.vfsEnabled) {
CoreContext.activateVFS()
}
val config = Factory.instance().createConfigWithFactory(corePreferences.configPath, corePreferences.factoryConfigPath) val config = Factory.instance().createConfigWithFactory(corePreferences.configPath, corePreferences.factoryConfigPath)
corePreferences.config = config corePreferences.config = config

View file

@ -23,6 +23,7 @@ import androidx.lifecycle.MutableLiveData
import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R import org.linphone.R
import org.linphone.activities.main.settings.SettingListenerStub import org.linphone.activities.main.settings.SettingListenerStub
import org.linphone.core.CoreContext
import org.linphone.core.Factory import org.linphone.core.Factory
import org.linphone.mediastream.Version import org.linphone.mediastream.Version
import org.linphone.utils.AppUtils import org.linphone.utils.AppUtils
@ -107,7 +108,7 @@ class AdvancedSettingsViewModel : GenericSettingsViewModel() {
val vfsListener = object : SettingListenerStub() { val vfsListener = object : SettingListenerStub() {
override fun onBoolValueChanged(newValue: Boolean) { override fun onBoolValueChanged(newValue: Boolean) {
prefs.vfsEnabled = newValue prefs.vfsEnabled = newValue
if (newValue) coreContext.activateVFS() if (newValue) CoreContext.activateVFS()
} }
} }
val vfs = MutableLiveData<Boolean>() val vfs = MutableLiveData<Boolean>()

View file

@ -291,9 +291,6 @@ class CoreContext(val context: Context, coreConfig: Config) {
Log.i("[Context] Crashlytics enabled, register logging service listener") Log.i("[Context] Crashlytics enabled, register logging service listener")
} }
if (corePreferences.vfsEnabled) {
activateVFS()
}
core = Factory.instance().createCoreWithConfig(coreConfig, context) core = Factory.instance().createCoreWithConfig(coreConfig, context)
stopped = false 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 LINPHONE_VFS_ENCRYPTION_AES256GCM128_SHA256 = 2
private const val VFS_IV = "vfsiv" private const val VFS_IV = "vfsiv"
private const val VFS_KEY = "vfskey" private const val VFS_KEY = "vfskey"
} @Throws(java.lang.Exception::class)
private fun generateSecretKey() {
@Throws(java.lang.Exception::class) val keyGenerator =
private fun generateSecretKey() { KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE)
val keyGenerator = keyGenerator.init(
KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE) KeyGenParameterSpec.Builder(
keyGenerator.init( ALIAS,
KeyGenParameterSpec.Builder( KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
ALIAS, )
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build()
) )
.setBlockModes(KeyProperties.BLOCK_MODE_GCM) keyGenerator.generateKey()
.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<ByteArray, ByteArray> {
val cipher = Cipher.getInstance(TRANSFORMATION)
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey())
val iv = cipher.iv
return Pair<ByteArray, ByteArray>(
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<String?, String?> {
val encryptedData = encryptData(string_to_encrypt)
return Pair<String?, String?>(
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) @Throws(java.lang.Exception::class)
fun getVfsKey(sharedPreferences: SharedPreferences): String { private fun getSecretKey(): SecretKey? {
val keyStore = KeyStore.getInstance(ANDROID_KEY_STORE) val ks = KeyStore.getInstance(ANDROID_KEY_STORE)
keyStore.load(null) ks.load(null)
return decryptData( val entry = ks.getEntry(ALIAS, null) as KeyStore.SecretKeyEntry
sharedPreferences.getString(VFS_KEY, null), return entry.secretKey
Base64.decode(sharedPreferences.getString(VFS_IV, null), Base64.DEFAULT) }
)
}
fun activateVFS() { @Throws(java.lang.Exception::class)
try { fun generateToken(): String? {
Log.i("[Context] Activating VFS") return sha512(UUID.randomUUID().toString())
}
if (corePreferences.encryptedSharedPreferences.getString(VFS_IV, null) == null) { @Throws(java.lang.Exception::class)
generateSecretKey() private fun encryptData(textToEncrypt: String): Pair<ByteArray, ByteArray> {
generateToken()?.let { encryptToken(it) }?.let { data -> val cipher = Cipher.getInstance(TRANSFORMATION)
corePreferences.encryptedSharedPreferences cipher.init(Cipher.ENCRYPT_MODE, getSecretKey())
.edit() val iv = cipher.iv
.putString(VFS_IV, data.first) return Pair<ByteArray, ByteArray>(
.putString(VFS_KEY, data.second) iv,
.commit() cipher.doFinal(textToEncrypt.toByteArray(StandardCharsets.UTF_8))
}
}
Factory.instance().setVfsEncryption(
LINPHONE_VFS_ENCRYPTION_AES256GCM128_SHA256,
getVfsKey(corePreferences.encryptedSharedPreferences).toByteArray().copyOfRange(0, 32),
32
) )
}
Log.i("[Context] VFS activated.") @Throws(java.lang.Exception::class)
} catch (e: Exception) { private fun decryptData(encrypted: String?, encryptionIv: ByteArray): String {
Log.f("[Context] Unable to activate VFS encryption: $e") 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<String?, String?> {
val encryptedData = encryptData(string_to_encrypt)
return Pair<String?, String?>(
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")
}
} }
} }
} }