From 7755da881e654e97c1d72856f537732099b4cbf2 Mon Sep 17 00:00:00 2001 From: yostyle Date: Fri, 13 Oct 2023 17:18:32 +0200 Subject: [PATCH 1/3] Move crypto migration --- .../sdk/internal/crypto/RustCryptoService.kt | 29 +++++++++++- .../internal/crypto/network/RequestSender.kt | 47 +------------------ 2 files changed, 29 insertions(+), 47 deletions(-) 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 44fd9e6797..1dc4ca665f 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 @@ -55,6 +55,7 @@ import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.events.model.Content 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.EncryptedEventContent import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent import org.matrix.android.sdk.api.session.events.model.content.RoomKeyContent import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent @@ -134,6 +135,7 @@ internal class RustCryptoService @Inject constructor( private val getRoomUserIds: GetRoomUserIdsUseCase, private val outgoingRequestsProcessor: OutgoingRequestsProcessor, private val matrixConfiguration: MatrixConfiguration, + private val perSessionBackupQueryRateLimiter: PerSessionBackupQueryRateLimiter, ) : CryptoService { private val isStarting = AtomicBoolean(false) @@ -494,7 +496,32 @@ internal class RustCryptoService @Inject constructor( */ @Throws(MXCryptoError::class) override suspend fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult { - return olmMachine.decryptRoomEvent(event) + return try { + olmMachine.decryptRoomEvent(event) + } catch (mxCryptoError: MXCryptoError) { + if (mxCryptoError is MXCryptoError.Base && ( + mxCryptoError.errorType == MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID + || mxCryptoError.errorType == MXCryptoError.ErrorType.UNKNOWN_MESSAGE_INDEX)) { + Timber.v("Try to perform a lazy migration from legacy store") + /** + * It's a bit hacky, check how this can be better integrated with rust? + */ + 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) + } + } + } + throw mxCryptoError + } } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt index b5212ee45a..88432c8fe6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt @@ -22,23 +22,17 @@ import dagger.Lazy import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.launch import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor -import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupLastVersionResult import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersion import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersionResult -import org.matrix.android.sdk.api.session.crypto.model.GossipingToDeviceObject import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.events.model.Content 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.uia.UiaResult import org.matrix.android.sdk.internal.auth.registration.handleUIA -import org.matrix.android.sdk.internal.crypto.OlmMachine -import org.matrix.android.sdk.internal.crypto.PerSessionBackupQueryRateLimiter import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysBackupData @@ -59,7 +53,6 @@ import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadBody import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo import org.matrix.android.sdk.internal.crypto.model.rest.SignatureUploadResponse -import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultSendVerificationMessageTask import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask @@ -102,10 +95,7 @@ internal class RequestSender @Inject constructor( private val getRoomSessionDataTask: GetRoomSessionDataTask, private val moshi: Moshi, cryptoCoroutineScope: CoroutineScope, - private val rateLimiter: PerSessionBackupQueryRateLimiter, - private val cryptoStore: IMXCommonCryptoStore, private val localEchoRepository: LocalEchoRepository, - private val olmMachine: Lazy, ) { private val scope = CoroutineScope( @@ -246,44 +236,9 @@ internal class RequestSender @Inject constructor( .newBuilder() .add(CheckNumberType.JSON_ADAPTER_FACTORY) .build() - .adapter>>(Map::class.java) + .adapter>>(Map::class.java) val jsonBody = adapter.fromJson(body)!! - if (eventType == EventType.ROOM_KEY_REQUEST) { - scope.launch { - Timber.v("Intercepting key request, try backup") - /** - * It's a bit hacky, check how this can be better integrated with rust? - */ - try { - jsonBody.forEach { (_, deviceToContent) -> - deviceToContent.forEach { (_, content) -> - val hashMap = content as? Map<*, *> - val action = hashMap?.get("action")?.toString() - if (GossipingToDeviceObject.ACTION_SHARE_REQUEST == action) { - val requestBody = hashMap["body"] as? Map<*, *> - val roomId = requestBody?.get("room_id") as? String - val sessionId = requestBody?.get("session_id") as? String - val senderKey = requestBody?.get("sender_key") as? String - 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.get().importRoomKey(legacy).isFailure) { - rateLimiter.tryFromBackupIfPossible(sessionId, roomId) - } - } - } - } - } - Timber.v("Intercepting key request, try backup") - } catch (failure: Throwable) { - Timber.v(failure, "Failed to use backup") - } - } - } - val userMap = MXUsersDevicesMap() userMap.join(jsonBody) From 31d3b9d385305551fe89d3ffc86b0d521944c168 Mon Sep 17 00:00:00 2001 From: yostyle Date: Fri, 13 Oct 2023 17:50:27 +0200 Subject: [PATCH 2/3] Add changelog --- changelog.d/8666.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/8666.bugfix diff --git a/changelog.d/8666.bugfix b/changelog.d/8666.bugfix new file mode 100644 index 0000000000..33a2b4bfc2 --- /dev/null +++ b/changelog.d/8666.bugfix @@ -0,0 +1 @@ +Fix crypto migration from kotlin to rust when an account has a single session and no backup. From 18ccc25575f531435c19f135df89e22ff6c6da86 Mon Sep 17 00:00:00 2001 From: yostyle Date: Fri, 15 Dec 2023 12:25:29 +0100 Subject: [PATCH 3/3] fix lint --- .../matrix/android/sdk/internal/crypto/RustCryptoService.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 1dc4ca665f..d743631264 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 @@ -500,8 +500,8 @@ internal class RustCryptoService @Inject constructor( olmMachine.decryptRoomEvent(event) } catch (mxCryptoError: MXCryptoError) { if (mxCryptoError is MXCryptoError.Base && ( - mxCryptoError.errorType == MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID - || mxCryptoError.errorType == MXCryptoError.ErrorType.UNKNOWN_MESSAGE_INDEX)) { + mxCryptoError.errorType == MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID || + mxCryptoError.errorType == MXCryptoError.ErrorType.UNKNOWN_MESSAGE_INDEX)) { Timber.v("Try to perform a lazy migration from legacy store") /** * It's a bit hacky, check how this can be better integrated with rust?