Skip to content

Commit e25dd9b

Browse files
- Share only the first chunk of inbound sessions instead of the whole key history
- Download keys if the user is unknown (first invite)
1 parent ffd0c80 commit e25dd9b

File tree

4 files changed

+58
-3
lines changed

4 files changed

+58
-3
lines changed

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic
4141
import org.matrix.android.sdk.api.session.events.model.Content
4242
import org.matrix.android.sdk.api.session.events.model.Event
4343
import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent
44+
import org.matrix.android.sdk.internal.database.helper.SessionInfoPair
4445

4546
interface CryptoService {
4647

@@ -164,7 +165,12 @@ interface CryptoService {
164165
fun prepareToEncrypt(roomId: String, callback: MatrixCallback<Unit>)
165166

166167
/**
167-
* Share existing inbound sessions with the provided userId devices
168+
* Share all existing inbound sessions to the provided userId devices
168169
*/
169170
fun sendSharedHistoryKeys(roomId: String, userId: String)
171+
172+
/**
173+
* Share all inbound sessions of the last chunk messages to the provided userId devices
174+
*/
175+
fun sendSharedHistoryKeysToLastChunk(roomId: String, userId: String, sessionInfoSet: Set<SessionInfoPair>?)
170176
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask
9292
import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask
9393
import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask
9494
import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService
95+
import org.matrix.android.sdk.internal.database.helper.SessionInfoPair
9596
import org.matrix.android.sdk.internal.di.DeviceId
9697
import org.matrix.android.sdk.internal.di.MoshiProvider
9798
import org.matrix.android.sdk.internal.di.UserId
@@ -1375,6 +1376,34 @@ internal class DefaultCryptoService @Inject constructor(
13751376
}
13761377
}
13771378

1379+
override fun sendSharedHistoryKeysToLastChunk(roomId: String, userId: String, sessionInfoSet: Set<SessionInfoPair>?) {
1380+
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
1381+
runCatching {
1382+
deviceListManager.downloadKeys(listOf(userId), false)
1383+
}.mapCatching {
1384+
val userDevices = cryptoStore.getUserDevices(userId)
1385+
userDevices?.forEach {
1386+
// Lets share the provided inbound sessions for every user device
1387+
val deviceId = it.key
1388+
sessionInfoSet?.mapNotNull { sessionInfoPair ->
1389+
// Get inbound session from sessionId and sessionKey
1390+
cryptoStore.getInboundGroupSession(sessionInfoPair.first, sessionInfoPair.second)
1391+
}?.filter { inboundGroupSession ->
1392+
// Filter only sessions with sharedHistory enabled
1393+
inboundGroupSession.sharedHistory
1394+
}?.forEach { inboundGroupSession ->
1395+
// Share the session to userId with deviceId
1396+
val exportedKeys = inboundGroupSession.exportKeys()
1397+
val algorithm = exportedKeys?.algorithm
1398+
val decryptor = roomDecryptorProvider.getRoomDecryptor(roomId, algorithm)
1399+
decryptor?.shareKeysWithDevice(exportedKeys, deviceId, userId)
1400+
Timber.i("## CRYPTO | Sharing inbound session")
1401+
}
1402+
}
1403+
}
1404+
}
1405+
}
1406+
13781407
override fun sendSharedHistoryKeys(roomId: String, userId: String) {
13791408
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
13801409
val userDevices = cryptoStore.getUserDevices(userId)
@@ -1385,7 +1414,7 @@ internal class DefaultCryptoService @Inject constructor(
13851414
inboundSessions.filter { inboundGroupSession ->
13861415
inboundGroupSession.sharedHistory
13871416
}.forEach { inboundGroupSession ->
1388-
// Share the session with the to userId with deviceId
1417+
// Share the session to userId with deviceId
13891418
val exportedKeys = inboundGroupSession.exportKeys()
13901419
val algorithm = exportedKeys?.algorithm
13911420
val decryptor = roomDecryptorProvider.getRoomDecryptor(roomId, algorithm)

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ package org.matrix.android.sdk.internal.database.helper
1919
import io.realm.Realm
2020
import io.realm.Sort
2121
import io.realm.kotlin.createObject
22+
import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent
23+
import org.matrix.android.sdk.api.session.events.model.toModel
2224
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
25+
import org.matrix.android.sdk.internal.database.mapper.asDomain
2326
import org.matrix.android.sdk.internal.database.model.ChunkEntity
2427
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields
2528
import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity
@@ -32,6 +35,7 @@ import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFie
3235
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
3336
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
3437
import org.matrix.android.sdk.internal.database.query.find
38+
import org.matrix.android.sdk.internal.database.query.findLastForwardChunkOfRoom
3539
import org.matrix.android.sdk.internal.database.query.getOrCreate
3640
import org.matrix.android.sdk.internal.database.query.where
3741
import org.matrix.android.sdk.internal.database.query.whereRoomId
@@ -236,3 +240,14 @@ internal fun ChunkEntity.isMoreRecentThan(chunkToCheck: ChunkEntity): Boolean {
236240
// We don't know, so we assume it's false
237241
return false
238242
}
243+
244+
internal fun ChunkEntity.Companion.findLatestSessionInfo(realm: Realm, roomId: String): Set<SessionInfoPair>? =
245+
ChunkEntity.findLastForwardChunkOfRoom(realm, roomId)?.timelineEvents?.mapNotNull { timelineEvent ->
246+
timelineEvent?.root?.asDomain()?.content?.toModel<EncryptedEventContent>()?.let { content ->
247+
content.sessionId ?: return@mapNotNull null
248+
content.senderKey ?: return@mapNotNull null
249+
Pair(content.sessionId, content.senderKey)
250+
}
251+
}?.toSet()
252+
253+
internal typealias SessionInfoPair = Pair<String, String>

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ import org.matrix.android.sdk.api.session.room.members.MembershipService
2929
import org.matrix.android.sdk.api.session.room.members.RoomMemberQueryParams
3030
import org.matrix.android.sdk.api.session.room.model.Membership
3131
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
32+
import org.matrix.android.sdk.internal.database.helper.findLatestSessionInfo
3233
import org.matrix.android.sdk.internal.database.mapper.asDomain
34+
import org.matrix.android.sdk.internal.database.model.ChunkEntity
3335
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity
3436
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields
3537
import org.matrix.android.sdk.internal.di.SessionDatabase
@@ -129,7 +131,10 @@ internal class DefaultMembershipService @AssistedInject constructor(
129131
}
130132

131133
override suspend fun invite(userId: String, reason: String?) {
132-
cryptoService.sendSharedHistoryKeys(roomId, userId)
134+
val sessionInfoSet = Realm.getInstance(monarchy.realmConfiguration).use {
135+
ChunkEntity.findLatestSessionInfo(it, roomId)
136+
}
137+
cryptoService.sendSharedHistoryKeysToLastChunk(roomId, userId, sessionInfoSet)
133138
val params = InviteTask.Params(roomId, userId, reason)
134139
inviteTask.execute(params)
135140
}

0 commit comments

Comments
 (0)