From b22bb3fa863b387166c655282f2b566f4586765a Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 24 Apr 2025 19:06:33 +0100 Subject: [PATCH] crypto: Move some test helpers out from `sender_data_finder` --- .../src/machine/test_helpers.rs | 77 ++++++++++++++++++- .../olm/group_sessions/sender_data_finder.rs | 62 +++------------ 2 files changed, 85 insertions(+), 54 deletions(-) diff --git a/crates/matrix-sdk-crypto/src/machine/test_helpers.rs b/crates/matrix-sdk-crypto/src/machine/test_helpers.rs index 99da97c54..ad763c443 100644 --- a/crates/matrix-sdk-crypto/src/machine/test_helpers.rs +++ b/crates/matrix-sdk-crypto/src/machine/test_helpers.rs @@ -15,7 +15,7 @@ //! A set of helper functions for creating [`OlmMachine`]s, and pairs of //! interconnected machines. -use std::collections::BTreeMap; +use std::{collections::BTreeMap, ops::Deref, sync::Arc}; use as_variant::as_variant; use matrix_sdk_test::{ruma_response_from_json, test_json}; @@ -32,11 +32,14 @@ use ruma::{ user_id, DeviceId, OwnedOneTimeKeyId, TransactionId, UserId, }; use serde_json::json; +use tokio::sync::Mutex; use crate::{ - store::{Changes, MemoryStore}, - types::{events::ToDeviceEvent, requests::AnyOutgoingRequest}, - CrossSigningBootstrapRequests, DeviceData, OlmMachine, + olm::PrivateCrossSigningIdentity, + store::{Changes, CryptoStoreWrapper, MemoryStore}, + types::{events::ToDeviceEvent, requests::AnyOutgoingRequest, DeviceKeys}, + verification::VerificationMachine, + Account, CrossSigningBootstrapRequests, Device, DeviceData, OlmMachine, OtherUserIdentityData, }; /// These keys need to be periodically uploaded to the server. @@ -276,3 +279,69 @@ pub fn bootstrap_requests_to_keys_query_response( ruma_response_from_json(&kq_response) } + +/// Create a [`VerificationMachine`] which won't do any useful verification. +/// +/// Helper for [`create_signed_device_of_unverified_user`] and +/// [`create_unsigned_device`]. +fn dummy_verification_machine() -> VerificationMachine { + let account = Account::new(user_id!("@TEST_USER:example.com")); + VerificationMachine::new( + account.deref().clone(), + Arc::new(Mutex::new(PrivateCrossSigningIdentity::new(account.user_id().to_owned()))), + Arc::new(CryptoStoreWrapper::new( + account.user_id(), + account.device_id(), + MemoryStore::new(), + )), + ) +} + +/// Wrap the given [`DeviceKeys`] into a [`Device`], with no known owner +/// identity. +pub fn create_unsigned_device(device_keys: DeviceKeys) -> Device { + Device { + inner: DeviceData::try_from(&device_keys).unwrap(), + verification_machine: dummy_verification_machine(), + own_identity: None, + device_owner_identity: None, + } +} + +/// Sign the given [`DeviceKeys`] with a cross-signing identity, and wrap it up +/// as a [`Device`] with that identity. +pub async fn create_signed_device_of_unverified_user( + mut device_keys: DeviceKeys, + device_owner_identity: &PrivateCrossSigningIdentity, +) -> Device { + { + let self_signing = device_owner_identity.self_signing_key.lock().await; + let self_signing = self_signing.as_ref().unwrap(); + self_signing.sign_device(&mut device_keys).unwrap(); + } + + let public_identity = OtherUserIdentityData::from_private(device_owner_identity).await; + + let device = Device { + inner: DeviceData::try_from(&device_keys).unwrap(), + verification_machine: dummy_verification_machine(), + own_identity: None, + device_owner_identity: Some(public_identity.into()), + }; + assert!(device.is_cross_signed_by_owner()); + device +} + +/// Sign a public user identity with our own user-signing key. +pub async fn sign_user_identity_data( + signer_private_identity: &PrivateCrossSigningIdentity, + other_user_identity: &mut OtherUserIdentityData, +) { + let user_signing = signer_private_identity.user_signing_key.lock().await; + + let user_signing = user_signing.as_ref().unwrap(); + let master = user_signing.sign_user(&*other_user_identity).unwrap(); + other_user_identity.master_key = Arc::new(master.try_into().unwrap()); + + user_signing.public_key().verify_master_key(other_user_identity.master_key()).unwrap(); +} diff --git a/crates/matrix-sdk-crypto/src/olm/group_sessions/sender_data_finder.rs b/crates/matrix-sdk-crypto/src/olm/group_sessions/sender_data_finder.rs index 142195203..672de4070 100644 --- a/crates/matrix-sdk-crypto/src/olm/group_sessions/sender_data_finder.rs +++ b/crates/matrix-sdk-crypto/src/olm/group_sessions/sender_data_finder.rs @@ -381,6 +381,10 @@ mod tests { use super::SenderDataFinder; use crate::{ error::MismatchedIdentityKeysError, + machine::test_helpers::{ + create_signed_device_of_unverified_user, create_unsigned_device, + sign_user_identity_data, + }, olm::{ group_sessions::sender_data_finder::SessionDeviceKeysCheckError, InboundGroupSession, KnownSenderData, PrivateCrossSigningIdentity, SenderData, @@ -394,7 +398,7 @@ mod tests { EventEncryptionAlgorithm, }, verification::VerificationMachine, - Account, Device, DeviceData, OtherUserIdentityData, OwnUserIdentityData, UserIdentityData, + Account, Device, OtherUserIdentityData, OwnUserIdentityData, UserIdentityData, }; impl<'a> SenderDataFinder<'a> { @@ -828,9 +832,13 @@ mod tests { let sender = TestUser::other(&me, &options).await; let sender_device = if options.device_is_signed { - create_signed_device(&sender.account, &*sender.private_identity.lock().await).await + create_signed_device_of_unverified_user( + sender.account.device_keys(), + &*sender.private_identity.lock().await, + ) + .await } else { - create_unsigned_device(&sender.account) + create_unsigned_device(sender.account.device_keys()) }; let store = create_store(&me); @@ -1008,14 +1016,7 @@ mod tests { ) { if let Some(signer) = signer { let signer_private_identity = signer.private_identity.lock().await; - - let user_signing = signer_private_identity.user_signing_key.lock().await; - - let user_signing = user_signing.as_ref().unwrap(); - let master = user_signing.sign_user(&*other_user_identity).unwrap(); - other_user_identity.master_key = Arc::new(master.try_into().unwrap()); - - user_signing.public_key().verify_master_key(other_user_identity.master_key()).unwrap(); + sign_user_identity_data(signer_private_identity.deref(), other_user_identity).await; } else { panic!("You must provide a `signer` if you want an Other to be verified!"); } @@ -1025,45 +1026,6 @@ mod tests { PrivateCrossSigningIdentity::with_account(account).await.0 } - async fn create_signed_device( - account: &Account, - private_identity: &PrivateCrossSigningIdentity, - ) -> Device { - let mut read_only_device = DeviceData::from_account(account); - - let self_signing = private_identity.self_signing_key.lock().await; - let self_signing = self_signing.as_ref().unwrap(); - - let mut device_keys = read_only_device.as_device_keys().to_owned(); - self_signing.sign_device(&mut device_keys).unwrap(); - read_only_device.update_device(&device_keys).unwrap(); - - wrap_device(account, read_only_device) - } - - fn create_unsigned_device(account: &Account) -> Device { - wrap_device(account, DeviceData::from_account(account)) - } - - fn wrap_device(account: &Account, read_only_device: DeviceData) -> Device { - Device { - inner: read_only_device, - verification_machine: VerificationMachine::new( - account.deref().clone(), - Arc::new(Mutex::new(PrivateCrossSigningIdentity::new( - account.user_id().to_owned(), - ))), - Arc::new(CryptoStoreWrapper::new( - account.user_id(), - account.device_id(), - MemoryStore::new(), - )), - ), - own_identity: None, - device_owner_identity: None, - } - } - fn create_room_key_event( sender: &UserId, receiver: &UserId,