diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 3ccbcca81c..02f1e371fe 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -205,9 +205,6 @@ dependencies { // Work implementation libs.androidx.work - // olm lib is now hosted in MavenCentral - implementation 'org.matrix.android:olm-sdk:3.2.12' - // DI implementation libs.dagger.dagger kapt libs.dagger.daggerCompiler @@ -224,7 +221,7 @@ dependencies { implementation libs.google.phonenumber - implementation("org.matrix.rustcomponents:crypto-android:0.4.1") + implementation("org.matrix.rustcomponents:crypto-android:0.4.3") // api project(":library:rustCrypto") testImplementation libs.tests.junit @@ -236,6 +233,7 @@ dependencies { testImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1' // Transitively required for mocking realm as monarchy doesn't expose Rx testImplementation libs.rx.rxKotlin + testImplementation libs.tests.robolectric kaptAndroidTest libs.dagger.daggerCompiler androidTestImplementation libs.androidx.testCore diff --git a/matrix-sdk-android/src/androidTest/assets/crypto_store_20.realm b/matrix-sdk-android/src/androidTest/assets/crypto_store_20.realm deleted file mode 100644 index cfdd2e6da6..0000000000 --- a/matrix-sdk-android/src/androidTest/assets/crypto_store_20.realm +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a7acd69f37612bab0a1ab7f456656712d7ba19dbb679f81b97b58ef44e239f42 -size 8523776 diff --git a/matrix-sdk-android/src/androidTest/assets/crypto_store_migration_16.realm b/matrix-sdk-android/src/androidTest/assets/crypto_store_migration_16.realm deleted file mode 100644 index 4995bfc4a1..0000000000 --- a/matrix-sdk-android/src/androidTest/assets/crypto_store_migration_16.realm +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:59b4957aa2f9cdc17b14ec8546e144537fac9dee050c6eb173f56fa8602c2736 -size 2097152 diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrix.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrix.kt index 60201b34c7..f042e0734f 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrix.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrix.kt @@ -36,7 +36,6 @@ import org.matrix.android.sdk.internal.network.ApiInterceptor import org.matrix.android.sdk.internal.network.UserAgentHolder import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver import org.matrix.android.sdk.internal.worker.MatrixWorkerFactory -import org.matrix.olm.OlmManager import java.util.concurrent.Executors import javax.inject.Inject @@ -49,7 +48,6 @@ internal class TestMatrix(context: Context, matrixConfiguration: MatrixConfigura @Inject internal lateinit var rawService: RawService @Inject internal lateinit var userAgentHolder: UserAgentHolder @Inject internal lateinit var backgroundDetectionObserver: BackgroundDetectionObserver - @Inject internal lateinit var olmManager: OlmManager @Inject internal lateinit var sessionManager: SessionManager @Inject internal lateinit var homeServerHistoryService: HomeServerHistoryService @Inject internal lateinit var apiInterceptor: ApiInterceptor diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPasswordTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPasswordTest.kt index 9bf08f6fc0..8d63f06d3e 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPasswordTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPasswordTest.kt @@ -20,7 +20,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue -import org.junit.Before import org.junit.FixMethodOrder import org.junit.Ignore import org.junit.Test @@ -29,19 +28,12 @@ import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.common.assertByteArrayNotEqual -import org.matrix.olm.OlmManager -import org.matrix.olm.OlmPkDecryption @Ignore("Ignored in order to speed up test run time") @RunWith(AndroidJUnit4::class) @FixMethodOrder(MethodSorters.JVM) class KeysBackupPasswordTest : InstrumentedTest { - @Before - fun ensureLibLoaded() { - OlmManager() - } - /** * Check KeysBackupPassword utilities */ @@ -51,7 +43,7 @@ class KeysBackupPasswordTest : InstrumentedTest { assertEquals(32, generatePrivateKeyResult.salt.length) assertEquals(500_000, generatePrivateKeyResult.iterations) - assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size) + assertEquals(EXPECTED_PRIVATE_KEY_LENGTH, generatePrivateKeyResult.privateKey.size) // Reverse operation val retrievedPrivateKey = retrievePrivateKeyWithPassword( @@ -60,7 +52,7 @@ class KeysBackupPasswordTest : InstrumentedTest { generatePrivateKeyResult.iterations ) - assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size) + assertEquals(EXPECTED_PRIVATE_KEY_LENGTH, retrievedPrivateKey.size) assertArrayEquals(generatePrivateKeyResult.privateKey, retrievedPrivateKey) } @@ -101,7 +93,7 @@ class KeysBackupPasswordTest : InstrumentedTest { assertEquals(32, generatePrivateKeyResult.salt.length) assertEquals(500_000, generatePrivateKeyResult.iterations) - assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size) + assertEquals(EXPECTED_PRIVATE_KEY_LENGTH, generatePrivateKeyResult.privateKey.size) // Reverse operation, with bad password val retrievedPrivateKey = retrievePrivateKeyWithPassword( @@ -110,7 +102,7 @@ class KeysBackupPasswordTest : InstrumentedTest { generatePrivateKeyResult.iterations ) - assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size) + assertEquals(EXPECTED_PRIVATE_KEY_LENGTH, retrievedPrivateKey.size) assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey) } @@ -123,7 +115,7 @@ class KeysBackupPasswordTest : InstrumentedTest { assertEquals(32, generatePrivateKeyResult.salt.length) assertEquals(500_000, generatePrivateKeyResult.iterations) - assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size) + assertEquals(EXPECTED_PRIVATE_KEY_LENGTH, generatePrivateKeyResult.privateKey.size) // Reverse operation, with bad iteration val retrievedPrivateKey = retrievePrivateKeyWithPassword( @@ -132,7 +124,7 @@ class KeysBackupPasswordTest : InstrumentedTest { 500_001 ) - assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size) + assertEquals(EXPECTED_PRIVATE_KEY_LENGTH, retrievedPrivateKey.size) assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey) } @@ -145,7 +137,7 @@ class KeysBackupPasswordTest : InstrumentedTest { assertEquals(32, generatePrivateKeyResult.salt.length) assertEquals(500_000, generatePrivateKeyResult.iterations) - assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size) + assertEquals(EXPECTED_PRIVATE_KEY_LENGTH, generatePrivateKeyResult.privateKey.size) // Reverse operation, with bad iteration val retrievedPrivateKey = retrievePrivateKeyWithPassword( @@ -154,7 +146,7 @@ class KeysBackupPasswordTest : InstrumentedTest { generatePrivateKeyResult.iterations ) - assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size) + assertEquals(EXPECTED_PRIVATE_KEY_LENGTH, retrievedPrivateKey.size) assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey) } @@ -169,7 +161,7 @@ class KeysBackupPasswordTest : InstrumentedTest { val retrievedPrivateKey = retrievePrivateKeyWithPassword(password, salt, iteration) - assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size) + assertEquals(EXPECTED_PRIVATE_KEY_LENGTH, retrievedPrivateKey.size) // Data from RiotWeb val privateKeyBytes = byteArrayOf( @@ -187,5 +179,7 @@ class KeysBackupPasswordTest : InstrumentedTest { private const val BAD_PASSWORD = "passw0rd" private const val BAD_SALT = "AA0lxhQ9aYgGfMsclVWPIAublg8h9Nlu" + + private const val EXPECTED_PRIVATE_KEY_LENGTH = 32 } } diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/store/migration/DynamicElementAndroidToElementRMigrationTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/store/migration/DynamicElementAndroidToElementRMigrationTest.kt deleted file mode 100644 index 52a75d0653..0000000000 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/store/migration/DynamicElementAndroidToElementRMigrationTest.kt +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.migration - -import android.content.Context -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import io.mockk.spyk -import io.realm.Realm -import io.realm.kotlin.where -import org.amshove.kluent.internal.assertEquals -import org.junit.After -import org.junit.Assert.assertNotNull -import org.junit.Assert.assertTrue -import org.junit.Before -import org.junit.Ignore -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.matrix.android.sdk.TestBuildVersionSdkIntProvider -import org.matrix.android.sdk.api.securestorage.SecretStoringUtils -import org.matrix.android.sdk.internal.crypto.RustEncryptionConfiguration -import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreMigration -import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule -import org.matrix.android.sdk.internal.crypto.store.db.RustMigrationInfoProvider -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntity -import org.matrix.android.sdk.internal.database.RealmKeysUtils -import org.matrix.android.sdk.internal.database.TestRealmConfigurationFactory -import org.matrix.android.sdk.internal.util.time.Clock -import org.matrix.android.sdk.test.shared.createTimberTestRule -import org.matrix.olm.OlmAccount -import org.matrix.olm.OlmManager -import org.matrix.rustcomponents.sdk.crypto.OlmMachine -import java.io.File -import java.security.KeyStore - -@RunWith(AndroidJUnit4::class) -class DynamicElementAndroidToElementRMigrationTest { - - @get:Rule val configurationFactory = TestRealmConfigurationFactory() - - @Rule - fun timberTestRule() = createTimberTestRule() - - var context: Context = InstrumentationRegistry.getInstrumentation().context - var realm: Realm? = null - - @Before - fun setUp() { - // Ensure Olm is initialized - OlmManager() - } - - @After - fun tearDown() { - realm?.close() - } - - private val keyStore = spyk(KeyStore.getInstance("AndroidKeyStore")).also { it.load(null) } - - private val rustEncryptionConfiguration = RustEncryptionConfiguration( - "foo", - RealmKeysUtils( - context, - SecretStoringUtils(context, keyStore, TestBuildVersionSdkIntProvider(), false) - ) - ) - - private val fakeClock = object : Clock { - override fun epochMillis() = 0L - } - - @Test - fun given_a_valid_crypto_store_realm_file_then_migration_should_be_successful() { - testMigrate(false) - } - - @Test - @Ignore("We don't migrate group sessions for now, and it's making this test suite unstable") - fun given_a_valid_crypto_store_realm_file_no_lazy_then_migration_should_be_successful() { - testMigrate(true) - } - - private fun testMigrate(migrateGroupSessions: Boolean) { - val targetFile = File(configurationFactory.root, "rust-sdk") - - val realmName = "crypto_store_migration_16.realm" - val infoProvider = RustMigrationInfoProvider( - targetFile, - rustEncryptionConfiguration - ).apply { - migrateMegolmGroupSessions = migrateGroupSessions - } - val migration = RealmCryptoStoreMigration(fakeClock, infoProvider) - - val realmConfiguration = configurationFactory.createConfiguration( - realmName, - null, - RealmCryptoStoreModule(), - migration.schemaVersion, - migration - ) - configurationFactory.copyRealmFromAssets(context, realmName, realmName) - - realm = Realm.getInstance(realmConfiguration) - val metaData = realm!!.where().findFirst()!! - val userId = metaData.userId!! - val deviceId = metaData.deviceId!! - val olmAccount = metaData.getOlmAccount()!! - - val machine = OlmMachine(userId, deviceId, targetFile.path, rustEncryptionConfiguration.getDatabasePassphrase()) - - assertEquals(olmAccount.identityKeys()[OlmAccount.JSON_KEY_FINGER_PRINT_KEY], machine.identityKeys()["ed25519"]) - assertNotNull(machine.getBackupKeys()) - val crossSigningStatus = machine.crossSigningStatus() - assertTrue(crossSigningStatus.hasMaster) - assertTrue(crossSigningStatus.hasSelfSigning) - assertTrue(crossSigningStatus.hasUserSigning) - - if (migrateGroupSessions) { - assertTrue("Some outbound sessions should be migrated", machine.roomKeyCounts().total.toInt() > 0) - assertTrue("There are some backed-up sessions", machine.roomKeyCounts().backedUp.toInt() > 0) - } else { - assertTrue(machine.roomKeyCounts().total.toInt() == 0) - assertTrue(machine.roomKeyCounts().backedUp.toInt() == 0) - } - - // legacy olm sessions should have been deleted - val remainingOlmSessions = realm!!.where().findAll().size - assertEquals("legacy olm sessions should have been removed from store", 0, remainingOlmSessions) - } -} diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/database/CryptoSanityMigrationTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/database/CryptoSanityMigrationTest.kt deleted file mode 100644 index 828c0f51d4..0000000000 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/database/CryptoSanityMigrationTest.kt +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2023 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.database - -import android.content.Context -import androidx.test.platform.app.InstrumentationRegistry -import io.mockk.spyk -import io.realm.Realm -import org.junit.After -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.matrix.android.sdk.TestBuildVersionSdkIntProvider -import org.matrix.android.sdk.api.securestorage.SecretStoringUtils -import org.matrix.android.sdk.internal.crypto.RustEncryptionConfiguration -import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreMigration -import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule -import org.matrix.android.sdk.internal.crypto.store.db.RustMigrationInfoProvider -import org.matrix.android.sdk.internal.util.time.Clock -import org.matrix.olm.OlmManager -import java.io.File -import java.security.KeyStore - -class CryptoSanityMigrationTest { - @get:Rule val configurationFactory = TestRealmConfigurationFactory() - - lateinit var context: Context - var realm: Realm? = null - - @Before - fun setUp() { - // Ensure Olm is initialized - OlmManager() - context = InstrumentationRegistry.getInstrumentation().context - } - - @After - fun tearDown() { - realm?.close() - } - - private val keyStore = spyk(KeyStore.getInstance("AndroidKeyStore")).also { it.load(null) } - - @Test - fun cryptoDatabaseShouldMigrateGracefully() { - val realmName = "crypto_store_20.realm" - - val rustMigrationInfo = RustMigrationInfoProvider( - File(configurationFactory.root, "test_rust"), - RustEncryptionConfiguration( - "foo", - RealmKeysUtils( - context, - SecretStoringUtils(context, keyStore, TestBuildVersionSdkIntProvider(), false) - ) - ), - ) - val migration = RealmCryptoStoreMigration( - object : Clock { - override fun epochMillis(): Long { - return 0L - } - }, - rustMigrationInfo - ) - - val realmConfiguration = configurationFactory.createConfiguration( - realmName, - "7b9a21a8a311e85d75b069a343c23fc952fc3fec5e0c83ecfa13f24b787479c487c3ed587db3dd1f5805d52041fc0ac246516e94b27ffa699ff928622e621aca", - RealmCryptoStoreModule(), - migration.schemaVersion, - migration - ) - configurationFactory.copyRealmFromAssets(context, realmName, realmName) - - realm = Realm.getInstance(realmConfiguration) - } -} diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/contentscanner/ScanEncryptorUtilsTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/contentscanner/ScanEncryptorUtilsTest.kt index 93b6797388..ba04e4607e 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/contentscanner/ScanEncryptorUtilsTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/contentscanner/ScanEncryptorUtilsTest.kt @@ -16,7 +16,6 @@ package org.matrix.android.sdk.internal.session.contentscanner -import okio.ByteString.Companion.decodeBase64 import org.amshove.kluent.shouldBe import org.amshove.kluent.shouldBeEqualTo import org.amshove.kluent.shouldNotBe @@ -24,11 +23,7 @@ import org.junit.Test import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileKey -import org.matrix.android.sdk.internal.crypto.tools.withOlmDecryption -import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.session.contentscanner.model.DownloadBody -import org.matrix.android.sdk.internal.session.contentscanner.model.EncryptedBody -import org.matrix.olm.OlmPkMessage class ScanEncryptorUtilsTest { private val anMxcUrl = "mxc://matrix.org/123456" @@ -67,7 +62,6 @@ class ScanEncryptorUtilsTest { @Test fun whenServerKeyIsProvidedTheContentIsEncrypted() { - System.loadLibrary("olm") val result = ScanEncryptorUtils.getDownloadBodyAndEncryptIfNeeded( publicServerKey = aPublicKey, mxcUrl = anMxcUrl, @@ -78,6 +72,8 @@ class ScanEncryptorUtilsTest { result.encryptedBody shouldNotBe null } + // Note: PkDecryption is not exposed in the FFI layer, so we cannot use this test. + /* @Test fun checkThatTheCodeIsAbleToDecryptContent() { System.loadLibrary("olm") @@ -121,4 +117,5 @@ class ScanEncryptorUtilsTest { .fromJson(result) parseResult shouldBeEqualTo clearInfo } + */ } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt index b9780b8021..5f87425cfc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt @@ -39,7 +39,6 @@ import org.matrix.android.sdk.internal.network.ApiInterceptor import org.matrix.android.sdk.internal.network.UserAgentHolder import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver import org.matrix.android.sdk.internal.worker.MatrixWorkerFactory -import org.matrix.olm.OlmManager import java.util.concurrent.Executors import javax.inject.Inject @@ -59,7 +58,6 @@ class Matrix(context: Context, matrixConfiguration: MatrixConfiguration) { @Inject internal lateinit var debugService: DebugService @Inject internal lateinit var userAgentHolder: UserAgentHolder @Inject internal lateinit var backgroundDetectionObserver: BackgroundDetectionObserver - @Inject internal lateinit var olmManager: OlmManager @Inject internal lateinit var sessionManager: SessionManager @Inject internal lateinit var homeServerHistoryService: HomeServerHistoryService @Inject internal lateinit var apiInterceptor: ApiInterceptor diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/CryptoConstants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/CryptoConstants.kt index aced0ca3a2..5b6bd0c3e1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/CryptoConstants.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/CryptoConstants.kt @@ -31,11 +31,6 @@ const val MXCRYPTO_ALGORITHM_MEGOLM = "m.megolm.v1.aes-sha2" */ const val MXCRYPTO_ALGORITHM_MEGOLM_BACKUP = "m.megolm_backup.v1.curve25519-aes-sha2" -/** - * Secured Shared Storage algorithm constant. - */ -const val SSSS_ALGORITHM_CURVE25519_AES_SHA2 = "m.secret_storage.v1.curve25519-aes-sha2" - /* Secrets are encrypted using AES-CTR-256 and MACed using HMAC-SHA-256. **/ const val SSSS_ALGORITHM_AES_HMAC_SHA2 = "m.secret_storage.v1.aes-hmac-sha2" diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/MXCryptoError.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/MXCryptoError.kt index 94ee7ba403..220a75bd3f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/MXCryptoError.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/MXCryptoError.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.api.session.crypto import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap -import org.matrix.olm.OlmException /** * Represents a crypto error response. @@ -34,8 +33,6 @@ sealed class MXCryptoError : Throwable() { val detailedErrorDescription: String? = null ) : MXCryptoError() - data class OlmError(val olmException: OlmException) : MXCryptoError() - data class UnknownDevice(val deviceList: MXUsersDevicesMap) : MXCryptoError() enum class ErrorType { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index b8d9711358..c45f85671e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -53,7 +53,6 @@ import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.internal.coroutines.builder.safeInvokeOnClose import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.DefaultKeysAlgorithmAndData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysAlgorithmAndData -import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrapper import org.matrix.android.sdk.internal.crypto.network.RequestSender import org.matrix.android.sdk.internal.crypto.verification.SasVerification import org.matrix.android.sdk.internal.crypto.verification.VerificationRequest @@ -318,22 +317,6 @@ internal class OlmMachine @Inject constructor( inner.receiveVerificationEvent(serializedEvent, roomId) } - /** - * Used for lazy migration of inboundGroupSession from EA to ER. - */ - suspend fun importRoomKey(inbound: MXInboundMegolmSessionWrapper): Result { - Timber.v("Migration:: Tentative lazy migration") - return withContext(coroutineDispatchers.io) { - val export = inbound.exportKeys() - ?: return@withContext Result.failure(Exception("Failed to export key")) - val result = importDecryptedKeys(listOf(export), null).also { - Timber.v("Migration:: Tentative lazy migration result: ${it.totalNumberOfKeys}") - } - if (result.totalNumberOfKeys == 1) return@withContext Result.success(Unit) - return@withContext Result.failure(Exception("Import failed")) - } - } - /** * Mark the given list of users to be tracked, triggering a key query request for them. * diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/PrepareToEncryptUseCase.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/PrepareToEncryptUseCase.kt index e4c0469c74..72242d876c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/PrepareToEncryptUseCase.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/PrepareToEncryptUseCase.kt @@ -121,7 +121,8 @@ internal class PrepareToEncryptUseCase @Inject constructor( HistoryVisibility.INVITED } else { HistoryVisibility.JOINED - } + }, + errorOnVerifiedUserProblem = false, ) measureTimeMillis { keyShareLock.withLock { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt index a6e4efd875..c998f104f4 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt @@ -504,15 +504,8 @@ internal class RustCryptoService @Inject constructor( val content = event.content?.toModel() ?: throw mxCryptoError val roomId = event.roomId val sessionId = content.sessionId - val senderKey = content.senderKey if (roomId != null && sessionId != null) { - // try to perform a lazy migration from legacy store - val legacy = tryOrNull("Failed to access legacy crypto store") { - cryptoStore.getInboundGroupSession(sessionId, senderKey.orEmpty()) - } - if (legacy == null || olmMachine.importRoomKey(legacy).isFailure) { - perSessionBackupQueryRateLimiter.tryFromBackupIfPossible(sessionId, roomId) - } + perSessionBackupQueryRateLimiter.tryFromBackupIfPossible(sessionId, roomId) } } throw mxCryptoError @@ -851,9 +844,9 @@ internal class RustCryptoService @Inject constructor( override fun removeSessionListener(listener: NewSessionListener) { megolmSessionImportManager.removeListener(listener) } -/* ========================================================================================== - * DEBUG INFO - * ========================================================================================== */ + /* ========================================================================================== + * DEBUG INFO + * ========================================================================================== */ override fun toString(): String { return "DefaultCryptoService of $myUserId ($deviceId)" diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 37d1bd4b89..6750808454 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -65,7 +65,6 @@ import org.matrix.android.sdk.internal.crypto.network.RequestSender import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.util.JsonCanonicalizer -import org.matrix.olm.OlmException import org.matrix.rustcomponents.sdk.crypto.Request import org.matrix.rustcomponents.sdk.crypto.RequestType import org.matrix.rustcomponents.sdk.crypto.SignatureVerification @@ -840,8 +839,8 @@ internal class RustKeyBackupService @Inject constructor( try { olmMachine.enableBackupV1(retrievedMegolmBackupAuthData.publicKey, keysVersionResult.version) keysBackupVersion = keysVersionResult - } catch (e: OlmException) { - Timber.e(e, "OlmException") + } catch (e: Exception) { + Timber.e(e, "Exception") keysBackupStateManager.state = KeysBackupState.Disabled return } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXInboundMegolmSessionWrapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXInboundMegolmSessionWrapper.kt deleted file mode 100644 index 2c6a0a967a..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXInboundMegolmSessionWrapper.kt +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.model - -import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.internal.crypto.MegolmSessionData -import org.matrix.olm.OlmInboundGroupSession -import timber.log.Timber - -data class MXInboundMegolmSessionWrapper( - // olm object - val session: OlmInboundGroupSession, - // data about the session - val sessionData: InboundGroupSessionData -) { - // shortcut - val roomId = sessionData.roomId - val senderKey = sessionData.senderKey - val safeSessionId = tryOrNull("Fail to get megolm session Id") { session.sessionIdentifier() } - - /** - * Export the inbound group session keys. - * @param index the index to export. If null, the first known index will be used - * @return the inbound group session as MegolmSessionData if the operation succeeds - */ - internal fun exportKeys(index: Long? = null): MegolmSessionData? { - return try { - val keysClaimed = sessionData.keysClaimed ?: return null - val wantedIndex = index ?: session.firstKnownIndex - - MegolmSessionData( - senderClaimedEd25519Key = sessionData.keysClaimed?.get("ed25519"), - forwardingCurve25519KeyChain = sessionData.forwardingCurve25519KeyChain?.toList().orEmpty(), - sessionKey = session.export(wantedIndex), - senderClaimedKeys = keysClaimed, - roomId = sessionData.roomId, - sessionId = session.sessionIdentifier(), - senderKey = senderKey, - algorithm = MXCRYPTO_ALGORITHM_MEGOLM, - sharedHistory = sessionData.sharedHistory - ) - } catch (e: Exception) { - Timber.e(e, "## Failed to export megolm : sessionID ${tryOrNull { session.sessionIdentifier() }} failed") - null - } - } - - companion object { - - /** - * @exportFormat true if the megolm keys are in export format - * (ie, they lack an ed25519 signature) - */ - @Throws - internal fun newFromMegolmData(megolmSessionData: MegolmSessionData, exportFormat: Boolean): MXInboundMegolmSessionWrapper { - val exportedKey = megolmSessionData.sessionKey ?: throw IllegalArgumentException("key data not found") - val inboundSession = if (exportFormat) { - OlmInboundGroupSession.importSession(exportedKey) - } else { - OlmInboundGroupSession(exportedKey) - } - .also { - if (it.sessionIdentifier() != megolmSessionData.sessionId) { - it.releaseSession() - throw IllegalStateException("Mismatched group session Id") - } - } - val data = InboundGroupSessionData( - roomId = megolmSessionData.roomId, - senderKey = megolmSessionData.senderKey, - keysClaimed = megolmSessionData.senderClaimedKeys, - forwardingCurve25519KeyChain = megolmSessionData.forwardingCurve25519KeyChain, - sharedHistory = megolmSessionData.sharedHistory, - trusted = false - ) - - return MXInboundMegolmSessionWrapper( - inboundSession, - data - ) - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXKey.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXKey.kt deleted file mode 100755 index 6b747d19f2..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXKey.kt +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.model - -import org.matrix.android.sdk.api.util.JsonDict -import timber.log.Timber - -internal data class MXKey( - /** - * The type of the key (in the example: "signed_curve25519"). - */ - val type: String, - - /** - * The id of the key (in the example: "AAAAFw"). - */ - private val keyId: String, - - /** - * The key (in the example: "IjwIcskng7YjYcn0tS8TUOT2OHHtBSfMpcfIczCgXj4"). - */ - val value: String, - - /** - * signature user Id to [deviceid][signature]. - */ - private val signatures: Map>, - - /** - * We have to store the original json because it can contain other fields - * that we don't support yet but they would be needed to check signatures. - */ - private val rawMap: JsonDict -) { - - /** - * @return the signed data map - */ - fun signalableJSONDictionary(): Map { - return rawMap.filter { - it.key != "signatures" && it.key != "unsigned" - } - } - - /** - * Returns a signature for an user Id and a signkey. - * - * @param userId the user id - * @param signkey the sign key - * @return the signature - */ - fun signatureForUserId(userId: String, signkey: String): String? { - // sanity checks - if (userId.isNotBlank() && signkey.isNotBlank()) { - return signatures[userId]?.get(signkey) - } - - return null - } - - companion object { - /** - * Key types. - */ - const val KEY_CURVE_25519_TYPE = "curve25519" - const val KEY_SIGNED_CURVE_25519_TYPE = "signed_curve25519" - // const val KEY_ED_25519_TYPE = "ed25519" - - /** - * Convert a map to a MXKey. - * - * @param map the map to convert - * - * Json Example: - * - *
-         *   "signed_curve25519:AAAAFw": {
-         *     "key": "IjwIcskng7YjYcn0tS8TUOT2OHHtBSfMpcfIczCgXj4",
-         *     "fallback" : true|false
-         *     "signatures": {
-         *       "@userId:matrix.org": {
-         *         "ed25519:GMJRREOASV": "EUjp6pXzK9u3SDFR\/qLbzpOi3bEREeI6qMnKzXu992HsfuDDZftfJfiUXv9b\/Hqq1og4qM\/vCQJGTHAWMmgkCg"
-         *       }
-         *     }
-         *   }
-         * 
- * - * into several val members - */ - fun from(map: Map?): MXKey? { - if (map?.isNotEmpty() == true) { - val firstKey = map.keys.first() - - val components = firstKey.split(":").dropLastWhile { it.isEmpty() } - - if (components.size == 2) { - val params = map[firstKey] - if (params != null) { - if (params["key"] is String) { - @Suppress("UNCHECKED_CAST") - return MXKey( - type = components[0], - keyId = components[1], - value = params["key"] as String, - signatures = params["signatures"] as Map>, - rawMap = params - ) - } - } - } - } - - // Error case - Timber.e("## Unable to parse map") - return null - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXOlmSessionResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXOlmSessionResult.kt deleted file mode 100755 index 666ab2d678..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXOlmSessionResult.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.model - -import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo -import java.io.Serializable - -internal data class MXOlmSessionResult( - /** - * the device. - */ - val deviceInfo: CryptoDeviceInfo, - /** - * Base64 olm session id. - * null if no session could be established. - */ - var sessionId: String? -) : Serializable diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXUsersDevicesMap.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXUsersDevicesMap.kt deleted file mode 100755 index 58aff14a3d..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXUsersDevicesMap.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.model - -import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap - -internal fun MXUsersDevicesMap.toDebugString() = - map.entries.joinToString { "${it.key} [${it.value.keys.joinToString { it }}]" } - -internal fun MXUsersDevicesMap.toDebugCount() = - map.entries.fold(0) { acc, new -> - acc + new.value.keys.size - } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper.kt deleted file mode 100755 index ecb2946680..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper.kt +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.model - -import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.MegolmSessionData -import org.matrix.olm.OlmInboundGroupSession -import timber.log.Timber -import java.io.Serializable - -/** - * This class adds more context to a OlmInboundGroupSession object. - * This allows additional checks. The class implements Serializable so that the context can be stored. - */ -internal class OlmInboundGroupSessionWrapper : Serializable { - - // The associated olm inbound group session. - var olmInboundGroupSession: OlmInboundGroupSession? = null - - // The room in which this session is used. - var roomId: String? = null - - // The base64-encoded curve25519 key of the sender. - var senderKey: String? = null - - // Other keys the sender claims. - var keysClaimed: Map? = null - - // Devices which forwarded this session to us (normally empty). - var forwardingCurve25519KeyChain: List? = ArrayList() - - /** - * @return the first known message index - */ - val firstKnownIndex: Long? - get() { - if (null != olmInboundGroupSession) { - try { - return olmInboundGroupSession!!.firstKnownIndex - } catch (e: Exception) { - Timber.e(e, "## getFirstKnownIndex() : getFirstKnownIndex failed") - } - } - - return null - } - - /** - * Constructor. - * - * @param sessionKey the session key - * @param isImported true if it is an imported session key - */ - constructor(sessionKey: String, isImported: Boolean) { - try { - if (!isImported) { - olmInboundGroupSession = OlmInboundGroupSession(sessionKey) - } else { - olmInboundGroupSession = OlmInboundGroupSession.importSession(sessionKey) - } - } catch (e: Exception) { - Timber.e(e, "Cannot create") - } - } - - /** - * Create a new instance from the provided keys map. - * - * @param megolmSessionData the megolm session data - * @throws Exception if the data are invalid - */ - @Throws(Exception::class) - constructor(megolmSessionData: MegolmSessionData) { - try { - olmInboundGroupSession = OlmInboundGroupSession.importSession(megolmSessionData.sessionKey!!) - - if (olmInboundGroupSession!!.sessionIdentifier() != megolmSessionData.sessionId) { - throw Exception("Mismatched group session Id") - } - - senderKey = megolmSessionData.senderKey - keysClaimed = megolmSessionData.senderClaimedKeys - roomId = megolmSessionData.roomId - } catch (e: Exception) { - throw Exception(e.message) - } - } - - /** - * Export the inbound group session keys. - * - * @return the inbound group session as MegolmSessionData if the operation succeeds - */ - fun exportKeys(): MegolmSessionData? { - return try { - if (null == forwardingCurve25519KeyChain) { - forwardingCurve25519KeyChain = ArrayList() - } - - if (keysClaimed == null) { - return null - } - - MegolmSessionData( - senderClaimedEd25519Key = keysClaimed?.get("ed25519"), - forwardingCurve25519KeyChain = ArrayList(forwardingCurve25519KeyChain!!), - senderKey = senderKey, - senderClaimedKeys = keysClaimed, - roomId = roomId, - sessionId = olmInboundGroupSession!!.sessionIdentifier(), - sessionKey = olmInboundGroupSession!!.export(olmInboundGroupSession!!.firstKnownIndex), - algorithm = MXCRYPTO_ALGORITHM_MEGOLM - ) - } catch (e: Exception) { - Timber.e(e, "## export() : senderKey $senderKey failed") - null - } - } - - /** - * Export the session for a message index. - * - * @param messageIndex the message index - * @return the exported data - */ - fun exportSession(messageIndex: Long): String? { - if (null != olmInboundGroupSession) { - try { - return olmInboundGroupSession!!.export(messageIndex) - } catch (e: Exception) { - Timber.e(e, "## exportSession() : export failed") - } - } - - return null - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt deleted file mode 100755 index 600fcb1003..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.model - -import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.MegolmSessionData -import org.matrix.olm.OlmInboundGroupSession -import timber.log.Timber -import java.io.Serializable - -/** - * This class adds more context to a OlmInboundGroupSession object. - * This allows additional checks. The class implements Serializable so that the context can be stored. - */ -// Note used anymore, just for database migration -// Deprecated("Use MXInboundMegolmSessionWrapper") -internal class OlmInboundGroupSessionWrapper2 : Serializable { - - // The associated olm inbound group session. - var olmInboundGroupSession: OlmInboundGroupSession? = null - - // The room in which this session is used. - var roomId: String? = null - - // The base64-encoded curve25519 key of the sender. - var senderKey: String? = null - - // Other keys the sender claims. - var keysClaimed: Map? = null - - // Devices which forwarded this session to us (normally empty). - var forwardingCurve25519KeyChain: List? = ArrayList() - - /** - * @return the first known message index - */ - val firstKnownIndex: Long? - get() { - return try { - olmInboundGroupSession?.firstKnownIndex - } catch (e: Exception) { - Timber.e(e, "## getFirstKnownIndex() : getFirstKnownIndex failed") - null - } - } - - /** - * Constructor. - * - * @param sessionKey the session key - * @param isImported true if it is an imported session key - */ - constructor(sessionKey: String, isImported: Boolean) { - try { - if (!isImported) { - olmInboundGroupSession = OlmInboundGroupSession(sessionKey) - } else { - olmInboundGroupSession = OlmInboundGroupSession.importSession(sessionKey) - } - } catch (e: Exception) { - Timber.e(e, "Cannot create") - } - } - - constructor() { - // empty - } - - /** - * Create a new instance from the provided keys map. - * - * @param megolmSessionData the megolm session data - * @throws Exception if the data are invalid - */ - @Throws(Exception::class) - constructor(megolmSessionData: MegolmSessionData) { - try { - val safeSessionKey = megolmSessionData.sessionKey ?: throw Exception("invalid data") - olmInboundGroupSession = OlmInboundGroupSession.importSession(safeSessionKey) - .also { - if (it.sessionIdentifier() != megolmSessionData.sessionId) { - throw Exception("Mismatched group session Id") - } - } - - senderKey = megolmSessionData.senderKey - keysClaimed = megolmSessionData.senderClaimedKeys - roomId = megolmSessionData.roomId - } catch (e: Exception) { - throw Exception(e.message) - } - } - - /** - * Export the inbound group session keys. - * @param index the index to export. If null, the first known index will be used - * - * @return the inbound group session as MegolmSessionData if the operation succeeds - */ - fun exportKeys(index: Long? = null): MegolmSessionData? { - return try { - if (null == forwardingCurve25519KeyChain) { - forwardingCurve25519KeyChain = ArrayList() - } - - if (keysClaimed == null) { - return null - } - - val safeOlmInboundGroupSession = olmInboundGroupSession ?: return null - - val wantedIndex = index ?: safeOlmInboundGroupSession.firstKnownIndex - - MegolmSessionData( - senderClaimedEd25519Key = keysClaimed?.get("ed25519"), - forwardingCurve25519KeyChain = forwardingCurve25519KeyChain?.toList().orEmpty(), - senderKey = senderKey, - senderClaimedKeys = keysClaimed, - roomId = roomId, - sessionId = safeOlmInboundGroupSession.sessionIdentifier(), - sessionKey = safeOlmInboundGroupSession.export(wantedIndex), - algorithm = MXCRYPTO_ALGORITHM_MEGOLM - ) - } catch (e: Exception) { - Timber.e(e, "## export() : senderKey $senderKey failed") - null - } - } - - /** - * Export the session for a message index. - * - * @param messageIndex the message index - * @return the exported data - */ - fun exportSession(messageIndex: Long): String? { - return try { - return olmInboundGroupSession?.export(messageIndex) - } catch (e: Exception) { - Timber.e(e, "## exportSession() : export failed") - null - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmSessionWrapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmSessionWrapper.kt deleted file mode 100644 index a1e58ead0c..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmSessionWrapper.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.model - -import kotlinx.coroutines.sync.Mutex -import org.matrix.olm.OlmSession - -/** - * Encapsulate a OlmSession and a last received message Timestamp. - */ -internal data class OlmSessionWrapper( - // The associated olm session. - val olmSession: OlmSession, - // Timestamp at which the session last received a message. - var lastReceivedMessageTs: Long = 0, - - val mutex: Mutex = Mutex() -) { - - /** - * Notify that a message has been received on this olm session so that it updates `lastReceivedMessageTs`. - */ - fun onMessageReceived(currentTimeMillis: Long) { - lastReceivedMessageTs = currentTimeMillis - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OutboundGroupSessionWrapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OutboundGroupSessionWrapper.kt deleted file mode 100644 index 5a6d1f4bc1..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OutboundGroupSessionWrapper.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.model - -import org.matrix.olm.OlmOutboundGroupSession - -internal data class OutboundGroupSessionWrapper( - val outboundGroupSession: OlmOutboundGroupSession, - val creationTime: Long, - /** - * As per MSC 3061, declares if this key could be shared when inviting a new user to the room. - */ - val sharedHistory: Boolean = false -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt index 05b9e14b82..f443e5b7f6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt @@ -20,7 +20,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.crypto.SSSS_ALGORITHM_AES_HMAC_SHA2 -import org.matrix.android.sdk.api.crypto.SSSS_ALGORITHM_CURVE25519_AES_SHA2 import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.accountdata.SessionAccountDataService @@ -44,9 +43,7 @@ import org.matrix.android.sdk.api.util.toBase64NoPadding import org.matrix.android.sdk.internal.crypto.SecretShareManager import org.matrix.android.sdk.internal.crypto.keysbackup.generatePrivateKeyWithPassword import org.matrix.android.sdk.internal.crypto.tools.HkdfSha256 -import org.matrix.android.sdk.internal.crypto.tools.withOlmDecryption import org.matrix.android.sdk.internal.di.UserId -import org.matrix.olm.OlmPkMessage import java.security.SecureRandom import javax.crypto.Cipher import javax.crypto.Mac @@ -321,22 +318,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor( ?: throw SharedSecretStorageError.ParsingError val algorithm = key.keyInfo.content - if (SSSS_ALGORITHM_CURVE25519_AES_SHA2 == algorithm.algorithm) { - val keySpec = secretKey as? RawBytesKeySpec ?: throw SharedSecretStorageError.BadKeyFormat - return withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.computation) { - // decrypt from recovery key - withOlmDecryption { olmPkDecryption -> - olmPkDecryption.setPrivateKey(keySpec.privateKey) - olmPkDecryption.decrypt(OlmPkMessage() - .apply { - mCipherText = secretContent.ciphertext - mEphemeralKey = secretContent.ephemeral - mMac = secretContent.mac - } - ) - } - } - } else if (SSSS_ALGORITHM_AES_HMAC_SHA2 == algorithm.algorithm) { + if (SSSS_ALGORITHM_AES_HMAC_SHA2 == algorithm.algorithm) { val keySpec = secretKey as? RawBytesKeySpec ?: throw SharedSecretStorageError.BadKeyFormat return withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.computation) { decryptAesHmacSha2(keySpec, name, secretContent) @@ -366,8 +348,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor( val keyInfo = (keyInfoResult as? KeyInfoResult.Success)?.keyInfo ?: return IntegrityResult.Error(SharedSecretStorageError.UnknownKey(keyId ?: "")) - if (keyInfo.content.algorithm != SSSS_ALGORITHM_AES_HMAC_SHA2 && - keyInfo.content.algorithm != SSSS_ALGORITHM_CURVE25519_AES_SHA2) { + if (keyInfo.content.algorithm != SSSS_ALGORITHM_AES_HMAC_SHA2) { // Unsupported algorithm return IntegrityResult.Error( SharedSecretStorageError.UnsupportedAlgorithm(keyInfo.content.algorithm ?: "") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCommonCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCommonCryptoStore.kt index 68b002c087..ca389c9b00 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCommonCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCommonCryptoStore.kt @@ -23,7 +23,6 @@ import org.matrix.android.sdk.api.session.crypto.model.CryptoRoomInfo import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent import org.matrix.android.sdk.api.util.Optional -import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrapper import org.matrix.android.sdk.internal.crypto.store.db.CryptoStoreAggregator /** @@ -143,14 +142,4 @@ interface IMXCommonCryptoStore { * @return the device or null if not found */ fun deviceWithIdentityKey(userId: String, identityKey: String): CryptoDeviceInfo? - - /** - * Retrieve an inbound group session. - * Used in rust for lazy migration - * - * @param sessionId the session identifier. - * @param senderKey the base64-encoded curve25519 key of the sender. - * @return an inbound group session. - */ - fun getInboundGroupSession(sessionId: String, senderKey: String): MXInboundMegolmSessionWrapper? } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/RustCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/RustCryptoStore.kt index 6854449861..93d4963c91 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/RustCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/RustCryptoStore.kt @@ -35,32 +35,23 @@ import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventCo import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.internal.crypto.OlmMachine -import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrapper import org.matrix.android.sdk.internal.crypto.store.db.CryptoStoreAggregator import org.matrix.android.sdk.internal.crypto.store.db.doRealmTransaction import org.matrix.android.sdk.internal.crypto.store.db.doRealmTransactionAsync import org.matrix.android.sdk.internal.crypto.store.db.doWithRealm import org.matrix.android.sdk.internal.crypto.store.db.mapper.CryptoRoomInfoMapper import org.matrix.android.sdk.internal.crypto.store.db.mapper.MyDeviceLastSeenInfoEntityMapper -import org.matrix.android.sdk.internal.crypto.store.db.model.AuditTrailEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.AuditTrailEntityFields import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntity import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntity import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingKeyRequestEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingKeyRequestEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.createPrimaryKey import org.matrix.android.sdk.internal.crypto.store.db.query.getById import org.matrix.android.sdk.internal.crypto.store.db.query.getOrCreate import org.matrix.android.sdk.internal.di.CryptoDatabase import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.SessionScope -import org.matrix.android.sdk.internal.util.time.Clock import timber.log.Timber import java.util.concurrent.Executors import java.util.concurrent.TimeUnit @@ -75,7 +66,6 @@ private val loggerTag = LoggerTag("RealmCryptoStore", LoggerTag.CRYPTO) @SessionScope internal class RustCryptoStore @Inject constructor( @CryptoDatabase private val realmConfiguration: RealmConfiguration, - private val clock: Clock, @UserId private val userId: String, @DeviceId private val deviceId: String, private val myDeviceLastSeenInfoEntityMapper: MyDeviceLastSeenInfoEntityMapper, @@ -134,20 +124,6 @@ internal class RustCryptoStore @Inject constructor( } } - /** - * Needed for lazy migration of sessions from the legacy store. - */ - override fun getInboundGroupSession(sessionId: String, senderKey: String): MXInboundMegolmSessionWrapper? { - val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionId, senderKey) - - return doWithRealm(realmConfiguration) { realm -> - realm.where() - .equalTo(OlmInboundGroupSessionEntityFields.PRIMARY_KEY, key) - .findFirst() - ?.toModel() - } - } - // ================================================ // Things that should be migrated to another store than realm // ================================================ @@ -163,30 +139,7 @@ internal class RustCryptoStore @Inject constructor( // nop } - override fun tidyUpDataBase() { - // These entities are not used in rust actually, but as they are not yet cleaned up, this will do it with time - val prevWeekTs = clock.epochMillis() - 7 * 24 * 60 * 60 * 1_000 - doRealmTransaction("tidyUpDataBase", realmConfiguration) { realm -> - - // Clean the old ones? - realm.where() - .lessThan(OutgoingKeyRequestEntityFields.CREATION_TIME_STAMP, prevWeekTs) - .findAll() - .also { Timber.i("## Crypto Clean up ${it.size} OutgoingKeyRequestEntity") } - .deleteAllFromRealm() - - // Only keep one month history - - val prevMonthTs = clock.epochMillis() - 4 * 7 * 24 * 60 * 60 * 1_000L - realm.where() - .lessThan(AuditTrailEntityFields.AGE_LOCAL_TS, prevMonthTs) - .findAll() - .also { Timber.i("## Crypto Clean up ${it.size} AuditTrailEntity") } - .deleteAllFromRealm() - - // Can we do something for WithHeldSessionEntity? - } - } + override fun tidyUpDataBase() = Unit override fun close() { val tasks = monarchyWriteAsyncExecutor.shutdownNow() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt deleted file mode 100644 index 914ce4704e..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2023 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store - -import org.matrix.android.sdk.api.session.crypto.crosssigning.UserIdentity -import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo - -internal data class UserDataToStore( - /** - * Map of userId -> (Map of deviceId -> [CryptoDeviceInfo]). - */ - val userDevices: MutableMap> = mutableMapOf(), - /** - * Map of userId -> [UserIdentity]. - */ - val userIdentities: MutableMap = mutableMapOf(), -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt index 6412df205f..fb10ecc999 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt @@ -16,15 +16,9 @@ package org.matrix.android.sdk.internal.crypto.store.db -import android.util.Base64 import io.realm.Realm import io.realm.RealmConfiguration -import io.realm.RealmObject import timber.log.Timber -import java.io.ByteArrayOutputStream -import java.io.ObjectOutputStream -import java.util.zip.GZIPInputStream -import java.util.zip.GZIPOutputStream import kotlin.system.measureTimeMillis /** @@ -36,24 +30,6 @@ internal fun doWithRealm(realmConfiguration: RealmConfiguration, action: (Re } } -/** - * Get realm, do the query, copy from realm, close realm, and return the copied result. - */ -internal fun doRealmQueryAndCopy(realmConfiguration: RealmConfiguration, action: (Realm) -> T?): T? { - return Realm.getInstance(realmConfiguration).use { realm -> - action.invoke(realm)?.let { realm.copyFromRealm(it) } - } -} - -/** - * Get realm, do the list query, copy from realm, close realm, and return the copied result. - */ -internal fun doRealmQueryAndCopyList(realmConfiguration: RealmConfiguration, action: (Realm) -> Iterable): Iterable { - return Realm.getInstance(realmConfiguration).use { realm -> - action.invoke(realm).let { realm.copyFromRealm(it) } - } -} - /** * Get realm instance, invoke the action in a transaction and close realm. */ @@ -70,38 +46,3 @@ internal fun doRealmTransactionAsync(realmConfiguration: RealmConfiguration, act realm.executeTransactionAsync { action.invoke(it) } } } - -/** - * Serialize any Serializable object, zip it and convert to Base64 String. - */ -internal fun serializeForRealm(o: Any?): String? { - if (o == null) { - return null - } - - val baos = ByteArrayOutputStream() - val gzis = GZIPOutputStream(baos) - val out = ObjectOutputStream(gzis) - out.use { - it.writeObject(o) - } - return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT) -} - -/** - * Do the opposite of serializeForRealm. - */ -@Suppress("UNCHECKED_CAST") -internal fun deserializeFromRealm(string: String?): T? { - if (string == null) { - return null - } - val decodedB64 = Base64.decode(string.toByteArray(), Base64.DEFAULT) - - val bais = decodedB64.inputStream() - val gzis = GZIPInputStream(bais) - val ois = SafeObjectInputStream(gzis) - return ois.use { - it.readObject() as T - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt index 1b0143f4fa..bbb14aaca0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt @@ -17,31 +17,8 @@ package org.matrix.android.sdk.internal.crypto.store.db import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo001Legacy -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo002Legacy -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo003RiotX -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo004 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo005 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo006 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo007 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo008 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo009 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo010 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo011 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo012 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo013 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo014 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo015 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo016 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo017 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo018 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo019 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo020 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo021 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo022 -import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo023 +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo024 import org.matrix.android.sdk.internal.util.database.MatrixRealmMigration -import org.matrix.android.sdk.internal.util.time.Clock import javax.inject.Inject /** @@ -49,13 +26,11 @@ import javax.inject.Inject * 0, 1, 2: legacy Riot-Android; * 3: migrate to RiotX schema; * 4, 5, 6, 7, 8, 9: migrations from RiotX (which was previously 1, 2, 3, 4, 5, 6). + * 24: Delete nearly all the crypto DB */ -internal class RealmCryptoStoreMigration @Inject constructor( - private val clock: Clock, - private val rustMigrationInfoProvider: RustMigrationInfoProvider, -) : MatrixRealmMigration( +internal class RealmCryptoStoreMigration @Inject constructor() : MatrixRealmMigration( dbName = "Crypto", - schemaVersion = 23L, + schemaVersion = 24L, ) { /** * Forces all RealmCryptoStoreMigration instances to be equal. @@ -65,33 +40,6 @@ internal class RealmCryptoStoreMigration @Inject constructor( override fun hashCode() = 5000 override fun doMigrate(realm: DynamicRealm, oldVersion: Long) { - if (oldVersion < 1) MigrateCryptoTo001Legacy(realm).perform() - if (oldVersion < 2) MigrateCryptoTo002Legacy(realm).perform() - if (oldVersion < 3) MigrateCryptoTo003RiotX(realm).perform() - if (oldVersion < 4) MigrateCryptoTo004(realm).perform() - if (oldVersion < 5) MigrateCryptoTo005(realm).perform() - if (oldVersion < 6) MigrateCryptoTo006(realm).perform() - if (oldVersion < 7) MigrateCryptoTo007(realm).perform() - if (oldVersion < 8) MigrateCryptoTo008(realm, clock).perform() - if (oldVersion < 9) MigrateCryptoTo009(realm).perform() - if (oldVersion < 10) MigrateCryptoTo010(realm).perform() - if (oldVersion < 11) MigrateCryptoTo011(realm).perform() - if (oldVersion < 12) MigrateCryptoTo012(realm).perform() - if (oldVersion < 13) MigrateCryptoTo013(realm).perform() - if (oldVersion < 14) MigrateCryptoTo014(realm).perform() - if (oldVersion < 15) MigrateCryptoTo015(realm).perform() - if (oldVersion < 16) MigrateCryptoTo016(realm).perform() - if (oldVersion < 17) MigrateCryptoTo017(realm).perform() - if (oldVersion < 18) MigrateCryptoTo018(realm).perform() - if (oldVersion < 19) MigrateCryptoTo019(realm).perform() - if (oldVersion < 20) MigrateCryptoTo020(realm).perform() - if (oldVersion < 21) MigrateCryptoTo021(realm).perform() - if (oldVersion < 22) MigrateCryptoTo022( - realm, - rustMigrationInfoProvider.rustDirectory, - rustMigrationInfoProvider.rustEncryptionConfiguration, - rustMigrationInfoProvider.migrateMegolmGroupSessions - ).perform() - if (oldVersion < 23) MigrateCryptoTo023(realm).perform() + if (oldVersion < 24) MigrateCryptoTo024(realm).perform() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreModule.kt index 6696cf8281..8b94baacde 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreModule.kt @@ -17,23 +17,9 @@ package org.matrix.android.sdk.internal.crypto.store.db import io.realm.annotations.RealmModule -import org.matrix.android.sdk.internal.crypto.store.db.model.AuditTrailEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntity import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.KeyInfoEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.KeyRequestReplyEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntity import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.OutboundGroupSessionInfoEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingKeyRequestEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.TrustLevelEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntity /** * Realm module for Crypto store classes. @@ -43,21 +29,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEnti classes = [ CryptoMetadataEntity::class, CryptoRoomEntity::class, - DeviceInfoEntity::class, - KeysBackupDataEntity::class, - OlmInboundGroupSessionEntity::class, - OlmSessionEntity::class, - UserEntity::class, - KeyInfoEntity::class, - CrossSigningInfoEntity::class, - TrustLevelEntity::class, - AuditTrailEntity::class, - OutgoingKeyRequestEntity::class, - KeyRequestReplyEntity::class, MyDeviceLastSeenInfoEntity::class, - WithHeldSessionEntity::class, - SharedSessionEntity::class, - OutboundGroupSessionInfoEntity::class ] ) internal class RealmCryptoStoreModule diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RustMigrationInfoProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RustMigrationInfoProvider.kt deleted file mode 100644 index 667990468c..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RustMigrationInfoProvider.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2023 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db - -import org.matrix.android.sdk.internal.crypto.RustEncryptionConfiguration -import org.matrix.android.sdk.internal.di.SessionRustFilesDirectory -import java.io.File -import javax.inject.Inject - -internal class RustMigrationInfoProvider @Inject constructor( - @SessionRustFilesDirectory - val rustDirectory: File, - val rustEncryptionConfiguration: RustEncryptionConfiguration -) { - - var migrateMegolmGroupSessions: Boolean = false -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/SafeObjectInputStream.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/SafeObjectInputStream.kt deleted file mode 100644 index 5897869a97..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/SafeObjectInputStream.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db - -import java.io.IOException -import java.io.InputStream -import java.io.ObjectInputStream -import java.io.ObjectStreamClass - -/** - * Package has been renamed from `im.vector.matrix.android` to `org.matrix.android.sdk` - * so ensure deserialization of previously stored objects still works - * - * Ref: https://stackoverflow.com/questions/3884492/how-can-i-change-package-for-a-bunch-of-java-serializable-classes - */ -internal class SafeObjectInputStream(inputStream: InputStream) : ObjectInputStream(inputStream) { - - init { - enableResolveObject(true) - } - - @Throws(IOException::class, ClassNotFoundException::class) - override fun readClassDescriptor(): ObjectStreamClass { - val read = super.readClassDescriptor() - if (read.name.startsWith("im.vector.matrix.android.")) { - return ObjectStreamClass.lookup(Class.forName(read.name.replace("im.vector.matrix.android.", "org.matrix.android.sdk."))) - } - return read - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/CrossSigningKeysMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/CrossSigningKeysMapper.kt deleted file mode 100644 index 8b7bf9c26b..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/CrossSigningKeysMapper.kt +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.mapper - -import com.squareup.moshi.Moshi -import com.squareup.moshi.Types -import io.realm.RealmList -import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey -import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.store.db.model.KeyInfoEntity -import timber.log.Timber -import javax.inject.Inject - -internal class CrossSigningKeysMapper @Inject constructor(moshi: Moshi) { - - private val signaturesAdapter = moshi.adapter>>( - Types.newParameterizedType( - Map::class.java, - String::class.java, - Any::class.java - ) - ) - - fun update(keyInfo: KeyInfoEntity, cryptoCrossSigningKey: CryptoCrossSigningKey) { - // update signatures? - keyInfo.signatures = serializeSignatures(cryptoCrossSigningKey.signatures) - keyInfo.usages = cryptoCrossSigningKey.usages?.toTypedArray()?.let { RealmList(*it) } - ?: RealmList() - } - - fun map(userId: String?, keyInfo: KeyInfoEntity?): CryptoCrossSigningKey? { - val pubKey = keyInfo?.publicKeyBase64 ?: return null - return CryptoCrossSigningKey( - userId = userId ?: "", - keys = mapOf("ed25519:$pubKey" to pubKey), - usages = keyInfo.usages.toList(), - signatures = deserializeSignatures(keyInfo.signatures), - trustLevel = keyInfo.trustLevelEntity?.let { - DeviceTrustLevel( - crossSigningVerified = it.crossSignedVerified ?: false, - locallyVerified = it.locallyVerified ?: false - ) - } - ) - } - - fun map(keyInfo: CryptoCrossSigningKey): KeyInfoEntity { - return KeyInfoEntity().apply { - publicKeyBase64 = keyInfo.unpaddedBase64PublicKey - usages = keyInfo.usages?.let { RealmList(*it.toTypedArray()) } ?: RealmList() - signatures = serializeSignatures(keyInfo.signatures) - // TODO how to handle better, check if same keys? - // reset trust - trustLevelEntity = null - } - } - - fun serializeSignatures(signatures: Map>?): String { - return signaturesAdapter.toJson(signatures) - } - - fun deserializeSignatures(signatures: String?): Map>? { - if (signatures == null) { - return null - } - return try { - signaturesAdapter.fromJson(signatures) - } catch (failure: Throwable) { - Timber.e(failure) - null - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo001Legacy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo001Legacy.kt deleted file mode 100644 index 7dee42e51a..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo001Legacy.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator -import timber.log.Timber - -internal class MigrateCryptoTo001Legacy(realm: DynamicRealm) : RealmMigrator(realm, 1) { - - override fun doMigrate(realm: DynamicRealm) { - Timber.d("Add field lastReceivedMessageTs (Long) and set the value to 0") - - realm.schema.get("OlmSessionEntity") - ?.addField(OlmSessionEntityFields.LAST_RECEIVED_MESSAGE_TS, Long::class.java) - ?.transform { - it.setLong(OlmSessionEntityFields.LAST_RECEIVED_MESSAGE_TS, 0) - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo002Legacy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo002Legacy.kt deleted file mode 100644 index 1b53e1928a..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo002Legacy.kt +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator -import timber.log.Timber - -internal class MigrateCryptoTo002Legacy(realm: DynamicRealm) : RealmMigrator(realm, 2) { - - override fun doMigrate(realm: DynamicRealm) { - Timber.d("Update IncomingRoomKeyRequestEntity format: requestBodyString field is exploded into several fields") - realm.schema.get("IncomingRoomKeyRequestEntity") - ?.addFieldIfNotExists("requestBodyAlgorithm", String::class.java) - ?.addFieldIfNotExists("requestBodyRoomId", String::class.java) - ?.addFieldIfNotExists("requestBodySenderKey", String::class.java) - ?.addFieldIfNotExists("requestBodySessionId", String::class.java) - ?.transform { dynamicObject -> - try { - val requestBodyString = dynamicObject.getString("requestBodyString") - // It was a map before - val map: Map? = deserializeFromRealm(requestBodyString) - - map?.let { - dynamicObject.setString("requestBodyAlgorithm", it["algorithm"]) - dynamicObject.setString("requestBodyRoomId", it["room_id"]) - dynamicObject.setString("requestBodySenderKey", it["sender_key"]) - dynamicObject.setString("requestBodySessionId", it["session_id"]) - } - } catch (e: Exception) { - Timber.e(e, "Error") - } - } - ?.removeFieldIfExists("requestBodyString") - - Timber.d("Update IncomingRoomKeyRequestEntity format: requestBodyString field is exploded into several fields") - realm.schema.get("OutgoingRoomKeyRequestEntity") - ?.addFieldIfNotExists("requestBodyAlgorithm", String::class.java) - ?.addFieldIfNotExists("requestBodyRoomId", String::class.java) - ?.addFieldIfNotExists("requestBodySenderKey", String::class.java) - ?.addFieldIfNotExists("requestBodySessionId", String::class.java) - ?.transform { dynamicObject -> - try { - val requestBodyString = dynamicObject.getString("requestBodyString") - // It was a map before - val map: Map? = deserializeFromRealm(requestBodyString) - - map?.let { - dynamicObject.setString("requestBodyAlgorithm", it["algorithm"]) - dynamicObject.setString("requestBodyRoomId", it["room_id"]) - dynamicObject.setString("requestBodySenderKey", it["sender_key"]) - dynamicObject.setString("requestBodySessionId", it["session_id"]) - } - } catch (e: Exception) { - Timber.e(e, "Error") - } - } - ?.removeFieldIfExists("requestBodyString") - - Timber.d("Create KeysBackupDataEntity") - if (!realm.schema.contains("KeysBackupDataEntity")) { - realm.schema.create("KeysBackupDataEntity") - .addField(KeysBackupDataEntityFields.PRIMARY_KEY, Integer::class.java) - .addPrimaryKey(KeysBackupDataEntityFields.PRIMARY_KEY) - .setRequired(KeysBackupDataEntityFields.PRIMARY_KEY, true) - .addField(KeysBackupDataEntityFields.BACKUP_LAST_SERVER_HASH, String::class.java) - .addField(KeysBackupDataEntityFields.BACKUP_LAST_SERVER_NUMBER_OF_KEYS, Integer::class.java) - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo003RiotX.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo003RiotX.kt deleted file mode 100644 index 34d1afa2d8..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo003RiotX.kt +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper -import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm -import org.matrix.android.sdk.internal.util.database.RealmMigrator -import org.matrix.androidsdk.crypto.data.MXDeviceInfo -import org.matrix.androidsdk.crypto.data.MXOlmInboundGroupSession2 -import timber.log.Timber - -internal class MigrateCryptoTo003RiotX(realm: DynamicRealm) : RealmMigrator(realm, 3) { - - override fun doMigrate(realm: DynamicRealm) { - Timber.d("Migrate to RiotX model") - realm.schema.get("CryptoRoomEntity") - ?.addFieldIfNotExists(CryptoRoomEntityFields.SHOULD_ENCRYPT_FOR_INVITED_MEMBERS, Boolean::class.java) - ?.setRequiredIfNotAlready(CryptoRoomEntityFields.SHOULD_ENCRYPT_FOR_INVITED_MEMBERS, false) - - // Convert format of MXDeviceInfo, package has to be the same. - realm.schema.get("DeviceInfoEntity") - ?.transform { obj -> - try { - val oldSerializedData = obj.getString("deviceInfoData") - deserializeFromRealm(oldSerializedData)?.let { legacyMxDeviceInfo -> - val newMxDeviceInfo = org.matrix.android.sdk.api.session.crypto.model.MXDeviceInfo( - deviceId = legacyMxDeviceInfo.deviceId, - userId = legacyMxDeviceInfo.userId, - algorithms = legacyMxDeviceInfo.algorithms, - keys = legacyMxDeviceInfo.keys, - signatures = legacyMxDeviceInfo.signatures, - unsigned = legacyMxDeviceInfo.unsigned, - verified = legacyMxDeviceInfo.mVerified - ) - - obj.setString("deviceInfoData", serializeForRealm(newMxDeviceInfo)) - } - } catch (e: Exception) { - Timber.e(e, "Error") - } - } - - // Convert MXOlmInboundGroupSession2 to OlmInboundGroupSessionWrapper - realm.schema.get("OlmInboundGroupSessionEntity") - ?.transform { obj -> - try { - val oldSerializedData = obj.getString("olmInboundGroupSessionData") - deserializeFromRealm(oldSerializedData)?.let { mxOlmInboundGroupSession2 -> - val sessionKey = mxOlmInboundGroupSession2.mSession.sessionIdentifier() - val newOlmInboundGroupSessionWrapper = OlmInboundGroupSessionWrapper(sessionKey, false) - .apply { - olmInboundGroupSession = mxOlmInboundGroupSession2.mSession - roomId = mxOlmInboundGroupSession2.mRoomId - senderKey = mxOlmInboundGroupSession2.mSenderKey - keysClaimed = mxOlmInboundGroupSession2.mKeysClaimed - forwardingCurve25519KeyChain = mxOlmInboundGroupSession2.mForwardingCurve25519KeyChain - } - - obj.setString("olmInboundGroupSessionData", serializeForRealm(newOlmInboundGroupSessionWrapper)) - } - } catch (e: Exception) { - Timber.e(e, "Error") - } - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo004.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo004.kt deleted file mode 100644 index 0a986892d9..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo004.kt +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import com.squareup.moshi.Moshi -import com.squareup.moshi.Types -import io.realm.DynamicRealm -import org.matrix.android.sdk.api.session.crypto.model.MXDeviceInfo -import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.KeyInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.TrustLevelEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields -import org.matrix.android.sdk.internal.di.SerializeNulls -import org.matrix.android.sdk.internal.util.database.RealmMigrator -import timber.log.Timber - -// Version 4L added Cross Signing info persistence -internal class MigrateCryptoTo004(realm: DynamicRealm) : RealmMigrator(realm, 4) { - - override fun doMigrate(realm: DynamicRealm) { - if (realm.schema.contains("TrustLevelEntity")) { - Timber.d("Skipping Step 3 -> 4 because entities already exist") - return - } - - Timber.d("Create KeyInfoEntity") - val trustLevelEntityEntitySchema = realm.schema.create("TrustLevelEntity") - .addField(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED, Boolean::class.java) - .setNullable(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED, true) - .addField(TrustLevelEntityFields.LOCALLY_VERIFIED, Boolean::class.java) - .setNullable(TrustLevelEntityFields.LOCALLY_VERIFIED, true) - - val keyInfoEntitySchema = realm.schema.create("KeyInfoEntity") - .addField(KeyInfoEntityFields.PUBLIC_KEY_BASE64, String::class.java) - .addField(KeyInfoEntityFields.SIGNATURES, String::class.java) - .addRealmListField(KeyInfoEntityFields.USAGES.`$`, String::class.java) - .addRealmObjectField(KeyInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevelEntityEntitySchema) - - Timber.d("Create CrossSigningInfoEntity") - - val crossSigningInfoSchema = realm.schema.create("CrossSigningInfoEntity") - .addField(CrossSigningInfoEntityFields.USER_ID, String::class.java) - .addPrimaryKey(CrossSigningInfoEntityFields.USER_ID) - .addRealmListField(CrossSigningInfoEntityFields.CROSS_SIGNING_KEYS.`$`, keyInfoEntitySchema) - - Timber.d("Updating UserEntity table") - realm.schema.get("UserEntity") - ?.addRealmObjectField(UserEntityFields.CROSS_SIGNING_INFO_ENTITY.`$`, crossSigningInfoSchema) - - Timber.d("Updating CryptoMetadataEntity table") - realm.schema.get("CryptoMetadataEntity") - ?.addField(CryptoMetadataEntityFields.X_SIGN_MASTER_PRIVATE_KEY, String::class.java) - ?.addField(CryptoMetadataEntityFields.X_SIGN_USER_PRIVATE_KEY, String::class.java) - ?.addField(CryptoMetadataEntityFields.X_SIGN_SELF_SIGNED_PRIVATE_KEY, String::class.java) - - val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build() - val listMigrationAdapter = moshi.adapter>( - Types.newParameterizedType( - List::class.java, - String::class.java, - Any::class.java - ) - ) - val mapMigrationAdapter = moshi.adapter( - Types.newParameterizedType( - Map::class.java, - String::class.java, - Any::class.java - ) - ) - - realm.schema.get("DeviceInfoEntity") - ?.addField(DeviceInfoEntityFields.USER_ID, String::class.java) - ?.addField(DeviceInfoEntityFields.ALGORITHM_LIST_JSON, String::class.java) - ?.addField(DeviceInfoEntityFields.KEYS_MAP_JSON, String::class.java) - ?.addField(DeviceInfoEntityFields.SIGNATURE_MAP_JSON, String::class.java) - ?.addField(DeviceInfoEntityFields.UNSIGNED_MAP_JSON, String::class.java) - ?.addField(DeviceInfoEntityFields.IS_BLOCKED, Boolean::class.java) - ?.setNullable(DeviceInfoEntityFields.IS_BLOCKED, true) - ?.addRealmObjectField(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevelEntityEntitySchema) - ?.transform { obj -> - - try { - val oldSerializedData = obj.getString("deviceInfoData") - deserializeFromRealm(oldSerializedData)?.let { oldDevice -> - - val trustLevel = realm.createObject("TrustLevelEntity") - when (oldDevice.verified) { - MXDeviceInfo.DEVICE_VERIFICATION_UNKNOWN -> { - obj.setNull(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`) - } - MXDeviceInfo.DEVICE_VERIFICATION_BLOCKED -> { - trustLevel.setNull(TrustLevelEntityFields.LOCALLY_VERIFIED) - trustLevel.setNull(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED) - obj.setBoolean(DeviceInfoEntityFields.IS_BLOCKED, oldDevice.isBlocked) - obj.setObject(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevel) - } - MXDeviceInfo.DEVICE_VERIFICATION_UNVERIFIED -> { - trustLevel.setBoolean(TrustLevelEntityFields.LOCALLY_VERIFIED, false) - trustLevel.setBoolean(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED, false) - obj.setObject(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevel) - } - MXDeviceInfo.DEVICE_VERIFICATION_VERIFIED -> { - trustLevel.setBoolean(TrustLevelEntityFields.LOCALLY_VERIFIED, true) - trustLevel.setBoolean(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED, false) - obj.setObject(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevel) - } - } - - obj.setString(DeviceInfoEntityFields.USER_ID, oldDevice.userId) - obj.setString(DeviceInfoEntityFields.IDENTITY_KEY, oldDevice.identityKey()) - obj.setString(DeviceInfoEntityFields.ALGORITHM_LIST_JSON, listMigrationAdapter.toJson(oldDevice.algorithms)) - obj.setString(DeviceInfoEntityFields.KEYS_MAP_JSON, mapMigrationAdapter.toJson(oldDevice.keys)) - obj.setString(DeviceInfoEntityFields.SIGNATURE_MAP_JSON, mapMigrationAdapter.toJson(oldDevice.signatures)) - obj.setString(DeviceInfoEntityFields.UNSIGNED_MAP_JSON, mapMigrationAdapter.toJson(oldDevice.unsigned)) - } - } catch (failure: Throwable) { - Timber.w(failure, "Crypto Data base migration error") - // an unfortunate refactor did modify that class, making deserialization failing - // so we just skip and ignore.. - } - } - ?.removeField("deviceInfoData") - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo005.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo005.kt deleted file mode 100644 index 8ec2932a8f..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo005.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.util.database.RealmMigrator - -internal class MigrateCryptoTo005(realm: DynamicRealm) : RealmMigrator(realm, 5) { - - override fun doMigrate(realm: DynamicRealm) { - realm.schema.remove("OutgoingRoomKeyRequestEntity") - realm.schema.remove("IncomingRoomKeyRequestEntity") - - // Not need to migrate existing request, just start fresh? - realm.schema.create("GossipingEventEntity") - .addField("type", String::class.java) - .addIndex("type") - .addField("content", String::class.java) - .addField("sender", String::class.java) - .addIndex("sender") - .addField("decryptionResultJson", String::class.java) - .addField("decryptionErrorCode", String::class.java) - .addField("ageLocalTs", Long::class.java) - .setNullable("ageLocalTs", true) - .addField("sendStateStr", String::class.java) - - realm.schema.create("IncomingGossipingRequestEntity") - .addField("requestId", String::class.java) - .addIndex("requestId") - .addField("typeStr", String::class.java) - .addIndex("typeStr") - .addField("otherUserId", String::class.java) - .addField("requestedInfoStr", String::class.java) - .addField("otherDeviceId", String::class.java) - .addField("requestStateStr", String::class.java) - .addField("localCreationTimestamp", Long::class.java) - .setNullable("localCreationTimestamp", true) - - realm.schema.create("OutgoingGossipingRequestEntity") - .addField("requestId", String::class.java) - .addIndex("requestId") - .addField("recipientsData", String::class.java) - .addField("requestedInfoStr", String::class.java) - .addField("typeStr", String::class.java) - .addIndex("typeStr") - .addField("requestStateStr", String::class.java) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo006.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo006.kt deleted file mode 100644 index 39b2898514..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo006.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator -import timber.log.Timber - -internal class MigrateCryptoTo006(realm: DynamicRealm) : RealmMigrator(realm, 6) { - - override fun doMigrate(realm: DynamicRealm) { - Timber.d("Updating CryptoMetadataEntity table") - realm.schema.get("CryptoMetadataEntity") - ?.addField(CryptoMetadataEntityFields.KEY_BACKUP_RECOVERY_KEY, String::class.java) - ?.addField(CryptoMetadataEntityFields.KEY_BACKUP_RECOVERY_KEY_VERSION, String::class.java) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo007.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo007.kt deleted file mode 100644 index 0e221e78f3..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo007.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper -import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper2 -import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm -import org.matrix.android.sdk.internal.crypto.store.db.mapper.CrossSigningKeysMapper -import org.matrix.android.sdk.internal.crypto.store.db.model.KeyInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm -import org.matrix.android.sdk.internal.di.MoshiProvider -import org.matrix.android.sdk.internal.util.database.RealmMigrator -import timber.log.Timber - -internal class MigrateCryptoTo007(realm: DynamicRealm) : RealmMigrator(realm, 7) { - - override fun doMigrate(realm: DynamicRealm) { - Timber.d("Updating KeyInfoEntity table") - val crossSigningKeysMapper = CrossSigningKeysMapper(MoshiProvider.providesMoshi()) - - val keyInfoEntities = realm.where("KeyInfoEntity").findAll() - try { - keyInfoEntities.forEach { - val stringSignatures = it.getString(KeyInfoEntityFields.SIGNATURES) - val objectSignatures: Map>? = deserializeFromRealm(stringSignatures) - val jsonSignatures = crossSigningKeysMapper.serializeSignatures(objectSignatures) - it.setString(KeyInfoEntityFields.SIGNATURES, jsonSignatures) - } - } catch (ignore: Throwable) { - } - - // Migrate frozen classes - val inboundGroupSessions = realm.where("OlmInboundGroupSessionEntity").findAll() - inboundGroupSessions.forEach { dynamicObject -> - dynamicObject.getString(OlmInboundGroupSessionEntityFields.OLM_INBOUND_GROUP_SESSION_DATA)?.let { serializedObject -> - try { - deserializeFromRealm(serializedObject)?.let { oldFormat -> - val newFormat = oldFormat.exportKeys()?.let { - OlmInboundGroupSessionWrapper2(it) - } - dynamicObject.setString(OlmInboundGroupSessionEntityFields.OLM_INBOUND_GROUP_SESSION_DATA, serializeForRealm(newFormat)) - } - } catch (failure: Throwable) { - Timber.e(failure, "## OlmInboundGroupSessionEntity migration failed") - } - } - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo008.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo008.kt deleted file mode 100644 index ad195e6e55..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo008.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator -import org.matrix.android.sdk.internal.util.time.Clock - -internal class MigrateCryptoTo008( - realm: DynamicRealm, - private val clock: Clock, -) : RealmMigrator(realm, 8) { - - override fun doMigrate(realm: DynamicRealm) { - realm.schema.create("MyDeviceLastSeenInfoEntity") - .addField(MyDeviceLastSeenInfoEntityFields.DEVICE_ID, String::class.java) - .addPrimaryKey(MyDeviceLastSeenInfoEntityFields.DEVICE_ID) - .addField(MyDeviceLastSeenInfoEntityFields.DISPLAY_NAME, String::class.java) - .addField(MyDeviceLastSeenInfoEntityFields.LAST_SEEN_IP, String::class.java) - .addField(MyDeviceLastSeenInfoEntityFields.LAST_SEEN_TS, Long::class.java) - .setNullable(MyDeviceLastSeenInfoEntityFields.LAST_SEEN_TS, true) - - val now = clock.epochMillis() - realm.schema.get("DeviceInfoEntity") - ?.addField(DeviceInfoEntityFields.FIRST_TIME_SEEN_LOCAL_TS, Long::class.java) - ?.setNullable(DeviceInfoEntityFields.FIRST_TIME_SEEN_LOCAL_TS, true) - ?.transform { deviceInfoEntity -> - tryOrNull { - deviceInfoEntity.setLong(DeviceInfoEntityFields.FIRST_TIME_SEEN_LOCAL_TS, now) - } - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo009.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo009.kt deleted file mode 100644 index 8d9d24dfba..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo009.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator -import timber.log.Timber - -// Fixes duplicate devices in UserEntity#devices -internal class MigrateCryptoTo009(realm: DynamicRealm) : RealmMigrator(realm, 9) { - - override fun doMigrate(realm: DynamicRealm) { - val userEntities = realm.where("UserEntity").findAll() - userEntities.forEach { - try { - val deviceList = it.getList(UserEntityFields.DEVICES.`$`) - ?: return@forEach - val distinct = deviceList.distinctBy { it.getString(DeviceInfoEntityFields.DEVICE_ID) } - if (distinct.size != deviceList.size) { - deviceList.clear() - deviceList.addAll(distinct) - } - } catch (failure: Throwable) { - Timber.w(failure, "Crypto Data base migration error for migrateTo9") - } - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo010.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo010.kt deleted file mode 100644 index faf0d58832..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo010.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator - -// Version 10L added WithHeld Keys Info (MSC2399) -internal class MigrateCryptoTo010(realm: DynamicRealm) : RealmMigrator(realm, 10) { - - override fun doMigrate(realm: DynamicRealm) { - realm.schema.create("WithHeldSessionEntity") - .addField(WithHeldSessionEntityFields.ROOM_ID, String::class.java) - .addField(WithHeldSessionEntityFields.ALGORITHM, String::class.java) - .addField(WithHeldSessionEntityFields.SESSION_ID, String::class.java) - .addIndex(WithHeldSessionEntityFields.SESSION_ID) - .addField(WithHeldSessionEntityFields.SENDER_KEY, String::class.java) - .addIndex(WithHeldSessionEntityFields.SENDER_KEY) - .addField(WithHeldSessionEntityFields.CODE_STRING, String::class.java) - .addField(WithHeldSessionEntityFields.REASON, String::class.java) - - realm.schema.create("SharedSessionEntity") - .addField(SharedSessionEntityFields.ROOM_ID, String::class.java) - .addField(SharedSessionEntityFields.ALGORITHM, String::class.java) - .addField(SharedSessionEntityFields.SESSION_ID, String::class.java) - .addIndex(SharedSessionEntityFields.SESSION_ID) - .addField(SharedSessionEntityFields.USER_ID, String::class.java) - .addIndex(SharedSessionEntityFields.USER_ID) - .addField(SharedSessionEntityFields.DEVICE_ID, String::class.java) - .addIndex(SharedSessionEntityFields.DEVICE_ID) - .addField(SharedSessionEntityFields.CHAIN_INDEX, Long::class.java) - .setNullable(SharedSessionEntityFields.CHAIN_INDEX, true) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo011.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo011.kt deleted file mode 100644 index feaab4bb19..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo011.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator - -// Version 11L added deviceKeysSentToServer boolean to CryptoMetadataEntity -internal class MigrateCryptoTo011(realm: DynamicRealm) : RealmMigrator(realm, 11) { - - override fun doMigrate(realm: DynamicRealm) { - realm.schema.get("CryptoMetadataEntity") - ?.addField(CryptoMetadataEntityFields.DEVICE_KEYS_SENT_TO_SERVER, Boolean::class.java) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo012.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo012.kt deleted file mode 100644 index 4626757a06..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo012.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.OutboundGroupSessionInfoEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator - -// Version 12L added outbound group session persistence -internal class MigrateCryptoTo012(realm: DynamicRealm) : RealmMigrator(realm, 12) { - - override fun doMigrate(realm: DynamicRealm) { - val outboundEntitySchema = realm.schema.create("OutboundGroupSessionInfoEntity") - .addField(OutboundGroupSessionInfoEntityFields.SERIALIZED_OUTBOUND_SESSION_DATA, String::class.java) - .addField(OutboundGroupSessionInfoEntityFields.CREATION_TIME, Long::class.java) - .setNullable(OutboundGroupSessionInfoEntityFields.CREATION_TIME, true) - - realm.schema.get("CryptoRoomEntity") - ?.addRealmObjectField(CryptoRoomEntityFields.OUTBOUND_SESSION_INFO.`$`, outboundEntitySchema) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo013.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo013.kt deleted file mode 100644 index dc8984da41..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo013.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.util.database.RealmMigrator -import timber.log.Timber - -// Version 13L delete unreferenced TrustLevelEntity -internal class MigrateCryptoTo013(realm: DynamicRealm) : RealmMigrator(realm, 13) { - - override fun doMigrate(realm: DynamicRealm) { - // Use a trick to do that... Ref: https://stackoverflow.com/questions/55221366 - val trustLevelEntitySchema = realm.schema.get("TrustLevelEntity") - - /* - Creating a new temp field called isLinked which is set to true for those which are - references by other objects. Rest of them are set to false. Then removing all - those which are false and hence duplicate and unnecessary. Then removing the temp field - isLinked - */ - var mainCounter = 0 - var deviceInfoCounter = 0 - var keyInfoCounter = 0 - val deleteCounter: Int - - trustLevelEntitySchema - ?.addField("isLinked", Boolean::class.java) - ?.transform { obj -> - // Setting to false for all by default - obj.set("isLinked", false) - mainCounter++ - } - - realm.schema.get("DeviceInfoEntity")?.transform { obj -> - // Setting to true for those which are referenced in DeviceInfoEntity - deviceInfoCounter++ - obj.getObject("trustLevelEntity")?.set("isLinked", true) - } - - realm.schema.get("KeyInfoEntity")?.transform { obj -> - // Setting to true for those which are referenced in KeyInfoEntity - keyInfoCounter++ - obj.getObject("trustLevelEntity")?.set("isLinked", true) - } - - // Removing all those which are set as false - realm.where("TrustLevelEntity") - .equalTo("isLinked", false) - .findAll() - .also { deleteCounter = it.size } - .deleteAllFromRealm() - - trustLevelEntitySchema?.removeField("isLinked") - - Timber.w("TrustLevelEntity cleanup: $mainCounter entities") - Timber.w("TrustLevelEntity cleanup: $deviceInfoCounter entities referenced in DeviceInfoEntities") - Timber.w("TrustLevelEntity cleanup: $keyInfoCounter entities referenced in KeyInfoEntity") - Timber.w("TrustLevelEntity cleanup: $deleteCounter entities deleted!") - if (mainCounter != deviceInfoCounter + keyInfoCounter + deleteCounter) { - Timber.e("TrustLevelEntity cleanup: Something is not correct...") - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo014.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo014.kt deleted file mode 100644 index 548672790a..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo014.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator - -// Version 14L Update the way we remember key sharing -internal class MigrateCryptoTo014(realm: DynamicRealm) : RealmMigrator(realm, 14) { - - override fun doMigrate(realm: DynamicRealm) { - realm.schema.get("SharedSessionEntity") - ?.addField(SharedSessionEntityFields.DEVICE_IDENTITY_KEY, String::class.java) - ?.addIndex(SharedSessionEntityFields.DEVICE_IDENTITY_KEY) - ?.transform { - val sharedUserId = it.getString(SharedSessionEntityFields.USER_ID) - val sharedDeviceId = it.getString(SharedSessionEntityFields.DEVICE_ID) - val knownDevice = realm.where("DeviceInfoEntity") - .equalTo(DeviceInfoEntityFields.USER_ID, sharedUserId) - .equalTo(DeviceInfoEntityFields.DEVICE_ID, sharedDeviceId) - .findFirst() - it.setString(SharedSessionEntityFields.DEVICE_IDENTITY_KEY, knownDevice?.getString(DeviceInfoEntityFields.IDENTITY_KEY)) - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt deleted file mode 100644 index bca02c2e6e..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator - -// Version 15L adds wasEncryptedOnce field to CryptoRoomEntity -internal class MigrateCryptoTo015(realm: DynamicRealm) : RealmMigrator(realm, 15) { - - override fun doMigrate(realm: DynamicRealm) { - realm.schema.get("CryptoRoomEntity") - ?.addField(CryptoRoomEntityFields.WAS_ENCRYPTED_ONCE, Boolean::class.java) - ?.setNullable(CryptoRoomEntityFields.WAS_ENCRYPTED_ONCE, true) - ?.transform { - val currentAlgorithm = it.getString(CryptoRoomEntityFields.ALGORITHM) - it.set(CryptoRoomEntityFields.WAS_ENCRYPTED_ONCE, currentAlgorithm == MXCRYPTO_ALGORITHM_MEGOLM) - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo016.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo016.kt deleted file mode 100644 index 5a14ebf85a..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo016.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.AuditTrailEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.KeyRequestReplyEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingKeyRequestEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator - -internal class MigrateCryptoTo016(realm: DynamicRealm) : RealmMigrator(realm, 16) { - - override fun doMigrate(realm: DynamicRealm) { - realm.schema.remove("OutgoingGossipingRequestEntity") - realm.schema.remove("IncomingGossipingRequestEntity") - realm.schema.remove("GossipingEventEntity") - - // No need to migrate existing request, just start fresh - - val replySchema = realm.schema.create("KeyRequestReplyEntity") - .addField(KeyRequestReplyEntityFields.SENDER_ID, String::class.java) - .addField(KeyRequestReplyEntityFields.FROM_DEVICE, String::class.java) - .addField(KeyRequestReplyEntityFields.EVENT_JSON, String::class.java) - - realm.schema.create("OutgoingKeyRequestEntity") - .addField(OutgoingKeyRequestEntityFields.REQUEST_ID, String::class.java) - .addIndex(OutgoingKeyRequestEntityFields.REQUEST_ID) - .addField(OutgoingKeyRequestEntityFields.MEGOLM_SESSION_ID, String::class.java) - .addIndex(OutgoingKeyRequestEntityFields.MEGOLM_SESSION_ID) - .addRealmListField(OutgoingKeyRequestEntityFields.REPLIES.`$`, replySchema) - .addField(OutgoingKeyRequestEntityFields.RECIPIENTS_DATA, String::class.java) - .addField(OutgoingKeyRequestEntityFields.REQUEST_STATE_STR, String::class.java) - .addIndex(OutgoingKeyRequestEntityFields.REQUEST_STATE_STR) - .addField(OutgoingKeyRequestEntityFields.REQUESTED_INFO_STR, String::class.java) - .addField(OutgoingKeyRequestEntityFields.ROOM_ID, String::class.java) - .addIndex(OutgoingKeyRequestEntityFields.ROOM_ID) - .addField(OutgoingKeyRequestEntityFields.REQUESTED_INDEX, Integer::class.java) - .addField(OutgoingKeyRequestEntityFields.CREATION_TIME_STAMP, Long::class.java) - .setNullable(OutgoingKeyRequestEntityFields.CREATION_TIME_STAMP, true) - - realm.schema.create("AuditTrailEntity") - .addField(AuditTrailEntityFields.AGE_LOCAL_TS, Long::class.java) - .setNullable(AuditTrailEntityFields.AGE_LOCAL_TS, true) - .addField(AuditTrailEntityFields.CONTENT_JSON, String::class.java) - .addField(AuditTrailEntityFields.TYPE, String::class.java) - .addIndex(AuditTrailEntityFields.TYPE) - - realm.schema.get("CryptoMetadataEntity") - ?.addField(CryptoMetadataEntityFields.GLOBAL_ENABLE_KEY_GOSSIPING, Boolean::class.java) - ?.transform { - // set the default value to true - it.setBoolean(CryptoMetadataEntityFields.GLOBAL_ENABLE_KEY_GOSSIPING, true) - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo017.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo017.kt deleted file mode 100644 index 8904c412cd..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo017.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.internal.crypto.model.InboundGroupSessionData -import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.OutboundGroupSessionInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm -import org.matrix.android.sdk.internal.di.MoshiProvider -import org.matrix.android.sdk.internal.util.database.RealmMigrator -import timber.log.Timber - -/** - * Version 17L enhance OlmInboundGroupSessionEntity to support shared history for MSC3061. - * Also migrates how megolm session are stored to avoid additional serialized frozen class. - */ -internal class MigrateCryptoTo017(realm: DynamicRealm) : RealmMigrator(realm, 17) { - - override fun doMigrate(realm: DynamicRealm) { - realm.schema.get("CryptoRoomEntity") - ?.addField(CryptoRoomEntityFields.SHOULD_SHARE_HISTORY, Boolean::class.java)?.transform { - // We don't have access to the session database to check for the state here and set the good value. - // But for now as it's behind a lab flag, will set to false and force initial sync when enabled - it.setBoolean(CryptoRoomEntityFields.SHOULD_SHARE_HISTORY, false) - } - - realm.schema.get("OutboundGroupSessionInfoEntity") - ?.addField(OutboundGroupSessionInfoEntityFields.SHOULD_SHARE_HISTORY, Boolean::class.java)?.transform { - // We don't have access to the session database to check for the state here and set the good value. - // But for now as it's behind a lab flag, will set to false and force initial sync when enabled - it.setBoolean(OutboundGroupSessionInfoEntityFields.SHOULD_SHARE_HISTORY, false) - } - - realm.schema.get("CryptoMetadataEntity") - ?.addField(CryptoMetadataEntityFields.ENABLE_KEY_FORWARDING_ON_INVITE, Boolean::class.java) - ?.transform { obj -> - // default to false - obj.setBoolean(CryptoMetadataEntityFields.ENABLE_KEY_FORWARDING_ON_INVITE, false) - } - - val moshiAdapter = MoshiProvider.providesMoshi().adapter(InboundGroupSessionData::class.java) - - realm.schema.get("OlmInboundGroupSessionEntity") - ?.addField(OlmInboundGroupSessionEntityFields.SHARED_HISTORY, Boolean::class.java) - ?.addField(OlmInboundGroupSessionEntityFields.ROOM_ID, String::class.java) - ?.addField(OlmInboundGroupSessionEntityFields.INBOUND_GROUP_SESSION_DATA_JSON, String::class.java) - ?.addField(OlmInboundGroupSessionEntityFields.SERIALIZED_OLM_INBOUND_GROUP_SESSION, String::class.java) - ?.transform { dynamicObject -> - try { - // we want to convert the old wrapper frozen class into a - // map of sessionData & the pickled session herself - dynamicObject.getString(OlmInboundGroupSessionEntityFields.OLM_INBOUND_GROUP_SESSION_DATA)?.let { oldData -> - val oldWrapper = tryOrNull("Failed to convert megolm inbound group data") { - @Suppress("DEPRECATION") - deserializeFromRealm(oldData) - } - val groupSession = oldWrapper?.olmInboundGroupSession - ?: return@transform Unit.also { - Timber.w("Failed to migrate megolm session, no olmInboundGroupSession") - } - // now convert to new data - val data = InboundGroupSessionData( - senderKey = oldWrapper.senderKey, - roomId = oldWrapper.roomId, - keysClaimed = oldWrapper.keysClaimed, - forwardingCurve25519KeyChain = oldWrapper.forwardingCurve25519KeyChain, - sharedHistory = false, - ) - - dynamicObject.setString(OlmInboundGroupSessionEntityFields.INBOUND_GROUP_SESSION_DATA_JSON, moshiAdapter.toJson(data)) - dynamicObject.setString(OlmInboundGroupSessionEntityFields.SERIALIZED_OLM_INBOUND_GROUP_SESSION, serializeForRealm(groupSession)) - - // denormalized fields - dynamicObject.setString(OlmInboundGroupSessionEntityFields.ROOM_ID, oldWrapper.roomId) - dynamicObject.setBoolean(OlmInboundGroupSessionEntityFields.SHARED_HISTORY, false) - } - } catch (failure: Throwable) { - Timber.e(failure, "Failed to migrate megolm session") - } - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo018.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo018.kt deleted file mode 100644 index 3bedf58ca2..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo018.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.model.InboundGroupSessionData -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields -import org.matrix.android.sdk.internal.di.MoshiProvider -import org.matrix.android.sdk.internal.util.database.RealmMigrator -import timber.log.Timber - -/** - * This migration is adding support for trusted flags on megolm sessions. - * We can't really assert the trust of existing keys, so for the sake of simplicity we are going to - * mark existing keys as safe. - * This migration can take long depending on the account - */ -internal class MigrateCryptoTo018(realm: DynamicRealm) : RealmMigrator(realm, 18) { - - private val moshiAdapter = MoshiProvider.providesMoshi().adapter(InboundGroupSessionData::class.java) - - override fun doMigrate(realm: DynamicRealm) { - realm.schema.get("OlmInboundGroupSessionEntity") - ?.transform { dynamicObject -> - try { - dynamicObject.getString(OlmInboundGroupSessionEntityFields.INBOUND_GROUP_SESSION_DATA_JSON)?.let { oldData -> - moshiAdapter.fromJson(oldData)?.let { dataToMigrate -> - dataToMigrate.copy(trusted = true).let { - dynamicObject.setString(OlmInboundGroupSessionEntityFields.INBOUND_GROUP_SESSION_DATA_JSON, moshiAdapter.toJson(it)) - } - } - } - } catch (failure: Throwable) { - Timber.e(failure, "Failed to migrate megolm session") - } - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo019.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo019.kt deleted file mode 100644 index 65280300ab..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo019.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import io.realm.DynamicRealmObject -import org.matrix.android.sdk.api.session.crypto.crosssigning.KeyUsage -import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.KeyInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.TrustLevelEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator - -/** - * This migration is adding support for trusted flags on megolm sessions. - * We can't really assert the trust of existing keys, so for the sake of simplicity we are going to - * mark existing keys as safe. - * This migration can take long depending on the account - */ -internal class MigrateCryptoTo019(realm: DynamicRealm) : RealmMigrator(realm, 19) { - - override fun doMigrate(realm: DynamicRealm) { - realm.schema.get("CrossSigningInfoEntity") - ?.addField(CrossSigningInfoEntityFields.WAS_USER_VERIFIED_ONCE, Boolean::class.java) - ?.transform { dynamicObject -> - - val knowKeys = dynamicObject.getList(CrossSigningInfoEntityFields.CROSS_SIGNING_KEYS.`$`) - val msk = knowKeys.firstOrNull { - it.getList(KeyInfoEntityFields.USAGES.`$`, String::class.java).orEmpty().contains(KeyUsage.MASTER.value) - } - val ssk = knowKeys.firstOrNull { - it.getList(KeyInfoEntityFields.USAGES.`$`, String::class.java).orEmpty().contains(KeyUsage.SELF_SIGNING.value) - } - val isTrusted = isDynamicKeyInfoTrusted(msk?.get(KeyInfoEntityFields.TRUST_LEVEL_ENTITY.`$`)) && - isDynamicKeyInfoTrusted(ssk?.get(KeyInfoEntityFields.TRUST_LEVEL_ENTITY.`$`)) - - dynamicObject.setBoolean(CrossSigningInfoEntityFields.WAS_USER_VERIFIED_ONCE, isTrusted) - } - } - - private fun isDynamicKeyInfoTrusted(keyInfo: DynamicRealmObject?): Boolean { - if (keyInfo == null) return false - return !keyInfo.isNull(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED) && keyInfo.getBoolean(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED) && - !keyInfo.isNull(TrustLevelEntityFields.LOCALLY_VERIFIED) && keyInfo.getBoolean(TrustLevelEntityFields.LOCALLY_VERIFIED) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo020.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo020.kt deleted file mode 100644 index 44d07ab538..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo020.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator - -/** - * This migration adds a new field into MyDeviceLastSeenInfoEntity corresponding to the last seen user agent. - */ -internal class MigrateCryptoTo020(realm: DynamicRealm) : RealmMigrator(realm, 20) { - - override fun doMigrate(realm: DynamicRealm) { - realm.schema.get("MyDeviceLastSeenInfoEntity") - ?.addField(MyDeviceLastSeenInfoEntityFields.LAST_SEEN_USER_AGENT, String::class.java) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo021.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo021.kt deleted file mode 100644 index a90614e53f..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo021.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2023 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.api.crypto.MEGOLM_DEFAULT_ROTATION_MSGS -import org.matrix.android.sdk.api.crypto.MEGOLM_DEFAULT_ROTATION_PERIOD_MS -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator - -/** - * This migration stores the rotation parameters for megolm oubound sessions. - */ -internal class MigrateCryptoTo021(realm: DynamicRealm) : RealmMigrator(realm, 21) { - - override fun doMigrate(realm: DynamicRealm) { - realm.schema.get("CryptoRoomEntity") - ?.addField(CryptoRoomEntityFields.ROTATION_PERIOD_MS, Long::class.java) - ?.setNullable(CryptoRoomEntityFields.ROTATION_PERIOD_MS, true) - ?.addField(CryptoRoomEntityFields.ROTATION_PERIOD_MSGS, Long::class.java) - ?.setNullable(CryptoRoomEntityFields.ROTATION_PERIOD_MSGS, true) - ?.transform { - // As a migration we set the default (will be on par with existing code) - // A clear cache will have the correct values. - it.setLong(CryptoRoomEntityFields.ROTATION_PERIOD_MS, MEGOLM_DEFAULT_ROTATION_PERIOD_MS) - it.setLong(CryptoRoomEntityFields.ROTATION_PERIOD_MSGS, MEGOLM_DEFAULT_ROTATION_MSGS) - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo022.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo022.kt deleted file mode 100644 index 5d1119778d..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo022.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2023 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.RustEncryptionConfiguration -import org.matrix.android.sdk.internal.session.MigrateEAtoEROperation -import org.matrix.android.sdk.internal.util.database.RealmMigrator -import java.io.File - -/** - * This migration creates the rust database and migrates from legacy crypto. - */ -internal class MigrateCryptoTo022( - realm: DynamicRealm, - private val rustDirectory: File, - private val rustEncryptionConfiguration: RustEncryptionConfiguration, - private val migrateMegolmGroupSessions: Boolean = false -) : RealmMigrator( - realm, - 22 -) { - override fun doMigrate(realm: DynamicRealm) { - // Migrate to rust! - val migrateOperation = MigrateEAtoEROperation(migrateMegolmGroupSessions) - migrateOperation.dynamicExecute(realm, rustDirectory, rustEncryptionConfiguration.getDatabasePassphrase()) - - // wa can't delete all for now, but we can do some cleaning - realm.schema.get("OlmSessionEntity")?.transform { - it.deleteFromRealm() - } - - // a future migration will clean the rest - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo023.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo023.kt deleted file mode 100644 index 1302b452bd..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo023.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2024 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration - -import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingKeyRequestEntityFields -import org.matrix.android.sdk.internal.util.database.RealmMigrator - -// Some fields are now required due to upgrade of Kotlin version. -// See https://github.com/realm/realm-java/issues/7810 for more details. -internal class MigrateCryptoTo023(realm: DynamicRealm) : RealmMigrator(realm, 23) { - override fun doMigrate(realm: DynamicRealm) { - realm.schema.get("OutgoingKeyRequestEntity") - ?.setRequired(OutgoingKeyRequestEntityFields.REQUEST_STATE_STR, true) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo024.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo024.kt new file mode 100644 index 0000000000..9a87eb4741 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo024.kt @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +internal class MigrateCryptoTo024(realm: DynamicRealm) : RealmMigrator(realm, 24) { + /** + * Delete the whole DB, except tables that are still used to store data. + * Keep: + * - CryptoMetadataEntity + * - MyDeviceLastSeenInfoEntity + * - CryptoRoomEntity (but remove unused member 'outboundSessionInfo: OutboundGroupSessionInfoEntity') + */ + override fun doMigrate(realm: DynamicRealm) { + with(realm.schema) { + get("CryptoRoomEntity")?.removeField("outboundSessionInfo") + + // Warning: order is important, first remove classes that depends on others. + remove("UserEntity") + remove("DeviceInfoEntity") + remove("CrossSigningInfoEntity") + remove("KeyInfoEntity") + remove("TrustLevelEntity") + remove("KeysBackupDataEntity") + remove("OlmInboundGroupSessionEntity") + remove("OlmSessionEntity") + remove("AuditTrailEntity") + remove("OutgoingKeyRequestEntity") + remove("KeyRequestReplyEntity") + remove("WithHeldSessionEntity") + remove("SharedSessionEntity") + remove("OutboundGroupSessionInfoEntity") + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/ExtractMigrationDataFailure.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/ExtractMigrationDataFailure.kt deleted file mode 100644 index fb4bd1c8fe..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/ExtractMigrationDataFailure.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration.rust - -data class ExtractMigrationDataFailure(override val cause: Throwable) : - java.lang.RuntimeException("Can't proceed with migration, crypto store is empty or some necessary data is missing.", cause) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/ExtractMigrationDataUseCase.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/ExtractMigrationDataUseCase.kt deleted file mode 100644 index 3dae9a6b13..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/ExtractMigrationDataUseCase.kt +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration.rust - -import io.realm.Realm -import io.realm.RealmConfiguration -import io.realm.kotlin.where -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity -import org.matrix.olm.OlmUtility -import org.matrix.rustcomponents.sdk.crypto.MigrationData -import timber.log.Timber -import kotlin.system.measureTimeMillis - -internal class ExtractMigrationDataUseCase(private val migrateGroupSessions: Boolean = false) { - - fun extractData(realm: RealmToMigrate, importPartial: ((MigrationData) -> Unit)) { - return try { - extract(realm, importPartial) - } catch (failure: Throwable) { - throw ExtractMigrationDataFailure(failure) - } - } - - fun hasExistingData(realmConfiguration: RealmConfiguration): Boolean { - return Realm.getInstance(realmConfiguration).use { realm -> - !realm.isEmpty && - // Check if there is a MetaData object - realm.where().count() > 0 && - realm.where().findFirst()?.olmAccountData != null - } - } - - private fun extract(realm: RealmToMigrate, importPartial: ((MigrationData) -> Unit)) { - val pickleKey = OlmUtility.getRandomKey() - - val baseExtract = realm.getPickledAccount(pickleKey) - // import the account asap - importPartial(baseExtract) - - val chunkSize = 500 - realm.trackedUsersChunk(500) { - importPartial( - baseExtract.copy(trackedUsers = it) - ) - } - - var migratedOlmSessionCount = 0 - var writeTime = 0L - measureTimeMillis { - realm.pickledOlmSessions(pickleKey, chunkSize) { pickledSessions -> - migratedOlmSessionCount += pickledSessions.size - measureTimeMillis { - importPartial( - baseExtract.copy(sessions = pickledSessions) - ) - }.also { writeTime += it } - } - }.also { - Timber.i("Migration: took $it ms to migrate $migratedOlmSessionCount olm sessions") - Timber.i("Migration: rust import time $writeTime") - } - - // We don't migrate outbound session by default directly after migration - // We are going to do it lazyly when decryption fails - if (migrateGroupSessions) { - var migratedInboundGroupSessionCount = 0 - measureTimeMillis { - realm.pickledOlmGroupSessions(pickleKey, chunkSize) { pickledSessions -> - migratedInboundGroupSessionCount += pickledSessions.size - measureTimeMillis { - importPartial( - baseExtract.copy(inboundGroupSessions = pickledSessions) - ) - }.also { writeTime += it } - } - }.also { - Timber.i("Migration: took $it ms to migrate $migratedInboundGroupSessionCount group sessions") - Timber.i("Migration: rust import time $writeTime") - } - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/RealmToMigrate.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/RealmToMigrate.kt deleted file mode 100644 index 7f9e7e212a..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/RealmToMigrate.kt +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (c) 2023 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.migration.rust - -import io.realm.kotlin.where -import okhttp3.internal.toImmutableList -import org.matrix.android.sdk.api.extensions.orFalse -import org.matrix.android.sdk.internal.crypto.model.InboundGroupSessionData -import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields -import org.matrix.android.sdk.internal.di.MoshiProvider -import org.matrix.olm.OlmAccount -import org.matrix.olm.OlmInboundGroupSession -import org.matrix.olm.OlmSession -import org.matrix.rustcomponents.sdk.crypto.CrossSigningKeyExport -import org.matrix.rustcomponents.sdk.crypto.MigrationData -import org.matrix.rustcomponents.sdk.crypto.PickledAccount -import org.matrix.rustcomponents.sdk.crypto.PickledInboundGroupSession -import org.matrix.rustcomponents.sdk.crypto.PickledSession -import timber.log.Timber -import java.nio.charset.Charset - -sealed class RealmToMigrate { - data class DynamicRealm(val realm: io.realm.DynamicRealm) : RealmToMigrate() - data class ClassicRealm(val realm: io.realm.Realm) : RealmToMigrate() -} - -fun RealmToMigrate.hasExistingData(): Boolean { - return when (this) { - is RealmToMigrate.ClassicRealm -> { - !this.realm.isEmpty && - // Check if there is a MetaData object - this.realm.where().count() > 0 && - this.realm.where().findFirst()?.olmAccountData != null - } - is RealmToMigrate.DynamicRealm -> { - return true - } - } -} - -@Throws -fun RealmToMigrate.getPickledAccount(pickleKey: ByteArray): MigrationData { - return when (this) { - is RealmToMigrate.ClassicRealm -> { - val metadataEntity = realm.where().findFirst() - ?: throw java.lang.IllegalArgumentException("Rust db migration: No existing metadataEntity") - - val masterKey = metadataEntity.xSignMasterPrivateKey - val userKey = metadataEntity.xSignUserPrivateKey - val selfSignedKey = metadataEntity.xSignSelfSignedPrivateKey - - Timber.i("## Migration: has private MSK ${masterKey.isNullOrBlank().not()}") - Timber.i("## Migration: has private USK ${userKey.isNullOrBlank().not()}") - Timber.i("## Migration: has private SSK ${selfSignedKey.isNullOrBlank().not()}") - - val userId = metadataEntity.userId - ?: throw java.lang.IllegalArgumentException("Rust db migration: userId is null") - val deviceId = metadataEntity.deviceId - ?: throw java.lang.IllegalArgumentException("Rust db migration: deviceID is null") - - val backupVersion = metadataEntity.backupVersion - val backupRecoveryKey = metadataEntity.keyBackupRecoveryKey - - Timber.i("## Migration: has private backup key ${backupRecoveryKey != null} for version $backupVersion") - - val isOlmAccountShared = metadataEntity.deviceKeysSentToServer - - val olmAccount = metadataEntity.getOlmAccount() - ?: throw java.lang.IllegalArgumentException("Rust db migration: No existing account") - val pickledOlmAccount = olmAccount.pickle(pickleKey, StringBuffer()).asString() - - val pickledAccount = PickledAccount( - userId = userId, - deviceId = deviceId, - pickle = pickledOlmAccount, - shared = isOlmAccountShared, - uploadedSignedKeyCount = 50 - ) - MigrationData( - account = pickledAccount, - pickleKey = pickleKey, - crossSigning = CrossSigningKeyExport( - masterKey = masterKey, - selfSigningKey = selfSignedKey, - userSigningKey = userKey - ), - sessions = emptyList(), - backupRecoveryKey = backupRecoveryKey, - trackedUsers = emptyList(), - inboundGroupSessions = emptyList(), - backupVersion = backupVersion, - // TODO import room settings from legacy DB - roomSettings = emptyMap() - ) - } - is RealmToMigrate.DynamicRealm -> { - val cryptoMetadataEntitySchema = realm.schema.get("CryptoMetadataEntity") - ?: throw java.lang.IllegalStateException("Missing Metadata entity") - - var migrationData: MigrationData? = null - cryptoMetadataEntitySchema.transform { dynMetaData -> - - val serializedOlmAccount = dynMetaData.getString(CryptoMetadataEntityFields.OLM_ACCOUNT_DATA) - - val masterKey = dynMetaData.getString(CryptoMetadataEntityFields.X_SIGN_MASTER_PRIVATE_KEY) - val userKey = dynMetaData.getString(CryptoMetadataEntityFields.X_SIGN_USER_PRIVATE_KEY) - val selfSignedKey = dynMetaData.getString(CryptoMetadataEntityFields.X_SIGN_SELF_SIGNED_PRIVATE_KEY) - - val userId = dynMetaData.getString(CryptoMetadataEntityFields.USER_ID) - ?: throw java.lang.IllegalArgumentException("Rust db migration: userId is null") - val deviceId = dynMetaData.getString(CryptoMetadataEntityFields.DEVICE_ID) - ?: throw java.lang.IllegalArgumentException("Rust db migration: deviceID is null") - - val backupVersion = dynMetaData.getString(CryptoMetadataEntityFields.BACKUP_VERSION) - val backupRecoveryKey = dynMetaData.getString(CryptoMetadataEntityFields.KEY_BACKUP_RECOVERY_KEY) - - val isOlmAccountShared = dynMetaData.getBoolean(CryptoMetadataEntityFields.DEVICE_KEYS_SENT_TO_SERVER) - - val olmAccount = deserializeFromRealm(serializedOlmAccount) - ?: throw java.lang.IllegalArgumentException("Rust db migration: No existing account") - - val pickledOlmAccount = olmAccount.pickle(pickleKey, StringBuffer()).asString() - - val pickledAccount = PickledAccount( - userId = userId, - deviceId = deviceId, - pickle = pickledOlmAccount, - shared = isOlmAccountShared, - uploadedSignedKeyCount = 50 - ) - - migrationData = MigrationData( - account = pickledAccount, - pickleKey = pickleKey, - crossSigning = CrossSigningKeyExport( - masterKey = masterKey, - selfSigningKey = selfSignedKey, - userSigningKey = userKey - ), - sessions = emptyList(), - backupRecoveryKey = backupRecoveryKey, - trackedUsers = emptyList(), - inboundGroupSessions = emptyList(), - backupVersion = backupVersion, - // TODO import room settings from legacy DB - roomSettings = emptyMap() - ) - } - migrationData!! - } - } -} - -fun RealmToMigrate.trackedUsersChunk(chunkSize: Int, onChunk: ((List) -> Unit)) { - when (this) { - is RealmToMigrate.ClassicRealm -> { - realm.where() - .findAll() - .chunked(chunkSize) - .onEach { - onChunk(it.mapNotNull { it.userId }) - } - } - is RealmToMigrate.DynamicRealm -> { - val userList = mutableListOf() - realm.schema.get("UserEntity")?.transform { - val userId = it.getString(UserEntityFields.USER_ID) - // should we check the tracking status? - userList.add(userId) - if (userList.size > chunkSize) { - onChunk(userList.toImmutableList()) - userList.clear() - } - } - if (userList.isNotEmpty()) { - onChunk(userList) - } - } - } -} - -fun RealmToMigrate.pickledOlmSessions(pickleKey: ByteArray, chunkSize: Int, onChunk: ((List) -> Unit)) { - when (this) { - is RealmToMigrate.ClassicRealm -> { - realm.where().findAll() - .chunked(chunkSize) { chunk -> - val export = chunk.map { it.toPickledSession(pickleKey) } - onChunk(export) - } - } - is RealmToMigrate.DynamicRealm -> { - val pickledSessions = mutableListOf() - realm.schema.get("OlmSessionEntity")?.transform { - val sessionData = it.getString(OlmSessionEntityFields.OLM_SESSION_DATA) - val deviceKey = it.getString(OlmSessionEntityFields.DEVICE_KEY) - val lastReceivedMessageTs = it.getLong(OlmSessionEntityFields.LAST_RECEIVED_MESSAGE_TS) - val olmSession = deserializeFromRealm(sessionData)!! - val pickle = olmSession.pickle(pickleKey, StringBuffer()).asString() - val pickledSession = PickledSession( - pickle = pickle, - senderKey = deviceKey, - createdUsingFallbackKey = false, - // / Unix timestamp (in seconds) when the session was created. - creationTime = (lastReceivedMessageTs / 1000).toULong(), - // / Unix timestamp (in seconds) when the session was last used. - lastUseTime = (lastReceivedMessageTs / 1000).toULong(), - ) - // should we check the tracking status? - pickledSessions.add(pickledSession) - if (pickledSessions.size > chunkSize) { - onChunk(pickledSessions.toImmutableList()) - pickledSessions.clear() - } - } - if (pickledSessions.isNotEmpty()) { - onChunk(pickledSessions) - } - } - } -} - -private val sessionDataAdapter = MoshiProvider.providesMoshi() - .adapter(InboundGroupSessionData::class.java) -fun RealmToMigrate.pickledOlmGroupSessions(pickleKey: ByteArray, chunkSize: Int, onChunk: ((List) -> Unit)) { - when (this) { - is RealmToMigrate.ClassicRealm -> { - realm.where() - .findAll() - .chunked(chunkSize) { chunk -> - val export = chunk.mapNotNull { it.toPickledInboundGroupSession(pickleKey) } - onChunk(export) - } - } - is RealmToMigrate.DynamicRealm -> { - val pickledSessions = mutableListOf() - realm.schema.get("OlmInboundGroupSessionEntity")?.transform { - val senderKey = it.getString(OlmInboundGroupSessionEntityFields.SENDER_KEY) - val roomId = it.getString(OlmInboundGroupSessionEntityFields.ROOM_ID) - val backedUp = it.getBoolean(OlmInboundGroupSessionEntityFields.BACKED_UP) - val serializedOlmInboundGroupSession = it.getString(OlmInboundGroupSessionEntityFields.SERIALIZED_OLM_INBOUND_GROUP_SESSION) - val inboundSession = deserializeFromRealm(serializedOlmInboundGroupSession) ?: return@transform Unit.also { - Timber.w("Rust db migration: Failed to migrated group session, no meta data") - } - val sessionData = it.getString(OlmInboundGroupSessionEntityFields.INBOUND_GROUP_SESSION_DATA_JSON).let { json -> - sessionDataAdapter.fromJson(json) - } ?: return@transform Unit.also { - Timber.w("Rust db migration: Failed to migrated group session, no meta data") - } - val pickle = inboundSession.pickle(pickleKey, StringBuffer()).asString() - val pickledSession = PickledInboundGroupSession( - pickle = pickle, - senderKey = senderKey, - signingKey = sessionData.keysClaimed.orEmpty(), - roomId = roomId, - forwardingChains = sessionData.forwardingCurve25519KeyChain.orEmpty(), - imported = sessionData.trusted.orFalse().not(), - backedUp = backedUp - ) - // should we check the tracking status? - pickledSessions.add(pickledSession) - if (pickledSessions.size > chunkSize) { - onChunk(pickledSessions.toImmutableList()) - pickledSessions.clear() - } - } - if (pickledSessions.isNotEmpty()) { - onChunk(pickledSessions) - } - } - } -} - -private fun OlmInboundGroupSessionEntity.toPickledInboundGroupSession(pickleKey: ByteArray): PickledInboundGroupSession? { - val senderKey = this.senderKey ?: return null - val backedUp = this.backedUp - val olmInboundGroupSession = this.getOlmGroupSession() ?: return null.also { - Timber.w("Rust db migration: Failed to migrated group session $sessionId") - } - val data = this.getData() ?: return null.also { - Timber.w("Rust db migration: Failed to migrated group session $sessionId, no meta data") - } - val roomId = data.roomId ?: return null.also { - Timber.w("Rust db migration: Failed to migrated group session $sessionId, no roomId") - } - val pickledInboundGroupSession = olmInboundGroupSession.pickle(pickleKey, StringBuffer()).asString() - return PickledInboundGroupSession( - pickle = pickledInboundGroupSession, - senderKey = senderKey, - signingKey = data.keysClaimed.orEmpty(), - roomId = roomId, - forwardingChains = data.forwardingCurve25519KeyChain.orEmpty(), - imported = data.trusted.orFalse().not(), - backedUp = backedUp - ) -} -private fun OlmSessionEntity.toPickledSession(pickleKey: ByteArray): PickledSession { - val deviceKey = this.deviceKey ?: "" - val lastReceivedMessageTs = this.lastReceivedMessageTs - val olmSessionStr = this.olmSessionData - val olmSession = deserializeFromRealm(olmSessionStr)!! - val pickledOlmSession = olmSession.pickle(pickleKey, StringBuffer()).asString() - return PickledSession( - pickle = pickledOlmSession, - senderKey = deviceKey, - createdUsingFallbackKey = false, - // Rust expect in seconds - creationTime = (lastReceivedMessageTs / 1000).toULong(), - // Rust expect in seconds - lastUseTime = (lastReceivedMessageTs / 1000).toULong(), - ) -} - -private val charset = Charset.forName("UTF-8") -private fun ByteArray.asString() = String(this, charset) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/AuditTrailEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/AuditTrailEntity.kt deleted file mode 100644 index 2e0e9c8c8b..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/AuditTrailEntity.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.model - -import io.realm.RealmObject -import io.realm.annotations.Index - -internal open class AuditTrailEntity( - var ageLocalTs: Long? = null, - @Index var type: String? = null, - var contentJson: String? = null -) : RealmObject() { - companion object -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/AuditTrailMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/AuditTrailMapper.kt deleted file mode 100644 index fe8e9f1db7..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/AuditTrailMapper.kt +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.model - -import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.api.session.crypto.model.AuditTrail -import org.matrix.android.sdk.api.session.crypto.model.ForwardInfo -import org.matrix.android.sdk.api.session.crypto.model.IncomingKeyRequestInfo -import org.matrix.android.sdk.api.session.crypto.model.TrailType -import org.matrix.android.sdk.api.session.crypto.model.UnknownInfo -import org.matrix.android.sdk.api.session.crypto.model.WithheldInfo -import org.matrix.android.sdk.internal.di.MoshiProvider - -internal object AuditTrailMapper { - - fun map(entity: AuditTrailEntity): AuditTrail? { - val contentJson = entity.contentJson ?: return null - return when (entity.type) { - TrailType.OutgoingKeyForward.name -> { - val info = tryOrNull { - MoshiProvider.providesMoshi().adapter(ForwardInfo::class.java).fromJson(contentJson) - } ?: return null - AuditTrail( - ageLocalTs = entity.ageLocalTs ?: 0, - type = TrailType.OutgoingKeyForward, - info = info - ) - } - TrailType.OutgoingKeyWithheld.name -> { - val info = tryOrNull { - MoshiProvider.providesMoshi().adapter(WithheldInfo::class.java).fromJson(contentJson) - } ?: return null - AuditTrail( - ageLocalTs = entity.ageLocalTs ?: 0, - type = TrailType.OutgoingKeyWithheld, - info = info - ) - } - TrailType.IncomingKeyRequest.name -> { - val info = tryOrNull { - MoshiProvider.providesMoshi().adapter(IncomingKeyRequestInfo::class.java).fromJson(contentJson) - } ?: return null - AuditTrail( - ageLocalTs = entity.ageLocalTs ?: 0, - type = TrailType.IncomingKeyRequest, - info = info - ) - } - TrailType.IncomingKeyForward.name -> { - val info = tryOrNull { - MoshiProvider.providesMoshi().adapter(ForwardInfo::class.java).fromJson(contentJson) - } ?: return null - AuditTrail( - ageLocalTs = entity.ageLocalTs ?: 0, - type = TrailType.IncomingKeyForward, - info = info - ) - } - else -> { - AuditTrail( - ageLocalTs = entity.ageLocalTs ?: 0, - type = TrailType.Unknown, - info = UnknownInfo - ) - } - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt deleted file mode 100644 index 033b7662c5..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.model - -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import org.matrix.android.sdk.api.session.crypto.crosssigning.KeyUsage -import org.matrix.android.sdk.internal.extensions.clearWith - -internal open class CrossSigningInfoEntity( - @PrimaryKey - var userId: String? = null, - var wasUserVerifiedOnce: Boolean = false, - var crossSigningKeys: RealmList = RealmList() -) : RealmObject() { - - companion object - - fun getMasterKey() = crossSigningKeys.firstOrNull { it.usages.contains(KeyUsage.MASTER.value) } - - fun setMasterKey(info: KeyInfoEntity?) { - crossSigningKeys - .filter { it.usages.contains(KeyUsage.MASTER.value) } - .forEach { crossSigningKeys.remove(it) } - info?.let { crossSigningKeys.add(it) } - } - - fun getSelfSignedKey() = crossSigningKeys.firstOrNull { it.usages.contains(KeyUsage.SELF_SIGNING.value) } - - fun setSelfSignedKey(info: KeyInfoEntity?) { - crossSigningKeys - .filter { it.usages.contains(KeyUsage.SELF_SIGNING.value) } - .forEach { crossSigningKeys.remove(it) } - info?.let { crossSigningKeys.add(it) } - } - - fun getUserSigningKey() = crossSigningKeys.firstOrNull { it.usages.contains(KeyUsage.USER_SIGNING.value) } - - fun setUserSignedKey(info: KeyInfoEntity?) { - crossSigningKeys - .filter { it.usages.contains(KeyUsage.USER_SIGNING.value) } - .forEach { crossSigningKeys.remove(it) } - info?.let { crossSigningKeys.add(it) } - } -} - -internal fun CrossSigningInfoEntity.deleteOnCascade() { - crossSigningKeys.clearWith { it.deleteOnCascade() } - deleteFromRealm() -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMapper.kt deleted file mode 100644 index ca41930f80..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMapper.kt +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.crypto.store.db.model - -import com.squareup.moshi.Moshi -import com.squareup.moshi.Types -import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.api.session.crypto.model.UnsignedDeviceInfo -import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.di.SerializeNulls -import timber.log.Timber - -internal object CryptoMapper { - - private val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build() - private val listMigrationAdapter = moshi.adapter>( - Types.newParameterizedType( - List::class.java, - String::class.java, - Any::class.java - ) - ) - private val mapMigrationAdapter = moshi.adapter( - Types.newParameterizedType( - Map::class.java, - String::class.java, - Any::class.java - ) - ) - private val mapOfStringMigrationAdapter = moshi.adapter>>( - Types.newParameterizedType( - Map::class.java, - String::class.java, - Any::class.java - ) - ) - - internal fun mapToEntity(deviceInfo: CryptoDeviceInfo): DeviceInfoEntity { - return DeviceInfoEntity(primaryKey = DeviceInfoEntity.createPrimaryKey(deviceInfo.userId, deviceInfo.deviceId)) - .also { updateDeviceInfoEntity(it, deviceInfo) } - } - - internal fun updateDeviceInfoEntity(entity: DeviceInfoEntity, deviceInfo: CryptoDeviceInfo) { - entity.userId = deviceInfo.userId - entity.deviceId = deviceInfo.deviceId - entity.algorithmListJson = listMigrationAdapter.toJson(deviceInfo.algorithms) - entity.keysMapJson = mapMigrationAdapter.toJson(deviceInfo.keys) - entity.signatureMapJson = mapMigrationAdapter.toJson(deviceInfo.signatures) - entity.isBlocked = deviceInfo.isBlocked - val deviceInfoTrustLevel = deviceInfo.trustLevel - if (deviceInfoTrustLevel == null) { - entity.trustLevelEntity?.deleteFromRealm() - entity.trustLevelEntity = null - } else { - if (entity.trustLevelEntity == null) { - // Create a new TrustLevelEntity object - entity.trustLevelEntity = TrustLevelEntity() - } - // Update the existing TrustLevelEntity object - entity.trustLevelEntity?.crossSignedVerified = deviceInfoTrustLevel.crossSigningVerified - entity.trustLevelEntity?.locallyVerified = deviceInfoTrustLevel.locallyVerified - } - // We store the device name if present now - entity.unsignedMapJson = deviceInfo.unsigned?.deviceDisplayName - } - - internal fun mapToModel(deviceInfoEntity: DeviceInfoEntity): CryptoDeviceInfo { - return CryptoDeviceInfo( - userId = deviceInfoEntity.userId ?: "", - deviceId = deviceInfoEntity.deviceId ?: "", - isBlocked = deviceInfoEntity.isBlocked ?: false, - trustLevel = deviceInfoEntity.trustLevelEntity?.let { - DeviceTrustLevel(it.crossSignedVerified ?: false, it.locallyVerified) - }, - unsigned = deviceInfoEntity.unsignedMapJson?.let { UnsignedDeviceInfo(deviceDisplayName = it) }, - signatures = deviceInfoEntity.signatureMapJson?.let { - try { - mapOfStringMigrationAdapter.fromJson(it) - } catch (failure: Throwable) { - Timber.e(failure) - null - } - }, - keys = deviceInfoEntity.keysMapJson?.let { - try { - moshi.adapter>( - Types.newParameterizedType( - Map::class.java, - String::class.java, - Any::class.java - ) - ).fromJson(it) - } catch (failure: Throwable) { - Timber.e(failure) - null - } - }, - algorithms = deviceInfoEntity.algorithmListJson?.let { - try { - listMigrationAdapter.fromJson(it) - } catch (failure: Throwable) { - Timber.e(failure) - null - } - }, - firstTimeSeenLocalTs = deviceInfoEntity.firstTimeSeenLocalTs - ) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMetadataEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMetadataEntity.kt index 88708f824e..73992485a6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMetadataEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMetadataEntity.kt @@ -18,9 +18,6 @@ package org.matrix.android.sdk.internal.crypto.store.db.model import io.realm.RealmObject import io.realm.annotations.PrimaryKey -import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm -import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm -import org.matrix.olm.OlmAccount internal open class CryptoMetadataEntity( // The current user id. @@ -53,15 +50,4 @@ internal open class CryptoMetadataEntity( var keyBackupRecoveryKeyVersion: String? = null // var crossSigningInfoEntity: CrossSigningInfoEntity? = null -) : RealmObject() { - - // Deserialize data - fun getOlmAccount(): OlmAccount? { - return deserializeFromRealm(olmAccountData) - } - - // Serialize data - fun putOlmAccount(olmAccount: OlmAccount?) { - olmAccountData = serializeForRealm(olmAccount) - } -} +) : RealmObject() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoRoomEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoRoomEntity.kt index dce47860c7..613bcee2f3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoRoomEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoRoomEntity.kt @@ -26,10 +26,6 @@ internal open class CryptoRoomEntity( var blacklistUnverifiedDevices: Boolean = false, // Determines whether or not room history should be shared on new member invites var shouldShareHistory: Boolean = false, - // Store the current outbound session for this room, - // to avoid re-create and re-share at each startup (if rotation not needed..) - // This is specific to megolm but not sure how to model it better - var outboundSessionInfo: OutboundGroupSessionInfoEntity? = null, // a security to ensure that a room will never revert to not encrypted // even if a new state event with empty encryption, or state is reset somehow var wasEncryptedOnce: Boolean? = false, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/DeviceInfoEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/DeviceInfoEntity.kt deleted file mode 100644 index 61870ec486..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/DeviceInfoEntity.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.model - -import io.realm.RealmObject -import io.realm.RealmResults -import io.realm.annotations.LinkingObjects -import io.realm.annotations.PrimaryKey - -internal fun DeviceInfoEntity.Companion.createPrimaryKey(userId: String, deviceId: String) = "$userId|$deviceId" - -internal open class DeviceInfoEntity( - @PrimaryKey var primaryKey: String = "", - var deviceId: String? = null, - var identityKey: String? = null, - var userId: String? = null, - var isBlocked: Boolean? = null, - var algorithmListJson: String? = null, - var keysMapJson: String? = null, - var signatureMapJson: String? = null, - // Will contain the device name from unsigned data if present - var unsignedMapJson: String? = null, - var trustLevelEntity: TrustLevelEntity? = null, - /** - * We use that to make distinction between old devices (there before mine) - * and new ones. Used for example to detect new unverified login - */ - var firstTimeSeenLocalTs: Long? = null -) : RealmObject() { - - @LinkingObjects("devices") - val users: RealmResults? = null - - companion object -} - -internal fun DeviceInfoEntity.deleteOnCascade() { - trustLevelEntity?.deleteFromRealm() - deleteFromRealm() -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/KeyInfoEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/KeyInfoEntity.kt deleted file mode 100644 index 9133413589..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/KeyInfoEntity.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.model - -import io.realm.RealmList -import io.realm.RealmObject - -internal open class KeyInfoEntity( - var publicKeyBase64: String? = null, -// var isTrusted: Boolean = false, - var usages: RealmList = RealmList(), - /** - * The signature of this MXDeviceInfo. - * A map from "" to a map from ":" to "" - */ - var signatures: String? = null, - var trustLevelEntity: TrustLevelEntity? = null -) : RealmObject() - -internal fun KeyInfoEntity.deleteOnCascade() { - trustLevelEntity?.deleteFromRealm() - deleteFromRealm() -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/KeyRequestReplyEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/KeyRequestReplyEntity.kt deleted file mode 100644 index 0c7cf79e78..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/KeyRequestReplyEntity.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.model - -import io.realm.RealmObject -import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.internal.di.MoshiProvider - -internal open class KeyRequestReplyEntity( - var senderId: String? = null, - var fromDevice: String? = null, - var eventJson: String? = null -) : RealmObject() { - companion object - - fun getEvent(): Event? { - return eventJson?.let { - MoshiProvider.providesMoshi().adapter(Event::class.java).fromJson(it) - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/KeysBackupDataEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/KeysBackupDataEntity.kt deleted file mode 100644 index 99b9e0ccdf..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/KeysBackupDataEntity.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.model - -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey - -internal open class KeysBackupDataEntity( - // Primary key to update this object. There is only one object, so it's a constant, please do not set it - @PrimaryKey - var primaryKey: Int = 0, - // The last known hash of the backed up keys on the server - var backupLastServerHash: String? = null, - // The last known number of backed up keys on the server - var backupLastServerNumberOfKeys: Int? = null -) : RealmObject() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OlmInboundGroupSessionEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OlmInboundGroupSessionEntity.kt deleted file mode 100644 index 62ab73e379..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OlmInboundGroupSessionEntity.kt +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.model - -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import org.matrix.android.sdk.internal.crypto.model.InboundGroupSessionData -import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrapper -import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm -import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm -import org.matrix.android.sdk.internal.di.MoshiProvider -import org.matrix.olm.OlmInboundGroupSession -import timber.log.Timber - -internal fun OlmInboundGroupSessionEntity.Companion.createPrimaryKey(sessionId: String?, senderKey: String?) = "$sessionId|$senderKey" - -internal open class OlmInboundGroupSessionEntity( - // Combined value to build a primary key - @PrimaryKey var primaryKey: String? = null, - - // denormalization for faster querying (these fields are in the inboundGroupSessionDataJson) - var sessionId: String? = null, - var senderKey: String? = null, - var roomId: String? = null, - - // Deprecated, used for migration / olmInboundGroupSessionData contains Json - // keep it in case of problem to have a chance to recover - var olmInboundGroupSessionData: String? = null, - - // Stores the session data in an extensible format - // to allow to store data not yet supported for later use - var inboundGroupSessionDataJson: String? = null, - - // The pickled session - var serializedOlmInboundGroupSession: String? = null, - - // Flag that indicates whether or not the current inboundSession will be shared to - // invited users to decrypt past messages - var sharedHistory: Boolean = false, - // Indicate if the key has been backed up to the homeserver - var backedUp: Boolean = false -) : - RealmObject() { - - fun store(wrapper: MXInboundMegolmSessionWrapper) { - this.serializedOlmInboundGroupSession = serializeForRealm(wrapper.session) - this.inboundGroupSessionDataJson = adapter.toJson(wrapper.sessionData) - this.roomId = wrapper.sessionData.roomId - this.senderKey = wrapper.sessionData.senderKey - this.sessionId = wrapper.session.sessionIdentifier() - this.sharedHistory = wrapper.sessionData.sharedHistory - } -// fun getInboundGroupSession(): OlmInboundGroupSessionWrapper2? { -// return try { -// deserializeFromRealm(olmInboundGroupSessionData) -// } catch (failure: Throwable) { -// Timber.e(failure, "## Deserialization failure") -// return null -// } -// } -// -// fun putInboundGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper2?) { -// olmInboundGroupSessionData = serializeForRealm(olmInboundGroupSessionWrapper) -// } - - fun getOlmGroupSession(): OlmInboundGroupSession? { - return try { - deserializeFromRealm(serializedOlmInboundGroupSession) - } catch (failure: Throwable) { - Timber.e(failure, "## Deserialization failure") - return null - } - } - - fun getData(): InboundGroupSessionData? { - return try { - inboundGroupSessionDataJson?.let { - adapter.fromJson(it) - } - } catch (failure: Throwable) { - Timber.e(failure, "## Deserialization failure") - return null - } - } - - fun toModel(): MXInboundMegolmSessionWrapper? { - val data = getData() ?: return null - val session = getOlmGroupSession() ?: return null - return MXInboundMegolmSessionWrapper( - session = session, - sessionData = data - ) - } - - companion object { - private val adapter = MoshiProvider.providesMoshi() - .adapter(InboundGroupSessionData::class.java) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OlmSessionEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OlmSessionEntity.kt deleted file mode 100644 index 9f010db288..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OlmSessionEntity.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.model - -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm -import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm -import org.matrix.olm.OlmSession - -internal fun OlmSessionEntity.Companion.createPrimaryKey(sessionId: String, deviceKey: String) = "$sessionId|$deviceKey" - -// olmSessionData is a serialized OlmSession -internal open class OlmSessionEntity( - @PrimaryKey var primaryKey: String = "", - var sessionId: String? = null, - var deviceKey: String? = null, - var olmSessionData: String? = null, - var lastReceivedMessageTs: Long = 0 -) : - RealmObject() { - - fun getOlmSession(): OlmSession? { - return deserializeFromRealm(olmSessionData) - } - - fun putOlmSession(olmSession: OlmSession?) { - olmSessionData = serializeForRealm(olmSession) - } - - companion object -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OutboundGroupSessionInfoEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OutboundGroupSessionInfoEntity.kt deleted file mode 100644 index 2ebd550201..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OutboundGroupSessionInfoEntity.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.model - -import io.realm.RealmObject -import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm -import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm -import org.matrix.olm.OlmOutboundGroupSession -import timber.log.Timber - -internal open class OutboundGroupSessionInfoEntity( - var serializedOutboundSessionData: String? = null, - var creationTime: Long? = null, - var shouldShareHistory: Boolean = false -) : RealmObject() { - - fun getOutboundGroupSession(): OlmOutboundGroupSession? { - return try { - deserializeFromRealm(serializedOutboundSessionData) - } catch (failure: Throwable) { - Timber.e(failure, "## getOutboundGroupSession() Deserialization failure") - return null - } - } - - fun putOutboundGroupSession(olmOutboundGroupSession: OlmOutboundGroupSession?) { - serializedOutboundSessionData = serializeForRealm(olmOutboundGroupSession) - } - - companion object -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OutgoingKeyRequestEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OutgoingKeyRequestEntity.kt deleted file mode 100644 index b10e7501d6..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OutgoingKeyRequestEntity.kt +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.model - -import com.squareup.moshi.JsonAdapter -import com.squareup.moshi.Types -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.annotations.Index -import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.api.session.crypto.OutgoingKeyRequest -import org.matrix.android.sdk.api.session.crypto.OutgoingRoomKeyRequestState -import org.matrix.android.sdk.api.session.crypto.RequestReply -import org.matrix.android.sdk.api.session.crypto.RequestResult -import org.matrix.android.sdk.api.session.crypto.model.RoomKeyRequestBody -import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent -import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.internal.di.MoshiProvider - -internal open class OutgoingKeyRequestEntity( - @Index var requestId: String? = null, - var requestedIndex: Int? = null, - var recipientsData: String? = null, - var requestedInfoStr: String? = null, - var creationTimeStamp: Long? = null, - // de-normalization for better query (if not have to query all and parse json) - @Index var roomId: String? = null, - @Index var megolmSessionId: String? = null, - - var replies: RealmList = RealmList() -) : RealmObject() { - - @Index private var requestStateStr: String = OutgoingRoomKeyRequestState.UNSENT.name - - companion object { - - private val recipientsDataMapper: JsonAdapter>> = - MoshiProvider - .providesMoshi() - .adapter( - Types.newParameterizedType(Map::class.java, String::class.java, List::class.java) - ) - } - - private fun getRequestedKeyInfo(): RoomKeyRequestBody? = RoomKeyRequestBody.fromJson(requestedInfoStr) - - fun setRequestBody(body: RoomKeyRequestBody) { - requestedInfoStr = body.toJson() - roomId = body.roomId - megolmSessionId = body.sessionId - } - - var requestState: OutgoingRoomKeyRequestState - get() { - return tryOrNull { OutgoingRoomKeyRequestState.valueOf(requestStateStr) } - ?: OutgoingRoomKeyRequestState.UNSENT - } - set(value) { - requestStateStr = value.name - } - - private fun getRecipients(): Map>? { - return this.recipientsData?.let { recipientsDataMapper.fromJson(it) } - } - - fun setRecipients(recipients: Map>) { - this.recipientsData = recipientsDataMapper.toJson(recipients) - } - - fun addReply(userId: String, fromDevice: String?, event: Event) { - val newReply = KeyRequestReplyEntity( - senderId = userId, - fromDevice = fromDevice, - eventJson = MoshiProvider.providesMoshi().adapter(Event::class.java).toJson(event) - ) - replies.add(newReply) - } - - fun toOutgoingKeyRequest(): OutgoingKeyRequest { - return OutgoingKeyRequest( - requestBody = getRequestedKeyInfo(), - recipients = getRecipients().orEmpty(), - requestId = requestId ?: "", - fromIndex = requestedIndex ?: 0, - state = requestState, - results = replies.mapNotNull { entity -> - val userId = entity.senderId ?: return@mapNotNull null - val result = entity.eventJson?.let { - MoshiProvider.providesMoshi().adapter(Event::class.java).fromJson(it) - }?.let { event -> - eventToResult(event) - } ?: return@mapNotNull null - RequestReply( - userId = userId, - fromDevice = entity.fromDevice, - result = result - ) - } - ) - } - - private fun eventToResult(event: Event): RequestResult? { - return when (event.getClearType()) { - in EventType.ROOM_KEY_WITHHELD.values -> { - event.content.toModel()?.code?.let { - RequestResult.Failure(it) - } - } - EventType.FORWARDED_ROOM_KEY -> { - RequestResult.Success((event.content?.get("chain_index") as? Number)?.toInt() ?: 0) - } - else -> null - } - } -} - -internal fun OutgoingKeyRequestEntity.deleteOnCascade() { - replies.deleteAllFromRealm() - deleteFromRealm() -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/SharedSessionEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/SharedSessionEntity.kt deleted file mode 100644 index e2ae512afd..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/SharedSessionEntity.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.model - -import io.realm.RealmObject -import io.realm.annotations.Index - -/** - * Keep a record of to whom (user/device) a given session should have been shared. - * It will be used to reply to keyshare requests from other users, in order to see if - * this session was originaly shared with a given user - */ -internal open class SharedSessionEntity( - var roomId: String? = null, - var algorithm: String? = null, - @Index var sessionId: String? = null, - @Index var userId: String? = null, - @Index var deviceId: String? = null, - @Index var deviceIdentityKey: String? = null, - var chainIndex: Int? = null -) : RealmObject() { - - companion object -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/UserEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/UserEntity.kt deleted file mode 100644 index df9482bf96..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/UserEntity.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.model - -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey -import org.matrix.android.sdk.internal.extensions.clearWith - -internal open class UserEntity( - @PrimaryKey var userId: String? = null, - var devices: RealmList = RealmList(), - var crossSigningInfoEntity: CrossSigningInfoEntity? = null, - var deviceTrackingStatus: Int = 0 -) : RealmObject() { - - companion object -} - -internal fun UserEntity.deleteOnCascade() { - devices.clearWith { it.deleteOnCascade() } - crossSigningInfoEntity?.deleteOnCascade() - deleteFromRealm() -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/WithHeldSessionEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/WithHeldSessionEntity.kt deleted file mode 100644 index 93048e5775..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/WithHeldSessionEntity.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.model - -import io.realm.RealmObject -import io.realm.annotations.Index -import org.matrix.android.sdk.api.session.events.model.content.WithHeldCode - -/** - * When an encrypted message is sent in a room, the megolm key might not be sent to all devices present in the room. - * Sometimes this may be inadvertent (for example, if the sending device is not aware of some devices that have joined), - * but some times, this may be purposeful. - * For example, the sender may have blacklisted certain devices or users, - * or may be choosing to not send the megolm key to devices that they have not verified yet. - */ -internal open class WithHeldSessionEntity( - var roomId: String? = null, - var algorithm: String? = null, - @Index var sessionId: String? = null, - @Index var senderKey: String? = null, - var codeString: String? = null, - var reason: String? = null -) : RealmObject() { - - var code: WithHeldCode? - get() { - return WithHeldCode.fromCode(codeString) - } - set(code) { - codeString = code?.value - } - - companion object -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/CrossSigningInfoEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/CrossSigningInfoEntityQueries.kt deleted file mode 100644 index 05eed9256e..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/CrossSigningInfoEntityQueries.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.query - -import io.realm.Realm -import io.realm.kotlin.createObject -import io.realm.kotlin.where -import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields - -internal fun CrossSigningInfoEntity.Companion.getOrCreate(realm: Realm, userId: String): CrossSigningInfoEntity { - return realm.where() - .equalTo(UserEntityFields.USER_ID, userId) - .findFirst() - ?: realm.createObject(userId) -} - -internal fun CrossSigningInfoEntity.Companion.get(realm: Realm, userId: String): CrossSigningInfoEntity? { - return realm.where() - .equalTo(UserEntityFields.USER_ID, userId) - .findFirst() -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/DeviceInfoEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/DeviceInfoEntityQueries.kt deleted file mode 100644 index 0a922e79bc..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/DeviceInfoEntityQueries.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.query - -import io.realm.Realm -import io.realm.kotlin.createObject -import io.realm.kotlin.where -import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.createPrimaryKey - -/** - * Get or create a device info. - */ -internal fun DeviceInfoEntity.Companion.getOrCreate(realm: Realm, userId: String, deviceId: String): DeviceInfoEntity { - val key = DeviceInfoEntity.createPrimaryKey(userId, deviceId) - - return realm.where() - .equalTo(DeviceInfoEntityFields.PRIMARY_KEY, key) - .findFirst() - ?: realm.createObject(key) - .apply { - this.deviceId = deviceId - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt deleted file mode 100644 index 85dd50c88e..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.query - -import io.realm.Realm -import io.realm.RealmResults -import io.realm.kotlin.createObject -import io.realm.kotlin.where -import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntityFields - -internal fun SharedSessionEntity.Companion.get( - realm: Realm, - roomId: String?, - sessionId: String, - userId: String, - deviceId: String, - deviceIdentityKey: String? -): SharedSessionEntity? { - return realm.where() - .equalTo(SharedSessionEntityFields.ROOM_ID, roomId) - .equalTo(SharedSessionEntityFields.SESSION_ID, sessionId) - .equalTo(SharedSessionEntityFields.ALGORITHM, MXCRYPTO_ALGORITHM_MEGOLM) - .equalTo(SharedSessionEntityFields.USER_ID, userId) - .equalTo(SharedSessionEntityFields.DEVICE_ID, deviceId) - .equalTo(SharedSessionEntityFields.DEVICE_IDENTITY_KEY, deviceIdentityKey) - .findFirst() -} - -internal fun SharedSessionEntity.Companion.get(realm: Realm, roomId: String?, sessionId: String): RealmResults { - return realm.where() - .equalTo(SharedSessionEntityFields.ROOM_ID, roomId) - .equalTo(SharedSessionEntityFields.SESSION_ID, sessionId) - .equalTo(SharedSessionEntityFields.ALGORITHM, MXCRYPTO_ALGORITHM_MEGOLM) - .findAll() -} - -internal fun SharedSessionEntity.Companion.create( - realm: Realm, - roomId: String?, - sessionId: String, - userId: String, - deviceId: String, - deviceIdentityKey: String, - chainIndex: Int -): SharedSessionEntity { - return realm.createObject().apply { - this.roomId = roomId - this.algorithm = MXCRYPTO_ALGORITHM_MEGOLM - this.sessionId = sessionId - this.userId = userId - this.deviceId = deviceId - this.deviceIdentityKey = deviceIdentityKey - this.chainIndex = chainIndex - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/UserEntitiesQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/UserEntitiesQueries.kt deleted file mode 100644 index 73c3997439..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/UserEntitiesQueries.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.query - -import io.realm.Realm -import io.realm.kotlin.createObject -import io.realm.kotlin.where -import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.deleteOnCascade - -/** - * Get or create a user. - */ -internal fun UserEntity.Companion.getOrCreate(realm: Realm, userId: String): UserEntity { - return realm.where() - .equalTo(UserEntityFields.USER_ID, userId) - .findFirst() - ?: realm.createObject(userId) -} - -/** - * Delete a user. - */ -internal fun UserEntity.Companion.delete(realm: Realm, userId: String) { - realm.where() - .equalTo(UserEntityFields.USER_ID, userId) - .findFirst() - ?.deleteOnCascade() -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/WithHeldSessionQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/WithHeldSessionQueries.kt deleted file mode 100644 index c253af2bf6..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/WithHeldSessionQueries.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.store.db.query - -import io.realm.Realm -import io.realm.kotlin.createObject -import io.realm.kotlin.where -import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntityFields - -internal fun WithHeldSessionEntity.Companion.get(realm: Realm, roomId: String, sessionId: String): WithHeldSessionEntity? { - return realm.where() - .equalTo(WithHeldSessionEntityFields.ROOM_ID, roomId) - .equalTo(WithHeldSessionEntityFields.SESSION_ID, sessionId) - .equalTo(WithHeldSessionEntityFields.ALGORITHM, MXCRYPTO_ALGORITHM_MEGOLM) - .findFirst() -} - -internal fun WithHeldSessionEntity.Companion.getOrCreate(realm: Realm, roomId: String, sessionId: String): WithHeldSessionEntity? { - return get(realm, roomId, sessionId) - ?: realm.createObject().apply { - this.roomId = roomId - this.algorithm = MXCRYPTO_ALGORITHM_MEGOLM - this.sessionId = sessionId - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/Tools.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/Tools.kt deleted file mode 100644 index 052b3f4e72..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/Tools.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.tools - -import org.matrix.olm.OlmPkDecryption -import org.matrix.olm.OlmPkEncryption -import org.matrix.olm.OlmPkSigning -import org.matrix.olm.OlmUtility - -internal fun withOlmEncryption(block: (OlmPkEncryption) -> T): T { - val olmPkEncryption = OlmPkEncryption() - try { - return block(olmPkEncryption) - } finally { - olmPkEncryption.releaseEncryption() - } -} - -internal fun withOlmDecryption(block: (OlmPkDecryption) -> T): T { - val olmPkDecryption = OlmPkDecryption() - try { - return block(olmPkDecryption) - } finally { - olmPkDecryption.releaseDecryption() - } -} - -internal fun withOlmSigning(block: (OlmPkSigning) -> T): T { - val olmPkSigning = OlmPkSigning() - try { - return block(olmPkSigning) - } finally { - olmPkSigning.releaseSigning() - } -} - -internal fun withOlmUtility(block: (OlmUtility) -> T): T { - val olmUtility = OlmUtility() - try { - return block(olmUtility) - } finally { - olmUtility.releaseUtility() - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SasVerification.kt index 9c8e327cd5..54f99248b1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SasVerification.kt @@ -34,6 +34,7 @@ import org.matrix.rustcomponents.sdk.crypto.CryptoStoreException import org.matrix.rustcomponents.sdk.crypto.Sas import org.matrix.rustcomponents.sdk.crypto.SasListener import org.matrix.rustcomponents.sdk.crypto.SasState +import timber.log.Timber /** Class representing a short auth string verification flow. */ internal class SasVerification @AssistedInject constructor( @@ -72,6 +73,11 @@ internal class SasVerification @AssistedInject constructor( override fun state(): SasTransactionState { return when (val state = innerState) { + SasState.Created -> { + // Note: this does not seem to be used, but emit a warning just in case. + Timber.w("SasState.Created received") + SasTransactionState.None + } SasState.Started -> SasTransactionState.SasStarted SasState.Accepted -> SasTransactionState.SasAccepted is SasState.KeysExchanged -> { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt index 44ec90ed40..9528efb411 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt @@ -43,7 +43,6 @@ import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver import org.matrix.android.sdk.internal.util.system.SystemModule import org.matrix.android.sdk.internal.worker.MatrixWorkerFactory -import org.matrix.olm.OlmManager import java.io.File @Component( @@ -89,8 +88,6 @@ internal interface MatrixComponent { @CacheDirectory fun cacheDir(): File - fun olmManager(): OlmManager - fun taskExecutor(): TaskExecutor fun sessionParamsStore(): SessionParamsStore diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixModule.kt index f2f8a5dc04..b0b0901adf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixModule.kt @@ -25,7 +25,6 @@ import kotlinx.coroutines.android.asCoroutineDispatcher import kotlinx.coroutines.asCoroutineDispatcher import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.internal.util.createBackgroundHandler -import org.matrix.olm.OlmManager import java.io.File import java.util.concurrent.Executors @@ -57,11 +56,4 @@ internal object MatrixModule { fun providesCacheDir(context: Context): File { return context.cacheDir } - - @JvmStatic - @Provides - @MatrixScope - fun providesOlmManager(): OlmManager { - return OlmManager() - } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/MigrateEAtoEROperation.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/MigrateEAtoEROperation.kt deleted file mode 100644 index b4944edbb9..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/MigrateEAtoEROperation.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2022 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.session - -import io.realm.DynamicRealm -import io.realm.Realm -import io.realm.RealmConfiguration -import org.matrix.android.sdk.internal.crypto.store.db.migration.rust.ExtractMigrationDataUseCase -import org.matrix.android.sdk.internal.crypto.store.db.migration.rust.RealmToMigrate -import org.matrix.rustcomponents.sdk.crypto.ProgressListener -import timber.log.Timber -import java.io.File - -class MigrateEAtoEROperation(private val migrateGroupSessions: Boolean = false) { - - fun execute(cryptoRealm: RealmConfiguration, rustFilesDir: File, passphrase: String?): File { - // Temporary code for migration - if (!rustFilesDir.exists()) { - rustFilesDir.mkdir() - // perform a migration? - val extractMigrationData = ExtractMigrationDataUseCase(migrateGroupSessions) - val hasExitingData = extractMigrationData.hasExistingData(cryptoRealm) - if (!hasExitingData) return rustFilesDir - - try { - val progressListener = object : ProgressListener { - override fun onProgress(progress: Int, total: Int) { - Timber.v("OnProgress: $progress/$total") - } - } - Realm.getInstance(cryptoRealm).use { realm -> - extractMigrationData.extractData(RealmToMigrate.ClassicRealm(realm)) { - org.matrix.rustcomponents.sdk.crypto.migrate(it, rustFilesDir.path, passphrase, progressListener) - } - } - } catch (failure: Throwable) { - Timber.e(failure, "Failure while calling rust migration method") - throw failure - } - } - return rustFilesDir - } - - fun dynamicExecute(dynamicRealm: DynamicRealm, rustFilesDir: File, passphrase: String?) { - if (!rustFilesDir.exists()) { - rustFilesDir.mkdir() - } - val extractMigrationData = ExtractMigrationDataUseCase(migrateGroupSessions) - - try { - val progressListener = object : ProgressListener { - override fun onProgress(progress: Int, total: Int) { - Timber.v("OnProgress: $progress/$total") - } - } - extractMigrationData.extractData(RealmToMigrate.DynamicRealm(dynamicRealm)) { - org.matrix.rustcomponents.sdk.crypto.migrate(it, rustFilesDir.path, passphrase, progressListener) - } - } catch (failure: Throwable) { - Timber.e(failure, "Failure while calling rust migration method") - throw failure - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/ScanEncryptorUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/ScanEncryptorUtils.kt index 7d14e4ed80..9cf8c90d12 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/ScanEncryptorUtils.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/ScanEncryptorUtils.kt @@ -19,13 +19,14 @@ package org.matrix.android.sdk.internal.session.contentscanner import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileKey -import org.matrix.android.sdk.internal.crypto.tools.withOlmEncryption import org.matrix.android.sdk.internal.session.contentscanner.model.DownloadBody import org.matrix.android.sdk.internal.session.contentscanner.model.EncryptedBody import org.matrix.android.sdk.internal.session.contentscanner.model.toCanonicalJson +import org.matrix.rustcomponents.sdk.crypto.PkEncryption internal object ScanEncryptorUtils { + @Throws fun getDownloadBodyAndEncryptIfNeeded(publicServerKey: String?, mxcUrl: String, elementToDecrypt: ElementToDecrypt): DownloadBody { // TODO, upstream refactoring changed the object model here... // it's bad we have to recreate and use hardcoded values @@ -43,19 +44,18 @@ internal object ScanEncryptorUtils { v = "v2" ) return if (publicServerKey != null) { - // We should encrypt - withOlmEncryption { olm -> - olm.setRecipientKey(publicServerKey) - - val olmResult = olm.encrypt(DownloadBody(encryptedInfo).toCanonicalJson()) - DownloadBody( - encryptedBody = EncryptedBody( - cipherText = olmResult.mCipherText, - ephemeral = olmResult.mEphemeralKey, - mac = olmResult.mMac - ) - ) + // Note: fromBase64 can throw Exception + val pkEncryption = PkEncryption.fromBase64(key = publicServerKey) + val pkMessage = pkEncryption.use { + pkEncryption.encrypt(DownloadBody(encryptedInfo).toCanonicalJson()) } + DownloadBody( + encryptedBody = EncryptedBody( + cipherText = pkMessage.ciphertext, + ephemeral = pkMessage.ephemeralKey, + mac = pkMessage.mac + ) + ) } else { DownloadBody(encryptedInfo) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/tasks/ScanEncryptedTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/tasks/ScanEncryptedTask.kt index e098607eb6..4550d12f30 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/tasks/ScanEncryptedTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/tasks/ScanEncryptedTask.kt @@ -42,12 +42,10 @@ internal class DefaultScanEncryptedTask @Inject constructor( override suspend fun execute(params: ScanEncryptedTask.Params): ScanResponse { val mxcUrl = params.mxcUrl - val dlBody = ScanEncryptorUtils.getDownloadBodyAndEncryptIfNeeded(params.publicServerKey, params.mxcUrl, params.encryptedInfo) - val scannerUrl = contentScannerStore.getScannerUrl() - contentScannerStore.updateStateForContent(params.mxcUrl, ScanState.IN_PROGRESS, scannerUrl) - + contentScannerStore.updateStateForContent(mxcUrl, ScanState.IN_PROGRESS, scannerUrl) try { + val dlBody = ScanEncryptorUtils.getDownloadBodyAndEncryptIfNeeded(params.publicServerKey, mxcUrl, params.encryptedInfo) val api = contentScannerApiProvider.contentScannerApi ?: throw IllegalArgumentException() val executeRequest = executeRequest(null) { api.scanFile(dlBody) @@ -60,7 +58,7 @@ internal class DefaultScanEncryptedTask @Inject constructor( ) return executeRequest } catch (failure: Throwable) { - contentScannerStore.updateStateForContent(params.mxcUrl, ScanState.UNKNOWN, scannerUrl) + contentScannerStore.updateStateForContent(mxcUrl, ScanState.UNKNOWN, scannerUrl) throw failure.toScanFailure() ?: failure } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityBulkLookupTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityBulkLookupTask.kt index 21b59cca9d..a9d6753d3a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityBulkLookupTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityBulkLookupTask.kt @@ -22,7 +22,6 @@ import org.matrix.android.sdk.api.session.identity.FoundThreePid import org.matrix.android.sdk.api.session.identity.IdentityServiceError import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.identity.toMedium -import org.matrix.android.sdk.internal.crypto.tools.withOlmUtility import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.identity.data.IdentityStore @@ -43,7 +42,8 @@ internal interface IdentityBulkLookupTask : Task { @@ -118,15 +118,12 @@ internal class DefaultIdentityBulkLookupTask @Inject constructor( } private fun getHashedAddresses(threePids: List, pepper: String): List { - return withOlmUtility { olmUtility -> - threePids.map { threePid -> - base64ToBase64Url( - olmUtility.sha256( - threePid.value.lowercase(Locale.ROOT) + - " " + threePid.toMedium() + " " + pepper - ) - ) - } + return threePids.map { threePid -> + base64ToBase64Url( + sha256Converter.convertToSha256( + str = threePid.value.lowercase(Locale.ROOT) + " " + threePid.toMedium() + " " + pepper + ) + ) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/TrustLevelEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/Sha256Converter.kt similarity index 54% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/TrustLevelEntity.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/Sha256Converter.kt index 5647eb8aa0..f68f7c488b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/TrustLevelEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/Sha256Converter.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2024 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.store.db.model +package org.matrix.android.sdk.internal.session.identity -import io.realm.RealmObject +import org.matrix.android.sdk.api.util.toBase64NoPadding +import java.security.MessageDigest +import javax.inject.Inject -internal open class TrustLevelEntity( - var crossSignedVerified: Boolean? = null, - var locallyVerified: Boolean? = null -) : RealmObject() { +class Sha256Converter @Inject constructor() { + private val sha256 by lazy { MessageDigest.getInstance("SHA-256") } - companion object - - fun isVerified(): Boolean = crossSignedVerified == true || locallyVerified == true + fun convertToSha256(str: String): String { + return sha256.digest(str.toByteArray()).toBase64NoPadding() + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/androidsdk/crypto/data/MXDeviceInfo.java b/matrix-sdk-android/src/main/java/org/matrix/androidsdk/crypto/data/MXDeviceInfo.java deleted file mode 100755 index 4612b8d6ff..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/androidsdk/crypto/data/MXDeviceInfo.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.androidsdk.crypto.data; - -import java.io.Serializable; -import java.util.List; -import java.util.Map; - -/** - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - */ -public class MXDeviceInfo implements Serializable { - private static final long serialVersionUID = 20129670646382964L; - - // This device is a new device and the user was not warned it has been added. - public static final int DEVICE_VERIFICATION_UNKNOWN = -1; - - // The user has not yet verified this device. - public static final int DEVICE_VERIFICATION_UNVERIFIED = 0; - - // The user has verified this device. - public static final int DEVICE_VERIFICATION_VERIFIED = 1; - - // The user has blocked this device. - public static final int DEVICE_VERIFICATION_BLOCKED = 2; - - /** - * The id of this device. - */ - public String deviceId; - - /** - * the user id - */ - public String userId; - - /** - * The list of algorithms supported by this device. - */ - public List algorithms; - - /** - * A map from : to >. - */ - public Map keys; - - /** - * The signature of this MXDeviceInfo. - * A map from : to >. - */ - public Map> signatures; - - /* - * Additional data from the homeserver. - */ - public Map unsigned; - - /** - * Verification state of this device. - */ - public int mVerified; - - /** - * Constructor - */ - public MXDeviceInfo() { - mVerified = DEVICE_VERIFICATION_UNKNOWN; - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/androidsdk/crypto/data/MXOlmInboundGroupSession2.java b/matrix-sdk-android/src/main/java/org/matrix/androidsdk/crypto/data/MXOlmInboundGroupSession2.java deleted file mode 100755 index c6a8c1443c..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/androidsdk/crypto/data/MXOlmInboundGroupSession2.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.androidsdk.crypto.data; - -import org.matrix.olm.OlmInboundGroupSession; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - * - * This class adds more context to a OLMInboundGroupSession object. - * This allows additional checks. The class implements NSCoding so that the context can be stored. - */ -public class MXOlmInboundGroupSession2 implements Serializable { - // define a serialVersionUID to avoid having to redefine the class after updates - private static final long serialVersionUID = 201702011617L; - - // The associated olm inbound group session. - public OlmInboundGroupSession mSession; - - // The room in which this session is used. - public String mRoomId; - - // The base64-encoded curve25519 key of the sender. - public String mSenderKey; - - // Other keys the sender claims. - public Map mKeysClaimed; - - // Devices which forwarded this session to us (normally empty). - public List mForwardingCurve25519KeyChain = new ArrayList<>(); -} \ No newline at end of file diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/identity/Sha256Test.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/identity/Sha256Test.kt new file mode 100644 index 0000000000..9aa8d0b36b --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/identity/Sha256Test.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.identity + +import org.amshove.kluent.shouldBeEqualTo +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +class Sha256Test { + /** + * Check that the behavior is the same than what is done in the Olm library. + * https://gitlab.matrix.org/matrix-org/olm/-/blob/master/tests/test_olm_sha256.cpp#L16 + */ + @Test + fun testSha256() { + val sut = Sha256Converter() + sut.convertToSha256("Hello, World") shouldBeEqualTo "A2daxT/5zRU1zMffzfosRYxSGDcfQY3BNvLRmsH76KU" + } +}