From 4118003622f1a7219602fc3717425039491ed0bc Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 17 Oct 2024 22:17:22 +0100 Subject: [PATCH] crypto: Add more UtdCauses --- crates/matrix-sdk-crypto/src/error.rs | 2 + .../src/types/events/utd_cause.rs | 68 +++++++++++++------ 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/crates/matrix-sdk-crypto/src/error.rs b/crates/matrix-sdk-crypto/src/error.rs index 89fe5c5edaf..4400da9d696 100644 --- a/crates/matrix-sdk-crypto/src/error.rs +++ b/crates/matrix-sdk-crypto/src/error.rs @@ -120,6 +120,8 @@ pub enum MegolmError { /// An encrypted message wasn't decrypted, because the sender's /// cross-signing identity did not satisfy the requested /// [`crate::TrustRequirement`]. + /// + /// The nested value is the sender's current verification level. #[error("decryption failed because trust requirement not satisfied: {0}")] SenderIdentityNotTrusted(VerificationLevel), } diff --git a/crates/matrix-sdk-crypto/src/types/events/utd_cause.rs b/crates/matrix-sdk-crypto/src/types/events/utd_cause.rs index ffb6813cfde..eef81bfcea5 100644 --- a/crates/matrix-sdk-crypto/src/types/events/utd_cause.rs +++ b/crates/matrix-sdk-crypto/src/types/events/utd_cause.rs @@ -12,6 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +use matrix_sdk_common::deserialized_responses::{ + DeviceLinkProblem, UnableToDecryptInfo, UnableToDecryptReason, VerificationLevel, +}; use ruma::{events::AnySyncTimelineEvent, serde::Raw}; use serde::Deserialize; @@ -27,13 +30,24 @@ pub enum UtdCause { /// We are missing the keys for this event, and the event was sent when we /// were not a member of the room (or invited). SentBeforeWeJoined = 1, - // - // TODO: Other causes for UTDs. For example, this message is device-historical, information - // extracted from the WithheldCode in the MissingRoomKey object, or various types of Olm - // session problems. - // - // Note: This needs to be a simple enum so we can export it via FFI, so if more information - // needs to be provided, it should be through a separate type. + + /// The message was sent by a user identity we have not verified, but the + /// user was previously verified. + VerificationViolation = 2, + + /// The [`crate::TrustRequirement`] requires that the sending device be + /// signed by its owner, and it was not. + UnsignedDevice = 3, + + /// The [`crate::TrustRequirement`] requires that the sending device be + /// signed by its owner, and we were unable to securely find the device. + /// + /// This could be because the device has since been deleted, because we + /// haven't yet downloaded it from the server, or because the session + /// data was obtained from an insecure source (imported from a file, + /// obtained from a legacy (asymmetric) backup, unsafe key forward, etc. + /// ) + UnknownDevice = 4, } /// MSC4115 membership info in the unsigned area. @@ -59,21 +73,37 @@ impl UtdCause { unable_to_decrypt_info: &UnableToDecryptInfo, ) -> Self { // TODO: in future, use more information to give a richer answer. E.g. - // is this event device-historical? Was the Olm communication disrupted? - // Did the sender refuse to send the key because we're not verified? - - // Look in the unsigned area for a `membership` field. - if let Some(raw_event) = raw_event { - if let Ok(Some(unsigned)) = raw_event.get_field::("unsigned") { - if let Membership::Leave = unsigned.membership { - // We were not a member - this is the cause of the UTD - return UtdCause::SentBeforeWeJoined; + match unable_to_decrypt_info.reason { + UnableToDecryptReason::MissingMegolmSession + | UnableToDecryptReason::UnknownMegolmMessageIndex => { + // Look in the unsigned area for a `membership` field. + if let Some(raw_event) = raw_event { + if let Ok(Some(unsigned)) = + raw_event.get_field::("unsigned") + { + if let Membership::Leave = unsigned.membership { + // We were not a member - this is the cause of the UTD + return UtdCause::SentBeforeWeJoined; + } + } } + UtdCause::Unknown + } + + UnableToDecryptReason::SenderIdentityNotTrusted( + VerificationLevel::VerificationViolation, + ) => UtdCause::VerificationViolation, + + UnableToDecryptReason::SenderIdentityNotTrusted(VerificationLevel::UnsignedDevice) => { + UtdCause::UnsignedDevice + } + + UnableToDecryptReason::SenderIdentityNotTrusted(VerificationLevel::None(_)) => { + UtdCause::UnknownDevice } - } - // We can't find an explanation for this UTD - UtdCause::Unknown + _ => UtdCause::Unknown, + } } }