From f53fc205e102accf0d269615f7dac913ae8a8a0b Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 11 Mar 2020 18:07:18 +0100 Subject: [PATCH 1/3] Fix Message transitions in encrypted rooms Fixes #518 --- .../internal/session/sync/RoomSyncHandler.kt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt index 5b7c39a3d9..c993dc1ea8 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt @@ -25,6 +25,7 @@ import im.vector.matrix.android.api.session.room.model.RoomMemberContent import im.vector.matrix.android.api.session.room.model.tag.RoomTagContent import im.vector.matrix.android.api.session.room.send.SendState import im.vector.matrix.android.internal.crypto.DefaultCryptoService +import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult import im.vector.matrix.android.internal.database.helper.addOrUpdate import im.vector.matrix.android.internal.database.helper.addTimelineEvent import im.vector.matrix.android.internal.database.mapper.ContentMapper @@ -260,6 +261,22 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle if (sendingEventEntity != null) { Timber.v("Remove local echo for tx:$it") roomEntity.sendingTimelineEvents.remove(sendingEventEntity) + if (event.isEncrypted()) { + // Maybe just a temp work around? + // Decrypt the remote echo right now, to avoid seeing it decrypt again + try { + val result = cryptoService.decryptEvent(event.copy(roomId = roomId), event.roomId ?: "") + event.mxDecryptionResult = OlmDecryptionResult( + payload = result.clearEvent, + senderKey = result.senderCurve25519Key, + keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) }, + forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain + ) + eventEntity.setDecryptionResult(result) + } catch (failure: Throwable) { + Timber.v("Failed to decrypt remote echo: ${failure.localizedMessage}") + } + } } else { Timber.v("Can't find corresponding local echo for tx:$it") } From 32fd4c1be96d6504781e74324c4cdedd7cd93e7b Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 11 Mar 2020 19:39:16 +0100 Subject: [PATCH 2/3] save decryption result at encryption --- .../session/room/send/EncryptEventWorker.kt | 19 ++++++++++++++++ .../session/room/send/LocalEchoUpdater.kt | 15 +++++++++++++ .../internal/session/sync/RoomSyncHandler.kt | 22 +++++++------------ 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt index 72f5ee56b8..bac4b29d87 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt @@ -23,7 +23,10 @@ import com.squareup.moshi.JsonClass import im.vector.matrix.android.api.failure.Failure import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.events.model.Event +import im.vector.matrix.android.api.session.events.model.toContent import im.vector.matrix.android.api.session.room.send.SendState +import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult import im.vector.matrix.android.internal.crypto.model.MXEncryptEventContentResult import im.vector.matrix.android.internal.util.awaitCallback import im.vector.matrix.android.internal.worker.SessionWorkerParams @@ -96,6 +99,22 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters) type = safeResult.eventType, content = safeResult.eventContent ) + // Better handling of local echo, to avoid decrypting transition on remote echo + // Should I only do it for text messages? + if (result.eventContent["algorithm"] == MXCRYPTO_ALGORITHM_MEGOLM) { + val decryptionLocalEcho = MXEventDecryptionResult( + clearEvent = Event( + type = localEvent.type, + content = localEvent.content, + roomId = localEvent.roomId + ).toContent(), + forwardingCurve25519KeyChain = emptyList(), + senderCurve25519Key = result.eventContent["sender_key"] as? String, + claimedEd25519Key = crypto.getMyDevice().fingerprint() + ) + localEchoUpdater.updateEncryptedEcho(localEvent.eventId, result.eventContent, decryptionLocalEcho) + } + val nextWorkerParams = SendEventWorker.Params(params.sessionId, encryptedEvent) return Result.success(WorkerParamsFactory.toData(nextWorkerParams)) } else { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoUpdater.kt index 60d1a217a7..09d82c7b07 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoUpdater.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoUpdater.kt @@ -17,7 +17,11 @@ package im.vector.matrix.android.internal.session.room.send import com.zhuinden.monarchy.Monarchy +import im.vector.matrix.android.api.session.events.model.Content +import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.room.send.SendState +import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult +import im.vector.matrix.android.internal.database.mapper.ContentMapper import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.query.where import timber.log.Timber @@ -38,4 +42,15 @@ internal class LocalEchoUpdater @Inject constructor(private val monarchy: Monarc } } } + + fun updateEncryptedEcho(eventId: String, encryptedContent: Content, mxEventDecryptionResult: MXEventDecryptionResult) { + monarchy.writeAsync { realm -> + val sendingEventEntity = EventEntity.where(realm, eventId).findFirst() + if (sendingEventEntity != null) { + sendingEventEntity.type = EventType.ENCRYPTED + sendingEventEntity.content = ContentMapper.map(encryptedContent) + sendingEventEntity.setDecryptionResult(mxEventDecryptionResult) + } + } + } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt index c993dc1ea8..70c1e39334 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt @@ -25,6 +25,7 @@ import im.vector.matrix.android.api.session.room.model.RoomMemberContent import im.vector.matrix.android.api.session.room.model.tag.RoomTagContent import im.vector.matrix.android.api.session.room.send.SendState import im.vector.matrix.android.internal.crypto.DefaultCryptoService +import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult import im.vector.matrix.android.internal.database.helper.addOrUpdate import im.vector.matrix.android.internal.database.helper.addTimelineEvent @@ -39,6 +40,7 @@ import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoo import im.vector.matrix.android.internal.database.query.getOrCreate import im.vector.matrix.android.internal.database.query.getOrNull import im.vector.matrix.android.internal.database.query.where +import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.matrix.android.internal.session.DefaultInitialSyncProgressService import im.vector.matrix.android.internal.session.mapWithProgress import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater @@ -261,20 +263,12 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle if (sendingEventEntity != null) { Timber.v("Remove local echo for tx:$it") roomEntity.sendingTimelineEvents.remove(sendingEventEntity) - if (event.isEncrypted()) { - // Maybe just a temp work around? - // Decrypt the remote echo right now, to avoid seeing it decrypt again - try { - val result = cryptoService.decryptEvent(event.copy(roomId = roomId), event.roomId ?: "") - event.mxDecryptionResult = OlmDecryptionResult( - payload = result.clearEvent, - senderKey = result.senderCurve25519Key, - keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) }, - forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain - ) - eventEntity.setDecryptionResult(result) - } catch (failure: Throwable) { - Timber.v("Failed to decrypt remote echo: ${failure.localizedMessage}") + if (event.isEncrypted() && event.content?.get("algorithm") as? String == MXCRYPTO_ALGORITHM_MEGOLM) { + // updated with echo decryption, to avoid seeing it decrypt again + val adapter = MoshiProvider.providesMoshi().adapter(OlmDecryptionResult::class.java) + sendingEventEntity.root?.decryptionResultJson?.let { json -> + eventEntity.decryptionResultJson = json + event.mxDecryptionResult = adapter.fromJson(json) } } } else { From 7c1428e097eaeeca5b8b190c404a1bed624966a5 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 12 Mar 2020 10:05:55 +0100 Subject: [PATCH 3/3] preserver relations as non encrypted --- .../android/internal/session/room/send/EncryptEventWorker.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt index bac4b29d87..e4424f1cb3 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt @@ -112,7 +112,7 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters) senderCurve25519Key = result.eventContent["sender_key"] as? String, claimedEd25519Key = crypto.getMyDevice().fingerprint() ) - localEchoUpdater.updateEncryptedEcho(localEvent.eventId, result.eventContent, decryptionLocalEcho) + localEchoUpdater.updateEncryptedEcho(localEvent.eventId, safeResult.eventContent, decryptionLocalEcho) } val nextWorkerParams = SendEventWorker.Params(params.sessionId, encryptedEvent)