PR remarks

This commit is contained in:
ariskotsomitopoulos 2022-05-18 14:05:58 +03:00
parent abbc57429a
commit b9adbb7d60
3 changed files with 16 additions and 22 deletions

View File

@ -20,6 +20,7 @@ import androidx.test.filters.LargeTest
import org.amshove.kluent.internal.assertFailsWith
import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Assert.fail
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@ -101,8 +102,12 @@ class ReplayAttackTest : InstrumentedTest {
val timelineId = "timelineId"
// Lets decrypt the original event
aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId)
// Lets try to decrypt the same event
aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId)
try {
// Lets try to decrypt the same event
aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId)
} catch (ex: Throwable) {
fail("Shouldn't throw a decryption error for same event")
}
}
cryptoTestData.cleanUp(testHelper)
}

View File

@ -96,10 +96,9 @@ internal class MXOlmDevice @Inject constructor(
// So, store these message indexes per timeline id.
//
// The first level keys are timeline ids.
// The second level keys are strings of form "<senderKey>|<session_id>|<message_index>"
private val inboundGroupSessionMessageIndexes: MutableMap<String, MutableSet<String>> = HashMap()
private val replayAttackMap: MutableMap<String, String> = HashMap()
// The second level values is a Map that represents:
// "<senderKey>|<session_id>|<roomId>|<message_index>" --> eventId
private val inboundGroupSessionMessageIndexes: MutableMap<String, MutableMap<String, String>> = HashMap()
init {
// Retrieve the account from the store
@ -798,15 +797,14 @@ internal class MXOlmDevice @Inject constructor(
Timber.tag(loggerTag.value).d("## decryptGroupMessage() mIndex: ${decryptResult.mIndex}")
if (timeline?.isNotBlank() == true) {
val timelineSet = inboundGroupSessionMessageIndexes.getOrPut(timeline) { mutableSetOf() }
if (timelineSet.contains(messageIndexKey) && messageIndexKey.alreadyUsed(eventId)) {
val replayAttackMap = inboundGroupSessionMessageIndexes.getOrPut(timeline) { mutableMapOf() }
if (replayAttackMap.contains(messageIndexKey) && replayAttackMap[messageIndexKey] != eventId) {
val reason = String.format(MXCryptoError.DUPLICATE_MESSAGE_INDEX_REASON, decryptResult.mIndex)
Timber.tag(loggerTag.value).e("## decryptGroupMessage() timelineId=$timeline: $reason")
throw MXCryptoError.Base(MXCryptoError.ErrorType.DUPLICATED_MESSAGE_INDEX, reason)
}
timelineSet.add(messageIndexKey)
replayAttackMap[messageIndexKey] = eventId
}
replayAttackMap[messageIndexKey] = eventId
inboundGroupSessionStore.storeInBoundGroupSession(sessionHolder, sessionId, senderKey)
val payload = try {
val adapter = MoshiProvider.providesMoshi().adapter<JsonDict>(JSON_DICT_PARAMETERIZED_TYPE)
@ -825,13 +823,6 @@ internal class MXOlmDevice @Inject constructor(
)
}
/**
* Determines whether or not the messageKey has already been used to decrypt another eventId
*/
private fun String.alreadyUsed(eventId: String): Boolean {
return replayAttackMap[this] != null && replayAttackMap[this] != eventId
}
/**
* Reset replay attack data for the given timeline.
*

View File

@ -25,7 +25,6 @@ import org.matrix.android.sdk.api.session.crypto.MXCryptoError
import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult
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.isThread
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
import org.matrix.android.sdk.api.session.initsync.InitSyncStep
@ -521,7 +520,7 @@ internal class RoomSyncHandler @Inject constructor(
private fun decryptIfNeeded(event: Event, roomId: String) {
try {
val timelineId = generateTimelineId(roomId, event)
val timelineId = generateTimelineId(roomId)
// Event from sync does not have roomId, so add it to the event first
// note: runBlocking should be used here while we are in realm single thread executor, to avoid thread switching
val result = runBlocking { cryptoService.decryptEvent(event.copy(roomId = roomId), timelineId) }
@ -539,9 +538,8 @@ internal class RoomSyncHandler @Inject constructor(
}
}
private fun generateTimelineId(roomId: String, event: Event): String {
val threadIndicator = if (event.isThread()) "_thread_" else "_"
return "${RoomSyncHandler::class.java.simpleName}$threadIndicator$roomId"
private fun generateTimelineId(roomId: String): String {
return "${RoomSyncHandler::class.java.simpleName}$roomId"
}
data class EphemeralResult(