From 7a62361cafeb0e346793ef8d8f88024296b36c4e Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Mon, 29 Jul 2024 13:20:21 +0100 Subject: [PATCH] crypto: Extract a new error type: MismatchedIdentityKeysError --- crates/matrix-sdk-crypto/src/error.rs | 38 ++++++++++++++----- .../src/identities/device.rs | 16 ++++---- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/crates/matrix-sdk-crypto/src/error.rs b/crates/matrix-sdk-crypto/src/error.rs index c73a8ed27e9..72297e82f22 100644 --- a/crates/matrix-sdk-crypto/src/error.rs +++ b/crates/matrix-sdk-crypto/src/error.rs @@ -13,6 +13,7 @@ // limitations under the License. use ruma::{CanonicalJsonError, IdParseError, OwnedDeviceId, OwnedRoomId, OwnedUserId}; +use serde::{ser::SerializeMap, Serializer}; use serde_json::Error as SerdeError; use thiserror::Error; use vodozemac::{Curve25519PublicKey, Ed25519PublicKey}; @@ -93,16 +94,7 @@ pub enum MegolmError { #[error( "decryption failed because of mismatched identity keys of the sending device and those recorded in the to-device message" )] - MismatchedIdentityKeys { - /// The Ed25519 key recorded in the room key's to-device message. - key_ed25519: Box, - /// The Ed25519 identity key of the device sending the room key. - device_ed25519: Option>, - /// The Curve25519 key recorded in the room key's to-device message. - key_curve25519: Box, - /// The Curve25519 identity key of the device sending the room key. - device_curve25519: Option>, - }, + MismatchedIdentityKeys(MismatchedIdentityKeysError), /// The encrypted megolm message couldn't be decoded. #[error(transparent)] @@ -117,6 +109,32 @@ pub enum MegolmError { Store(#[from] CryptoStoreError), } +/// Decryption failed because of a mismatch between the identity keys of the +/// device we received the room key from and the identity keys recorded in +/// the plaintext of the room key to-device message. +#[derive(Error, Debug)] +pub struct MismatchedIdentityKeysError { + /// The Ed25519 key recorded in the room key's to-device message. + pub key_ed25519: Box, + /// The Ed25519 identity key of the device sending the room key. + pub device_ed25519: Option>, + /// The Curve25519 key recorded in the room key's to-device message. + pub key_curve25519: Box, + /// The Curve25519 identity key of the device sending the room key. + pub device_curve25519: Option>, +} + +impl std::fmt::Display for MismatchedIdentityKeysError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut ser = f.serialize_struct("MismatchedIdentityKeysError", 4)?; + ser.serialize_entry("key_ed25519", &self.key_ed25519)?; + ser.serialize_entry("device_ed25519", &self.device_ed25519)?; + ser.serialize_entry("key_curve25519", &self.key_curve25519)?; + ser.serialize_entry("device_curve25519", &self.device_curve25519)?; + ser.end() + } +} + /// Error that occurs when decrypting an event that is malformed. #[derive(Error, Debug)] pub enum EventError { diff --git a/crates/matrix-sdk-crypto/src/identities/device.rs b/crates/matrix-sdk-crypto/src/identities/device.rs index eaeb24bc979..ef4be5e5711 100644 --- a/crates/matrix-sdk-crypto/src/identities/device.rs +++ b/crates/matrix-sdk-crypto/src/identities/device.rs @@ -38,7 +38,7 @@ use super::{atomic_bool_deserializer, atomic_bool_serializer}; #[cfg(any(test, feature = "testing", doc))] use crate::OlmMachine; use crate::{ - error::{EventError, OlmError, OlmResult, SignatureError}, + error::{EventError, MismatchedIdentityKeysError, OlmError, OlmResult, SignatureError}, identities::{OwnUserIdentityData, UserIdentityData}, olm::{ InboundGroupSession, OutboundGroupSession, Session, ShareInfo, SignedJsonObject, VerifyJson, @@ -261,12 +261,14 @@ impl Device { match (ed25519_comparison, curve25519_comparison) { // If we have any of the keys but they don't turn out to match, refuse to decrypt // instead. - (_, Some(false)) | (Some(false), _) => Err(MegolmError::MismatchedIdentityKeys { - key_ed25519: key.into(), - device_ed25519: self.ed25519_key().map(Into::into), - key_curve25519: session.sender_key().into(), - device_curve25519: self.curve25519_key().map(Into::into), - }), + (_, Some(false)) | (Some(false), _) => { + Err(MegolmError::MismatchedIdentityKeys(MismatchedIdentityKeysError { + key_ed25519: key.into(), + device_ed25519: self.ed25519_key().map(Into::into), + key_curve25519: session.sender_key().into(), + device_curve25519: self.curve25519_key().map(Into::into), + })) + } // If both keys match, we have ourselves an owner. (Some(true), Some(true)) => Ok(true), // In the remaining cases, the device is missing at least one of the required