verification state integration
fix rust/kotlin flavor compilation pbs
This commit is contained in:
parent
f1d3eeb0a4
commit
f9ed8a4dcf
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:a5b58eecbbaa8354901a57c7df727eb2ad6e401dd286ecf049d7a438788ac6ef
|
oid sha256:755bd2766aa1f317722c60259faf9759b9049885f20b91ed2a4dcfbcba861bfc
|
||||||
size 16077430
|
size 17402892
|
||||||
|
|
|
@ -23,7 +23,6 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.flow.cancellable
|
import kotlinx.coroutines.flow.cancellable
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.amshove.kluent.fail
|
import org.amshove.kluent.fail
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package org.matrix.android.sdk.internal.crypto
|
package org.matrix.android.sdk.internal.crypto
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult
|
import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult
|
||||||
|
@ -63,7 +62,7 @@ internal class DecryptRoomEventUseCase @Inject constructor(
|
||||||
claimedEd25519Key = olmDecryptionResult.keysClaimed?.get("ed25519"),
|
claimedEd25519Key = olmDecryptionResult.keysClaimed?.get("ed25519"),
|
||||||
forwardingCurve25519KeyChain = olmDecryptionResult.forwardingCurve25519KeyChain
|
forwardingCurve25519KeyChain = olmDecryptionResult.forwardingCurve25519KeyChain
|
||||||
.orEmpty(),
|
.orEmpty(),
|
||||||
isSafe = olmDecryptionResult.isSafe.orFalse()
|
messageVerificationState = olmDecryptionResult.verificationState
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON)
|
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON)
|
||||||
|
@ -139,7 +138,7 @@ internal class DecryptRoomEventUseCase @Inject constructor(
|
||||||
senderKey = result.senderCurve25519Key,
|
senderKey = result.senderCurve25519Key,
|
||||||
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
||||||
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
||||||
isSafe = result.isSafe
|
verificationState = result.messageVerificationState
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ internal class EventDecryptor @Inject constructor(
|
||||||
senderKey = result.senderCurve25519Key,
|
senderKey = result.senderCurve25519Key,
|
||||||
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
||||||
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
||||||
isSafe = result.isSafe
|
verificationState = result.messageVerificationState
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,15 @@ import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.logger.LoggerTag
|
import org.matrix.android.sdk.api.logger.LoggerTag
|
||||||
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
||||||
|
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
|
||||||
|
import org.matrix.android.sdk.api.session.crypto.model.MessageVerificationState
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult
|
import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult
|
||||||
import org.matrix.android.sdk.api.util.JSON_DICT_PARAMETERIZED_TYPE
|
import org.matrix.android.sdk.api.util.JSON_DICT_PARAMETERIZED_TYPE
|
||||||
import org.matrix.android.sdk.api.util.JsonDict
|
import org.matrix.android.sdk.api.util.JsonDict
|
||||||
import org.matrix.android.sdk.internal.crypto.algorithms.megolm.MXOutboundSessionInfo
|
import org.matrix.android.sdk.internal.crypto.algorithms.megolm.MXOutboundSessionInfo
|
||||||
import org.matrix.android.sdk.internal.crypto.algorithms.megolm.SharedWithHelper
|
import org.matrix.android.sdk.internal.crypto.algorithms.megolm.SharedWithHelper
|
||||||
|
import org.matrix.android.sdk.internal.crypto.crosssigning.CrossSigningOlm
|
||||||
|
import org.matrix.android.sdk.internal.crypto.crosssigning.canonicalSignable
|
||||||
import org.matrix.android.sdk.internal.crypto.model.InboundGroupSessionData
|
import org.matrix.android.sdk.internal.crypto.model.InboundGroupSessionData
|
||||||
import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrapper
|
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.OlmSessionWrapper
|
||||||
|
@ -59,6 +63,7 @@ internal class MXOlmDevice @Inject constructor(
|
||||||
private val store: IMXCryptoStore,
|
private val store: IMXCryptoStore,
|
||||||
private val olmSessionStore: OlmSessionStore,
|
private val olmSessionStore: OlmSessionStore,
|
||||||
private val inboundGroupSessionStore: InboundGroupSessionStore,
|
private val inboundGroupSessionStore: InboundGroupSessionStore,
|
||||||
|
private val crossSigningOlm: CrossSigningOlm,
|
||||||
private val clock: Clock,
|
private val clock: Clock,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@ -851,15 +856,60 @@ internal class MXOlmDevice @Inject constructor(
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_DECRYPTED_FORMAT, MXCryptoError.BAD_DECRYPTED_FORMAT_TEXT_REASON)
|
throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_DECRYPTED_FORMAT, MXCryptoError.BAD_DECRYPTED_FORMAT_TEXT_REASON)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val verificationState = if (sessionHolder.wrapper.sessionData.trusted.orFalse()) {
|
||||||
|
// let's get info on the device
|
||||||
|
val sendingDevice = store.deviceWithIdentityKey(senderKey)
|
||||||
|
if (sendingDevice == null) {
|
||||||
|
MessageVerificationState.UNKNOWN_DEVICE
|
||||||
|
} else {
|
||||||
|
val isDeviceOwnerOfSession = sessionHolder.wrapper.sessionData.keysClaimed?.get("ed25519") == sendingDevice.fingerprint()
|
||||||
|
if (!isDeviceOwnerOfSession) {
|
||||||
|
MessageVerificationState.MISMATCH
|
||||||
|
} else if (sendingDevice.isVerified) {
|
||||||
|
MessageVerificationState.VERIFIED
|
||||||
|
} else {
|
||||||
|
val isDeviceOwnerVerified = store.getCrossSigningInfo(sendingDevice.userId)?.isTrusted() ?: false
|
||||||
|
val isDeviceSignedByItsOwner = isDeviceSignByItsOwner(sendingDevice)
|
||||||
|
if (isDeviceSignedByItsOwner) {
|
||||||
|
if (isDeviceOwnerVerified) MessageVerificationState.VERIFIED
|
||||||
|
else MessageVerificationState.SIGNED_DEVICE_OF_UNVERIFIED_USER
|
||||||
|
} else {
|
||||||
|
if (isDeviceOwnerVerified) MessageVerificationState.UN_SIGNED_DEVICE_OF_VERIFIED_USER
|
||||||
|
else MessageVerificationState.UN_SIGNED_DEVICE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MessageVerificationState.UNSAFE_SOURCE
|
||||||
|
}
|
||||||
return OlmDecryptionResult(
|
return OlmDecryptionResult(
|
||||||
payload,
|
payload,
|
||||||
wrapper.sessionData.keysClaimed,
|
wrapper.sessionData.keysClaimed,
|
||||||
senderKey,
|
senderKey,
|
||||||
wrapper.sessionData.forwardingCurve25519KeyChain,
|
wrapper.sessionData.forwardingCurve25519KeyChain,
|
||||||
isSafe = sessionHolder.wrapper.sessionData.trusted.orFalse()
|
isSafe = sessionHolder.wrapper.sessionData.trusted.orFalse(),
|
||||||
|
verificationState = verificationState,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isDeviceSignByItsOwner(device: CryptoDeviceInfo): Boolean {
|
||||||
|
val otherKeys = store.getCrossSigningInfo(device.userId) ?: return false
|
||||||
|
val otherSSKSignature = device.signatures?.get(device.userId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}")
|
||||||
|
?: return false
|
||||||
|
|
||||||
|
// Check bob's device is signed by bob's SSK
|
||||||
|
try {
|
||||||
|
crossSigningOlm.olmUtility.verifyEd25519Signature(
|
||||||
|
otherSSKSignature,
|
||||||
|
otherKeys.selfSigningKey()?.unpaddedBase64PublicKey,
|
||||||
|
device.canonicalSignable()
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset replay attack data for the given timeline.
|
* Reset replay attack data for the given timeline.
|
||||||
*
|
*
|
||||||
|
|
|
@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.crypto.algorithms.megolm
|
||||||
|
|
||||||
import dagger.Lazy
|
import dagger.Lazy
|
||||||
import org.matrix.android.sdk.api.crypto.MXCryptoConfig
|
import org.matrix.android.sdk.api.crypto.MXCryptoConfig
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
|
||||||
import org.matrix.android.sdk.api.logger.LoggerTag
|
import org.matrix.android.sdk.api.logger.LoggerTag
|
||||||
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
||||||
import org.matrix.android.sdk.api.session.crypto.NewSessionListener
|
import org.matrix.android.sdk.api.session.crypto.NewSessionListener
|
||||||
|
@ -100,7 +99,7 @@ internal class MXMegolmDecryption(
|
||||||
claimedEd25519Key = olmDecryptionResult.keysClaimed?.get("ed25519"),
|
claimedEd25519Key = olmDecryptionResult.keysClaimed?.get("ed25519"),
|
||||||
forwardingCurve25519KeyChain = olmDecryptionResult.forwardingCurve25519KeyChain
|
forwardingCurve25519KeyChain = olmDecryptionResult.forwardingCurve25519KeyChain
|
||||||
.orEmpty(),
|
.orEmpty(),
|
||||||
isSafe = olmDecryptionResult.isSafe.orFalse()
|
messageVerificationState = olmDecryptionResult.verificationState,
|
||||||
).also {
|
).also {
|
||||||
liveEventManager.get().dispatchLiveEventDecrypted(event, it)
|
liveEventManager.get().dispatchLiveEventDecrypted(event, it)
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ internal class CryptoSyncHandler @Inject constructor(
|
||||||
senderKey = result.senderCurve25519Key,
|
senderKey = result.senderCurve25519Key,
|
||||||
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
||||||
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
||||||
isSafe = result.isSafe
|
verificationState = result.messageVerificationState,
|
||||||
)
|
)
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -18,6 +18,16 @@ package org.matrix.android.sdk.api.session.crypto.model
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.util.JsonDict
|
import org.matrix.android.sdk.api.util.JsonDict
|
||||||
|
|
||||||
|
enum class MessageVerificationState {
|
||||||
|
VERIFIED,
|
||||||
|
SIGNED_DEVICE_OF_UNVERIFIED_USER,
|
||||||
|
UN_SIGNED_DEVICE_OF_VERIFIED_USER,
|
||||||
|
UN_SIGNED_DEVICE,
|
||||||
|
UNKNOWN_DEVICE,
|
||||||
|
UNSAFE_SOURCE,
|
||||||
|
MISMATCH,
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The result of a (successful) call to decryptEvent.
|
* The result of a (successful) call to decryptEvent.
|
||||||
*/
|
*/
|
||||||
|
@ -45,5 +55,5 @@ data class MXEventDecryptionResult(
|
||||||
*/
|
*/
|
||||||
val forwardingCurve25519KeyChain: List<String> = emptyList(),
|
val forwardingCurve25519KeyChain: List<String> = emptyList(),
|
||||||
|
|
||||||
val isSafe: Boolean = false
|
val messageVerificationState: MessageVerificationState? = null,
|
||||||
)
|
)
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.matrix.android.sdk.api.util.JsonDict
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents the decryption result.
|
* This class represents the decryption result.
|
||||||
|
* It's serialized in eventEntity to remember the decryption result
|
||||||
*/
|
*/
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
data class OlmDecryptionResult(
|
data class OlmDecryptionResult(
|
||||||
|
@ -50,4 +51,9 @@ data class OlmDecryptionResult(
|
||||||
* True if the key used to decrypt is considered safe (trusted).
|
* True if the key used to decrypt is considered safe (trusted).
|
||||||
*/
|
*/
|
||||||
@Json(name = "key_safety") val isSafe: Boolean? = null,
|
@Json(name = "key_safety") val isSafe: Boolean? = null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticity info for that message
|
||||||
|
*/
|
||||||
|
@Json(name = "verification_state") val verificationState: MessageVerificationState? = null,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,8 +16,6 @@
|
||||||
|
|
||||||
package org.matrix.android.sdk.api.session.crypto.verification
|
package org.matrix.android.sdk.api.session.crypto.verification
|
||||||
|
|
||||||
import org.matrix.android.sdk.internal.crypto.verification.qrcode.QrCodeVerification
|
|
||||||
|
|
||||||
interface VerificationTransaction {
|
interface VerificationTransaction {
|
||||||
|
|
||||||
val method: VerificationMethod
|
val method: VerificationMethod
|
||||||
|
@ -44,7 +42,7 @@ interface VerificationTransaction {
|
||||||
internal fun VerificationTransaction.dbgState(): String? {
|
internal fun VerificationTransaction.dbgState(): String? {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is SasVerificationTransaction -> "${this.state()}"
|
is SasVerificationTransaction -> "${this.state()}"
|
||||||
is QrCodeVerification -> "${this.state()}"
|
is QrCodeVerificationTransaction -> "${this.state()}"
|
||||||
else -> "??"
|
else -> "??"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import dagger.Lazy
|
||||||
import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult
|
import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult
|
||||||
|
import org.matrix.android.sdk.api.session.crypto.model.MessageVerificationState
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
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.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
import org.matrix.android.sdk.api.session.events.model.toContent
|
||||||
|
@ -78,7 +79,7 @@ internal class DefaultEncryptEventTask @Inject constructor(
|
||||||
forwardingCurve25519KeyChain = emptyList(),
|
forwardingCurve25519KeyChain = emptyList(),
|
||||||
senderCurve25519Key = result.eventContent["sender_key"] as? String,
|
senderCurve25519Key = result.eventContent["sender_key"] as? String,
|
||||||
claimedEd25519Key = cryptoService.get().getMyCryptoDevice().fingerprint(),
|
claimedEd25519Key = cryptoService.get().getMyCryptoDevice().fingerprint(),
|
||||||
isSafe = true
|
messageVerificationState = MessageVerificationState.VERIFIED
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
|
|
|
@ -210,7 +210,7 @@ private fun decryptIfNeeded(cryptoService: CryptoService?, eventEntity: EventEnt
|
||||||
senderKey = result.senderCurve25519Key,
|
senderKey = result.senderCurve25519Key,
|
||||||
keysClaimed = result.claimedEd25519Key?.let { k -> mapOf("ed25519" to k) },
|
keysClaimed = result.claimedEd25519Key?.let { k -> mapOf("ed25519" to k) },
|
||||||
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
||||||
isSafe = result.isSafe
|
verificationState = result.messageVerificationState
|
||||||
)
|
)
|
||||||
// Save decryption result, to not decrypt every time we enter the thread list
|
// Save decryption result, to not decrypt every time we enter the thread list
|
||||||
eventEntity.setDecryptionResult(result)
|
eventEntity.setDecryptionResult(result)
|
||||||
|
|
|
@ -88,7 +88,7 @@ internal open class EventEntity(
|
||||||
senderKey = result.senderCurve25519Key,
|
senderKey = result.senderCurve25519Key,
|
||||||
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
||||||
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
||||||
isSafe = result.isSafe
|
verificationState = result.messageVerificationState
|
||||||
)
|
)
|
||||||
val adapter = MoshiProvider.providesMoshi().adapter(OlmDecryptionResult::class.java)
|
val adapter = MoshiProvider.providesMoshi().adapter(OlmDecryptionResult::class.java)
|
||||||
decryptionResultJson = adapter.toJson(decryptionResult)
|
decryptionResultJson = adapter.toJson(decryptionResult)
|
||||||
|
|
|
@ -251,7 +251,7 @@ internal class DefaultFetchThreadTimelineTask @Inject constructor(
|
||||||
senderKey = result.senderCurve25519Key,
|
senderKey = result.senderCurve25519Key,
|
||||||
keysClaimed = result.claimedEd25519Key?.let { k -> mapOf("ed25519" to k) },
|
keysClaimed = result.claimedEd25519Key?.let { k -> mapOf("ed25519" to k) },
|
||||||
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
||||||
isSafe = result.isSafe
|
verificationState = result.messageVerificationState
|
||||||
)
|
)
|
||||||
} catch (e: MXCryptoError) {
|
} catch (e: MXCryptoError) {
|
||||||
if (e is MXCryptoError.Base) {
|
if (e is MXCryptoError.Base) {
|
||||||
|
|
|
@ -139,14 +139,13 @@ internal class SyncResponseHandler @Inject constructor(
|
||||||
try {
|
try {
|
||||||
val timelineId = generateTimelineId(roomId)
|
val timelineId = generateTimelineId(roomId)
|
||||||
// Event from sync does not have roomId, so add it to the event first
|
// Event from sync does not have roomId, so add it to the event first
|
||||||
// note: runBlocking should be used here while we are in realm single thread executor, to avoid thread switching
|
|
||||||
val result = cryptoService.decryptEvent(event.copy(roomId = roomId), timelineId)
|
val result = cryptoService.decryptEvent(event.copy(roomId = roomId), timelineId)
|
||||||
event.mxDecryptionResult = OlmDecryptionResult(
|
event.mxDecryptionResult = OlmDecryptionResult(
|
||||||
payload = result.clearEvent,
|
payload = result.clearEvent,
|
||||||
senderKey = result.senderCurve25519Key,
|
senderKey = result.senderCurve25519Key,
|
||||||
keysClaimed = result.claimedEd25519Key?.let { k -> mapOf("ed25519" to k) },
|
keysClaimed = result.claimedEd25519Key?.let { k -> mapOf("ed25519" to k) },
|
||||||
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
||||||
isSafe = result.isSafe
|
verificationState = result.messageVerificationState
|
||||||
)
|
)
|
||||||
} catch (e: MXCryptoError) {
|
} catch (e: MXCryptoError) {
|
||||||
Timber.v(e, "Failed to decrypt $roomId")
|
Timber.v(e, "Failed to decrypt $roomId")
|
||||||
|
|
|
@ -105,7 +105,7 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor(
|
||||||
.enqueue()
|
.enqueue()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleUserIdsForCheckingTrustAndAffectedRoomShields(userIdsWithDeviceUpdate: Collection<String>) {
|
private suspend fun handleUserIdsForCheckingTrustAndAffectedRoomShields(userIdsWithDeviceUpdate: Collection<String>) {
|
||||||
if (userIdsWithDeviceUpdate.isEmpty()) return
|
if (userIdsWithDeviceUpdate.isEmpty()) return
|
||||||
crossSigningService.checkTrustAndAffectedRoomShields(userIdsWithDeviceUpdate.toList())
|
crossSigningService.checkTrustAndAffectedRoomShields(userIdsWithDeviceUpdate.toList())
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ internal class DecryptRoomEventUseCase @Inject constructor(private val olmMachin
|
||||||
senderKey = result.senderCurve25519Key,
|
senderKey = result.senderCurve25519Key,
|
||||||
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
||||||
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
||||||
isSafe = result.isSafe
|
verificationState = result.messageVerificationState
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,6 @@ import org.matrix.rustcomponents.sdk.crypto.DecryptionException
|
||||||
import org.matrix.rustcomponents.sdk.crypto.DeviceLists
|
import org.matrix.rustcomponents.sdk.crypto.DeviceLists
|
||||||
import org.matrix.rustcomponents.sdk.crypto.EncryptionSettings
|
import org.matrix.rustcomponents.sdk.crypto.EncryptionSettings
|
||||||
import org.matrix.rustcomponents.sdk.crypto.KeyRequestPair
|
import org.matrix.rustcomponents.sdk.crypto.KeyRequestPair
|
||||||
import org.matrix.rustcomponents.sdk.crypto.KeySafety
|
|
||||||
import org.matrix.rustcomponents.sdk.crypto.KeysImportResult
|
import org.matrix.rustcomponents.sdk.crypto.KeysImportResult
|
||||||
import org.matrix.rustcomponents.sdk.crypto.Logger
|
import org.matrix.rustcomponents.sdk.crypto.Logger
|
||||||
import org.matrix.rustcomponents.sdk.crypto.MegolmV1BackupKey
|
import org.matrix.rustcomponents.sdk.crypto.MegolmV1BackupKey
|
||||||
|
@ -431,7 +430,7 @@ internal class OlmMachine @Inject constructor(
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON)
|
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON)
|
||||||
}
|
}
|
||||||
val serializedEvent = adapter.toJson(event)
|
val serializedEvent = adapter.toJson(event)
|
||||||
val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId)
|
val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId, false)
|
||||||
|
|
||||||
val deserializationAdapter =
|
val deserializationAdapter =
|
||||||
moshi.adapter<JsonDict>(Map::class.java)
|
moshi.adapter<JsonDict>(Map::class.java)
|
||||||
|
@ -443,7 +442,7 @@ internal class OlmMachine @Inject constructor(
|
||||||
senderCurve25519Key = decrypted.senderCurve25519Key,
|
senderCurve25519Key = decrypted.senderCurve25519Key,
|
||||||
claimedEd25519Key = decrypted.claimedEd25519Key,
|
claimedEd25519Key = decrypted.claimedEd25519Key,
|
||||||
forwardingCurve25519KeyChain = decrypted.forwardingCurve25519Chain,
|
forwardingCurve25519KeyChain = decrypted.forwardingCurve25519Chain,
|
||||||
isSafe = decrypted.keySafety == KeySafety.SAFE,
|
messageVerificationState = decrypted.verificationState.fromInner(),
|
||||||
)
|
)
|
||||||
} catch (throwable: Throwable) {
|
} catch (throwable: Throwable) {
|
||||||
val reThrow = when (throwable) {
|
val reThrow = when (throwable) {
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 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 org.matrix.android.sdk.api.session.crypto.model.MessageVerificationState
|
||||||
|
import org.matrix.rustcomponents.sdk.crypto.VerificationState as InnerVerificationState
|
||||||
|
|
||||||
|
fun InnerVerificationState.fromInner(): MessageVerificationState {
|
||||||
|
return when (this) {
|
||||||
|
InnerVerificationState.VERIFIED -> MessageVerificationState.VERIFIED
|
||||||
|
InnerVerificationState.SIGNED_DEVICE_OF_UNVERIFIED_USER -> MessageVerificationState.SIGNED_DEVICE_OF_UNVERIFIED_USER
|
||||||
|
InnerVerificationState.UN_SIGNED_DEVICE_OF_VERIFIED_USER -> MessageVerificationState.UN_SIGNED_DEVICE_OF_VERIFIED_USER
|
||||||
|
InnerVerificationState.UN_SIGNED_DEVICE -> MessageVerificationState.UN_SIGNED_DEVICE
|
||||||
|
InnerVerificationState.UNKNOWN_DEVICE -> MessageVerificationState.UNKNOWN_DEVICE
|
||||||
|
InnerVerificationState.UNSAFE_SOURCE -> MessageVerificationState.UNSAFE_SOURCE
|
||||||
|
InnerVerificationState.MISMATCH -> MessageVerificationState.MISMATCH
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,7 +30,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
|
@ -84,7 +84,7 @@ class ViewEditHistoryViewModel @AssistedInject constructor(
|
||||||
senderKey = result.senderCurve25519Key,
|
senderKey = result.senderCurve25519Key,
|
||||||
keysClaimed = result.claimedEd25519Key?.let { k -> mapOf("ed25519" to k) },
|
keysClaimed = result.claimedEd25519Key?.let { k -> mapOf("ed25519" to k) },
|
||||||
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
||||||
isSafe = result.isSafe
|
verificationState = result.messageVerificationState
|
||||||
)
|
)
|
||||||
} catch (e: MXCryptoError) {
|
} catch (e: MXCryptoError) {
|
||||||
Timber.w("Failed to decrypt event in history")
|
Timber.w("Failed to decrypt event in history")
|
||||||
|
|
|
@ -29,6 +29,7 @@ import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLay
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
import org.matrix.android.sdk.api.session.crypto.model.MessageVerificationState
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationState
|
import org.matrix.android.sdk.api.session.crypto.verification.VerificationState
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
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.EventType
|
||||||
|
@ -74,9 +75,10 @@ class MessageInformationDataFactory @Inject constructor(
|
||||||
prevDisplayableEvent?.root?.localDateTime()?.toLocalDate() != date.toLocalDate()
|
prevDisplayableEvent?.root?.localDateTime()?.toLocalDate() != date.toLocalDate()
|
||||||
|
|
||||||
val time = dateFormatter.format(event.root.originServerTs, DateFormatKind.MESSAGE_SIMPLE)
|
val time = dateFormatter.format(event.root.originServerTs, DateFormatKind.MESSAGE_SIMPLE)
|
||||||
val e2eDecoration = runBlocking {
|
// val e2eDecoration = runBlocking {
|
||||||
getE2EDecoration(roomSummary, params.lastEdit ?: event.root)
|
// getE2EDecoration(roomSummary, params.lastEdit ?: event.root)
|
||||||
}
|
// }
|
||||||
|
val e2eDecoration = getE2EDecorationV2(roomSummary, params.lastEdit ?: event.root)
|
||||||
val senderId = runBlocking { getSenderId(event) }
|
val senderId = runBlocking { getSenderId(event) }
|
||||||
// SendState Decoration
|
// SendState Decoration
|
||||||
val sendStateDecoration = if (isSentByMe) {
|
val sendStateDecoration = if (isSentByMe) {
|
||||||
|
@ -147,6 +149,47 @@ class MessageInformationDataFactory @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getE2EDecorationV2(roomSummary: RoomSummary?, event: Event): E2EDecoration {
|
||||||
|
if (roomSummary?.isEncrypted != true) {
|
||||||
|
// No decoration for clear room
|
||||||
|
// Questionable? what if the event is E2E?
|
||||||
|
return E2EDecoration.NONE
|
||||||
|
}
|
||||||
|
if (event.sendState != SendState.SYNCED) {
|
||||||
|
// we don't display e2e decoration if event not synced back
|
||||||
|
return E2EDecoration.NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (event.mxDecryptionResult?.verificationState) {
|
||||||
|
MessageVerificationState.VERIFIED -> E2EDecoration.NONE
|
||||||
|
MessageVerificationState.SIGNED_DEVICE_OF_UNVERIFIED_USER -> E2EDecoration.NONE
|
||||||
|
MessageVerificationState.UN_SIGNED_DEVICE_OF_VERIFIED_USER -> E2EDecoration.WARN_SENT_BY_UNVERIFIED
|
||||||
|
// We neither verified this user so not interesting in that warning?
|
||||||
|
MessageVerificationState.UN_SIGNED_DEVICE -> E2EDecoration.NONE
|
||||||
|
MessageVerificationState.UNKNOWN_DEVICE -> E2EDecoration.WARN_SENT_BY_DELETED_SESSION
|
||||||
|
MessageVerificationState.UNSAFE_SOURCE -> E2EDecoration.WARN_UNSAFE_KEY
|
||||||
|
MessageVerificationState.MISMATCH -> E2EDecoration.WARN_UNSAFE_KEY
|
||||||
|
null -> {
|
||||||
|
// No verification state.
|
||||||
|
// So could be a clear event, or a legacy decryption, or an UTD event
|
||||||
|
if (!event.isEncrypted()) {
|
||||||
|
e2EDecorationForClearEventInE2ERoom(event, roomSummary)
|
||||||
|
} else if (event.mxDecryptionResult != null) {
|
||||||
|
// No verification state, so could be a migrated old decryption?
|
||||||
|
if (event.mxDecryptionResult?.isSafe == true) {
|
||||||
|
// for past legacy decryption let's not decorate
|
||||||
|
E2EDecoration.NONE
|
||||||
|
} else {
|
||||||
|
E2EDecoration.WARN_UNSAFE_KEY
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Undecrypted event
|
||||||
|
E2EDecoration.NONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun getE2EDecoration(roomSummary: RoomSummary?, event: Event): E2EDecoration {
|
private suspend fun getE2EDecoration(roomSummary: RoomSummary?, event: Event): E2EDecoration {
|
||||||
if (roomSummary?.isEncrypted != true) {
|
if (roomSummary?.isEncrypted != true) {
|
||||||
// No decoration for clear room
|
// No decoration for clear room
|
||||||
|
|
|
@ -217,7 +217,7 @@ class NotifiableEventResolver @Inject constructor(
|
||||||
senderKey = result.senderCurve25519Key,
|
senderKey = result.senderCurve25519Key,
|
||||||
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
||||||
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain,
|
||||||
isSafe = result.isSafe
|
verificationState = result.messageVerificationState
|
||||||
)
|
)
|
||||||
} catch (ignore: MXCryptoError) {
|
} catch (ignore: MXCryptoError) {
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue