diff --git a/matrix_sdk_crypto/src/identities/device.rs b/matrix_sdk_crypto/src/identities/device.rs index d9f6e8cc..79884c84 100644 --- a/matrix_sdk_crypto/src/identities/device.rs +++ b/matrix_sdk_crypto/src/identities/device.rs @@ -39,11 +39,11 @@ use tracing::warn; use super::{atomic_bool_deserializer, atomic_bool_serializer}; use crate::{ error::{EventError, OlmError, OlmResult, SignatureError}, - identities::{OwnUserIdentity, UserIdentities}, + identities::{ReadOnlyOwnUserIdentity, ReadOnlyUserIdentities}, olm::{InboundGroupSession, PrivateCrossSigningIdentity, Session, Utility}, store::{Changes, CryptoStore, DeviceChanges, Result as StoreResult}, verification::VerificationMachine, - OutgoingVerificationRequest, Sas, ToDeviceRequest, + OutgoingVerificationRequest, Sas, ToDeviceRequest, VerificationRequest, }; #[cfg(test)] use crate::{OlmMachine, ReadOnlyAccount}; @@ -104,8 +104,8 @@ pub struct Device { pub(crate) inner: ReadOnlyDevice, pub(crate) private_identity: Arc>, pub(crate) verification_machine: VerificationMachine, - pub(crate) own_identity: Option, - pub(crate) device_owner_identity: Option, + pub(crate) own_identity: Option, + pub(crate) device_owner_identity: Option, } impl std::fmt::Debug for Device { @@ -228,8 +228,8 @@ pub struct UserDevices { pub(crate) inner: HashMap, pub(crate) private_identity: Arc>, pub(crate) verification_machine: VerificationMachine, - pub(crate) own_identity: Option, - pub(crate) device_owner_identity: Option, + pub(crate) own_identity: Option, + pub(crate) device_owner_identity: Option, } impl UserDevices { @@ -382,16 +382,16 @@ impl ReadOnlyDevice { pub(crate) fn verified( &self, - own_identity: &Option, - device_owner: &Option, + own_identity: &Option, + device_owner: &Option, ) -> bool { self.is_locally_trusted() || self.is_cross_signing_trusted(own_identity, device_owner) } pub(crate) fn is_cross_signing_trusted( &self, - own_identity: &Option, - device_owner: &Option, + own_identity: &Option, + device_owner: &Option, ) -> bool { own_identity.as_ref().map_or(false, |own_identity| { // Our own identity needs to be marked as verified. @@ -401,14 +401,14 @@ impl ReadOnlyDevice { .map(|device_identity| match device_identity { // If it's one of our own devices, just check that // we signed the device. - UserIdentities::Own(_) => { + ReadOnlyUserIdentities::Own(_) => { own_identity.is_device_signed(self).map_or(false, |_| true) } // If it's a device from someone else, first check // that our user has signed the other user and then // check if the other user has signed this device. - UserIdentities::Other(device_identity) => { + ReadOnlyUserIdentities::Other(device_identity) => { own_identity.is_identity_signed(device_identity).map_or(false, |_| true) && device_identity.is_device_signed(self).map_or(false, |_| true) } diff --git a/matrix_sdk_crypto/src/identities/manager.rs b/matrix_sdk_crypto/src/identities/manager.rs index e8e7fedc..58763126 100644 --- a/matrix_sdk_crypto/src/identities/manager.rs +++ b/matrix_sdk_crypto/src/identities/manager.rs @@ -29,8 +29,8 @@ use tracing::{trace, warn}; use crate::{ error::OlmResult, identities::{ - MasterPubkey, OwnUserIdentity, ReadOnlyDevice, SelfSigningPubkey, UserIdentities, - UserIdentity, UserSigningPubkey, + MasterPubkey, ReadOnlyDevice, ReadOnlyOwnUserIdentity, ReadOnlyUserIdentities, + ReadOnlyUserIdentity, SelfSigningPubkey, UserSigningPubkey, }, requests::KeysQueryRequest, store::{Changes, DeviceChanges, IdentityChanges, Result as StoreResult, Store}, @@ -246,7 +246,7 @@ impl IdentityManager { let result = if let Some(mut i) = self.store.get_user_identity(user_id).await? { match &mut i { - UserIdentities::Own(ref mut identity) => { + ReadOnlyUserIdentities::Own(ref mut identity) => { let user_signing = if let Some(s) = response.user_signing_keys.get(user_id) { UserSigningPubkey::from(s) @@ -261,7 +261,7 @@ impl IdentityManager { identity.update(master_key, self_signing, user_signing).map(|_| (i, false)) } - UserIdentities::Other(ref mut identity) => { + ReadOnlyUserIdentities::Other(ref mut identity) => { identity.update(master_key, self_signing).map(|_| (i, false)) } } @@ -280,8 +280,8 @@ impl IdentityManager { continue; } - OwnUserIdentity::new(master_key, self_signing, user_signing) - .map(|i| (UserIdentities::Own(i), true)) + ReadOnlyOwnUserIdentity::new(master_key, self_signing, user_signing) + .map(|i| (ReadOnlyUserIdentities::Own(i), true)) } else { warn!( "User identity for our own user {} didn't contain a \ @@ -294,8 +294,8 @@ impl IdentityManager { warn!("User id mismatch in one of the cross signing keys for user {}", user_id); continue; } else { - UserIdentity::new(master_key, self_signing) - .map(|i| (UserIdentities::Other(i), true)) + ReadOnlyUserIdentity::new(master_key, self_signing) + .map(|i| (ReadOnlyUserIdentities::Other(i), true)) }; match result { diff --git a/matrix_sdk_crypto/src/identities/mod.rs b/matrix_sdk_crypto/src/identities/mod.rs index 873cecfa..d90206b3 100644 --- a/matrix_sdk_crypto/src/identities/mod.rs +++ b/matrix_sdk_crypto/src/identities/mod.rs @@ -53,8 +53,8 @@ pub use device::{Device, LocalTrust, ReadOnlyDevice, UserDevices}; pub(crate) use manager::IdentityManager; use serde::{Deserialize, Deserializer, Serializer}; pub use user::{ - MasterPubkey, OwnUserIdentity, SelfSigningPubkey, UserIdentities, UserIdentity, - UserSigningPubkey, + MasterPubkey, OwnUserIdentity, ReadOnlyOwnUserIdentity, ReadOnlyUserIdentities, + ReadOnlyUserIdentity, SelfSigningPubkey, UserIdentities, UserIdentity, UserSigningPubkey, }; // These methods are only here because Serialize and Deserialize don't seem to diff --git a/matrix_sdk_crypto/src/identities/user.rs b/matrix_sdk_crypto/src/identities/user.rs index 184d64c2..c124d4e4 100644 --- a/matrix_sdk_crypto/src/identities/user.rs +++ b/matrix_sdk_crypto/src/identities/user.rs @@ -15,6 +15,7 @@ use std::{ collections::{btree_map::Iter, BTreeMap}, convert::TryFrom, + ops::Deref, sync::{ atomic::{AtomicBool, Ordering}, Arc, @@ -23,7 +24,10 @@ use std::{ use ruma::{ encryption::{CrossSigningKey, KeyUsage}, - DeviceKeyId, UserId, + events::{ + key::verification::VerificationMethod, room::message::KeyVerificationRequestEventContent, + }, + DeviceKeyId, EventId, RoomId, UserId, }; use serde::{Deserialize, Serialize}; use serde_json::to_value; @@ -31,7 +35,153 @@ use serde_json::to_value; use super::{atomic_bool_deserializer, atomic_bool_serializer}; #[cfg(test)] use crate::olm::PrivateCrossSigningIdentity; -use crate::{error::SignatureError, olm::Utility, ReadOnlyDevice}; +use crate::{ + error::SignatureError, olm::Utility, verification::VerificationMachine, CryptoStoreError, + OutgoingVerificationRequest, ReadOnlyDevice, VerificationRequest, +}; + +/// Enum over the different user identity types we can have. +#[derive(Debug, Clone)] +pub enum UserIdentities { + /// Our own user identity. + Own(OwnUserIdentity), + /// An identity belonging to another user. + Other(UserIdentity), +} + +impl UserIdentities { + /// Destructure the enum into an `OwnUserIdentity` if it's of the correct + /// type. + pub fn own(self) -> Option { + match self { + Self::Own(i) => Some(i), + _ => None, + } + } + + /// Destructure the enum into an `UserIdentity` if it's of the correct + /// type. + pub fn other(self) -> Option { + match self { + Self::Other(i) => Some(i), + _ => None, + } + } +} + +impl From for UserIdentities { + fn from(i: OwnUserIdentity) -> Self { + Self::Own(i) + } +} + +impl From for UserIdentities { + fn from(i: UserIdentity) -> Self { + Self::Other(i) + } +} + +/// Struct representing a cross signing identity of a user. +/// +/// This is the user identity of a user that isn't our own. Other users will +/// only contain a master key and a self signing key, meaning that only device +/// signatures can be checked with this identity. +/// +/// This struct wraps a read-only version of the struct and allows verifications +/// to be requested to verify our own device with the user identity. +#[derive(Debug, Clone)] +pub struct OwnUserIdentity { + pub(crate) inner: ReadOnlyOwnUserIdentity, + pub(crate) verification_machine: VerificationMachine, +} + +impl Deref for OwnUserIdentity { + type Target = ReadOnlyOwnUserIdentity; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl OwnUserIdentity { + /// Send a verification request to our other devices. + pub async fn request_verification( + &self, + ) -> Result<(VerificationRequest, OutgoingVerificationRequest), CryptoStoreError> { + self.verification_machine.request_self_verification(&self.inner, None).await + } + + /// Send a verification request to our other devices while specifying our + /// supported methods. + /// + /// # Arguments + /// + /// * `methods` - The verification methods that we're supporting. + pub async fn request_verification_with_methods( + &self, + methods: Vec, + ) -> Result<(VerificationRequest, OutgoingVerificationRequest), CryptoStoreError> { + self.verification_machine.request_self_verification(&self.inner, Some(methods)).await + } +} + +/// Struct representing a cross signing identity of a user. +/// +/// This is the user identity of a user that isn't our own. Other users will +/// only contain a master key and a self signing key, meaning that only device +/// signatures can be checked with this identity. +/// +/// This struct wraps a read-only version of the struct and allows verifications +/// to be requested to verify our own device with the user identity. +#[derive(Debug, Clone)] +pub struct UserIdentity { + pub(crate) inner: ReadOnlyUserIdentity, + pub(crate) verification_machine: VerificationMachine, +} + +impl Deref for UserIdentity { + type Target = ReadOnlyUserIdentity; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl UserIdentity { + /// Create a `VerificationRequest` object after the verification request + /// content has been sent out. + pub async fn request_verification( + &self, + room_id: &RoomId, + request_event_id: &EventId, + methods: Option>, + ) -> VerificationRequest { + self.verification_machine + .request_verification(&self.inner, room_id, request_event_id, methods) + .await + } + + /// Send a verification request to the given user. + /// + /// The returned content needs to be sent out into a DM room with the given + /// user. + /// + /// After the content has been sent out a `VerificationRequest` can be + /// started with the [`request_verification`] method. + /// + /// [`request_verification()`]: #method.request_verification + pub async fn verification_request_content( + &self, + methods: Option>, + ) -> KeyVerificationRequestEventContent { + VerificationRequest::request( + self.verification_machine.own_user_id(), + self.verification_machine.own_device_id(), + self.user_id(), + methods, + ) + } +} /// Wrapper for a cross signing key marking it as the master key. /// @@ -358,47 +508,47 @@ impl<'a> IntoIterator for &'a SelfSigningPubkey { /// Enum over the different user identity types we can have. #[derive(Debug, Clone, Serialize, Deserialize)] -pub enum UserIdentities { +pub enum ReadOnlyUserIdentities { /// Our own user identity. - Own(OwnUserIdentity), + Own(ReadOnlyOwnUserIdentity), /// Identities of other users. - Other(UserIdentity), + Other(ReadOnlyUserIdentity), } -impl From for UserIdentities { - fn from(identity: OwnUserIdentity) -> Self { - UserIdentities::Own(identity) +impl From for ReadOnlyUserIdentities { + fn from(identity: ReadOnlyOwnUserIdentity) -> Self { + ReadOnlyUserIdentities::Own(identity) } } -impl From for UserIdentities { - fn from(identity: UserIdentity) -> Self { - UserIdentities::Other(identity) +impl From for ReadOnlyUserIdentities { + fn from(identity: ReadOnlyUserIdentity) -> Self { + ReadOnlyUserIdentities::Other(identity) } } -impl UserIdentities { +impl ReadOnlyUserIdentities { /// The unique user id of this identity. pub fn user_id(&self) -> &UserId { match self { - UserIdentities::Own(i) => i.user_id(), - UserIdentities::Other(i) => i.user_id(), + ReadOnlyUserIdentities::Own(i) => i.user_id(), + ReadOnlyUserIdentities::Other(i) => i.user_id(), } } /// Get the master key of the identity. pub fn master_key(&self) -> &MasterPubkey { match self { - UserIdentities::Own(i) => i.master_key(), - UserIdentities::Other(i) => i.master_key(), + ReadOnlyUserIdentities::Own(i) => i.master_key(), + ReadOnlyUserIdentities::Other(i) => i.master_key(), } } /// Get the self-signing key of the identity. pub fn self_signing_key(&self) -> &SelfSigningPubkey { match self { - UserIdentities::Own(i) => &i.self_signing_key, - UserIdentities::Other(i) => &i.self_signing_key, + ReadOnlyUserIdentities::Own(i) => &i.self_signing_key, + ReadOnlyUserIdentities::Other(i) => &i.self_signing_key, } } @@ -406,32 +556,32 @@ impl UserIdentities { /// own user identity.. pub fn user_signing_key(&self) -> Option<&UserSigningPubkey> { match self { - UserIdentities::Own(i) => Some(&i.user_signing_key), - UserIdentities::Other(_) => None, + ReadOnlyUserIdentities::Own(i) => Some(&i.user_signing_key), + ReadOnlyUserIdentities::Other(_) => None, } } - /// Destructure the enum into an `OwnUserIdentity` if it's of the correct - /// type. - pub fn own(&self) -> Option<&OwnUserIdentity> { + /// Destructure the enum into an `ReadOnlyOwnUserIdentity` if it's of the + /// correct type. + pub fn own(&self) -> Option<&ReadOnlyOwnUserIdentity> { match self { - UserIdentities::Own(i) => Some(i), + ReadOnlyUserIdentities::Own(i) => Some(i), _ => None, } } /// Destructure the enum into an `UserIdentity` if it's of the correct /// type. - pub fn other(&self) -> Option<&UserIdentity> { + pub fn other(&self) -> Option<&ReadOnlyUserIdentity> { match self { - UserIdentities::Other(i) => Some(i), + ReadOnlyUserIdentities::Other(i) => Some(i), _ => None, } } } -impl PartialEq for UserIdentities { - fn eq(&self, other: &UserIdentities) -> bool { +impl PartialEq for ReadOnlyUserIdentities { + fn eq(&self, other: &ReadOnlyUserIdentities) -> bool { self.user_id() == other.user_id() } } @@ -442,13 +592,13 @@ impl PartialEq for UserIdentities { /// only contain a master key and a self signing key, meaning that only device /// signatures can be checked with this identity. #[derive(Debug, Clone, Deserialize, Serialize)] -pub struct UserIdentity { +pub struct ReadOnlyUserIdentity { user_id: Arc, pub(crate) master_key: MasterPubkey, self_signing_key: SelfSigningPubkey, } -impl UserIdentity { +impl ReadOnlyUserIdentity { /// Create a new user identity with the given master and self signing key. /// /// # Arguments @@ -543,7 +693,7 @@ impl UserIdentity { /// This identity can verify other identities as well as devices belonging to /// the identity. #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OwnUserIdentity { +pub struct ReadOnlyOwnUserIdentity { user_id: Arc, master_key: MasterPubkey, self_signing_key: SelfSigningPubkey, @@ -555,7 +705,7 @@ pub struct OwnUserIdentity { verified: Arc, } -impl OwnUserIdentity { +impl ReadOnlyOwnUserIdentity { /// Create a new own user identity with the given master, self signing, and /// user signing key. /// @@ -615,7 +765,10 @@ impl OwnUserIdentity { /// /// Returns an empty result if the signature check succeeded, otherwise a /// SignatureError indicating why the check failed. - pub fn is_identity_signed(&self, identity: &UserIdentity) -> Result<(), SignatureError> { + pub fn is_identity_signed( + &self, + identity: &ReadOnlyUserIdentity, + ) -> Result<(), SignatureError> { self.user_signing_key.verify_master_key(&identity.master_key) } @@ -692,7 +845,7 @@ pub(crate) mod test { use matrix_sdk_test::async_test; use ruma::{api::client::r0::keys::get_keys::Response as KeyQueryResponse, user_id}; - use super::{OwnUserIdentity, UserIdentities, UserIdentity}; + use super::{ReadOnlyOwnUserIdentity, ReadOnlyUserIdentities, ReadOnlyUserIdentity}; use crate::{ identities::{ manager::test::{other_key_query, own_key_query}, @@ -710,28 +863,29 @@ pub(crate) mod test { (first, second) } - fn own_identity(response: &KeyQueryResponse) -> OwnUserIdentity { + fn own_identity(response: &KeyQueryResponse) -> ReadOnlyOwnUserIdentity { let user_id = user_id!("@example:localhost"); let master_key = response.master_keys.get(&user_id).unwrap(); let user_signing = response.user_signing_keys.get(&user_id).unwrap(); let self_signing = response.self_signing_keys.get(&user_id).unwrap(); - OwnUserIdentity::new(master_key.into(), self_signing.into(), user_signing.into()).unwrap() + ReadOnlyOwnUserIdentity::new(master_key.into(), self_signing.into(), user_signing.into()) + .unwrap() } - pub(crate) fn get_own_identity() -> OwnUserIdentity { + pub(crate) fn get_own_identity() -> ReadOnlyOwnUserIdentity { own_identity(&own_key_query()) } - pub(crate) fn get_other_identity() -> UserIdentity { + pub(crate) fn get_other_identity() -> ReadOnlyUserIdentity { let user_id = user_id!("@example2:localhost"); let response = other_key_query(); let master_key = response.master_keys.get(&user_id).unwrap(); let self_signing = response.self_signing_keys.get(&user_id).unwrap(); - UserIdentity::new(master_key.into(), self_signing.into()).unwrap() + ReadOnlyUserIdentity::new(master_key.into(), self_signing.into()).unwrap() } #[test] @@ -743,7 +897,8 @@ pub(crate) mod test { let user_signing = response.user_signing_keys.get(&user_id).unwrap(); let self_signing = response.self_signing_keys.get(&user_id).unwrap(); - OwnUserIdentity::new(master_key.into(), self_signing.into(), user_signing.into()).unwrap(); + ReadOnlyOwnUserIdentity::new(master_key.into(), self_signing.into(), user_signing.into()) + .unwrap(); } #[test] @@ -773,7 +928,7 @@ pub(crate) mod test { verification_machine: verification_machine.clone(), private_identity: private_identity.clone(), own_identity: Some(identity.clone()), - device_owner_identity: Some(UserIdentities::Own(identity.clone())), + device_owner_identity: Some(ReadOnlyUserIdentities::Own(identity.clone())), }; let second = Device { @@ -781,7 +936,7 @@ pub(crate) mod test { verification_machine, private_identity, own_identity: Some(identity.clone()), - device_owner_identity: Some(UserIdentities::Own(identity.clone())), + device_owner_identity: Some(ReadOnlyUserIdentities::Own(identity.clone())), }; assert!(!second.is_locally_trusted()); diff --git a/matrix_sdk_crypto/src/lib.rs b/matrix_sdk_crypto/src/lib.rs index dcd4db02..a3d7a244 100644 --- a/matrix_sdk_crypto/src/lib.rs +++ b/matrix_sdk_crypto/src/lib.rs @@ -45,7 +45,8 @@ pub use file_encryption::{ DecryptorError, EncryptionInfo, KeyExportError, }; pub use identities::{ - Device, LocalTrust, OwnUserIdentity, ReadOnlyDevice, UserDevices, UserIdentities, UserIdentity, + Device, LocalTrust, OwnUserIdentity, ReadOnlyDevice, ReadOnlyOwnUserIdentity, + ReadOnlyUserIdentities, ReadOnlyUserIdentity, UserDevices, UserIdentities, UserIdentity, }; pub use machine::OlmMachine; pub use matrix_qrcode; diff --git a/matrix_sdk_crypto/src/machine.rs b/matrix_sdk_crypto/src/machine.rs index 68b4426b..f2f4f22e 100644 --- a/matrix_sdk_crypto/src/machine.rs +++ b/matrix_sdk_crypto/src/machine.rs @@ -46,7 +46,7 @@ use tracing::{debug, error, info, trace, warn}; use crate::store::sled::SledStore; use crate::{ error::{EventError, MegolmError, MegolmResult, OlmError, OlmResult}, - identities::{Device, IdentityManager, UserDevices}, + identities::{user::UserIdentities, Device, IdentityManager, UserDevices}, key_request::KeyRequestMachine, olm::{ Account, EncryptionSettings, ExportedRoomKey, GroupSessionKey, IdentityKeys, @@ -1052,6 +1052,18 @@ impl OlmMachine { self.store.get_device(user_id, device_id).await } + /// Get the cross signing user identity of a user. + /// + /// # Arguments + /// + /// * `user_id` - The unique id of the user that the identity belongs to + /// + /// Returns a `UserIdentities` enum if one is found and the crypto store + /// didn't throw an error. + pub async fn get_identity(&self, user_id: &UserId) -> StoreResult> { + self.store.get_identity(user_id).await + } + /// Get a map holding all the devices of an user. /// /// # Arguments diff --git a/matrix_sdk_crypto/src/olm/signing/mod.rs b/matrix_sdk_crypto/src/olm/signing/mod.rs index 523c274b..469cdbce 100644 --- a/matrix_sdk_crypto/src/olm/signing/mod.rs +++ b/matrix_sdk_crypto/src/olm/signing/mod.rs @@ -34,7 +34,7 @@ use serde_json::Error as JsonError; use crate::{ error::SignatureError, identities::MasterPubkey, requests::UploadSigningKeysRequest, - OwnUserIdentity, ReadOnlyAccount, ReadOnlyDevice, UserIdentity, + ReadOnlyAccount, ReadOnlyDevice, ReadOnlyOwnUserIdentity, ReadOnlyUserIdentity, }; /// Private cross signing identity. @@ -117,7 +117,9 @@ impl PrivateCrossSigningIdentity { } } - pub(crate) async fn to_public_identity(&self) -> Result { + pub(crate) async fn to_public_identity( + &self, + ) -> Result { let master = self .master_key .lock() @@ -142,7 +144,7 @@ impl PrivateCrossSigningIdentity { .ok_or(SignatureError::MissingSigningKey)? .public_key .clone(); - let identity = OwnUserIdentity::new(master, self_signing, user_signing)?; + let identity = ReadOnlyOwnUserIdentity::new(master, self_signing, user_signing)?; identity.mark_as_verified(); Ok(identity) @@ -151,7 +153,7 @@ impl PrivateCrossSigningIdentity { /// Sign the given public user identity with this private identity. pub(crate) async fn sign_user( &self, - user_identity: &UserIdentity, + user_identity: &ReadOnlyUserIdentity, ) -> Result { let signed_keys = self .user_signing_key @@ -407,7 +409,7 @@ mod test { use super::{PrivateCrossSigningIdentity, Signing}; use crate::{ - identities::{ReadOnlyDevice, UserIdentity}, + identities::{ReadOnlyDevice, ReadOnlyUserIdentity}, olm::ReadOnlyAccount, }; @@ -518,7 +520,7 @@ mod test { let bob_account = ReadOnlyAccount::new(&user_id!("@bob:localhost"), "DEVICEID".into()); let (bob_private, _, _) = PrivateCrossSigningIdentity::new_with_account(&bob_account).await; - let mut bob_public = UserIdentity::from_private(&bob_private).await; + let mut bob_public = ReadOnlyUserIdentity::from_private(&bob_private).await; let user_signing = identity.user_signing_key.lock().await; let user_signing = user_signing.as_ref().unwrap(); diff --git a/matrix_sdk_crypto/src/olm/signing/pk_signing.rs b/matrix_sdk_crypto/src/olm/signing/pk_signing.rs index 00589e6d..61ba5bcd 100644 --- a/matrix_sdk_crypto/src/olm/signing/pk_signing.rs +++ b/matrix_sdk_crypto/src/olm/signing/pk_signing.rs @@ -37,7 +37,7 @@ use crate::{ error::SignatureError, identities::{MasterPubkey, SelfSigningPubkey, UserSigningPubkey}, utilities::{decode_url_safe as decode, encode_url_safe as encode, DecodeError}, - UserIdentity, + ReadOnlyUserIdentity, }; const NONCE_SIZE: usize = 12; @@ -186,7 +186,7 @@ impl UserSigning { pub async fn sign_user( &self, - user: &UserIdentity, + user: &ReadOnlyUserIdentity, ) -> Result>, SignatureError> { let user_master: &CrossSigningKey = user.master_key().as_ref(); let signature = self.inner.sign_json(serde_json::to_value(user_master)?).await?; diff --git a/matrix_sdk_crypto/src/store/memorystore.rs b/matrix_sdk_crypto/src/store/memorystore.rs index 348b0c79..ef52fd44 100644 --- a/matrix_sdk_crypto/src/store/memorystore.rs +++ b/matrix_sdk_crypto/src/store/memorystore.rs @@ -26,7 +26,7 @@ use super::{ Changes, CryptoStore, InboundGroupSession, ReadOnlyAccount, Result, Session, }; use crate::{ - identities::{ReadOnlyDevice, UserIdentities}, + identities::{ReadOnlyDevice, ReadOnlyUserIdentities}, key_request::OutgoingKeyRequest, olm::{OutboundGroupSession, PrivateCrossSigningIdentity}, }; @@ -44,7 +44,7 @@ pub struct MemoryStore { users_for_key_query: Arc>, olm_hashes: Arc>>, devices: DeviceStore, - identities: Arc>, + identities: Arc>, outgoing_key_requests: Arc>, key_requests_by_info: Arc>, } @@ -215,7 +215,7 @@ impl CryptoStore for MemoryStore { Ok(self.devices.user_devices(user_id)) } - async fn get_user_identity(&self, user_id: &UserId) -> Result> { + async fn get_user_identity(&self, user_id: &UserId) -> Result> { #[allow(clippy::map_clone)] Ok(self.identities.get(user_id).map(|i| i.clone())) } diff --git a/matrix_sdk_crypto/src/store/mod.rs b/matrix_sdk_crypto/src/store/mod.rs index 37c413cb..74f5aacf 100644 --- a/matrix_sdk_crypto/src/store/mod.rs +++ b/matrix_sdk_crypto/src/store/mod.rs @@ -66,7 +66,10 @@ use thiserror::Error; pub use self::sled::SledStore; use crate::{ error::SessionUnpicklingError, - identities::{Device, ReadOnlyDevice, UserDevices, UserIdentities}, + identities::{ + user::{OwnUserIdentity, UserIdentities, UserIdentity}, + Device, ReadOnlyDevice, ReadOnlyUserIdentities, UserDevices, + }, key_request::OutgoingKeyRequest, olm::{ InboundGroupSession, OlmMessageHash, OutboundGroupSession, PrivateCrossSigningIdentity, @@ -109,8 +112,8 @@ pub struct Changes { #[derive(Debug, Clone, Default)] #[allow(missing_docs)] pub struct IdentityChanges { - pub new: Vec, - pub changed: Vec, + pub new: Vec, + pub changed: Vec, } #[derive(Debug, Clone, Default)] @@ -215,8 +218,8 @@ impl Store { device_id: &DeviceId, ) -> Result> { let own_identity = - self.get_user_identity(&self.user_id).await?.map(|i| i.own().cloned()).flatten(); - let device_owner_identity = self.get_user_identity(user_id).await?; + self.inner.get_user_identity(&self.user_id).await?.map(|i| i.own().cloned()).flatten(); + let device_owner_identity = self.inner.get_user_identity(user_id).await?; Ok(self.inner.get_device(user_id, device_id).await?.map(|d| Device { inner: d, @@ -226,6 +229,20 @@ impl Store { device_owner_identity, })) } + + pub async fn get_identity(&self, user_id: &UserId) -> Result> { + Ok(self.inner.get_user_identity(user_id).await?.map(|i| match i { + ReadOnlyUserIdentities::Own(i) => OwnUserIdentity { + inner: i, + verification_machine: self.verification_machine.clone(), + } + .into(), + ReadOnlyUserIdentities::Other(i) => { + UserIdentity { inner: i, verification_machine: self.verification_machine.clone() } + .into() + } + })) + } } impl Deref for Store { @@ -388,7 +405,7 @@ pub trait CryptoStore: AsyncTraitDeps { /// # Arguments /// /// * `user_id` - The user for which we should get the identity. - async fn get_user_identity(&self, user_id: &UserId) -> Result>; + async fn get_user_identity(&self, user_id: &UserId) -> Result>; /// Check if a hash for an Olm message stored in the database. async fn is_message_known(&self, message_hash: &OlmMessageHash) -> Result; diff --git a/matrix_sdk_crypto/src/store/sled.rs b/matrix_sdk_crypto/src/store/sled.rs index b803496c..9ed76e07 100644 --- a/matrix_sdk_crypto/src/store/sled.rs +++ b/matrix_sdk_crypto/src/store/sled.rs @@ -35,7 +35,7 @@ use super::{ ReadOnlyAccount, Result, Session, }; use crate::{ - identities::{ReadOnlyDevice, UserIdentities}, + identities::{ReadOnlyDevice, ReadOnlyUserIdentities}, key_request::OutgoingKeyRequest, olm::{OutboundGroupSession, PickledInboundGroupSession, PrivateCrossSigningIdentity}, }; @@ -669,7 +669,7 @@ impl CryptoStore for SledStore { .collect() } - async fn get_user_identity(&self, user_id: &UserId) -> Result> { + async fn get_user_identity(&self, user_id: &UserId) -> Result> { Ok(self .identities .get(user_id.encode())? diff --git a/matrix_sdk_crypto/src/verification/machine.rs b/matrix_sdk_crypto/src/verification/machine.rs index 330f02cc..374e4410 100644 --- a/matrix_sdk_crypto/src/verification/machine.rs +++ b/matrix_sdk_crypto/src/verification/machine.rs @@ -20,9 +20,13 @@ use std::{ use dashmap::DashMap; use matrix_sdk_common::{locks::Mutex, uuid::Uuid}; use ruma::{ - events::{AnyToDeviceEvent, AnyToDeviceEventContent, ToDeviceEvent}, + events::{ + key::verification::VerificationMethod, AnyToDeviceEvent, AnyToDeviceEventContent, + ToDeviceEvent, + }, serde::Raw, - DeviceId, MilliSecondsSinceUnixEpoch, UserId, + to_device::DeviceIdOrAllDevices, + DeviceId, EventId, MilliSecondsSinceUnixEpoch, RoomId, UserId, }; use tracing::{info, trace, warn}; @@ -37,8 +41,8 @@ use crate::{ olm::PrivateCrossSigningIdentity, requests::OutgoingRequest, store::{CryptoStore, CryptoStoreError}, - OutgoingVerificationRequest, ReadOnlyAccount, ReadOnlyDevice, RoomMessageRequest, - ToDeviceRequest, + OutgoingVerificationRequest, ReadOnlyAccount, ReadOnlyDevice, ReadOnlyOwnUserIdentity, + ReadOnlyUserIdentity, RoomMessageRequest, ToDeviceRequest, }; #[derive(Clone, Debug)] @@ -65,6 +69,69 @@ impl VerificationMachine { } } + pub(crate) fn own_user_id(&self) -> &UserId { + self.account.user_id() + } + + pub(crate) fn own_device_id(&self) -> &DeviceId { + self.account.device_id() + } + + pub(crate) async fn request_self_verification( + &self, + identity: &ReadOnlyOwnUserIdentity, + methods: Option>, + ) -> Result<(VerificationRequest, OutgoingVerificationRequest), CryptoStoreError> { + let flow_id = FlowId::from(Uuid::new_v4().to_string()); + + let verification = VerificationRequest::new( + self.verifications.clone(), + self.account.clone(), + self.private_identity.lock().await.clone(), + self.store.clone(), + flow_id, + identity.user_id(), + methods, + ); + + // TODO get all the device ids of the user instead of using AllDevices + // make sure to remember this so we can cancel once someone picks up + let request: OutgoingVerificationRequest = ToDeviceRequest::new( + identity.user_id(), + DeviceIdOrAllDevices::AllDevices, + AnyToDeviceEventContent::KeyVerificationRequest(verification.request_to_device()), + ) + .into(); + + self.insert_request(verification.clone()); + + Ok((verification, request)) + } + + pub async fn request_verification( + &self, + identity: &ReadOnlyUserIdentity, + room_id: &RoomId, + request_event_id: &EventId, + methods: Option>, + ) -> VerificationRequest { + let flow_id = FlowId::InRoom(room_id.to_owned(), request_event_id.to_owned()); + + let request = VerificationRequest::new( + self.verifications.clone(), + self.account.clone(), + self.private_identity.lock().await.clone(), + self.store.clone(), + flow_id, + identity.user_id(), + methods, + ); + + self.insert_request(request.clone()); + + request + } + pub async fn start_sas( &self, device: ReadOnlyDevice, diff --git a/matrix_sdk_crypto/src/verification/mod.rs b/matrix_sdk_crypto/src/verification/mod.rs index b77d758b..025fca1e 100644 --- a/matrix_sdk_crypto/src/verification/mod.rs +++ b/matrix_sdk_crypto/src/verification/mod.rs @@ -44,7 +44,7 @@ use crate::{ error::SignatureError, olm::PrivateCrossSigningIdentity, store::{Changes, CryptoStore}, - CryptoStoreError, LocalTrust, ReadOnlyDevice, UserIdentities, + CryptoStoreError, LocalTrust, ReadOnlyDevice, ReadOnlyUserIdentities, }; /// An enum over the different verification types the SDK supports. @@ -144,7 +144,7 @@ impl From for Verification { #[derive(Clone, Debug)] pub struct Done { verified_devices: Arc<[ReadOnlyDevice]>, - verified_master_keys: Arc<[UserIdentities]>, + verified_master_keys: Arc<[ReadOnlyUserIdentities]>, } impl Done { @@ -277,7 +277,7 @@ pub struct IdentitiesBeingVerified { private_identity: PrivateCrossSigningIdentity, store: Arc, device_being_verified: ReadOnlyDevice, - identity_being_verified: Option, + identity_being_verified: Option, } impl IdentitiesBeingVerified { @@ -308,7 +308,7 @@ impl IdentitiesBeingVerified { pub async fn mark_as_done( &self, verified_devices: Option<&[ReadOnlyDevice]>, - verified_identities: Option<&[UserIdentities]>, + verified_identities: Option<&[ReadOnlyUserIdentities]>, ) -> Result { let device = self.mark_device_as_verified(verified_devices).await?; let identity = self.mark_identity_as_verified(verified_identities).await?; @@ -415,8 +415,8 @@ impl IdentitiesBeingVerified { async fn mark_identity_as_verified( &self, - verified_identities: Option<&[UserIdentities]>, - ) -> Result, CryptoStoreError> { + verified_identities: Option<&[ReadOnlyUserIdentities]>, + ) -> Result, CryptoStoreError> { // If there wasn't an identity available during the verification flow // return early as there's nothing to do. if self.identity_being_verified.is_none() { @@ -437,7 +437,7 @@ impl IdentitiesBeingVerified { "Marking the user identity of as verified." ); - if let UserIdentities::Own(i) = &identity { + if let ReadOnlyUserIdentities::Own(i) = &identity { i.mark_as_verified(); } diff --git a/matrix_sdk_crypto/src/verification/qrcode.rs b/matrix_sdk_crypto/src/verification/qrcode.rs index 0dd4b576..9ded7336 100644 --- a/matrix_sdk_crypto/src/verification/qrcode.rs +++ b/matrix_sdk_crypto/src/verification/qrcode.rs @@ -45,8 +45,8 @@ use super::{ use crate::{ olm::{PrivateCrossSigningIdentity, ReadOnlyAccount}, store::CryptoStore, - CryptoStoreError, OutgoingVerificationRequest, ReadOnlyDevice, RoomMessageRequest, - ToDeviceRequest, UserIdentities, + CryptoStoreError, OutgoingVerificationRequest, ReadOnlyDevice, ReadOnlyUserIdentities, + RoomMessageRequest, ToDeviceRequest, }; const SECRET_SIZE: usize = 16; @@ -518,7 +518,7 @@ impl QrVerification { ScanError::MissingDeviceKeys(other_user_id.clone(), other_device_id.clone()) })?; - let check_master_key = |key, identity: &UserIdentities| { + let check_master_key = |key, identity: &ReadOnlyUserIdentities| { let master_key = identity.master_key().get_first_key().ok_or_else(|| { ScanError::MissingCrossSigningIdentity(identity.user_id().clone()) })?; @@ -719,7 +719,7 @@ impl QrState { self.state.as_content(flow_id) } - fn verified_identities(&self) -> (Arc<[ReadOnlyDevice]>, Arc<[UserIdentities]>) { + fn verified_identities(&self) -> (Arc<[ReadOnlyDevice]>, Arc<[ReadOnlyUserIdentities]>) { (self.state.verified_devices.clone(), self.state.verified_master_keys.clone()) } } @@ -729,7 +729,7 @@ impl QrState { self, _: &DoneContent, verified_device: Option<&ReadOnlyDevice>, - verified_identity: Option<&UserIdentities>, + verified_identity: Option<&ReadOnlyUserIdentities>, ) -> QrState { let devices: Vec<_> = verified_device.into_iter().cloned().collect(); let identities: Vec<_> = verified_identity.into_iter().cloned().collect(); @@ -768,7 +768,7 @@ impl QrState { self, _: &DoneContent, verified_device: Option<&ReadOnlyDevice>, - verified_identity: Option<&UserIdentities>, + verified_identity: Option<&ReadOnlyUserIdentities>, ) -> QrState { let devices: Vec<_> = verified_device.into_iter().cloned().collect(); let identities: Vec<_> = verified_identity.into_iter().cloned().collect(); diff --git a/matrix_sdk_crypto/src/verification/requests.rs b/matrix_sdk_crypto/src/verification/requests.rs index e84193e1..7c224d55 100644 --- a/matrix_sdk_crypto/src/verification/requests.rs +++ b/matrix_sdk_crypto/src/verification/requests.rs @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#![allow(dead_code)] - use std::sync::{Arc, Mutex}; use matrix_qrcode::QrVerificationData; @@ -31,7 +29,7 @@ use ruma::{ AnyMessageEventContent, AnyToDeviceEventContent, }, to_device::DeviceIdOrAllDevices, - DeviceId, DeviceIdBox, DeviceKeyAlgorithm, EventId, MilliSecondsSinceUnixEpoch, RoomId, UserId, + DeviceId, DeviceIdBox, DeviceKeyAlgorithm, MilliSecondsSinceUnixEpoch, RoomId, UserId, }; use tracing::{info, trace, warn}; @@ -46,8 +44,8 @@ use super::{ use crate::{ olm::{PrivateCrossSigningIdentity, ReadOnlyAccount}, store::CryptoStore, - CryptoStoreError, OutgoingVerificationRequest, ReadOnlyDevice, RoomMessageRequest, Sas, - ToDeviceRequest, UserIdentities, + CryptoStoreError, OutgoingVerificationRequest, ReadOnlyDevice, ReadOnlyUserIdentities, + RoomMessageRequest, Sas, ToDeviceRequest, }; const SUPPORTED_METHODS: &[VerificationMethod] = &[ @@ -79,41 +77,10 @@ impl VerificationRequest { account: ReadOnlyAccount, private_cross_signing_identity: PrivateCrossSigningIdentity, store: Arc, - room_id: &RoomId, - event_id: &EventId, + flow_id: FlowId, other_user: &UserId, + methods: Option>, ) -> Self { - let flow_id = (room_id.to_owned(), event_id.to_owned()).into(); - - let inner = Mutex::new(InnerRequest::Created(RequestState::new( - account.clone(), - private_cross_signing_identity, - cache.clone(), - store, - other_user, - &flow_id, - ))) - .into(); - - Self { - account, - verification_cache: cache, - flow_id: flow_id.into(), - inner, - other_user_id: other_user.to_owned().into(), - we_started: true, - } - } - - pub(crate) fn new_to_device( - cache: VerificationCache, - account: ReadOnlyAccount, - private_cross_signing_identity: PrivateCrossSigningIdentity, - store: Arc, - other_user: &UserId, - ) -> Self { - let flow_id = Uuid::new_v4().to_string().into(); - let inner = Mutex::new(InnerRequest::Created(RequestState::new( account.clone(), private_cross_signing_identity, @@ -121,6 +88,7 @@ impl VerificationRequest { store, other_user, &flow_id, + methods, ))) .into(); @@ -138,11 +106,19 @@ impl VerificationRequest { /// verification from the other side. This should be used only for /// self-verifications and it should be sent to the specific device that we /// want to verify. - pub fn request_to_device(&self) -> RequestToDeviceEventContent { + pub(crate) fn request_to_device(&self) -> RequestToDeviceEventContent { + let inner = self.inner.lock().unwrap(); + + let methods = if let InnerRequest::Created(c) = &*inner { + c.state.our_methods.clone() + } else { + SUPPORTED_METHODS.to_vec() + }; + RequestToDeviceEventContent::new( self.account.device_id().into(), self.flow_id().as_str().to_string(), - SUPPORTED_METHODS.to_vec(), + methods, MilliSecondsSinceUnixEpoch::now(), ) } @@ -155,6 +131,7 @@ impl VerificationRequest { own_user_id: &UserId, own_device_id: &DeviceId, other_user_id: &UserId, + methods: Option>, ) -> KeyVerificationRequestEventContent { KeyVerificationRequestEventContent::new( format!( @@ -163,7 +140,7 @@ impl VerificationRequest { key verification to verify keys.", own_user_id ), - SUPPORTED_METHODS.to_vec(), + methods.unwrap_or_else(|| SUPPORTED_METHODS.to_vec()), own_device_id.into(), other_user_id.to_owned(), ) @@ -376,6 +353,15 @@ impl VerificationRequest { /// Cancel the verification request pub fn cancel(&self) -> Option { + if let Some(verification) = + self.verification_cache.get(self.other_user(), self.flow_id().as_str()) + { + match verification { + crate::Verification::SasV1(s) => s.cancel(), + crate::Verification::QrV1(q) => q.cancel(), + }; + } + let mut inner = self.inner.lock().unwrap(); inner.cancel(true, &CancelCode::User); @@ -398,12 +384,20 @@ impl VerificationRequest { pub(crate) fn receive_ready(&self, sender: &UserId, content: &ReadyContent) { let mut inner = self.inner.lock().unwrap(); - if let InnerRequest::Created(s) = &*inner { - if sender == self.own_user_id() && content.from_device() == self.account.device_id() { - *inner = InnerRequest::Passive(s.clone().into_passive(content)) - } else { + match &*inner { + InnerRequest::Created(s) => { *inner = InnerRequest::Ready(s.clone().into_ready(sender, content)); } + InnerRequest::Requested(s) => { + if sender == self.own_user_id() && content.from_device() != self.account.device_id() + { + *inner = InnerRequest::Passive(s.clone().into_passive(content)) + } + } + InnerRequest::Ready(_) + | InnerRequest::Passive(_) + | InnerRequest::Done(_) + | InnerRequest::Cancelled(_) => {} } } @@ -512,17 +506,6 @@ impl InnerRequest { } } - fn other_user_id(&self) -> &UserId { - match self { - InnerRequest::Created(s) => &s.other_user_id, - InnerRequest::Requested(s) => &s.other_user_id, - InnerRequest::Ready(s) => &s.other_user_id, - InnerRequest::Passive(s) => &s.other_user_id, - InnerRequest::Done(s) => &s.other_user_id, - InnerRequest::Cancelled(s) => &s.other_user_id, - } - } - fn accept(&mut self, methods: Vec) -> Option { if let InnerRequest::Requested(s) = self { let (state, content) = s.clone().accept(methods); @@ -569,20 +552,6 @@ impl InnerRequest { InnerRequest::Cancelled(_) => Ok(None), } } - - fn to_started_sas( - &self, - content: &StartContent, - other_device: ReadOnlyDevice, - other_identity: Option, - we_started: bool, - ) -> Result, OutgoingContent> { - if let InnerRequest::Ready(s) = self { - Ok(Some(s.to_started_sas(content, other_device, other_identity, we_started)?)) - } else { - Ok(None) - } - } } #[derive(Clone, Debug)] @@ -638,30 +607,21 @@ impl RequestState { store: Arc, other_user_id: &UserId, flow_id: &FlowId, + methods: Option>, ) -> Self { + let our_methods = methods.unwrap_or_else(|| SUPPORTED_METHODS.to_vec()); + Self { account, other_user_id: other_user_id.to_owned(), private_cross_signing_identity: private_identity, - state: Created { our_methods: SUPPORTED_METHODS.to_vec() }, + state: Created { our_methods }, verification_cache: cache, store, flow_id: flow_id.to_owned().into(), } } - fn into_passive(self, content: &ReadyContent) -> RequestState { - RequestState { - account: self.account, - flow_id: self.flow_id, - verification_cache: self.verification_cache, - private_cross_signing_identity: self.private_cross_signing_identity, - store: self.store, - other_user_id: self.other_user_id, - state: Passive { other_device_id: content.from_device().to_owned() }, - } - } - fn into_ready(self, _sender: &UserId, content: &ReadyContent) -> RequestState { // TODO check the flow id, and that the methods match what we suggested. RequestState { @@ -720,6 +680,18 @@ impl RequestState { } } + fn into_passive(self, content: &ReadyContent) -> RequestState { + RequestState { + account: self.account, + flow_id: self.flow_id, + verification_cache: self.verification_cache, + private_cross_signing_identity: self.private_cross_signing_identity, + store: self.store, + other_user_id: self.other_user_id, + state: Passive { other_device_id: content.from_device().to_owned() }, + } + } + fn accept(self, methods: Vec) -> (RequestState, OutgoingContent) { let state = RequestState { account: self.account.clone(), @@ -776,7 +748,7 @@ impl RequestState { &self, content: &StartContent<'a>, other_device: ReadOnlyDevice, - other_identity: Option, + other_identity: Option, we_started: bool, ) -> Result { Sas::from_start_event( @@ -827,7 +799,7 @@ impl RequestState { let verification = if let Some(identity) = &identites.identity_being_verified { match &identity { - UserIdentities::Own(i) => { + ReadOnlyUserIdentities::Own(i) => { if let Some(master_key) = i.master_key().get_first_key() { if identites.can_sign_devices().await { if let Some(device_key) = @@ -870,7 +842,7 @@ impl RequestState { None } } - UserIdentities::Other(i) => { + ReadOnlyUserIdentities::Other(i) => { if let Some(other_master) = i.master_key().get_first_key() { // TODO we can get the master key from the public // identity if we don't have the private one and we @@ -1117,20 +1089,21 @@ mod test { let bob_store: Box = Box::new(MemoryStore::new()); let bob_identity = PrivateCrossSigningIdentity::empty(alice_id()); - let content = VerificationRequest::request(bob.user_id(), bob.device_id(), &alice_id()); + let content = + VerificationRequest::request(bob.user_id(), bob.device_id(), &alice_id(), None); + + let flow_id = FlowId::InRoom(room_id, event_id); let bob_request = VerificationRequest::new( VerificationCache::new(), bob, bob_identity, bob_store.into(), - &room_id, - &event_id, + flow_id.clone(), &alice_id(), + None, ); - let flow_id = FlowId::from((room_id, event_id)); - let alice_request = VerificationRequest::from_request( VerificationCache::new(), alice, @@ -1174,20 +1147,20 @@ mod test { changes.devices.new.push(alice_device.clone()); bob_store.save_changes(changes).await.unwrap(); - let content = VerificationRequest::request(bob.user_id(), bob.device_id(), &alice_id()); + let content = + VerificationRequest::request(bob.user_id(), bob.device_id(), &alice_id(), None); + let flow_id = FlowId::from((room_id, event_id)); let bob_request = VerificationRequest::new( VerificationCache::new(), bob, bob_identity, bob_store.into(), - &room_id, - &event_id, + flow_id.clone(), &alice_id(), + None, ); - let flow_id = FlowId::from((room_id, event_id)); - let alice_request = VerificationRequest::from_request( VerificationCache::new(), alice, @@ -1240,12 +1213,16 @@ mod test { changes.devices.new.push(alice_device.clone()); bob_store.save_changes(changes).await.unwrap(); - let bob_request = VerificationRequest::new_to_device( + let flow_id = FlowId::from("TEST_FLOW_ID".to_owned()); + + let bob_request = VerificationRequest::new( VerificationCache::new(), bob, bob_identity, bob_store.into(), + flow_id, &alice_id(), + None, ); let content = bob_request.request_to_device(); diff --git a/matrix_sdk_crypto/src/verification/sas/helpers.rs b/matrix_sdk_crypto/src/verification/sas/helpers.rs index 868df891..f39869b0 100644 --- a/matrix_sdk_crypto/src/verification/sas/helpers.rs +++ b/matrix_sdk_crypto/src/verification/sas/helpers.rs @@ -31,7 +31,7 @@ use tracing::{trace, warn}; use super::{FlowId, OutgoingContent}; use crate::{ - identities::{ReadOnlyDevice, UserIdentities}, + identities::{ReadOnlyDevice, ReadOnlyUserIdentities}, utilities::encode, verification::event_enums::{MacContent, StartContent}, ReadOnlyAccount, @@ -41,7 +41,7 @@ use crate::{ pub struct SasIds { pub account: ReadOnlyAccount, pub other_device: ReadOnlyDevice, - pub other_identity: Option, + pub other_identity: Option, } /// Calculate the commitment for a accept event from the public key and the @@ -182,7 +182,7 @@ pub fn receive_mac_event( flow_id: &str, sender: &UserId, content: &MacContent, -) -> Result<(Vec, Vec), CancelCode> { +) -> Result<(Vec, Vec), CancelCode> { let mut verified_devices = Vec::new(); let mut verified_identities = Vec::new(); diff --git a/matrix_sdk_crypto/src/verification/sas/inner_sas.rs b/matrix_sdk_crypto/src/verification/sas/inner_sas.rs index fd6fe7a1..04267442 100644 --- a/matrix_sdk_crypto/src/verification/sas/inner_sas.rs +++ b/matrix_sdk_crypto/src/verification/sas/inner_sas.rs @@ -29,7 +29,7 @@ use super::{ FlowId, }; use crate::{ - identities::{ReadOnlyDevice, UserIdentities}, + identities::{ReadOnlyDevice, ReadOnlyUserIdentities}, verification::{ event_enums::{AnyVerificationContent, OutgoingContent, OwnedAcceptContent, StartContent}, Cancelled, Done, @@ -55,7 +55,7 @@ impl InnerSas { pub fn start( account: ReadOnlyAccount, other_device: ReadOnlyDevice, - other_identity: Option, + other_identity: Option, transaction_id: Option, ) -> (InnerSas, OutgoingContent) { let sas = SasState::::new(account, other_device, other_identity, transaction_id); @@ -131,7 +131,7 @@ impl InnerSas { room_id: RoomId, account: ReadOnlyAccount, other_device: ReadOnlyDevice, - other_identity: Option, + other_identity: Option, ) -> (InnerSas, OutgoingContent) { let sas = SasState::::new_in_room( room_id, @@ -149,7 +149,7 @@ impl InnerSas { other_device: ReadOnlyDevice, flow_id: FlowId, content: &StartContent, - other_identity: Option, + other_identity: Option, started_from_request: bool, ) -> Result { match SasState::::from_start_event( @@ -204,7 +204,9 @@ impl InnerSas { InnerSas::WeAccepted(s) => s.cancel(cancelled_by_us, code), InnerSas::KeyReceived(s) => s.cancel(cancelled_by_us, code), InnerSas::MacReceived(s) => s.cancel(cancelled_by_us, code), - _ => return (self, None), + InnerSas::Confirmed(s) => s.cancel(cancelled_by_us, code), + InnerSas::WaitingForDone(s) => s.cancel(cancelled_by_us, code), + InnerSas::Done(_) | InnerSas::Cancelled(_) => return (self, None), }; let content = sas.as_content(); @@ -423,7 +425,7 @@ impl InnerSas { } } - pub fn verified_identities(&self) -> Option> { + pub fn verified_identities(&self) -> Option> { if let InnerSas::Done(s) = self { Some(s.verified_identities()) } else { diff --git a/matrix_sdk_crypto/src/verification/sas/mod.rs b/matrix_sdk_crypto/src/verification/sas/mod.rs index eb4b78af..bdf1f107 100644 --- a/matrix_sdk_crypto/src/verification/sas/mod.rs +++ b/matrix_sdk_crypto/src/verification/sas/mod.rs @@ -41,7 +41,7 @@ use super::{ FlowId, IdentitiesBeingVerified, VerificationResult, }; use crate::{ - identities::{ReadOnlyDevice, UserIdentities}, + identities::{ReadOnlyDevice, ReadOnlyUserIdentities}, olm::PrivateCrossSigningIdentity, requests::{OutgoingVerificationRequest, RoomMessageRequest}, store::{CryptoStore, CryptoStoreError}, @@ -151,7 +151,7 @@ impl Sas { private_identity: PrivateCrossSigningIdentity, other_device: ReadOnlyDevice, store: Arc, - other_identity: Option, + other_identity: Option, we_started: bool, ) -> Sas { let flow_id = inner_sas.verification_flow_id(); @@ -187,7 +187,7 @@ impl Sas { private_identity: PrivateCrossSigningIdentity, other_device: ReadOnlyDevice, store: Arc, - other_identity: Option, + other_identity: Option, transaction_id: Option, we_started: bool, ) -> (Sas, OutgoingContent) { @@ -230,7 +230,7 @@ impl Sas { private_identity: PrivateCrossSigningIdentity, other_device: ReadOnlyDevice, store: Arc, - other_identity: Option, + other_identity: Option, we_started: bool, ) -> (Sas, OutgoingContent) { let (inner, content) = InnerSas::start_in_room( @@ -273,7 +273,7 @@ impl Sas { account: ReadOnlyAccount, private_identity: PrivateCrossSigningIdentity, other_device: ReadOnlyDevice, - other_identity: Option, + other_identity: Option, started_from_request: bool, we_started: bool, ) -> Result { @@ -503,7 +503,7 @@ impl Sas { self.inner.lock().unwrap().verified_devices() } - pub(crate) fn verified_identities(&self) -> Option> { + pub(crate) fn verified_identities(&self) -> Option> { self.inner.lock().unwrap().verified_identities() } diff --git a/matrix_sdk_crypto/src/verification/sas/sas_state.rs b/matrix_sdk_crypto/src/verification/sas/sas_state.rs index af5dad17..f4e77c2a 100644 --- a/matrix_sdk_crypto/src/verification/sas/sas_state.rs +++ b/matrix_sdk_crypto/src/verification/sas/sas_state.rs @@ -52,7 +52,7 @@ use super::{ OutgoingContent, }; use crate::{ - identities::{ReadOnlyDevice, UserIdentities}, + identities::{ReadOnlyDevice, ReadOnlyUserIdentities}, verification::{ event_enums::{ AcceptContent, DoneContent, KeyContent, MacContent, OwnedAcceptContent, @@ -277,7 +277,7 @@ pub struct MacReceived { we_started: bool, their_pubkey: String, verified_devices: Arc<[ReadOnlyDevice]>, - verified_master_keys: Arc<[UserIdentities]>, + verified_master_keys: Arc<[ReadOnlyUserIdentities]>, pub accepted_protocols: Arc, } @@ -287,7 +287,7 @@ pub struct MacReceived { #[derive(Clone, Debug)] pub struct WaitingForDone { verified_devices: Arc<[ReadOnlyDevice]>, - verified_master_keys: Arc<[UserIdentities]>, + verified_master_keys: Arc<[ReadOnlyUserIdentities]>, } impl SasState { @@ -362,7 +362,7 @@ impl SasState { pub fn new( account: ReadOnlyAccount, other_device: ReadOnlyDevice, - other_identity: Option, + other_identity: Option, transaction_id: Option, ) -> SasState { let started_from_request = transaction_id.is_some(); @@ -388,7 +388,7 @@ impl SasState { event_id: EventId, account: ReadOnlyAccount, other_device: ReadOnlyDevice, - other_identity: Option, + other_identity: Option, ) -> SasState { let flow_id = FlowId::InRoom(room_id, event_id); Self::new_helper(flow_id, account, other_device, other_identity, false) @@ -398,7 +398,7 @@ impl SasState { flow_id: FlowId, account: ReadOnlyAccount, other_device: ReadOnlyDevice, - other_identity: Option, + other_identity: Option, started_from_request: bool, ) -> SasState { SasState { @@ -497,7 +497,7 @@ impl SasState { pub fn from_start_event( account: ReadOnlyAccount, other_device: ReadOnlyDevice, - other_identity: Option, + other_identity: Option, flow_id: FlowId, content: &StartContent, started_from_request: bool, @@ -1096,7 +1096,7 @@ impl SasState { } /// Get the list of verified identities. - pub fn verified_identities(&self) -> Arc<[UserIdentities]> { + pub fn verified_identities(&self) -> Arc<[ReadOnlyUserIdentities]> { self.state.verified_master_keys.clone() } }