Store device key in SharedSessionEntity

Code review changes


Fix database migraiton


Fix wrong self assignement + comment
This commit is contained in:
Valere 2021-09-10 14:27:39 +02:00 committed by Benoit Marty
parent 60004f02c3
commit 3a0734f6e2
7 changed files with 70 additions and 18 deletions

View File

@ -170,7 +170,7 @@ internal class MXMegolmEncryption(
val deviceIds = devicesInRoom.getUserDeviceIds(userId)
for (deviceId in deviceIds!!) {
val deviceInfo = devicesInRoom.getObject(userId, deviceId)
if (deviceInfo != null && !cryptoStore.getSharedSessionInfo(roomId, safeSession.sessionId, userId, deviceId).found) {
if (deviceInfo != null && !cryptoStore.getSharedSessionInfo(roomId, safeSession.sessionId, deviceInfo).found) {
val devices = shareMap.getOrPut(userId) { ArrayList() }
devices.add(deviceInfo)
}
@ -270,8 +270,8 @@ internal class MXMegolmEncryption(
// for dead devices on every message.
val gossipingEventBuffer = arrayListOf<Event>()
for ((userId, devicesToShareWith) in devicesByUser) {
for ((deviceId) in devicesToShareWith) {
session.sharedWithHelper.markedSessionAsShared(userId, deviceId, chainIndex)
for (deviceInfo in devicesToShareWith) {
session.sharedWithHelper.markedSessionAsShared(deviceInfo, chainIndex)
gossipingEventBuffer.add(
Event(
type = EventType.ROOM_KEY,
@ -279,7 +279,7 @@ internal class MXMegolmEncryption(
content = submap.apply {
this["session_key"] = ""
// we add a fake key for trail
this["_dest"] = "$userId|$deviceId"
this["_dest"] = "$userId|${deviceInfo.deviceId}"
}
))
}
@ -429,7 +429,7 @@ internal class MXMegolmEncryption(
.also { Timber.w("## Crypto reshareKey: Device not found") }
// Get the chain index of the key we previously sent this device
val wasSessionSharedWithUser = cryptoStore.getSharedSessionInfo(roomId, sessionId, userId, deviceId)
val wasSessionSharedWithUser = cryptoStore.getSharedSessionInfo(roomId, sessionId, deviceInfo)
if (!wasSessionSharedWithUser.found) {
// This session was never shared with this user
// Send a room key with held

View File

@ -16,6 +16,7 @@
package org.matrix.android.sdk.internal.crypto.algorithms.megolm
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
@ -28,7 +29,13 @@ internal class SharedWithHelper(
return cryptoStore.getSharedWithInfo(roomId, sessionId)
}
fun markedSessionAsShared(userId: String, deviceId: String, chainIndex: Int) {
cryptoStore.markedSessionAsShared(roomId, sessionId, userId, deviceId, chainIndex)
fun markedSessionAsShared(deviceInfo: CryptoDeviceInfo, chainIndex: Int) {
cryptoStore.markedSessionAsShared(
roomId = roomId,
sessionId = sessionId,
userId = deviceInfo.userId,
deviceId = deviceInfo.deviceId,
deviceIdentityKey = deviceInfo.identityKey() ?: "",
chainIndex = chainIndex)
}
}

View File

@ -450,7 +450,8 @@ internal interface IMXCryptoStore {
fun addWithHeldMegolmSession(withHeldContent: RoomKeyWithHeldContent)
fun getWithHeldMegolmSession(roomId: String, sessionId: String): RoomKeyWithHeldContent?
fun markedSessionAsShared(roomId: String?, sessionId: String, userId: String, deviceId: String, chainIndex: Int)
fun markedSessionAsShared(roomId: String?, sessionId: String, userId: String, deviceId: String,
deviceIdentityKey: String, chainIndex: Int)
/**
* Query for information on this session sharing history.
@ -459,7 +460,7 @@ internal interface IMXCryptoStore {
* in this case chainIndex is not nullindicates the ratchet position.
* In found is false, chainIndex is null
*/
fun getSharedSessionInfo(roomId: String?, sessionId: String, userId: String, deviceId: String): SharedSessionResult
fun getSharedSessionInfo(roomId: String?, sessionId: String, deviceInfo: CryptoDeviceInfo): SharedSessionResult
data class SharedSessionResult(val found: Boolean, val chainIndex: Int?)
fun getSharedWithInfo(roomId: String?, sessionId: String): MXUsersDevicesMap<Int>

View File

@ -1681,7 +1681,12 @@ internal class RealmCryptoStore @Inject constructor(
}
}
override fun markedSessionAsShared(roomId: String?, sessionId: String, userId: String, deviceId: String, chainIndex: Int) {
override fun markedSessionAsShared(roomId: String?,
sessionId: String,
userId: String,
deviceId: String,
deviceIdentityKey: String,
chainIndex: Int) {
doRealmTransaction(realmConfiguration) { realm ->
SharedSessionEntity.create(
realm = realm,
@ -1689,14 +1694,22 @@ internal class RealmCryptoStore @Inject constructor(
sessionId = sessionId,
userId = userId,
deviceId = deviceId,
deviceIdentityKey = deviceIdentityKey,
chainIndex = chainIndex
)
}
}
override fun getSharedSessionInfo(roomId: String?, sessionId: String, userId: String, deviceId: String): IMXCryptoStore.SharedSessionResult {
override fun getSharedSessionInfo(roomId: String?, sessionId: String, deviceInfo: CryptoDeviceInfo): IMXCryptoStore.SharedSessionResult {
return doWithRealm(realmConfiguration) { realm ->
SharedSessionEntity.get(realm, roomId, sessionId, userId, deviceId)?.let {
SharedSessionEntity.get(
realm = realm,
roomId = roomId,
sessionId = sessionId,
userId = deviceInfo.userId,
deviceId = deviceInfo.deviceId,
deviceIdentityKey = deviceInfo.identityKey()
)?.let {
IMXCryptoStore.SharedSessionResult(true, it.chainIndex)
} ?: IMXCryptoStore.SharedSessionResult(false, null)
}

View File

@ -55,7 +55,7 @@ internal object RealmCryptoStoreMigration : RealmMigration {
// 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)
const val CRYPTO_STORE_SCHEMA_VERSION = 13L
const val CRYPTO_STORE_SCHEMA_VERSION = 14L
private fun RealmObjectSchema.addFieldIfNotExists(fieldName: String, fieldType: Class<*>): RealmObjectSchema {
if (!hasField(fieldName)) {
@ -94,6 +94,7 @@ internal object RealmCryptoStoreMigration : RealmMigration {
if (oldVersion <= 10) migrateTo11(realm)
if (oldVersion <= 11) migrateTo12(realm)
if (oldVersion <= 12) migrateTo13(realm)
if (oldVersion <= 13) migrateTo14(realm)
}
private fun migrateTo1Legacy(realm: DynamicRealm) {
@ -554,4 +555,21 @@ internal object RealmCryptoStoreMigration : RealmMigration {
Timber.e("TrustLevelEntity cleanup: Something is not correct...")
}
}
// Version 14L Update the way we remember key sharing
private fun migrateTo14(realm: DynamicRealm) {
Timber.d("Step 13 -> 14")
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))
}
}
}

View File

@ -30,6 +30,7 @@ internal open class SharedSessionEntity(
@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() {

View File

@ -16,15 +16,20 @@
package org.matrix.android.sdk.internal.crypto.store.db.query
import org.matrix.android.sdk.internal.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
import io.realm.Realm
import io.realm.RealmResults
import io.realm.kotlin.createObject
import io.realm.kotlin.where
import org.matrix.android.sdk.internal.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)
internal fun SharedSessionEntity.Companion.get(realm: Realm,
roomId: String?,
sessionId: String,
userId: String,
deviceId: String,
deviceIdentityKey: String?)
: SharedSessionEntity? {
return realm.where<SharedSessionEntity>()
.equalTo(SharedSessionEntityFields.ROOM_ID, roomId)
@ -32,6 +37,7 @@ internal fun SharedSessionEntity.Companion.get(realm: Realm, roomId: String?, se
.equalTo(SharedSessionEntityFields.ALGORITHM, MXCRYPTO_ALGORITHM_MEGOLM)
.equalTo(SharedSessionEntityFields.USER_ID, userId)
.equalTo(SharedSessionEntityFields.DEVICE_ID, deviceId)
.equalTo(SharedSessionEntityFields.DEVICE_IDENTITY_KEY, deviceIdentityKey)
.findFirst()
}
@ -44,7 +50,12 @@ internal fun SharedSessionEntity.Companion.get(realm: Realm, roomId: String?, se
.findAll()
}
internal fun SharedSessionEntity.Companion.create(realm: Realm, roomId: String?, sessionId: String, userId: String, deviceId: String, chainIndex: Int)
internal fun SharedSessionEntity.Companion.create(realm: Realm, roomId: String?,
sessionId: String,
userId: String,
deviceId: String,
deviceIdentityKey: String,
chainIndex: Int)
: SharedSessionEntity {
return realm.createObject<SharedSessionEntity>().apply {
this.roomId = roomId
@ -52,6 +63,7 @@ internal fun SharedSessionEntity.Companion.create(realm: Realm, roomId: String?,
this.sessionId = sessionId
this.userId = userId
this.deviceId = deviceId
this.deviceIdentityKey = deviceIdentityKey
this.chainIndex = chainIndex
}
}