Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract common crypto interface for all flavors #8470

Merged
merged 4 commits into from
May 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/8470.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Refactoring: Extract a new interface for common access to crypto store between kotlin and rust crypto
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreRoomSessionD
import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreRoomSessionsDataTask
import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreSessionsDataTask
import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.UpdateKeysBackupVersionTask
import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStore
import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreMigration
Expand Down Expand Up @@ -254,6 +255,9 @@ internal abstract class CryptoModule {
@Binds
abstract fun bindCryptoStore(store: RealmCryptoStore): IMXCryptoStore

@Binds
abstract fun bindCommonCryptoStore(store: RealmCryptoStore): IMXCommonCryptoStore

@Binds
abstract fun bindSendEventTask(task: DefaultSendEventTask): SendEventTask

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -506,10 +506,7 @@ internal class DefaultCryptoService @Inject constructor(
null
} else {
withContext(coroutineDispatchers.io) {
cryptoStore.deviceWithIdentityKey(senderKey).takeIf {
// check that the claimed user id matches
it?.userId == userId
}
cryptoStore.deviceWithIdentityKey(userId, senderKey)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,24 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.UserIdentity
import org.matrix.android.sdk.api.session.crypto.keysbackup.SavedKeyBackupKeyInfo
import org.matrix.android.sdk.api.session.crypto.model.AuditTrail
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.api.session.crypto.model.CryptoRoomInfo
import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.api.session.crypto.model.RoomKeyRequestBody
import org.matrix.android.sdk.api.session.crypto.model.TrailType
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent
import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent
import org.matrix.android.sdk.api.session.events.model.content.WithHeldCode
import org.matrix.android.sdk.api.util.Optional
import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrapper
import org.matrix.android.sdk.internal.crypto.model.OlmSessionWrapper
import org.matrix.android.sdk.internal.crypto.model.OutboundGroupSessionWrapper
import org.matrix.android.sdk.internal.crypto.store.db.CryptoStoreAggregator
import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntity
import org.matrix.olm.OlmAccount
import org.matrix.olm.OlmOutboundGroupSession

/**
* The crypto data store.
*/
internal interface IMXCryptoStore {
internal interface IMXCryptoStore : IMXCommonCryptoStore {

/**
* @return the device id
Expand Down Expand Up @@ -78,21 +74,6 @@ internal interface IMXCryptoStore {
*/
fun getInboundGroupSessions(roomId: String): List<MXInboundMegolmSessionWrapper>

/**
* @return true to unilaterally blacklist all unverified devices.
*/
fun getGlobalBlacklistUnverifiedDevices(): Boolean

/**
* Set the global override for whether the client should ever send encrypted
* messages to unverified devices.
* If false, it can still be overridden per-room.
* If true, it overrides the per-room settings.
*
* @param block true to unilaterally blacklist all
*/
fun setGlobalBlacklistUnverifiedDevices(block: Boolean)

/**
* Enable or disable key gossiping.
* Default is true.
Expand Down Expand Up @@ -123,28 +104,6 @@ internal interface IMXCryptoStore {
*/
fun getRoomsListBlacklistUnverifiedDevices(): List<String>

/**
* A live status regarding sharing keys for unverified devices in this room.
*
* @return Live status
*/
fun getLiveBlockUnverifiedDevices(roomId: String): LiveData<Boolean>

/**
* Tell if unverified devices should be blacklisted when sending keys.
*
* @return true if should not send keys to unverified devices
*/
fun getBlockUnverifiedDevices(roomId: String): Boolean

/**
* Define if encryption keys should be sent to unverified devices in this room.
*
* @param roomId the roomId
* @param block if true will not send keys to unverified devices
*/
fun blockUnverifiedDevicesInRoom(roomId: String, block: Boolean)

/**
* Get the current keys backup version.
*/
Expand Down Expand Up @@ -186,16 +145,6 @@ internal interface IMXCryptoStore {
*/
fun deleteStore()

/**
* open any existing crypto store.
*/
fun open()

/**
* Close the store.
*/
fun close()

/**
* Store the device id.
*
Expand Down Expand Up @@ -262,14 +211,6 @@ internal interface IMXCryptoStore {

fun getLiveDeviceWithId(deviceId: String): LiveData<Optional<CryptoDeviceInfo>>

fun getMyDevicesInfo(): List<DeviceInfo>

fun getLiveMyDevicesInfo(): LiveData<List<DeviceInfo>>

fun getLiveMyDevicesInfo(deviceId: String): LiveData<Optional<DeviceInfo>>

fun saveMyDevicesInfo(info: List<DeviceInfo>)

/**
* Store the crypto algorithm for a room.
*
Expand All @@ -278,47 +219,8 @@ internal interface IMXCryptoStore {
*/
fun storeRoomAlgorithm(roomId: String, algorithm: String?)

/**
* Provides the algorithm used in a dedicated room.
*
* @param roomId the room id
* @return the algorithm, null is the room is not encrypted
*/
fun getRoomAlgorithm(roomId: String): String?

fun getRoomCryptoInfo(roomId: String): CryptoRoomInfo?
fun setAlgorithmInfo(roomId: String, encryption: EncryptionEventContent?)

/**
* This is a bit different than isRoomEncrypted.
* A room is encrypted when there is a m.room.encryption state event in the room (malformed/invalid or not).
* But the crypto layer has additional guaranty to ensure that encryption would never been reverted.
* It's defensive coding out of precaution (if ever state is reset).
*/
fun roomWasOnceEncrypted(roomId: String): Boolean

fun shouldEncryptForInvitedMembers(roomId: String): Boolean

/**
* Sets a boolean flag that will determine whether or not this device should encrypt Events for
* invited members.
*
* @param roomId the room id
* @param shouldEncryptForInvitedMembers The boolean flag
*/
fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean)

fun shouldShareHistory(roomId: String): Boolean

/**
* Sets a boolean flag that will determine whether or not room history (existing inbound sessions)
* will be shared to new user invites.
*
* @param roomId the room id
* @param shouldShareHistory The boolean flag
*/
fun setShouldShareHistory(roomId: String, shouldShareHistory: Boolean)

/**
* Store a session between the logged-in user and another device.
*
Expand Down Expand Up @@ -361,15 +263,6 @@ internal interface IMXCryptoStore {
*/
fun storeInboundGroupSessions(sessions: List<MXInboundMegolmSessionWrapper>)

/**
* Retrieve an inbound group session.
*
* @param sessionId the session identifier.
* @param senderKey the base64-encoded curve25519 key of the sender.
* @return an inbound group session.
*/
fun getInboundGroupSession(sessionId: String, senderKey: String): MXInboundMegolmSessionWrapper?

/**
* Retrieve an inbound group session, filtering shared history.
*
Expand Down Expand Up @@ -552,7 +445,6 @@ internal interface IMXCryptoStore {
// fun getCrossSigningPrivateKeysFlow(): Flow<Optional<PrivateKeysInfo>>

fun getGlobalCryptoConfig(): GlobalCryptoConfig
fun getLiveGlobalCryptoConfig(): LiveData<GlobalCryptoConfig>

fun saveBackupRecoveryKey(recoveryKey: String?, version: String?)
fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo?
Expand Down Expand Up @@ -597,14 +489,8 @@ internal interface IMXCryptoStore {

fun setDeviceKeysUploaded(uploaded: Boolean)
fun areDeviceKeysUploaded(): Boolean
fun tidyUpDataBase()
fun getOutgoingRoomKeyRequests(inStates: Set<OutgoingRoomKeyRequestState>): List<OutgoingKeyRequest>

/**
* Store a bunch of data collected during a sync response treatment. @See [CryptoStoreAggregator].
*/
fun storeData(cryptoStoreAggregator: CryptoStoreAggregator)

/**
* Store a bunch of data related to the users. @See [UserDataToStore].
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,19 @@ internal class RealmCryptoStore @Inject constructor(
}
}

override fun deviceWithIdentityKey(userId: String, identityKey: String): CryptoDeviceInfo? {
return doWithRealm(realmConfiguration) { realm ->
realm.where<DeviceInfoEntity>()
.equalTo(DeviceInfoEntityFields.USER_ID, userId)
.contains(DeviceInfoEntityFields.KEYS_MAP_JSON, identityKey)
.findAll()
.mapNotNull { CryptoMapper.mapToModel(it) }
.firstOrNull {
it.identityKey() == identityKey
}
}
}

override fun storeUserDevices(userId: String, devices: Map<String, CryptoDeviceInfo>?) {
doRealmTransaction("storeUserDevices", realmConfiguration) { realm ->
storeUserDevices(realm, userId, devices)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
package org.matrix.android.sdk.internal.crypto

import org.matrix.android.sdk.api.crypto.MXCryptoConfig
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore
import javax.inject.Inject

internal class ShouldEncryptForInvitedMembersUseCase @Inject constructor(private val cryptoConfig: MXCryptoConfig,
private val cryptoStore: IMXCryptoStore) {
private val cryptoStore: IMXCommonCryptoStore) {

operator fun invoke(roomId: String): Boolean {
return cryptoConfig.enableEncryptionForInvitedMembers && cryptoStore.shouldEncryptForInvitedMembers(roomId)
Expand Down
Loading