crypto: Collect common verification stuff into a VerificationStore

master
Damir Jelić 2021-08-04 11:07:28 +02:00
parent e401c87246
commit 7d851a10b5
6 changed files with 145 additions and 128 deletions

View File

@ -232,7 +232,7 @@ impl Device {
&self, &self,
content: AnyToDeviceEventContent, content: AnyToDeviceEventContent,
) -> OlmResult<(Session, EncryptedToDeviceEventContent)> { ) -> OlmResult<(Session, EncryptedToDeviceEventContent)> {
self.inner.encrypt(&*self.verification_machine.store, content).await self.inner.encrypt(self.verification_machine.store.inner(), content).await
} }
/// Encrypt the given inbound group session as a forwarded room key for this /// Encrypt the given inbound group session as a forwarded room key for this

View File

@ -34,7 +34,7 @@ use super::{
event_enums::{AnyEvent, AnyVerificationContent, OutgoingContent}, event_enums::{AnyEvent, AnyVerificationContent, OutgoingContent},
requests::VerificationRequest, requests::VerificationRequest,
sas::Sas, sas::Sas,
FlowId, Verification, VerificationResult, FlowId, Verification, VerificationResult, VerificationStore,
}; };
use crate::{ use crate::{
olm::PrivateCrossSigningIdentity, olm::PrivateCrossSigningIdentity,
@ -46,9 +46,8 @@ use crate::{
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct VerificationMachine { pub struct VerificationMachine {
account: ReadOnlyAccount,
private_identity: Arc<Mutex<PrivateCrossSigningIdentity>>, private_identity: Arc<Mutex<PrivateCrossSigningIdentity>>,
pub(crate) store: Arc<dyn CryptoStore>, pub(crate) store: VerificationStore,
verifications: VerificationCache, verifications: VerificationCache,
requests: Arc<DashMap<UserId, DashMap<String, VerificationRequest>>>, requests: Arc<DashMap<UserId, DashMap<String, VerificationRequest>>>,
} }
@ -60,20 +59,19 @@ impl VerificationMachine {
store: Arc<dyn CryptoStore>, store: Arc<dyn CryptoStore>,
) -> Self { ) -> Self {
Self { Self {
account,
private_identity: identity, private_identity: identity,
store, store: VerificationStore { account, inner: store },
verifications: VerificationCache::new(), verifications: VerificationCache::new(),
requests: DashMap::new().into(), requests: DashMap::new().into(),
} }
} }
pub(crate) fn own_user_id(&self) -> &UserId { pub(crate) fn own_user_id(&self) -> &UserId {
self.account.user_id() self.store.account.user_id()
} }
pub(crate) fn own_device_id(&self) -> &DeviceId { pub(crate) fn own_device_id(&self) -> &DeviceId {
self.account.device_id() self.store.account.device_id()
} }
pub(crate) async fn request_to_device_verification( pub(crate) async fn request_to_device_verification(
@ -86,7 +84,6 @@ impl VerificationMachine {
let verification = VerificationRequest::new( let verification = VerificationRequest::new(
self.verifications.clone(), self.verifications.clone(),
self.account.clone(),
self.private_identity.lock().await.clone(), self.private_identity.lock().await.clone(),
self.store.clone(), self.store.clone(),
flow_id, flow_id,
@ -113,7 +110,6 @@ impl VerificationMachine {
let request = VerificationRequest::new( let request = VerificationRequest::new(
self.verifications.clone(), self.verifications.clone(),
self.account.clone(),
self.private_identity.lock().await.clone(), self.private_identity.lock().await.clone(),
self.store.clone(), self.store.clone(),
flow_id, flow_id,
@ -135,7 +131,6 @@ impl VerificationMachine {
let private_identity = self.private_identity.lock().await.clone(); let private_identity = self.private_identity.lock().await.clone();
let (sas, content) = Sas::start( let (sas, content) = Sas::start(
self.account.clone(),
private_identity, private_identity,
device.clone(), device.clone(),
self.store.clone(), self.store.clone(),
@ -260,7 +255,7 @@ impl VerificationMachine {
content, content,
))) = request.clone().try_into() ))) = request.clone().try_into()
{ {
let event = ToDeviceEvent { content, sender: self.account.user_id().to_owned() }; let event = ToDeviceEvent { content, sender: self.own_user_id().to_owned() };
events.push(AnyToDeviceEvent::KeyVerificationCancel(event).into()); events.push(AnyToDeviceEvent::KeyVerificationCancel(event).into());
} }
@ -324,8 +319,8 @@ impl VerificationMachine {
}; };
let event_sent_from_us = |event: &AnyEvent<'_>, from_device: &DeviceId| { let event_sent_from_us = |event: &AnyEvent<'_>, from_device: &DeviceId| {
if event.sender() == self.account.user_id() { if event.sender() == self.store.account.user_id() {
from_device == self.account.device_id() || event.is_room_event() from_device == self.store.account.device_id() || event.is_room_event()
} else { } else {
false false
} }
@ -345,7 +340,6 @@ impl VerificationMachine {
if !event_sent_from_us(&event, r.from_device()) { if !event_sent_from_us(&event, r.from_device()) {
let request = VerificationRequest::from_request( let request = VerificationRequest::from_request(
self.verifications.clone(), self.verifications.clone(),
self.account.clone(),
self.private_identity.lock().await.clone(), self.private_identity.lock().await.clone(),
self.store.clone(), self.store.clone(),
event.sender(), event.sender(),
@ -423,7 +417,6 @@ impl VerificationMachine {
flow_id, flow_id,
c, c,
self.store.clone(), self.store.clone(),
self.account.clone(),
private_identity, private_identity,
device, device,
identity, identity,
@ -519,10 +512,11 @@ mod test {
use super::{Sas, VerificationMachine}; use super::{Sas, VerificationMachine};
use crate::{ use crate::{
olm::PrivateCrossSigningIdentity, olm::PrivateCrossSigningIdentity,
store::{CryptoStore, MemoryStore}, store::MemoryStore,
verification::{ verification::{
event_enums::{AcceptContent, KeyContent, MacContent, OutgoingContent}, event_enums::{AcceptContent, KeyContent, MacContent, OutgoingContent},
test::wrap_any_to_device_content, test::wrap_any_to_device_content,
VerificationStore,
}, },
ReadOnlyAccount, ReadOnlyDevice, ReadOnlyAccount, ReadOnlyDevice,
}; };
@ -555,11 +549,11 @@ mod test {
store.save_devices(vec![bob_device]).await; store.save_devices(vec![bob_device]).await;
bob_store.save_devices(vec![alice_device.clone()]).await; bob_store.save_devices(vec![alice_device.clone()]).await;
let bob_store: Arc<dyn CryptoStore> = Arc::new(bob_store); let bob_store = VerificationStore { account: bob, inner: Arc::new(bob_store) };
let identity = Arc::new(Mutex::new(PrivateCrossSigningIdentity::empty(alice_id()))); let identity = Arc::new(Mutex::new(PrivateCrossSigningIdentity::empty(alice_id())));
let machine = VerificationMachine::new(alice, identity, Arc::new(store)); let machine = VerificationMachine::new(alice, identity, Arc::new(store));
let (bob_sas, start_content) = Sas::start( let (bob_sas, start_content) = Sas::start(
bob,
PrivateCrossSigningIdentity::empty(bob_id()), PrivateCrossSigningIdentity::empty(bob_id()),
alice_device, alice_device,
bob_store, bob_store,

View File

@ -19,10 +19,11 @@ mod qrcode;
mod requests; mod requests;
mod sas; mod sas;
use std::sync::Arc; use std::{collections::HashMap, sync::Arc};
use event_enums::OutgoingContent; use event_enums::OutgoingContent;
pub use machine::VerificationMachine; pub use machine::VerificationMachine;
use matrix_sdk_common::locks::Mutex;
pub use qrcode::QrVerification; pub use qrcode::QrVerification;
pub use requests::VerificationRequest; pub use requests::VerificationRequest;
use ruma::{ use ruma::{
@ -35,7 +36,7 @@ use ruma::{
}, },
AnyMessageEventContent, AnyToDeviceEventContent, AnyMessageEventContent, AnyToDeviceEventContent,
}, },
DeviceId, EventId, RoomId, UserId, DeviceId, DeviceIdBox, EventId, RoomId, UserId,
}; };
pub use sas::{AcceptSettings, Sas}; pub use sas::{AcceptSettings, Sas};
use tracing::{error, info, trace, warn}; use tracing::{error, info, trace, warn};
@ -43,11 +44,58 @@ use tracing::{error, info, trace, warn};
use crate::{ use crate::{
error::SignatureError, error::SignatureError,
gossiping::{GossipMachine, GossipRequest}, gossiping::{GossipMachine, GossipRequest},
olm::PrivateCrossSigningIdentity, olm::{PrivateCrossSigningIdentity, ReadOnlyAccount, Session},
store::{Changes, CryptoStore}, store::{Changes, CryptoStore},
CryptoStoreError, LocalTrust, ReadOnlyDevice, ReadOnlyUserIdentities, CryptoStoreError, LocalTrust, ReadOnlyDevice, ReadOnlyUserIdentities,
}; };
#[derive(Clone, Debug)]
pub(crate) struct VerificationStore {
pub account: ReadOnlyAccount,
inner: Arc<dyn CryptoStore>,
}
impl VerificationStore {
pub async fn get_device(
&self,
user_id: &UserId,
device_id: &DeviceId,
) -> Result<Option<ReadOnlyDevice>, CryptoStoreError> {
Ok(self.inner.get_device(user_id, device_id).await?.filter(|d| {
!(d.user_id() == self.account.user_id() && d.device_id() == self.account.device_id())
}))
}
pub async fn get_user_identity(
&self,
user_id: &UserId,
) -> Result<Option<ReadOnlyUserIdentities>, CryptoStoreError> {
self.inner.get_user_identity(user_id).await
}
pub async fn save_changes(&self, changes: Changes) -> Result<(), CryptoStoreError> {
self.inner.save_changes(changes).await
}
pub async fn get_user_devices(
&self,
user_id: &UserId,
) -> Result<HashMap<DeviceIdBox, ReadOnlyDevice>, CryptoStoreError> {
self.inner.get_user_devices(user_id).await
}
pub async fn get_sessions(
&self,
sender_key: &str,
) -> Result<Option<Arc<Mutex<Vec<Session>>>>, CryptoStoreError> {
self.inner.get_sessions(sender_key).await
}
pub fn inner(&self) -> &dyn CryptoStore {
&*self.inner
}
}
/// An enum over the different verification types the SDK supports. /// An enum over the different verification types the SDK supports.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Verification { pub enum Verification {
@ -308,7 +356,7 @@ pub enum VerificationResult {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct IdentitiesBeingVerified { pub struct IdentitiesBeingVerified {
private_identity: PrivateCrossSigningIdentity, private_identity: PrivateCrossSigningIdentity,
store: Arc<dyn CryptoStore>, store: VerificationStore,
device_being_verified: ReadOnlyDevice, device_being_verified: ReadOnlyDevice,
identity_being_verified: Option<ReadOnlyUserIdentities>, identity_being_verified: Option<ReadOnlyUserIdentities>,
} }

View File

@ -42,12 +42,11 @@ use super::{
event_enums::{CancelContent, DoneContent, OutgoingContent, OwnedStartContent, StartContent}, event_enums::{CancelContent, DoneContent, OutgoingContent, OwnedStartContent, StartContent},
requests::RequestHandle, requests::RequestHandle,
CancelInfo, Cancelled, Done, FlowId, IdentitiesBeingVerified, VerificationResult, CancelInfo, Cancelled, Done, FlowId, IdentitiesBeingVerified, VerificationResult,
VerificationStore,
}; };
use crate::{ use crate::{
olm::{PrivateCrossSigningIdentity, ReadOnlyAccount}, olm::PrivateCrossSigningIdentity, CryptoStoreError, OutgoingVerificationRequest,
store::CryptoStore, ReadOnlyDevice, ReadOnlyUserIdentities, RoomMessageRequest, ToDeviceRequest,
CryptoStoreError, OutgoingVerificationRequest, ReadOnlyDevice, ReadOnlyUserIdentities,
RoomMessageRequest, ToDeviceRequest,
}; };
const SECRET_SIZE: usize = 16; const SECRET_SIZE: usize = 16;
@ -81,7 +80,7 @@ pub enum ScanError {
#[derive(Clone)] #[derive(Clone)]
pub struct QrVerification { pub struct QrVerification {
flow_id: FlowId, flow_id: FlowId,
store: Arc<dyn CryptoStore>, store: VerificationStore,
inner: Arc<QrVerificationData>, inner: Arc<QrVerificationData>,
state: Arc<Mutex<InnerState>>, state: Arc<Mutex<InnerState>>,
identities: IdentitiesBeingVerified, identities: IdentitiesBeingVerified,
@ -430,7 +429,7 @@ impl QrVerification {
} }
pub(crate) fn new_self( pub(crate) fn new_self(
store: Arc<dyn CryptoStore>, store: VerificationStore,
flow_id: FlowId, flow_id: FlowId,
own_master_key: String, own_master_key: String,
other_device_key: String, other_device_key: String,
@ -452,8 +451,7 @@ impl QrVerification {
} }
pub(crate) fn new_self_no_master( pub(crate) fn new_self_no_master(
account: ReadOnlyAccount, store: VerificationStore,
store: Arc<dyn CryptoStore>,
flow_id: FlowId, flow_id: FlowId,
own_master_key: String, own_master_key: String,
identities: IdentitiesBeingVerified, identities: IdentitiesBeingVerified,
@ -464,7 +462,7 @@ impl QrVerification {
let inner: QrVerificationData = SelfVerificationNoMasterKey::new( let inner: QrVerificationData = SelfVerificationNoMasterKey::new(
flow_id.as_str().to_owned(), flow_id.as_str().to_owned(),
account.identity_keys().ed25519().to_string(), store.account.identity_keys().ed25519().to_string(),
own_master_key, own_master_key,
secret, secret,
) )
@ -474,7 +472,7 @@ impl QrVerification {
} }
pub(crate) fn new_cross( pub(crate) fn new_cross(
store: Arc<dyn CryptoStore>, store: VerificationStore,
flow_id: FlowId, flow_id: FlowId,
own_master_key: String, own_master_key: String,
other_master_key: String, other_master_key: String,
@ -498,8 +496,7 @@ impl QrVerification {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub(crate) async fn from_scan( pub(crate) async fn from_scan(
store: Arc<dyn CryptoStore>, store: VerificationStore,
own_account: ReadOnlyAccount,
private_identity: PrivateCrossSigningIdentity, private_identity: PrivateCrossSigningIdentity,
other_user_id: UserId, other_user_id: UserId,
other_device_id: DeviceIdBox, other_device_id: DeviceIdBox,
@ -516,8 +513,8 @@ impl QrVerification {
} }
let own_identity = let own_identity =
store.get_user_identity(own_account.user_id()).await?.ok_or_else(|| { store.get_user_identity(store.account.user_id()).await?.ok_or_else(|| {
ScanError::MissingCrossSigningIdentity(own_account.user_id().to_owned()) ScanError::MissingCrossSigningIdentity(store.account.user_id().to_owned())
})?; })?;
let other_identity = store let other_identity = store
.get_user_identity(&other_user_id) .get_user_identity(&other_user_id)
@ -543,33 +540,23 @@ impl QrVerification {
} }
}; };
let identities = match qr_code { let (device_being_verified, identity_being_verified) = match qr_code {
QrVerificationData::Verification(_) => { QrVerificationData::Verification(_) => {
check_master_key(qr_code.first_key(), &other_identity)?; check_master_key(qr_code.first_key(), &other_identity)?;
check_master_key(qr_code.second_key(), &own_identity)?; check_master_key(qr_code.second_key(), &own_identity)?;
IdentitiesBeingVerified { (other_device, Some(other_identity))
private_identity,
store: store.clone(),
device_being_verified: other_device,
identity_being_verified: Some(other_identity),
}
} }
QrVerificationData::SelfVerification(_) => { QrVerificationData::SelfVerification(_) => {
check_master_key(qr_code.first_key(), &other_identity)?; check_master_key(qr_code.first_key(), &other_identity)?;
if qr_code.second_key() != own_account.identity_keys().ed25519() { if qr_code.second_key() != store.account.identity_keys().ed25519() {
return Err(ScanError::KeyMismatch { return Err(ScanError::KeyMismatch {
expected: own_account.identity_keys().ed25519().to_owned(), expected: store.account.identity_keys().ed25519().to_owned(),
found: qr_code.second_key().to_owned(), found: qr_code.second_key().to_owned(),
}); });
} }
IdentitiesBeingVerified { (other_device, Some(other_identity))
private_identity,
store: store.clone(),
device_being_verified: other_device,
identity_being_verified: Some(other_identity),
}
} }
QrVerificationData::SelfVerificationNoMasterKey(_) => { QrVerificationData::SelfVerificationNoMasterKey(_) => {
let device_key = let device_key =
@ -583,23 +570,26 @@ impl QrVerification {
}); });
} }
check_master_key(qr_code.second_key(), &other_identity)?; check_master_key(qr_code.second_key(), &other_identity)?;
IdentitiesBeingVerified { (other_device, Some(other_identity))
private_identity,
store: store.clone(),
device_being_verified: other_device,
identity_being_verified: None,
}
} }
}; };
let identities = IdentitiesBeingVerified {
private_identity,
store: store.clone(),
device_being_verified,
identity_being_verified,
};
let secret = qr_code.secret().to_owned(); let secret = qr_code.secret().to_owned();
let own_device_id = store.account.device_id().to_owned();
Ok(Self { Ok(Self {
store, store,
flow_id, flow_id,
inner: qr_code.into(), inner: qr_code.into(),
state: Mutex::new(InnerState::Reciprocated(QrState { state: Mutex::new(InnerState::Reciprocated(QrState {
state: Reciprocated { secret, own_device_id: own_account.device_id().to_owned() }, state: Reciprocated { secret, own_device_id },
})) }))
.into(), .into(),
identities, identities,
@ -609,7 +599,7 @@ impl QrVerification {
} }
fn new_helper( fn new_helper(
store: Arc<dyn CryptoStore>, store: VerificationStore,
flow_id: FlowId, flow_id: FlowId,
inner: QrVerificationData, inner: QrVerificationData,
identities: IdentitiesBeingVerified, identities: IdentitiesBeingVerified,
@ -808,7 +798,7 @@ mod test {
store::{Changes, CryptoStore, MemoryStore}, store::{Changes, CryptoStore, MemoryStore},
verification::{ verification::{
event_enums::{DoneContent, OutgoingContent, StartContent}, event_enums::{DoneContent, OutgoingContent, StartContent},
FlowId, IdentitiesBeingVerified, FlowId, IdentitiesBeingVerified, VerificationStore,
}, },
QrVerification, ReadOnlyDevice, QrVerification, ReadOnlyDevice,
}; };
@ -828,8 +818,10 @@ mod test {
#[async_test] #[async_test]
async fn test_verification_creation() { async fn test_verification_creation() {
let store = memory_store(); let store = memory_store();
let account = ReadOnlyAccount::new(&user_id(), &device_id()); let account = ReadOnlyAccount::new(&user_id(), &device_id());
let store = VerificationStore { account: account.clone(), inner: store };
let private_identity = PrivateCrossSigningIdentity::new(user_id()).await; let private_identity = PrivateCrossSigningIdentity::new(user_id()).await;
let flow_id = FlowId::ToDevice("test_transaction".to_owned()); let flow_id = FlowId::ToDevice("test_transaction".to_owned());
@ -847,7 +839,6 @@ mod test {
}; };
let verification = QrVerification::new_self_no_master( let verification = QrVerification::new_self_no_master(
account,
store.clone(), store.clone(),
flow_id.clone(), flow_id.clone(),
master_key.clone(), master_key.clone(),
@ -898,6 +889,8 @@ mod test {
let alice_account = ReadOnlyAccount::new(&user_id(), &device_id()); let alice_account = ReadOnlyAccount::new(&user_id(), &device_id());
let store = memory_store(); let store = memory_store();
let store = VerificationStore { account: alice_account.clone(), inner: store };
let bob_account = ReadOnlyAccount::new(alice_account.user_id(), "BOBDEVICE".into()); let bob_account = ReadOnlyAccount::new(alice_account.user_id(), "BOBDEVICE".into());
let private_identity = PrivateCrossSigningIdentity::new(user_id()).await; let private_identity = PrivateCrossSigningIdentity::new(user_id()).await;
@ -924,7 +917,6 @@ mod test {
}; };
let alice_verification = QrVerification::new_self_no_master( let alice_verification = QrVerification::new_self_no_master(
alice_account.clone(),
store, store,
flow_id.clone(), flow_id.clone(),
master_key.clone(), master_key.clone(),
@ -935,6 +927,8 @@ mod test {
let bob_store = memory_store(); let bob_store = memory_store();
let bob_store = VerificationStore { account: bob_account.clone(), inner: bob_store };
let mut changes = Changes::default(); let mut changes = Changes::default();
changes.identities.new.push(identity.into()); changes.identities.new.push(identity.into());
changes.devices.new.push(alice_device.clone()); changes.devices.new.push(alice_device.clone());
@ -945,7 +939,6 @@ mod test {
let bob_verification = QrVerification::from_scan( let bob_verification = QrVerification::from_scan(
bob_store, bob_store,
bob_account,
private_identity, private_identity,
alice_account.user_id().to_owned(), alice_account.user_id().to_owned(),
alice_account.device_id().to_owned(), alice_account.device_id().to_owned(),

View File

@ -42,11 +42,10 @@ use super::{
CancelContent, DoneContent, OutgoingContent, ReadyContent, RequestContent, StartContent, CancelContent, DoneContent, OutgoingContent, ReadyContent, RequestContent, StartContent,
}, },
qrcode::{QrVerification, ScanError}, qrcode::{QrVerification, ScanError},
CancelInfo, Cancelled, FlowId, IdentitiesBeingVerified, CancelInfo, Cancelled, FlowId, IdentitiesBeingVerified, VerificationStore,
}; };
use crate::{ use crate::{
olm::{PrivateCrossSigningIdentity, ReadOnlyAccount}, olm::{PrivateCrossSigningIdentity, ReadOnlyAccount},
store::CryptoStore,
CryptoStoreError, OutgoingVerificationRequest, ReadOnlyDevice, ReadOnlyUserIdentities, CryptoStoreError, OutgoingVerificationRequest, ReadOnlyDevice, ReadOnlyUserIdentities,
RoomMessageRequest, Sas, ToDeviceRequest, RoomMessageRequest, Sas, ToDeviceRequest,
}; };
@ -107,16 +106,15 @@ impl VerificationRequest {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub(crate) fn new( pub(crate) fn new(
cache: VerificationCache, cache: VerificationCache,
account: ReadOnlyAccount,
private_cross_signing_identity: PrivateCrossSigningIdentity, private_cross_signing_identity: PrivateCrossSigningIdentity,
store: Arc<dyn CryptoStore>, store: VerificationStore,
flow_id: FlowId, flow_id: FlowId,
other_user: &UserId, other_user: &UserId,
recipient_devices: Vec<DeviceIdBox>, recipient_devices: Vec<DeviceIdBox>,
methods: Option<Vec<VerificationMethod>>, methods: Option<Vec<VerificationMethod>>,
) -> Self { ) -> Self {
let account = store.account.clone();
let inner = Mutex::new(InnerRequest::Created(RequestState::new( let inner = Mutex::new(InnerRequest::Created(RequestState::new(
account.clone(),
private_cross_signing_identity, private_cross_signing_identity,
cache.clone(), cache.clone(),
store, store,
@ -327,7 +325,6 @@ impl VerificationRequest {
if let InnerRequest::Ready(r) = &*state { if let InnerRequest::Ready(r) = &*state {
let qr_verification = QrVerification::from_scan( let qr_verification = QrVerification::from_scan(
r.store.clone(), r.store.clone(),
r.account.clone(),
r.private_cross_signing_identity.clone(), r.private_cross_signing_identity.clone(),
r.other_user_id.clone(), r.other_user_id.clone(),
r.state.other_device_id.clone(), r.state.other_device_id.clone(),
@ -348,17 +345,17 @@ impl VerificationRequest {
pub(crate) fn from_request( pub(crate) fn from_request(
cache: VerificationCache, cache: VerificationCache,
account: ReadOnlyAccount,
private_cross_signing_identity: PrivateCrossSigningIdentity, private_cross_signing_identity: PrivateCrossSigningIdentity,
store: Arc<dyn CryptoStore>, store: VerificationStore,
sender: &UserId, sender: &UserId,
flow_id: FlowId, flow_id: FlowId,
content: &RequestContent, content: &RequestContent,
) -> Self { ) -> Self {
let account = store.account.clone();
Self { Self {
verification_cache: cache.clone(), verification_cache: cache.clone(),
inner: Arc::new(Mutex::new(InnerRequest::Requested(RequestState::from_request_event( inner: Arc::new(Mutex::new(InnerRequest::Requested(RequestState::from_request_event(
account.clone(),
private_cross_signing_identity, private_cross_signing_identity,
cache, cache,
store, store,
@ -621,7 +618,6 @@ impl VerificationRequest {
.clone() .clone()
.start_sas( .start_sas(
s.store.clone(), s.store.clone(),
s.account.clone(),
s.private_cross_signing_identity.clone(), s.private_cross_signing_identity.clone(),
self.we_started, self.we_started,
self.inner.clone().into(), self.inner.clone().into(),
@ -742,10 +738,9 @@ impl InnerRequest {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct RequestState<S: Clone> { struct RequestState<S: Clone> {
account: ReadOnlyAccount,
private_cross_signing_identity: PrivateCrossSigningIdentity, private_cross_signing_identity: PrivateCrossSigningIdentity,
verification_cache: VerificationCache, verification_cache: VerificationCache,
store: Arc<dyn CryptoStore>, store: VerificationStore,
flow_id: Arc<FlowId>, flow_id: Arc<FlowId>,
/// The id of the user which is participating in this verification request. /// The id of the user which is participating in this verification request.
@ -758,7 +753,6 @@ struct RequestState<S: Clone> {
impl<S: Clone> RequestState<S> { impl<S: Clone> RequestState<S> {
fn into_done(self, _: &DoneContent) -> RequestState<Done> { fn into_done(self, _: &DoneContent) -> RequestState<Done> {
RequestState::<Done> { RequestState::<Done> {
account: self.account,
private_cross_signing_identity: self.private_cross_signing_identity, private_cross_signing_identity: self.private_cross_signing_identity,
verification_cache: self.verification_cache, verification_cache: self.verification_cache,
store: self.store, store: self.store,
@ -774,7 +768,6 @@ impl<S: Clone> RequestState<S> {
cancel_code: &CancelCode, cancel_code: &CancelCode,
) -> RequestState<Cancelled> { ) -> RequestState<Cancelled> {
RequestState::<Cancelled> { RequestState::<Cancelled> {
account: self.account,
private_cross_signing_identity: self.private_cross_signing_identity, private_cross_signing_identity: self.private_cross_signing_identity,
verification_cache: self.verification_cache, verification_cache: self.verification_cache,
store: self.store, store: self.store,
@ -787,10 +780,9 @@ impl<S: Clone> RequestState<S> {
impl RequestState<Created> { impl RequestState<Created> {
fn new( fn new(
account: ReadOnlyAccount,
private_identity: PrivateCrossSigningIdentity, private_identity: PrivateCrossSigningIdentity,
cache: VerificationCache, cache: VerificationCache,
store: Arc<dyn CryptoStore>, store: VerificationStore,
other_user_id: &UserId, other_user_id: &UserId,
flow_id: &FlowId, flow_id: &FlowId,
methods: Option<Vec<VerificationMethod>>, methods: Option<Vec<VerificationMethod>>,
@ -798,7 +790,6 @@ impl RequestState<Created> {
let our_methods = methods.unwrap_or_else(|| SUPPORTED_METHODS.to_vec()); let our_methods = methods.unwrap_or_else(|| SUPPORTED_METHODS.to_vec());
Self { Self {
account,
other_user_id: other_user_id.to_owned(), other_user_id: other_user_id.to_owned(),
private_cross_signing_identity: private_identity, private_cross_signing_identity: private_identity,
state: Created { our_methods }, state: Created { our_methods },
@ -811,7 +802,6 @@ impl RequestState<Created> {
fn into_ready(self, _sender: &UserId, content: &ReadyContent) -> RequestState<Ready> { fn into_ready(self, _sender: &UserId, content: &ReadyContent) -> RequestState<Ready> {
// TODO check the flow id, and that the methods match what we suggested. // TODO check the flow id, and that the methods match what we suggested.
RequestState { RequestState {
account: self.account,
flow_id: self.flow_id, flow_id: self.flow_id,
verification_cache: self.verification_cache, verification_cache: self.verification_cache,
private_cross_signing_identity: self.private_cross_signing_identity, private_cross_signing_identity: self.private_cross_signing_identity,
@ -843,17 +833,15 @@ struct Requested {
impl RequestState<Requested> { impl RequestState<Requested> {
fn from_request_event( fn from_request_event(
account: ReadOnlyAccount,
private_identity: PrivateCrossSigningIdentity, private_identity: PrivateCrossSigningIdentity,
cache: VerificationCache, cache: VerificationCache,
store: Arc<dyn CryptoStore>, store: VerificationStore,
sender: &UserId, sender: &UserId,
flow_id: &FlowId, flow_id: &FlowId,
content: &RequestContent, content: &RequestContent,
) -> RequestState<Requested> { ) -> RequestState<Requested> {
// TODO only create this if we support the methods // TODO only create this if we support the methods
RequestState { RequestState {
account,
private_cross_signing_identity: private_identity, private_cross_signing_identity: private_identity,
store, store,
verification_cache: cache, verification_cache: cache,
@ -868,7 +856,6 @@ impl RequestState<Requested> {
fn into_passive(self, content: &ReadyContent) -> RequestState<Passive> { fn into_passive(self, content: &ReadyContent) -> RequestState<Passive> {
RequestState { RequestState {
account: self.account,
flow_id: self.flow_id, flow_id: self.flow_id,
verification_cache: self.verification_cache, verification_cache: self.verification_cache,
private_cross_signing_identity: self.private_cross_signing_identity, private_cross_signing_identity: self.private_cross_signing_identity,
@ -880,7 +867,6 @@ impl RequestState<Requested> {
fn accept(self, methods: Vec<VerificationMethod>) -> (RequestState<Ready>, OutgoingContent) { fn accept(self, methods: Vec<VerificationMethod>) -> (RequestState<Ready>, OutgoingContent) {
let state = RequestState { let state = RequestState {
account: self.account.clone(),
store: self.store, store: self.store,
verification_cache: self.verification_cache, verification_cache: self.verification_cache,
private_cross_signing_identity: self.private_cross_signing_identity, private_cross_signing_identity: self.private_cross_signing_identity,
@ -896,7 +882,7 @@ impl RequestState<Requested> {
let content = match self.flow_id.as_ref() { let content = match self.flow_id.as_ref() {
FlowId::ToDevice(i) => { FlowId::ToDevice(i) => {
AnyToDeviceEventContent::KeyVerificationReady(ReadyToDeviceEventContent::new( AnyToDeviceEventContent::KeyVerificationReady(ReadyToDeviceEventContent::new(
self.account.device_id().to_owned(), state.store.account.device_id().to_owned(),
methods, methods,
i.to_owned(), i.to_owned(),
)) ))
@ -905,7 +891,7 @@ impl RequestState<Requested> {
FlowId::InRoom(r, e) => ( FlowId::InRoom(r, e) => (
r.to_owned(), r.to_owned(),
AnyMessageEventContent::KeyVerificationReady(ReadyEventContent::new( AnyMessageEventContent::KeyVerificationReady(ReadyEventContent::new(
self.account.device_id().to_owned(), state.store.account.device_id().to_owned(),
methods, methods,
Relation::new(e.to_owned()), Relation::new(e.to_owned()),
)), )),
@ -942,7 +928,6 @@ impl RequestState<Ready> {
(&*self.flow_id).to_owned(), (&*self.flow_id).to_owned(),
content, content,
self.store.clone(), self.store.clone(),
self.account.clone(),
self.private_cross_signing_identity.clone(), self.private_cross_signing_identity.clone(),
other_device, other_device,
other_identity, other_identity,
@ -1013,7 +998,6 @@ impl RequestState<Ready> {
} }
} else { } else {
Some(QrVerification::new_self_no_master( Some(QrVerification::new_self_no_master(
self.account.clone(),
self.store.clone(), self.store.clone(),
self.flow_id.as_ref().to_owned(), self.flow_id.as_ref().to_owned(),
master_key.to_owned(), master_key.to_owned(),
@ -1174,8 +1158,7 @@ impl RequestState<Ready> {
async fn start_sas( async fn start_sas(
self, self,
store: Arc<dyn CryptoStore>, store: VerificationStore,
account: ReadOnlyAccount,
private_identity: PrivateCrossSigningIdentity, private_identity: PrivateCrossSigningIdentity,
we_started: bool, we_started: bool,
request_handle: RequestHandle, request_handle: RequestHandle,
@ -1204,7 +1187,6 @@ impl RequestState<Ready> {
Ok(Some(match self.flow_id.as_ref() { Ok(Some(match self.flow_id.as_ref() {
FlowId::ToDevice(t) => { FlowId::ToDevice(t) => {
let (sas, content) = Sas::start( let (sas, content) = Sas::start(
account,
private_identity, private_identity,
device, device,
store, store,
@ -1219,7 +1201,6 @@ impl RequestState<Ready> {
let (sas, content) = Sas::start_in_room( let (sas, content) = Sas::start_in_room(
e.to_owned(), e.to_owned(),
r.to_owned(), r.to_owned(),
account,
private_identity, private_identity,
device, device,
store, store,
@ -1256,7 +1237,7 @@ mod test {
verification::{ verification::{
cache::VerificationCache, cache::VerificationCache,
event_enums::{OutgoingContent, ReadyContent, RequestContent, StartContent}, event_enums::{OutgoingContent, ReadyContent, RequestContent, StartContent},
FlowId, FlowId, VerificationStore,
}, },
ReadOnlyDevice, ReadOnlyDevice,
}; };
@ -1286,10 +1267,14 @@ mod test {
let alice_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new()); let alice_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new());
let alice_identity = PrivateCrossSigningIdentity::empty(alice_id()); let alice_identity = PrivateCrossSigningIdentity::empty(alice_id());
let alice_store = VerificationStore { account: alice.clone(), inner: alice_store.into() };
let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id()); let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id());
let bob_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new()); let bob_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new());
let bob_identity = PrivateCrossSigningIdentity::empty(alice_id()); let bob_identity = PrivateCrossSigningIdentity::empty(alice_id());
let bob_store = VerificationStore { account: bob.clone(), inner: bob_store.into() };
let content = let content =
VerificationRequest::request(bob.user_id(), bob.device_id(), &alice_id(), None); VerificationRequest::request(bob.user_id(), bob.device_id(), &alice_id(), None);
@ -1297,9 +1282,8 @@ mod test {
let bob_request = VerificationRequest::new( let bob_request = VerificationRequest::new(
VerificationCache::new(), VerificationCache::new(),
bob,
bob_identity, bob_identity,
bob_store.into(), bob_store,
flow_id.clone(), flow_id.clone(),
&alice_id(), &alice_id(),
vec![], vec![],
@ -1308,7 +1292,6 @@ mod test {
let alice_request = VerificationRequest::from_request( let alice_request = VerificationRequest::from_request(
VerificationCache::new(), VerificationCache::new(),
alice,
alice_identity, alice_identity,
alice_store.into(), alice_store.into(),
&bob_id(), &bob_id(),
@ -1336,11 +1319,15 @@ mod test {
let alice_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new()); let alice_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new());
let alice_identity = PrivateCrossSigningIdentity::empty(alice_id()); let alice_identity = PrivateCrossSigningIdentity::empty(alice_id());
let alice_store = VerificationStore { account: alice.clone(), inner: alice_store.into() };
let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id()); let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id());
let bob_device = ReadOnlyDevice::from_account(&bob).await; let bob_device = ReadOnlyDevice::from_account(&bob).await;
let bob_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new()); let bob_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new());
let bob_identity = PrivateCrossSigningIdentity::empty(alice_id()); let bob_identity = PrivateCrossSigningIdentity::empty(alice_id());
let bob_store = VerificationStore { account: bob.clone(), inner: bob_store.into() };
let mut changes = Changes::default(); let mut changes = Changes::default();
changes.devices.new.push(bob_device.clone()); changes.devices.new.push(bob_device.clone());
alice_store.save_changes(changes).await.unwrap(); alice_store.save_changes(changes).await.unwrap();
@ -1355,7 +1342,6 @@ mod test {
let bob_request = VerificationRequest::new( let bob_request = VerificationRequest::new(
VerificationCache::new(), VerificationCache::new(),
bob,
bob_identity, bob_identity,
bob_store.into(), bob_store.into(),
flow_id.clone(), flow_id.clone(),
@ -1366,7 +1352,6 @@ mod test {
let alice_request = VerificationRequest::from_request( let alice_request = VerificationRequest::from_request(
VerificationCache::new(), VerificationCache::new(),
alice,
alice_identity, alice_identity,
alice_store.into(), alice_store.into(),
&bob_id(), &bob_id(),
@ -1403,6 +1388,8 @@ mod test {
let alice_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new()); let alice_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new());
let alice_identity = PrivateCrossSigningIdentity::empty(alice_id()); let alice_identity = PrivateCrossSigningIdentity::empty(alice_id());
let alice_store = VerificationStore { account: alice.clone(), inner: alice_store.into() };
let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id()); let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id());
let bob_device = ReadOnlyDevice::from_account(&bob).await; let bob_device = ReadOnlyDevice::from_account(&bob).await;
let bob_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new()); let bob_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new());
@ -1416,11 +1403,12 @@ mod test {
changes.devices.new.push(alice_device.clone()); changes.devices.new.push(alice_device.clone());
bob_store.save_changes(changes).await.unwrap(); bob_store.save_changes(changes).await.unwrap();
let bob_store = VerificationStore { account: bob.clone(), inner: bob_store.into() };
let flow_id = FlowId::from("TEST_FLOW_ID".to_owned()); let flow_id = FlowId::from("TEST_FLOW_ID".to_owned());
let bob_request = VerificationRequest::new( let bob_request = VerificationRequest::new(
VerificationCache::new(), VerificationCache::new(),
bob,
bob_identity, bob_identity,
bob_store.into(), bob_store.into(),
flow_id, flow_id,
@ -1436,7 +1424,6 @@ mod test {
let alice_request = VerificationRequest::from_request( let alice_request = VerificationRequest::from_request(
VerificationCache::new(), VerificationCache::new(),
alice,
alice_identity, alice_identity,
alice_store.into(), alice_store.into(),
&bob_id(), &bob_id(),

View File

@ -35,13 +35,13 @@ use tracing::trace;
use super::{ use super::{
event_enums::{AnyVerificationContent, OutgoingContent, OwnedAcceptContent, StartContent}, event_enums::{AnyVerificationContent, OutgoingContent, OwnedAcceptContent, StartContent},
requests::RequestHandle, requests::RequestHandle,
CancelInfo, FlowId, IdentitiesBeingVerified, VerificationResult, CancelInfo, FlowId, IdentitiesBeingVerified, VerificationResult, VerificationStore,
}; };
use crate::{ use crate::{
identities::{ReadOnlyDevice, ReadOnlyUserIdentities}, identities::{ReadOnlyDevice, ReadOnlyUserIdentities},
olm::PrivateCrossSigningIdentity, olm::PrivateCrossSigningIdentity,
requests::{OutgoingVerificationRequest, RoomMessageRequest}, requests::{OutgoingVerificationRequest, RoomMessageRequest},
store::{CryptoStore, CryptoStoreError}, store::CryptoStoreError,
ReadOnlyAccount, ToDeviceRequest, ReadOnlyAccount, ToDeviceRequest,
}; };
@ -146,16 +146,17 @@ impl Sas {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn start_helper( fn start_helper(
inner_sas: InnerSas, inner_sas: InnerSas,
account: ReadOnlyAccount,
private_identity: PrivateCrossSigningIdentity, private_identity: PrivateCrossSigningIdentity,
other_device: ReadOnlyDevice, other_device: ReadOnlyDevice,
store: Arc<dyn CryptoStore>, store: VerificationStore,
other_identity: Option<ReadOnlyUserIdentities>, other_identity: Option<ReadOnlyUserIdentities>,
we_started: bool, we_started: bool,
request_handle: Option<RequestHandle>, request_handle: Option<RequestHandle>,
) -> Sas { ) -> Sas {
let flow_id = inner_sas.verification_flow_id(); let flow_id = inner_sas.verification_flow_id();
let account = store.account.clone();
let identities = IdentitiesBeingVerified { let identities = IdentitiesBeingVerified {
private_identity, private_identity,
store: store.clone(), store: store.clone(),
@ -185,17 +186,16 @@ impl Sas {
/// sent out through the server to the other device. /// sent out through the server to the other device.
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub(crate) fn start( pub(crate) fn start(
account: ReadOnlyAccount,
private_identity: PrivateCrossSigningIdentity, private_identity: PrivateCrossSigningIdentity,
other_device: ReadOnlyDevice, other_device: ReadOnlyDevice,
store: Arc<dyn CryptoStore>, store: VerificationStore,
other_identity: Option<ReadOnlyUserIdentities>, other_identity: Option<ReadOnlyUserIdentities>,
transaction_id: Option<String>, transaction_id: Option<String>,
we_started: bool, we_started: bool,
request_handle: Option<RequestHandle>, request_handle: Option<RequestHandle>,
) -> (Sas, OutgoingContent) { ) -> (Sas, OutgoingContent) {
let (inner, content) = InnerSas::start( let (inner, content) = InnerSas::start(
account.clone(), store.account.clone(),
other_device.clone(), other_device.clone(),
other_identity.clone(), other_identity.clone(),
transaction_id, transaction_id,
@ -204,7 +204,6 @@ impl Sas {
( (
Self::start_helper( Self::start_helper(
inner, inner,
account,
private_identity, private_identity,
other_device, other_device,
store, store,
@ -230,10 +229,9 @@ impl Sas {
pub(crate) fn start_in_room( pub(crate) fn start_in_room(
flow_id: EventId, flow_id: EventId,
room_id: RoomId, room_id: RoomId,
account: ReadOnlyAccount,
private_identity: PrivateCrossSigningIdentity, private_identity: PrivateCrossSigningIdentity,
other_device: ReadOnlyDevice, other_device: ReadOnlyDevice,
store: Arc<dyn CryptoStore>, store: VerificationStore,
other_identity: Option<ReadOnlyUserIdentities>, other_identity: Option<ReadOnlyUserIdentities>,
we_started: bool, we_started: bool,
request_handle: RequestHandle, request_handle: RequestHandle,
@ -241,7 +239,7 @@ impl Sas {
let (inner, content) = InnerSas::start_in_room( let (inner, content) = InnerSas::start_in_room(
flow_id, flow_id,
room_id, room_id,
account.clone(), store.account.clone(),
other_device.clone(), other_device.clone(),
other_identity.clone(), other_identity.clone(),
); );
@ -249,7 +247,6 @@ impl Sas {
( (
Self::start_helper( Self::start_helper(
inner, inner,
account,
private_identity, private_identity,
other_device, other_device,
store, store,
@ -275,8 +272,7 @@ impl Sas {
pub(crate) fn from_start_event( pub(crate) fn from_start_event(
flow_id: FlowId, flow_id: FlowId,
content: &StartContent, content: &StartContent,
store: Arc<dyn CryptoStore>, store: VerificationStore,
account: ReadOnlyAccount,
private_identity: PrivateCrossSigningIdentity, private_identity: PrivateCrossSigningIdentity,
other_device: ReadOnlyDevice, other_device: ReadOnlyDevice,
other_identity: Option<ReadOnlyUserIdentities>, other_identity: Option<ReadOnlyUserIdentities>,
@ -284,7 +280,7 @@ impl Sas {
we_started: bool, we_started: bool,
) -> Result<Sas, OutgoingContent> { ) -> Result<Sas, OutgoingContent> {
let inner = InnerSas::from_start_event( let inner = InnerSas::from_start_event(
account.clone(), store.account.clone(),
other_device.clone(), other_device.clone(),
flow_id, flow_id,
content, content,
@ -294,7 +290,6 @@ impl Sas {
Ok(Self::start_helper( Ok(Self::start_helper(
inner, inner,
account,
private_identity, private_identity,
other_device, other_device,
store, store,
@ -562,9 +557,10 @@ mod test {
use super::Sas; use super::Sas;
use crate::{ use crate::{
olm::PrivateCrossSigningIdentity, olm::PrivateCrossSigningIdentity,
store::{CryptoStore, MemoryStore}, store::MemoryStore,
verification::event_enums::{ verification::{
AcceptContent, KeyContent, MacContent, OutgoingContent, StartContent, event_enums::{AcceptContent, KeyContent, MacContent, OutgoingContent, StartContent},
VerificationStore,
}, },
ReadOnlyAccount, ReadOnlyDevice, ReadOnlyAccount, ReadOnlyDevice,
}; };
@ -593,15 +589,15 @@ mod test {
let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id()); let bob = ReadOnlyAccount::new(&bob_id(), &bob_device_id());
let bob_device = ReadOnlyDevice::from_account(&bob).await; let bob_device = ReadOnlyDevice::from_account(&bob).await;
let alice_store: Arc<dyn CryptoStore> = Arc::new(MemoryStore::new()); let alice_store =
let bob_store = MemoryStore::new(); VerificationStore { account: alice.clone(), inner: Arc::new(MemoryStore::new()) };
let bob_store = MemoryStore::new();
bob_store.save_devices(vec![alice_device.clone()]).await; bob_store.save_devices(vec![alice_device.clone()]).await;
let bob_store: Arc<dyn CryptoStore> = Arc::new(bob_store); let bob_store = VerificationStore { account: bob.clone(), inner: Arc::new(bob_store) };
let (alice, content) = Sas::start( let (alice, content) = Sas::start(
alice,
PrivateCrossSigningIdentity::empty(alice_id()), PrivateCrossSigningIdentity::empty(alice_id()),
bob_device, bob_device,
alice_store, alice_store,
@ -618,7 +614,6 @@ mod test {
flow_id, flow_id,
&content, &content,
bob_store, bob_store,
bob,
PrivateCrossSigningIdentity::empty(bob_id()), PrivateCrossSigningIdentity::empty(bob_id()),
alice_device, alice_device,
None, None,