mirror of
https://github.com/vector-im/riotX-android
synced 2025-10-06 00:02:48 +02:00
Create Manager to inject directly instead of service
Cleanup the Service from app point of view
This commit is contained in:
@@ -77,9 +77,4 @@ interface CrossSigningService {
|
||||
fun checkDeviceTrust(otherUserId: String,
|
||||
otherDeviceId: String,
|
||||
locallyTrusted: Boolean?): DeviceTrustResult
|
||||
|
||||
// FIXME Those method do not have to be in the service
|
||||
fun onSecretMSKGossip(mskPrivateKey: String)
|
||||
fun onSecretSSKGossip(sskPrivateKey: String)
|
||||
fun onSecretUSKGossip(uskPrivateKey: String)
|
||||
}
|
||||
|
@@ -173,8 +173,6 @@ interface KeysBackupService {
|
||||
password: String,
|
||||
callback: MatrixCallback<Unit>)
|
||||
|
||||
fun onSecretKeyGossip(secret: String)
|
||||
|
||||
/**
|
||||
* Restore a backup with a recovery key from a given backup version stored on the homeserver.
|
||||
*
|
||||
|
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.matrix.android.sdk.api.session.crypto.verification
|
||||
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.events.model.LocalEcho
|
||||
|
||||
/**
|
||||
@@ -137,6 +136,4 @@ interface VerificationService {
|
||||
return age in tooInThePast..tooInTheFuture
|
||||
}
|
||||
}
|
||||
|
||||
fun onPotentiallyInterestingEventRoomFailToDecrypt(event: Event)
|
||||
}
|
||||
|
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
|
||||
internal interface CryptoDecryptor {
|
||||
fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult
|
||||
}
|
@@ -57,9 +57,10 @@ import org.matrix.android.sdk.internal.crypto.algorithms.IMXGroupEncryption
|
||||
import org.matrix.android.sdk.internal.crypto.algorithms.IMXWithHeldExtension
|
||||
import org.matrix.android.sdk.internal.crypto.algorithms.megolm.MXMegolmEncryptionFactory
|
||||
import org.matrix.android.sdk.internal.crypto.algorithms.olm.MXOlmEncryptionFactory
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.CrossSigningManagerInput
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.KeysBackupManager
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.KeysBackupManagerInput
|
||||
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
|
||||
import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult
|
||||
import org.matrix.android.sdk.internal.crypto.model.MXDeviceInfo
|
||||
@@ -80,7 +81,6 @@ import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask
|
||||
import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask
|
||||
import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask
|
||||
import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask
|
||||
import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService
|
||||
import org.matrix.android.sdk.internal.di.DeviceId
|
||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
@@ -101,14 +101,7 @@ import javax.inject.Inject
|
||||
import kotlin.math.max
|
||||
|
||||
/**
|
||||
* A `CryptoService` class instance manages the end-to-end crypto for a session.
|
||||
*
|
||||
*
|
||||
* Messages posted by the user are automatically redirected to CryptoService in order to be encrypted
|
||||
* before sending.
|
||||
* In the other hand, received events goes through CryptoService for decrypting.
|
||||
* CryptoService maintains all necessary keys and their sharing with other devices required for the crypto.
|
||||
* Specially, it tracks all room membership changes events in order to do keys updates.
|
||||
*/
|
||||
@SessionScope
|
||||
internal class CryptoManager @Inject constructor(
|
||||
@@ -129,18 +122,15 @@ internal class CryptoManager @Inject constructor(
|
||||
private val mxCryptoConfig: MXCryptoConfig,
|
||||
// Device list manager
|
||||
private val deviceListManager: DeviceListManager,
|
||||
// The key backup service.
|
||||
private val keysBackupService: DefaultKeysBackupService,
|
||||
private val keysBackupManager: KeysBackupManager,
|
||||
private val keysBackupManagerInput: KeysBackupManagerInput,
|
||||
//
|
||||
private val objectSigner: ObjectSigner,
|
||||
//
|
||||
private val oneTimeKeysUploader: OneTimeKeysUploader,
|
||||
//
|
||||
private val roomDecryptorProvider: RoomDecryptorProvider,
|
||||
// The verification service.
|
||||
private val verificationService: DefaultVerificationService,
|
||||
|
||||
private val crossSigningService: DefaultCrossSigningService,
|
||||
private val crossSigningManagerInput: CrossSigningManagerInput,
|
||||
//
|
||||
private val incomingGossipingRequestManager: IncomingGossipingRequestManager,
|
||||
//
|
||||
@@ -164,12 +154,15 @@ internal class CryptoManager @Inject constructor(
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val cryptoCoroutineScope: CoroutineScope,
|
||||
private val eventDecryptor: EventDecryptor
|
||||
) : CryptoService {
|
||||
) : CryptoService,
|
||||
CryptoManagerInput,
|
||||
CryptoDecryptor,
|
||||
CryptoSyncInput {
|
||||
|
||||
private val isStarting = AtomicBoolean(false)
|
||||
private val isStarted = AtomicBoolean(false)
|
||||
|
||||
fun onStateEvent(roomId: String, event: Event) {
|
||||
override fun onStateEvent(roomId: String, event: Event) {
|
||||
when (event.getClearType()) {
|
||||
EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event)
|
||||
EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event)
|
||||
@@ -177,7 +170,7 @@ internal class CryptoManager @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun onLiveEvent(roomId: String, event: Event) {
|
||||
override fun onLiveEvent(roomId: String, event: Event) {
|
||||
when (event.getClearType()) {
|
||||
EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event)
|
||||
EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event)
|
||||
@@ -185,7 +178,7 @@ internal class CryptoManager @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
val gossipingBuffer = mutableListOf<Event>()
|
||||
private val gossipingBuffer = mutableListOf<Event>()
|
||||
|
||||
override fun setDeviceName(deviceId: String, deviceName: String, callback: MatrixCallback<Unit>) {
|
||||
setDeviceNameTask
|
||||
@@ -322,12 +315,12 @@ internal class CryptoManager @Inject constructor(
|
||||
oneTimeKeysUploader.maybeUploadOneTimeKeys()
|
||||
// this can throw if no backup
|
||||
tryOrNull {
|
||||
keysBackupService.checkAndStartKeysBackup()
|
||||
keysBackupManager.checkAndStartKeysBackup()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onSyncWillProcess(isInitialSync: Boolean) {
|
||||
override fun onSyncWillProcess(isInitialSync: Boolean) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
if (isInitialSync) {
|
||||
try {
|
||||
@@ -391,24 +384,18 @@ internal class CryptoManager @Inject constructor(
|
||||
// Always enabled on Matrix Android SDK2
|
||||
override fun isCryptoEnabled() = true
|
||||
|
||||
/**
|
||||
* @return the Keys backup Service
|
||||
*/
|
||||
override fun keysBackupService() = keysBackupService
|
||||
override fun keysBackupService() = error("Dev error")
|
||||
|
||||
/**
|
||||
* @return the VerificationService
|
||||
*/
|
||||
override fun verificationService() = verificationService
|
||||
override fun verificationService() = error("Dev error")
|
||||
|
||||
override fun crossSigningService() = crossSigningService
|
||||
override fun crossSigningService() = error("Dev error")
|
||||
|
||||
/**
|
||||
* A sync response has been received
|
||||
*
|
||||
* @param syncResponse the syncResponse
|
||||
*/
|
||||
fun onSyncCompleted(syncResponse: SyncResponse) {
|
||||
override fun onSyncCompleted(syncResponse: SyncResponse) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
runCatching {
|
||||
if (syncResponse.deviceLists != null) {
|
||||
@@ -685,7 +672,7 @@ internal class CryptoManager @Inject constructor(
|
||||
*/
|
||||
@Throws(MXCryptoError::class)
|
||||
override fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult {
|
||||
return internalDecryptEvent(event, timeline)
|
||||
return eventDecryptor.decryptEvent(event, timeline)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -699,18 +686,6 @@ internal class CryptoManager @Inject constructor(
|
||||
eventDecryptor.decryptEventAsync(event, timeline, callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt an event
|
||||
*
|
||||
* @param event the raw event.
|
||||
* @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack.
|
||||
* @return the MXEventDecryptionResult data, or null in case of error
|
||||
*/
|
||||
@Throws(MXCryptoError::class)
|
||||
private fun internalDecryptEvent(event: Event, timeline: String): MXEventDecryptionResult {
|
||||
return eventDecryptor.decryptEvent(event, timeline)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset replay attack data for the given timeline.
|
||||
*
|
||||
@@ -725,7 +700,7 @@ internal class CryptoManager @Inject constructor(
|
||||
*
|
||||
* @param event the event
|
||||
*/
|
||||
fun onToDeviceEvent(event: Event) {
|
||||
override fun onToDeviceEvent(event: Event) {
|
||||
// event have already been decrypted
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
when (event.getClearType()) {
|
||||
@@ -772,7 +747,10 @@ internal class CryptoManager @Inject constructor(
|
||||
Timber.e("## CRYPTO | GOSSIP onRoomKeyEvent() : Unable to handle keys for ${roomKeyContent.algorithm}")
|
||||
return
|
||||
}
|
||||
alg.onRoomKeyEvent(event, keysBackupService)
|
||||
val doKeyBackup = alg.onRoomKeyEvent(event)
|
||||
if (doKeyBackup) {
|
||||
keysBackupManager.maybeBackupKeys()
|
||||
}
|
||||
}
|
||||
|
||||
private fun onKeyWithHeldReceived(event: Event) {
|
||||
@@ -825,19 +803,19 @@ internal class CryptoManager @Inject constructor(
|
||||
private fun handleSDKLevelGossip(secretName: String?, secretValue: String): Boolean {
|
||||
return when (secretName) {
|
||||
MASTER_KEY_SSSS_NAME -> {
|
||||
crossSigningService.onSecretMSKGossip(secretValue)
|
||||
crossSigningManagerInput.onSecretMSKGossip(secretValue)
|
||||
true
|
||||
}
|
||||
SELF_SIGNING_KEY_SSSS_NAME -> {
|
||||
crossSigningService.onSecretSSKGossip(secretValue)
|
||||
crossSigningManagerInput.onSecretSSKGossip(secretValue)
|
||||
true
|
||||
}
|
||||
USER_SIGNING_KEY_SSSS_NAME -> {
|
||||
crossSigningService.onSecretUSKGossip(secretValue)
|
||||
crossSigningManagerInput.onSecretUSKGossip(secretValue)
|
||||
true
|
||||
}
|
||||
KEYBACKUP_SECRET_SSSS_NAME -> {
|
||||
keysBackupService.onSecretKeyGossip(secretValue)
|
||||
keysBackupManagerInput.onSecretKeyGossip(secretValue)
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
|
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
|
||||
internal interface CryptoManagerInput {
|
||||
fun onSyncWillProcess(isInitialSync: Boolean)
|
||||
|
||||
fun onStateEvent(roomId: String, event: Event)
|
||||
|
||||
fun onLiveEvent(roomId: String, event: Event)
|
||||
}
|
@@ -96,6 +96,14 @@ import org.matrix.android.sdk.internal.session.cache.RealmClearCacheTask
|
||||
import io.realm.RealmConfiguration
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.CrossSigningManager
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.CrossSigningManagerInput
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.KeysBackupManager
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.KeysBackupManagerInput
|
||||
import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService
|
||||
import retrofit2.Retrofit
|
||||
import java.io.File
|
||||
|
||||
@@ -160,6 +168,21 @@ internal abstract class CryptoModule {
|
||||
@Binds
|
||||
abstract fun bindCryptoService(service: DefaultCryptoService): CryptoService
|
||||
|
||||
@Binds
|
||||
abstract fun bindKeysBackupService(service: DefaultKeysBackupService): KeysBackupService
|
||||
|
||||
@Binds
|
||||
abstract fun bindVerificationService(service: DefaultVerificationService): VerificationService
|
||||
|
||||
@Binds
|
||||
abstract fun bindCryptoManagerInput(manager: CryptoManager): CryptoManagerInput
|
||||
|
||||
@Binds
|
||||
abstract fun bindKeysBackupManagerInput(manager: KeysBackupManager): KeysBackupManagerInput
|
||||
|
||||
@Binds
|
||||
abstract fun bindCrossSigningManagerInput(manager: CrossSigningManager): CrossSigningManagerInput
|
||||
|
||||
@Binds
|
||||
abstract fun bindDeleteDeviceTask(task: DefaultDeleteDeviceTask): DeleteDeviceTask
|
||||
|
||||
|
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.internal.session.sync.model.SyncResponse
|
||||
|
||||
internal interface CryptoSyncInput {
|
||||
fun onToDeviceEvent(event: Event)
|
||||
|
||||
fun onSyncCompleted(syncResponse: SyncResponse)
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* A `CryptoService` class instance manages the end-to-end crypto for a session.
|
||||
*
|
||||
* Messages posted by the user are automatically redirected to CryptoService in order to be encrypted
|
||||
* before sending.
|
||||
* In the other hand, received events goes through CryptoService for decrypting.
|
||||
* CryptoService maintains all necessary keys and their sharing with other devices required for the crypto.
|
||||
* Specially, it tracks all room membership changes events in order to do keys updates.
|
||||
*
|
||||
* Implementation is basically a wrapper for [CryptoManager]
|
||||
*/
|
||||
internal class DefaultCryptoService @Inject constructor(
|
||||
private val cryptoManager: CryptoManager,
|
||||
private val keysBackupService: KeysBackupService,
|
||||
private val verificationService: VerificationService,
|
||||
private val crossSigningService: CrossSigningService,
|
||||
) : CryptoService by cryptoManager {
|
||||
|
||||
override fun keysBackupService() = keysBackupService
|
||||
|
||||
override fun verificationService() = verificationService
|
||||
|
||||
override fun crossSigningService() = crossSigningService
|
||||
|
||||
/* ==========================================================================================
|
||||
* For test only
|
||||
* ========================================================================================== */
|
||||
|
||||
@VisibleForTesting
|
||||
val cryptoStoreForTesting = cryptoManager.cryptoStoreForTesting
|
||||
}
|
@@ -44,10 +44,6 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
|
||||
coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val taskExecutor: TaskExecutor) {
|
||||
|
||||
interface UserDevicesUpdateListener {
|
||||
fun onUsersDeviceUpdate(userIds: List<String>)
|
||||
}
|
||||
|
||||
private val deviceChangeListeners = mutableListOf<UserDevicesUpdateListener>()
|
||||
|
||||
fun addListener(listener: UserDevicesUpdateListener) {
|
||||
|
@@ -136,7 +136,7 @@ internal class EventDecryptor @Inject constructor(
|
||||
|
||||
val lastForcedDate = lastNewSessionForcedDates.getObject(senderId, deviceKey) ?: 0
|
||||
val now = System.currentTimeMillis()
|
||||
if (now - lastForcedDate < DefaultCryptoService.CRYPTO_MIN_FORCE_SESSION_PERIOD_MILLIS) {
|
||||
if (now - lastForcedDate < CryptoManager.CRYPTO_MIN_FORCE_SESSION_PERIOD_MILLIS) {
|
||||
Timber.w("## CRYPTO | markOlmSessionForUnwedging: New session already forced with device at $lastForcedDate. Not forcing another")
|
||||
return
|
||||
}
|
||||
|
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
internal interface UserDevicesUpdateListener {
|
||||
fun onUsersDeviceUpdate(userIds: List<String>)
|
||||
}
|
@@ -17,7 +17,7 @@
|
||||
package org.matrix.android.sdk.internal.crypto.actions
|
||||
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.KeysBackupManager
|
||||
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import timber.log.Timber
|
||||
@@ -26,7 +26,8 @@ import javax.inject.Inject
|
||||
internal class SetDeviceVerificationAction @Inject constructor(
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
@UserId private val userId: String,
|
||||
private val defaultKeysBackupService: DefaultKeysBackupService) {
|
||||
private val keysBackupManager: KeysBackupManager
|
||||
) {
|
||||
|
||||
fun handle(trustLevel: DeviceTrustLevel, userId: String, deviceId: String) {
|
||||
val device = cryptoStore.getUserDevice(userId, deviceId)
|
||||
@@ -42,7 +43,7 @@ internal class SetDeviceVerificationAction @Inject constructor(
|
||||
// If one of the user's own devices is being marked as verified / unverified,
|
||||
// check the key backup status, since whether or not we use this depends on
|
||||
// whether it has a signature from a verified device
|
||||
defaultKeysBackupService.checkAndStartKeysBackup()
|
||||
keysBackupManager.checkAndStartKeysBackup()
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -21,7 +21,6 @@ import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest
|
||||
import org.matrix.android.sdk.internal.crypto.IncomingSecretShareRequest
|
||||
import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService
|
||||
|
||||
/**
|
||||
* An interface for decrypting data
|
||||
@@ -42,8 +41,9 @@ internal interface IMXDecrypting {
|
||||
* Handle a key event.
|
||||
*
|
||||
* @param event the key event.
|
||||
* @return true if the key should be backed up
|
||||
*/
|
||||
fun onRoomKeyEvent(event: Event, defaultKeysBackupService: DefaultKeysBackupService) {}
|
||||
fun onRoomKeyEvent(event: Event): Boolean = false
|
||||
|
||||
/**
|
||||
* Check if the some messages can be decrypted with a new session
|
||||
|
@@ -30,7 +30,6 @@ import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevice
|
||||
import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter
|
||||
import org.matrix.android.sdk.internal.crypto.algorithms.IMXDecrypting
|
||||
import org.matrix.android.sdk.internal.crypto.algorithms.IMXWithHeldExtension
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService
|
||||
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
|
||||
import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent
|
||||
import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent
|
||||
@@ -229,10 +228,10 @@ internal class MXMegolmDecryption(private val userId: String,
|
||||
*
|
||||
* @param event the key event.
|
||||
*/
|
||||
override fun onRoomKeyEvent(event: Event, defaultKeysBackupService: DefaultKeysBackupService) {
|
||||
override fun onRoomKeyEvent(event: Event): Boolean {
|
||||
Timber.v("## CRYPTO | onRoomKeyEvent()")
|
||||
var exportFormat = false
|
||||
val roomKeyContent = event.getClearContent().toModel<RoomKeyContent>() ?: return
|
||||
val roomKeyContent = event.getClearContent().toModel<RoomKeyContent>() ?: return false
|
||||
|
||||
var senderKey: String? = event.getSenderKey()
|
||||
var keysClaimed: MutableMap<String, String> = HashMap()
|
||||
@@ -240,12 +239,12 @@ internal class MXMegolmDecryption(private val userId: String,
|
||||
|
||||
if (roomKeyContent.roomId.isNullOrEmpty() || roomKeyContent.sessionId.isNullOrEmpty() || roomKeyContent.sessionKey.isNullOrEmpty()) {
|
||||
Timber.e("## CRYPTO | onRoomKeyEvent() : Key event is missing fields")
|
||||
return
|
||||
return false
|
||||
}
|
||||
if (event.getClearType() == EventType.FORWARDED_ROOM_KEY) {
|
||||
Timber.i("## CRYPTO | onRoomKeyEvent(), forward adding key : ${roomKeyContent.roomId}|${roomKeyContent.sessionId}")
|
||||
val forwardedRoomKeyContent = event.getClearContent().toModel<ForwardedRoomKeyContent>()
|
||||
?: return
|
||||
?: return false
|
||||
|
||||
forwardedRoomKeyContent.forwardingCurve25519KeyChain?.let {
|
||||
forwardingCurve25519KeyChain.addAll(it)
|
||||
@@ -253,7 +252,7 @@ internal class MXMegolmDecryption(private val userId: String,
|
||||
|
||||
if (senderKey == null) {
|
||||
Timber.e("## CRYPTO | onRoomKeyEvent() : event is missing sender_key field")
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
forwardingCurve25519KeyChain.add(senderKey)
|
||||
@@ -262,12 +261,12 @@ internal class MXMegolmDecryption(private val userId: String,
|
||||
senderKey = forwardedRoomKeyContent.senderKey
|
||||
if (null == senderKey) {
|
||||
Timber.e("## CRYPTO | onRoomKeyEvent() : forwarded_room_key event is missing sender_key field")
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
if (null == forwardedRoomKeyContent.senderClaimedEd25519Key) {
|
||||
Timber.e("## CRYPTO | forwarded_room_key_event is missing sender_claimed_ed25519_key field")
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
keysClaimed["ed25519"] = forwardedRoomKeyContent.senderClaimedEd25519Key
|
||||
@@ -275,7 +274,7 @@ internal class MXMegolmDecryption(private val userId: String,
|
||||
Timber.i("## CRYPTO | onRoomKeyEvent(), Adding key : ${roomKeyContent.roomId}|${roomKeyContent.sessionId}")
|
||||
if (null == senderKey) {
|
||||
Timber.e("## onRoomKeyEvent() : key event has no sender key (not encrypted?)")
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
// inherit the claimed ed25519 key from the setup message
|
||||
@@ -292,8 +291,6 @@ internal class MXMegolmDecryption(private val userId: String,
|
||||
exportFormat)
|
||||
|
||||
if (added) {
|
||||
defaultKeysBackupService.maybeBackupKeys()
|
||||
|
||||
val content = RoomKeyRequestBody(
|
||||
algorithm = roomKeyContent.algorithm,
|
||||
roomId = roomKeyContent.roomId,
|
||||
@@ -305,6 +302,8 @@ internal class MXMegolmDecryption(private val userId: String,
|
||||
|
||||
onNewSession(senderKey, roomKeyContent.sessionId)
|
||||
}
|
||||
|
||||
return added
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -29,7 +29,7 @@ import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevice
|
||||
import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter
|
||||
import org.matrix.android.sdk.internal.crypto.algorithms.IMXEncrypting
|
||||
import org.matrix.android.sdk.internal.crypto.algorithms.IMXGroupEncryption
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.KeysBackupManager
|
||||
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.model.event.RoomKeyWithHeldContent
|
||||
@@ -47,7 +47,7 @@ internal class MXMegolmEncryption(
|
||||
// The id of the room we will be sending to.
|
||||
private val roomId: String,
|
||||
private val olmDevice: MXOlmDevice,
|
||||
private val defaultKeysBackupService: DefaultKeysBackupService,
|
||||
private val keysBackupManager: KeysBackupManager,
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
private val deviceListManager: DeviceListManager,
|
||||
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
||||
@@ -142,7 +142,7 @@ internal class MXMegolmEncryption(
|
||||
olmDevice.addInboundGroupSession(sessionId!!, olmDevice.getSessionKey(sessionId)!!, roomId, olmDevice.deviceCurve25519Key!!,
|
||||
emptyList(), keysClaimedMap, false)
|
||||
|
||||
defaultKeysBackupService.maybeBackupKeys()
|
||||
keysBackupManager.maybeBackupKeys()
|
||||
|
||||
return MXOutboundSessionInfo(sessionId, SharedWithHelper(roomId, sessionId, cryptoStore))
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.crypto.DeviceListManager
|
||||
import org.matrix.android.sdk.internal.crypto.MXOlmDevice
|
||||
import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevicesAction
|
||||
import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.KeysBackupManager
|
||||
import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository
|
||||
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
|
||||
import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask
|
||||
@@ -32,7 +32,7 @@ import javax.inject.Inject
|
||||
|
||||
internal class MXMegolmEncryptionFactory @Inject constructor(
|
||||
private val olmDevice: MXOlmDevice,
|
||||
private val defaultKeysBackupService: DefaultKeysBackupService,
|
||||
private val keysBackupManager: KeysBackupManager,
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
private val deviceListManager: DeviceListManager,
|
||||
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
|
||||
@@ -48,7 +48,7 @@ internal class MXMegolmEncryptionFactory @Inject constructor(
|
||||
return MXMegolmEncryption(
|
||||
roomId = roomId,
|
||||
olmDevice = olmDevice,
|
||||
defaultKeysBackupService = defaultKeysBackupService,
|
||||
keysBackupManager = keysBackupManager,
|
||||
cryptoStore = cryptoStore,
|
||||
deviceListManager = deviceListManager,
|
||||
ensureOlmSessionsForDevicesAction = ensureOlmSessionsForDevicesAction,
|
||||
|
@@ -28,6 +28,7 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningServic
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.internal.crypto.DeviceListManager
|
||||
import org.matrix.android.sdk.internal.crypto.UserDevicesUpdateListener
|
||||
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.UploadSignatureQueryBuilder
|
||||
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
|
||||
@@ -65,7 +66,8 @@ internal class CrossSigningManager @Inject constructor(
|
||||
private val workManagerProvider: WorkManagerProvider,
|
||||
private val updateTrustWorkerDataRepository: UpdateTrustWorkerDataRepository
|
||||
) : CrossSigningService,
|
||||
DeviceListManager.UserDevicesUpdateListener {
|
||||
CrossSigningManagerInput,
|
||||
UserDevicesUpdateListener {
|
||||
|
||||
private var olmUtility: OlmUtility? = null
|
||||
|
||||
|
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto.crosssigning
|
||||
|
||||
internal interface CrossSigningManagerInput {
|
||||
fun onSecretMSKGossip(mskPrivateKey: String)
|
||||
fun onSecretSSKGossip(sskPrivateKey: String)
|
||||
fun onSecretUSKGossip(uskPrivateKey: String)
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto.crosssigning
|
||||
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultCrossSigningService @Inject constructor(
|
||||
crossSigningManager: CrossSigningManager
|
||||
) : CrossSigningService by crossSigningManager
|
@@ -65,7 +65,7 @@ internal class UpdateTrustWorker(context: Context,
|
||||
val filename: String? = null
|
||||
) : SessionWorkerParams
|
||||
|
||||
@Inject lateinit var crossSigningService: DefaultCrossSigningService
|
||||
@Inject lateinit var crossSigningManager: CrossSigningManager
|
||||
|
||||
// It breaks the crypto store contract, but we need to batch things :/
|
||||
@CryptoDatabase
|
||||
@@ -133,7 +133,7 @@ internal class UpdateTrustWorker(context: Context,
|
||||
?.devices
|
||||
?.map { CryptoMapper.mapToModel(it) }
|
||||
|
||||
myTrustResult = crossSigningService.checkSelfTrust(myCrossSigningInfo, myDevices)
|
||||
myTrustResult = crossSigningManager.checkSelfTrust(myCrossSigningInfo, myDevices)
|
||||
updateCrossSigningKeysTrust(cryptoRealm, myUserId, myTrustResult.isVerified())
|
||||
// update model reference
|
||||
myCrossSigningInfo = getCrossSigningInfo(cryptoRealm, myUserId)
|
||||
@@ -147,7 +147,7 @@ internal class UpdateTrustWorker(context: Context,
|
||||
when (entry.key) {
|
||||
myUserId -> myTrustResult
|
||||
else -> {
|
||||
crossSigningService.checkOtherMSKTrusted(myCrossSigningInfo, entry.value).also {
|
||||
crossSigningManager.checkOtherMSKTrusted(myCrossSigningInfo, entry.value).also {
|
||||
Timber.d("## CrossSigning - user:${entry.key} result:$it")
|
||||
}
|
||||
}
|
||||
@@ -172,7 +172,7 @@ internal class UpdateTrustWorker(context: Context,
|
||||
val trustMap = devicesEntities?.associateWith { device ->
|
||||
// get up to date from DB has could have been updated
|
||||
val otherInfo = getCrossSigningInfo(cryptoRealm, userId)
|
||||
crossSigningService.checkDeviceTrust(myCrossSigningInfo, otherInfo, CryptoMapper.mapToModel(device))
|
||||
crossSigningManager.checkDeviceTrust(myCrossSigningInfo, otherInfo, CryptoMapper.mapToModel(device))
|
||||
}
|
||||
|
||||
// Update trust if needed
|
||||
|
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto.keysbackup
|
||||
|
||||
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* A DefaultKeysBackupService class instance manage incremental backup of e2e keys (megolm keys)
|
||||
* to the user's homeserver.
|
||||
*/
|
||||
internal class DefaultKeysBackupService @Inject constructor(
|
||||
keysBackupManager: KeysBackupManager
|
||||
) : KeysBackupService by keysBackupManager
|
@@ -21,6 +21,10 @@ import android.os.Looper
|
||||
import androidx.annotation.UiThread
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.annotation.WorkerThread
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.auth.data.Credentials
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
@@ -40,6 +44,7 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersion
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrustSignature
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.model.SignalableMegolmBackupAuthData
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeyBackupData
|
||||
@@ -80,11 +85,6 @@ import org.matrix.android.sdk.internal.task.configureWith
|
||||
import org.matrix.android.sdk.internal.util.JsonCanonicalizer
|
||||
import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.internal.util.awaitCallback
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.model.SignalableMegolmBackupAuthData
|
||||
import org.matrix.olm.OlmException
|
||||
import org.matrix.olm.OlmPkDecryption
|
||||
import org.matrix.olm.OlmPkEncryption
|
||||
@@ -95,8 +95,7 @@ import javax.inject.Inject
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* A DefaultKeysBackupService class instance manage incremental backup of e2e keys (megolm keys)
|
||||
* to the user's homeserver.
|
||||
*
|
||||
*/
|
||||
@SessionScope
|
||||
internal class KeysBackupManager @Inject constructor(
|
||||
@@ -126,7 +125,8 @@ internal class KeysBackupManager @Inject constructor(
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val cryptoCoroutineScope: CoroutineScope
|
||||
) : KeysBackupService {
|
||||
) : KeysBackupService,
|
||||
KeysBackupManagerInput {
|
||||
|
||||
private val uiHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
|
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto.keysbackup
|
||||
|
||||
internal interface KeysBackupManagerInput {
|
||||
fun onSecretKeyGossip(secret: String)
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto.verification
|
||||
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultVerificationService @Inject constructor(
|
||||
verificationManager: VerificationManager
|
||||
) : VerificationService by verificationManager
|
@@ -84,6 +84,8 @@ import org.matrix.android.sdk.internal.task.TaskExecutor
|
||||
import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.internal.crypto.CryptoSyncInput
|
||||
import org.matrix.android.sdk.internal.session.sync.model.SyncResponse
|
||||
import timber.log.Timber
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
@@ -105,7 +107,10 @@ internal class VerificationManager @Inject constructor(
|
||||
private val crossSigningService: CrossSigningService,
|
||||
private val cryptoCoroutineScope: CoroutineScope,
|
||||
private val taskExecutor: TaskExecutor
|
||||
) : DefaultVerificationTransaction.Listener, VerificationService {
|
||||
) : VerificationService,
|
||||
CryptoSyncInput,
|
||||
VerificationManagerInput,
|
||||
DefaultVerificationTransaction.Listener {
|
||||
|
||||
private val uiHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
@@ -123,7 +128,7 @@ internal class VerificationManager @Inject constructor(
|
||||
private val pendingRequests = HashMap<String, MutableList<PendingVerificationRequest>>()
|
||||
|
||||
// Event received from the sync
|
||||
fun onToDeviceEvent(event: Event) {
|
||||
override fun onToDeviceEvent(event: Event) {
|
||||
Timber.d("## SAS onToDeviceEvent ${event.getClearType()}")
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.dmVerif) {
|
||||
when (event.getClearType()) {
|
||||
@@ -158,7 +163,11 @@ internal class VerificationManager @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun onRoomEvent(event: Event) {
|
||||
override fun onSyncCompleted(syncResponse: SyncResponse) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
override fun onRoomEvent(event: Event) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.dmVerif) {
|
||||
when (event.getClearType()) {
|
||||
EventType.KEY_VERIFICATION_START -> {
|
||||
@@ -274,7 +283,7 @@ internal class VerificationManager @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun onRoomRequestHandledByOtherDevice(event: Event) {
|
||||
override fun onRoomRequestHandledByOtherDevice(event: Event) {
|
||||
val requestInfo = event.content.toModel<MessageRelationContent>()
|
||||
?: return
|
||||
val requestId = requestInfo.relatesTo?.eventId ?: return
|
||||
@@ -325,7 +334,7 @@ internal class VerificationManager @Inject constructor(
|
||||
dispatchRequestAdded(pendingVerificationRequest)
|
||||
}
|
||||
|
||||
suspend fun onRoomRequestReceived(event: Event) {
|
||||
override suspend fun onRoomRequestReceived(event: Event) {
|
||||
Timber.v("## SAS Verification request from ${event.senderId} in room ${event.roomId}")
|
||||
val requestInfo = event.getClearContent().toModel<MessageVerificationRequestContent>() ?: return
|
||||
val validRequestInfo = requestInfo
|
||||
|
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto.verification
|
||||
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
|
||||
internal interface VerificationManagerInput {
|
||||
fun onPotentiallyInterestingEventRoomFailToDecrypt(event: Event)
|
||||
|
||||
fun onRoomRequestHandledByOtherDevice(event: Event)
|
||||
|
||||
fun onRoomEvent(event: Event)
|
||||
|
||||
suspend fun onRoomRequestReceived(event: Event)
|
||||
}
|
@@ -40,7 +40,7 @@ import javax.inject.Inject
|
||||
|
||||
internal class VerificationMessageProcessor @Inject constructor(
|
||||
private val eventDecryptor: EventDecryptor,
|
||||
private val verificationService: DefaultVerificationService,
|
||||
private val verificationManager: VerificationManager,
|
||||
@UserId private val userId: String,
|
||||
@DeviceId private val deviceId: String?
|
||||
) : EventInsertLiveProcessor {
|
||||
@@ -91,7 +91,7 @@ internal class VerificationMessageProcessor @Inject constructor(
|
||||
)
|
||||
} catch (e: MXCryptoError) {
|
||||
Timber.e("## SAS Failed to decrypt event: ${event.eventId}")
|
||||
verificationService.onPotentiallyInterestingEventRoomFailToDecrypt(event)
|
||||
verificationManager.onPotentiallyInterestingEventRoomFailToDecrypt(event)
|
||||
}
|
||||
}
|
||||
Timber.v("## SAS Verification live observer: received msgId: ${event.eventId} type: ${event.getClearType()}")
|
||||
@@ -120,7 +120,7 @@ internal class VerificationMessageProcessor @Inject constructor(
|
||||
// The verification is started from another device
|
||||
Timber.v("## SAS Verification live observer: Transaction started by other device tid:$relatesToEventId ")
|
||||
relatesToEventId?.let { txId -> transactionsHandledByOtherDevice.add(txId) }
|
||||
verificationService.onRoomRequestHandledByOtherDevice(event)
|
||||
verificationManager.onRoomRequestHandledByOtherDevice(event)
|
||||
}
|
||||
}
|
||||
} else if (EventType.KEY_VERIFICATION_READY == event.getClearType()) {
|
||||
@@ -129,13 +129,13 @@ internal class VerificationMessageProcessor @Inject constructor(
|
||||
// The verification is started from another device
|
||||
Timber.v("## SAS Verification live observer: Transaction started by other device tid:$relatesToEventId ")
|
||||
relatesToEventId?.let { txId -> transactionsHandledByOtherDevice.add(txId) }
|
||||
verificationService.onRoomRequestHandledByOtherDevice(event)
|
||||
verificationManager.onRoomRequestHandledByOtherDevice(event)
|
||||
}
|
||||
}
|
||||
} else if (EventType.KEY_VERIFICATION_CANCEL == event.getClearType() || EventType.KEY_VERIFICATION_DONE == event.getClearType()) {
|
||||
relatesToEventId?.let {
|
||||
transactionsHandledByOtherDevice.remove(it)
|
||||
verificationService.onRoomRequestHandledByOtherDevice(event)
|
||||
verificationManager.onRoomRequestHandledByOtherDevice(event)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,11 +156,11 @@ internal class VerificationMessageProcessor @Inject constructor(
|
||||
EventType.KEY_VERIFICATION_CANCEL,
|
||||
EventType.KEY_VERIFICATION_READY,
|
||||
EventType.KEY_VERIFICATION_DONE -> {
|
||||
verificationService.onRoomEvent(event)
|
||||
verificationManager.onRoomEvent(event)
|
||||
}
|
||||
EventType.MESSAGE -> {
|
||||
if (MessageType.MSGTYPE_VERIFICATION_REQUEST == event.getClearContent().toModel<MessageContent>()?.msgType) {
|
||||
verificationService.onRoomRequestReceived(event)
|
||||
verificationManager.onRoomRequestReceived(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -17,6 +17,9 @@
|
||||
package org.matrix.android.sdk.internal.database
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import io.realm.RealmConfiguration
|
||||
import io.realm.RealmResults
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
||||
import org.matrix.android.sdk.internal.database.model.EventEntity
|
||||
import org.matrix.android.sdk.internal.database.model.EventInsertEntity
|
||||
@@ -24,17 +27,13 @@ import org.matrix.android.sdk.internal.database.model.EventInsertEntityFields
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor
|
||||
import io.realm.RealmConfiguration
|
||||
import io.realm.RealmResults
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.internal.crypto.EventDecryptor
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration,
|
||||
private val processors: Set<@JvmSuppressWildcards EventInsertLiveProcessor>,
|
||||
private val eventDecryptor: EventDecryptor)
|
||||
: RealmLiveEntityObserver<EventInsertEntity>(realmConfiguration) {
|
||||
internal class EventInsertLiveObserver @Inject constructor(
|
||||
@SessionDatabase realmConfiguration: RealmConfiguration,
|
||||
private val processors: Set<@JvmSuppressWildcards EventInsertLiveProcessor>,
|
||||
) : RealmLiveEntityObserver<EventInsertEntity>(realmConfiguration) {
|
||||
|
||||
override val query = Monarchy.Query<EventInsertEntity> {
|
||||
it.where(EventInsertEntity::class.java)
|
||||
@@ -86,23 +85,6 @@ internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase real
|
||||
}
|
||||
}
|
||||
|
||||
// private fun decryptIfNeeded(event: Event) {
|
||||
// if (event.isEncrypted() && event.mxDecryptionResult == null) {
|
||||
// try {
|
||||
// val result = eventDecryptor.decryptEvent(event, event.roomId ?: "")
|
||||
// event.mxDecryptionResult = OlmDecryptionResult(
|
||||
// payload = result.clearEvent,
|
||||
// senderKey = result.senderCurve25519Key,
|
||||
// keysClaimed = result.claimedEd25519Key?.let { k -> mapOf("ed25519" to k) },
|
||||
// forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain
|
||||
// )
|
||||
// } catch (e: MXCryptoError) {
|
||||
// Timber.v("Failed to decrypt event")
|
||||
// // TODO -> we should keep track of this and retry, or some processing will never be handled
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private fun shouldProcess(eventInsertEntity: EventInsertEntity): Boolean {
|
||||
return processors.any {
|
||||
it.shouldProcess(eventInsertEntity.eventId, eventInsertEntity.eventType, eventInsertEntity.insertType)
|
||||
|
@@ -63,7 +63,7 @@ import org.matrix.android.sdk.api.session.widgets.WidgetService
|
||||
import org.matrix.android.sdk.api.util.appendParamToUrl
|
||||
import org.matrix.android.sdk.internal.auth.SSO_UIA_FALLBACK_PATH
|
||||
import org.matrix.android.sdk.internal.auth.SessionParamsStore
|
||||
import org.matrix.android.sdk.internal.crypto.DefaultCryptoService
|
||||
import org.matrix.android.sdk.internal.crypto.CryptoManager
|
||||
import org.matrix.android.sdk.internal.database.tools.RealmDebugTools
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.di.SessionId
|
||||
@@ -101,7 +101,8 @@ internal class DefaultSession @Inject constructor(
|
||||
private val pushersService: Lazy<PushersService>,
|
||||
private val termsService: Lazy<TermsService>,
|
||||
private val searchService: Lazy<SearchService>,
|
||||
private val cryptoService: Lazy<DefaultCryptoService>,
|
||||
private val cryptoService: Lazy<CryptoService>,
|
||||
private val cryptoManager: Lazy<CryptoManager>,
|
||||
private val defaultFileService: Lazy<FileService>,
|
||||
private val permalinkService: Lazy<PermalinkService>,
|
||||
private val secureStorageService: Lazy<SecureStorageService>,
|
||||
@@ -164,7 +165,7 @@ internal class DefaultSession @Inject constructor(
|
||||
assert(!isOpen)
|
||||
isOpen = true
|
||||
globalErrorHandler.listener = this
|
||||
cryptoService.get().ensureDevice()
|
||||
cryptoManager.get().ensureDevice()
|
||||
uiHandler.post {
|
||||
lifecycleObservers.forEach {
|
||||
it.onSessionStarted(this)
|
||||
@@ -216,7 +217,7 @@ internal class DefaultSession @Inject constructor(
|
||||
listener.onSessionStopped(this)
|
||||
}
|
||||
}
|
||||
cryptoService.get().close()
|
||||
cryptoManager.get().close()
|
||||
globalErrorHandler.listener = null
|
||||
isOpen = false
|
||||
}
|
||||
|
@@ -34,7 +34,7 @@ import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
|
||||
import org.matrix.android.sdk.api.session.room.send.SendState
|
||||
import org.matrix.android.sdk.internal.crypto.EventDecryptor
|
||||
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.CrossSigningManager
|
||||
import org.matrix.android.sdk.internal.database.mapper.ContentMapper
|
||||
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
||||
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
||||
@@ -72,7 +72,7 @@ internal class RoomSummaryUpdater @Inject constructor(
|
||||
private val roomDisplayNameResolver: RoomDisplayNameResolver,
|
||||
private val roomAvatarResolver: RoomAvatarResolver,
|
||||
private val eventDecryptor: EventDecryptor,
|
||||
private val crossSigningService: DefaultCrossSigningService,
|
||||
private val crossSigningManager: CrossSigningManager,
|
||||
private val roomAccountDataDataSource: RoomAccountDataDataSource) {
|
||||
|
||||
fun update(realm: Realm,
|
||||
@@ -177,7 +177,7 @@ internal class RoomSummaryUpdater @Inject constructor(
|
||||
roomSummaryEntity.otherMemberIds.addAll(otherRoomMembers)
|
||||
if (roomSummaryEntity.isEncrypted && otherRoomMembers.isNotEmpty()) {
|
||||
// mmm maybe we could only refresh shield instead of checking trust also?
|
||||
crossSigningService.onUsersDeviceUpdate(otherRoomMembers)
|
||||
crossSigningManager.onUsersDeviceUpdate(otherRoomMembers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -21,19 +21,21 @@ 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.toModel
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
||||
import org.matrix.android.sdk.internal.crypto.DefaultCryptoService
|
||||
import org.matrix.android.sdk.internal.crypto.CryptoManager
|
||||
import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult
|
||||
import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult
|
||||
import org.matrix.android.sdk.internal.crypto.model.event.OlmEventContent
|
||||
import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService
|
||||
import org.matrix.android.sdk.internal.crypto.verification.VerificationManager
|
||||
import org.matrix.android.sdk.internal.session.initsync.ProgressReporter
|
||||
import org.matrix.android.sdk.internal.session.sync.model.SyncResponse
|
||||
import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class CryptoSyncHandler @Inject constructor(private val cryptoService: DefaultCryptoService,
|
||||
private val verificationService: DefaultVerificationService) {
|
||||
internal class CryptoSyncHandler @Inject constructor(
|
||||
private val cryptoManager: CryptoManager,
|
||||
private val verificationManager: VerificationManager
|
||||
) {
|
||||
|
||||
fun handleToDevice(toDevice: ToDeviceSyncResponse, progressReporter: ProgressReporter? = null) {
|
||||
val total = toDevice.events?.size ?: 0
|
||||
@@ -46,14 +48,14 @@ internal class CryptoSyncHandler @Inject constructor(private val cryptoService:
|
||||
&& event.getClearContent()?.toModel<MessageContent>()?.msgType == "m.bad.encrypted") {
|
||||
Timber.e("## CRYPTO | handleToDeviceEvent() : Warning: Unable to decrypt to-device event : ${event.content}")
|
||||
} else {
|
||||
verificationService.onToDeviceEvent(event)
|
||||
cryptoService.onToDeviceEvent(event)
|
||||
verificationManager.onToDeviceEvent(event)
|
||||
cryptoManager.onToDeviceEvent(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onSyncCompleted(syncResponse: SyncResponse) {
|
||||
cryptoService.onSyncCompleted(syncResponse)
|
||||
cryptoManager.onSyncCompleted(syncResponse)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,12 +70,12 @@ internal class CryptoSyncHandler @Inject constructor(private val cryptoService:
|
||||
if (event.getClearType() == EventType.ENCRYPTED) {
|
||||
var result: MXEventDecryptionResult? = null
|
||||
try {
|
||||
result = cryptoService.decryptEvent(event, timelineId ?: "")
|
||||
result = cryptoManager.decryptEvent(event, timelineId ?: "")
|
||||
} catch (exception: MXCryptoError) {
|
||||
event.mCryptoError = (exception as? MXCryptoError.Base)?.errorType // setCryptoError(exception.cryptoError)
|
||||
val senderKey = event.content.toModel<OlmEventContent>()?.senderKey ?: "<unknown sender key>"
|
||||
// try to find device id to ease log reading
|
||||
val deviceId = cryptoService.getCryptoDeviceInfo(event.senderId!!).firstOrNull {
|
||||
val deviceId = cryptoManager.getCryptoDeviceInfo(event.senderId!!).firstOrNull {
|
||||
it.identityKey() == senderKey
|
||||
}?.deviceId ?: senderKey
|
||||
Timber.e("## CRYPTO | Failed to decrypt to device event from ${event.senderId}|$deviceId reason:<${event.mCryptoError ?: exception}>")
|
||||
|
@@ -26,7 +26,8 @@ import org.matrix.android.sdk.api.session.initsync.InitSyncStep
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||
import org.matrix.android.sdk.api.session.room.send.SendState
|
||||
import org.matrix.android.sdk.internal.crypto.DefaultCryptoService
|
||||
import org.matrix.android.sdk.internal.crypto.CryptoManagerInput
|
||||
import org.matrix.android.sdk.internal.crypto.EventDecryptor
|
||||
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||
import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult
|
||||
import org.matrix.android.sdk.internal.database.helper.addIfNecessary
|
||||
@@ -70,7 +71,8 @@ import javax.inject.Inject
|
||||
internal class RoomSyncHandler @Inject constructor(private val readReceiptHandler: ReadReceiptHandler,
|
||||
private val roomSummaryUpdater: RoomSummaryUpdater,
|
||||
private val roomAccountDataHandler: RoomSyncAccountDataHandler,
|
||||
private val cryptoService: DefaultCryptoService,
|
||||
private val cryptoManagerInput: CryptoManagerInput,
|
||||
private val eventDecryptor: EventDecryptor,
|
||||
private val roomMemberEventHandler: RoomMemberEventHandler,
|
||||
private val roomTypingUsersHandler: RoomTypingUsersHandler,
|
||||
private val roomChangeMembershipStateDataSource: RoomChangeMembershipStateDataSource,
|
||||
@@ -220,7 +222,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
||||
root = eventEntity
|
||||
}
|
||||
// Give info to crypto module
|
||||
cryptoService.onStateEvent(roomId, event)
|
||||
cryptoManagerInput.onStateEvent(roomId, event)
|
||||
roomMemberEventHandler.handle(realm, roomId, event)
|
||||
}
|
||||
}
|
||||
@@ -382,7 +384,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
||||
|
||||
chunkEntity.addTimelineEvent(roomId, eventEntity, PaginationDirection.FORWARDS, roomMemberContentsByUser)
|
||||
// Give info to crypto module
|
||||
cryptoService.onLiveEvent(roomEntity.roomId, event)
|
||||
cryptoManagerInput.onLiveEvent(roomEntity.roomId, event)
|
||||
|
||||
// Try to remove local echo
|
||||
event.unsignedData?.transactionId?.also {
|
||||
@@ -413,7 +415,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
||||
private fun decryptIfNeeded(event: Event, roomId: String) {
|
||||
try {
|
||||
// Event from sync does not have roomId, so add it to the event first
|
||||
val result = cryptoService.decryptEvent(event.copy(roomId = roomId), "")
|
||||
val result = eventDecryptor.decryptEvent(event.copy(roomId = roomId), "")
|
||||
event.mxDecryptionResult = OlmDecryptionResult(
|
||||
payload = result.clearEvent,
|
||||
senderKey = result.senderCurve25519Key,
|
||||
|
@@ -21,7 +21,7 @@ import com.zhuinden.monarchy.Monarchy
|
||||
import org.matrix.android.sdk.api.pushrules.PushRuleService
|
||||
import org.matrix.android.sdk.api.pushrules.RuleScope
|
||||
import org.matrix.android.sdk.api.session.initsync.InitSyncStep
|
||||
import org.matrix.android.sdk.internal.crypto.DefaultCryptoService
|
||||
import org.matrix.android.sdk.internal.crypto.CryptoManager
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.di.SessionId
|
||||
import org.matrix.android.sdk.internal.di.WorkManagerProvider
|
||||
@@ -52,7 +52,7 @@ internal class SyncResponseHandler @Inject constructor(
|
||||
private val groupSyncHandler: GroupSyncHandler,
|
||||
private val cryptoSyncHandler: CryptoSyncHandler,
|
||||
private val aggregatorHandler: SyncResponsePostTreatmentAggregatorHandler,
|
||||
private val cryptoService: DefaultCryptoService,
|
||||
private val cryptoManager: CryptoManager,
|
||||
private val tokenStore: SyncTokenStore,
|
||||
private val processEventForPushTask: ProcessEventForPushTask,
|
||||
private val pushRuleService: PushRuleService) {
|
||||
@@ -64,11 +64,11 @@ internal class SyncResponseHandler @Inject constructor(
|
||||
Timber.v("Start handling sync, is InitialSync: $isInitialSync")
|
||||
|
||||
measureTimeMillis {
|
||||
if (!cryptoService.isStarted()) {
|
||||
if (!cryptoManager.isStarted()) {
|
||||
Timber.v("Should start cryptoService")
|
||||
cryptoService.start()
|
||||
cryptoManager.start()
|
||||
}
|
||||
cryptoService.onSyncWillProcess(isInitialSync)
|
||||
cryptoManager.onSyncWillProcess(isInitialSync)
|
||||
}.also {
|
||||
Timber.v("Finish handling start cryptoService in $it ms")
|
||||
}
|
||||
|
Reference in New Issue
Block a user