This commit is contained in:
Benoit Marty 2020-02-06 16:00:05 +01:00
parent 1917fbcc93
commit 5fedfd9286
9 changed files with 47 additions and 56 deletions

View File

@ -18,7 +18,6 @@ package im.vector.matrix.android.api.session.crypto.crosssigning
import androidx.lifecycle.LiveData
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.crypto.RoomEncryptionTrustLevel
import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustResult
import im.vector.matrix.android.internal.crypto.crosssigning.UserTrustResult
@ -63,6 +62,4 @@ interface CrossSigningService {
fun checkDeviceTrust(otherUserId: String,
otherDeviceId: String,
locallyTrusted: Boolean?): DeviceTrustResult
suspend fun getTrustLevelForUsers(userIds: List<String>): RoomEncryptionTrustLevel
}

View File

@ -44,7 +44,7 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
taskExecutor: TaskExecutor) {
interface UserDevicesUpdateListener {
fun onUsersDeviceUpdate(users: List<String>)
fun onUsersDeviceUpdate(userIds: List<String>)
}
private val deviceChangeListeners = mutableListOf<UserDevicesUpdateListener>()

View File

@ -24,7 +24,7 @@ import javax.inject.Inject
internal interface ComputeTrustTask : Task<ComputeTrustTask.Params, RoomEncryptionTrustLevel> {
data class Params(
val userList: List<String>
val userIds: List<String>
)
}
@ -33,36 +33,38 @@ internal class DefaultComputeTrustTask @Inject constructor(
) : ComputeTrustTask {
override suspend fun execute(params: ComputeTrustTask.Params): RoomEncryptionTrustLevel {
val userIds = params.userList
val allTrusted = userIds
.filter { getUserCrossSigningKeys(it)?.isTrusted() == true }
val allTrustedUserIds = params.userIds
.filter { userId -> getUserCrossSigningKeys(userId)?.isTrusted() == true }
val allUsersAreVerified = userIds.size == allTrusted.size
return if (allTrusted.isEmpty()) {
return if (allTrustedUserIds.isEmpty()) {
RoomEncryptionTrustLevel.Default
} else {
// If one of the verified user as an untrusted device -> warning
// Green if all devices of all verified users are trusted -> green
// else black
val allDevices = allTrusted.mapNotNull {
cryptoStore.getUserDeviceList(it)
}.flatten()
if (getMyCrossSigningKeys() != null) {
val hasWarning = allDevices.any { !it.trustLevel?.crossSigningVerified.orFalse() }
if (hasWarning) {
RoomEncryptionTrustLevel.Warning
} else {
if (allUsersAreVerified) RoomEncryptionTrustLevel.Trusted else RoomEncryptionTrustLevel.Default
}
} else {
val hasWarningLegacy = allDevices.any { !it.isVerified }
if (hasWarningLegacy) {
RoomEncryptionTrustLevel.Warning
} else {
if (allUsersAreVerified) RoomEncryptionTrustLevel.Trusted else RoomEncryptionTrustLevel.Default
}
}
// If all devices of all verified users are trusted -> green
// else -> black
allTrustedUserIds
.mapNotNull { cryptoStore.getUserDeviceList(it) }
.flatten()
.let { allDevices ->
if (getMyCrossSigningKeys() != null) {
allDevices.any { !it.trustLevel?.crossSigningVerified.orFalse() }
} else {
// Legacy method
allDevices.any { !it.isVerified }
}
}
.let { hasWarning ->
if (hasWarning) {
RoomEncryptionTrustLevel.Warning
} else {
if (params.userIds.size == allTrustedUserIds.size) {
// all users are trusted and all devices are verified
RoomEncryptionTrustLevel.Trusted
} else {
RoomEncryptionTrustLevel.Default
}
}
}
}
}

View File

@ -19,7 +19,6 @@ package im.vector.matrix.android.internal.crypto.crosssigning
import androidx.lifecycle.LiveData
import dagger.Lazy
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.crypto.RoomEncryptionTrustLevel
import im.vector.matrix.android.api.session.crypto.crosssigning.CrossSigningService
import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
import im.vector.matrix.android.api.util.Optional
@ -616,11 +615,10 @@ internal class DefaultCrossSigningService @Inject constructor(
}
}
override fun onUsersDeviceUpdate(users: List<String>) {
override fun onUsersDeviceUpdate(userIds: List<String>) {
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
Timber.d("## CrossSigning - onUsersDeviceUpdate for ${users.size} users")
users.forEach { otherUserId ->
Timber.d("## CrossSigning - onUsersDeviceUpdate for ${userIds.size} users")
userIds.forEach { otherUserId ->
checkUserTrust(otherUserId).let {
Timber.d("## CrossSigning - update trust for $otherUserId , verified=${it.isVerified()}")
setUserKeysAsTrusted(otherUserId, it.isVerified())
@ -640,7 +638,7 @@ internal class DefaultCrossSigningService @Inject constructor(
setUserKeysAsTrusted(otherUserId, checkSelfTrust().isVerified())
}
eventBus.post(CryptoToSessionUserTrustChange(users))
eventBus.post(CryptoToSessionUserTrustChange(userIds))
}
}
}
@ -667,8 +665,4 @@ internal class DefaultCrossSigningService @Inject constructor(
}
}
}
override suspend fun getTrustLevelForUsers(userIds: List<String>): RoomEncryptionTrustLevel {
return computeTrustTask.execute(ComputeTrustTask.Params(userIds))
}
}

View File

@ -16,10 +16,10 @@
package im.vector.matrix.android.internal.crypto.crosssigning
data class SessionToCryptoRoomMembersUpdate(
val encryptedRoomMembersUpdate: String,
val userList: List<String>
val roomId: String,
val userIds: List<String>
)
data class CryptoToSessionUserTrustChange(
val userList: List<String>
val userIds: List<String>
)

View File

@ -32,12 +32,12 @@ import java.util.concurrent.atomic.AtomicReference
import javax.inject.Inject
internal class ShieldTrustUpdater @Inject constructor(
val eventBus: EventBus,
private val eventBus: EventBus,
private val computeTrustTask: ComputeTrustTask,
val taskExecutor: TaskExecutor,
@CryptoDatabase val cryptoRealmConfiguration: RealmConfiguration,
@SessionDatabase val sessionRealmConfiguration: RealmConfiguration,
val roomSummaryUpdater: RoomSummaryUpdater
private val taskExecutor: TaskExecutor,
@CryptoDatabase private val cryptoRealmConfiguration: RealmConfiguration,
@SessionDatabase private val sessionRealmConfiguration: RealmConfiguration,
private val roomSummaryUpdater: RoomSummaryUpdater
) {
companion object {
@ -84,12 +84,12 @@ internal class ShieldTrustUpdater @Inject constructor(
@Subscribe
fun onRoomMemberChange(update: SessionToCryptoRoomMembersUpdate) {
taskExecutor.executorScope.launch {
val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(update.userList))
val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(update.userIds))
// We need to send that back to session base
BACKGROUND_HANDLER.post {
backgroundSessionRealm.get().executeTransaction { realm ->
roomSummaryUpdater.updateShieldTrust(realm, update.encryptedRoomMembersUpdate, updatedTrust)
roomSummaryUpdater.updateShieldTrust(realm, update.roomId, updatedTrust)
}
}
}
@ -97,7 +97,7 @@ internal class ShieldTrustUpdater @Inject constructor(
@Subscribe
fun onTrustUpdate(update: CryptoToSessionUserTrustChange) {
onCryptoDevicesChange(update.userList)
onCryptoDevicesChange(update.userIds)
}
private fun onCryptoDevicesChange(users: List<String>) {

View File

@ -17,7 +17,6 @@
package im.vector.matrix.android.internal.database.mapper
import im.vector.matrix.android.api.session.crypto.CryptoService
import im.vector.matrix.android.api.session.crypto.MXCryptoError
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.model.tag.RoomTag
import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult

View File

@ -144,7 +144,7 @@ internal class RoomSummaryUpdater @Inject constructor(
roomSummaryEntity.otherMemberIds.clear()
roomSummaryEntity.otherMemberIds.addAll(otherRoomMembers)
if (roomSummaryEntity.isEncrypted) {
eventBus.post(SessionToCryptoRoomMembersUpdate(roomId, roomSummaryEntity.otherMemberIds.map { it } + userId))
eventBus.post(SessionToCryptoRoomMembersUpdate(roomId, roomSummaryEntity.otherMemberIds.toList() + userId))
}
}
}

View File

@ -31,14 +31,13 @@ class RxConfig @Inject constructor(
fun setupRxPlugin() {
RxJavaPlugins.setErrorHandler { throwable ->
Timber.e(throwable, "RxError")
//is InterruptedException -> fine, some blocking code was interrupted by a dispose call
// is InterruptedException -> fine, some blocking code was interrupted by a dispose call
if (throwable !is InterruptedException) {
// Avoid crash in production, except if user wants it
if (vectorPreferences.failFast()) {
throw throwable
}
}
}
}
}