Skip to content

Commit

Permalink
test(crypto): Test the double verification cancellation
Browse files Browse the repository at this point in the history
  • Loading branch information
poljar committed Jun 13, 2022
1 parent b8069af commit 1a162e5
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 93 deletions.
155 changes: 119 additions & 36 deletions crates/matrix-sdk-crypto/src/verification/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,61 +510,41 @@ mod tests {

use matrix_sdk_common::{instant::Instant, locks::Mutex};
use matrix_sdk_test::async_test;
use ruma::{device_id, user_id, DeviceId, TransactionId, UserId};
use ruma::TransactionId;

use super::{Sas, VerificationMachine};
use crate::{
olm::PrivateCrossSigningIdentity,
store::MemoryStore,
verification::{
cache::VerificationCache,
event_enums::{AcceptContent, KeyContent, MacContent, OutgoingContent},
test::{alice_device_id, alice_id, setup_stores},
tests::wrap_any_to_device_content,
VerificationStore,
FlowId, VerificationStore,
},
ReadOnlyAccount, ReadOnlyDevice,
ReadOnlyAccount, VerificationRequest,
};

fn alice_id() -> &'static UserId {
user_id!("@alice:example.org")
}

fn alice_device_id() -> &'static DeviceId {
device_id!("JLAFKJWSCS")
}
async fn verification_machine() -> (VerificationMachine, VerificationStore) {
let (store, bob_store) = setup_stores().await;

fn bob_id() -> &'static UserId {
user_id!("@bob:example.org")
}
let machine = VerificationMachine {
store,
verifications: VerificationCache::new(),
requests: Default::default(),
};

fn bob_device_id() -> &'static DeviceId {
device_id!("BOBDEVCIE")
(machine, bob_store)
}

async fn setup_verification_machine() -> (VerificationMachine, Sas) {
let alice = ReadOnlyAccount::new(alice_id(), alice_device_id());
let bob = ReadOnlyAccount::new(bob_id(), bob_device_id());
let store = MemoryStore::new();
let bob_store = MemoryStore::new();

let bob_device = ReadOnlyDevice::from_account(&bob).await;
let alice_device = ReadOnlyDevice::from_account(&alice).await;
let (machine, bob_store) = verification_machine().await;

store.save_devices(vec![bob_device]).await;
bob_store.save_devices(vec![alice_device.clone()]).await;

let identity = Arc::new(Mutex::new(PrivateCrossSigningIdentity::empty(bob_id())));
let bob_store = VerificationStore {
account: bob,
inner: Arc::new(bob_store),
private_identity: identity,
};
let alice_device =
bob_store.get_device(alice_id(), alice_device_id()).await.unwrap().unwrap();

let identities = bob_store.get_identities(alice_device).await.unwrap();
let machine = VerificationMachine::new(
alice,
Mutex::new(PrivateCrossSigningIdentity::empty(alice_id())).into(),
Arc::new(store),
);
let (bob_sas, start_content) = Sas::start(identities, TransactionId::new(), true, None);

machine
Expand Down Expand Up @@ -651,4 +631,107 @@ mod tests {
alice_machine.garbage_collect();
assert!(alice_machine.verifications.is_empty());
}

/// Test to ensure that we cancel both verifications if a second one gets
/// started while another one is going on.
#[async_test]
async fn double_verification_cancellation() {
let (machine, bob_store) = verification_machine().await;

let alice_device =
bob_store.get_device(alice_id(), alice_device_id()).await.unwrap().unwrap();
let identities = bob_store.get_identities(alice_device).await.unwrap();

// Start the first sas verification.
let (bob_sas, start_content) =
Sas::start(identities.clone(), TransactionId::new(), true, None);

machine
.receive_any_event(&wrap_any_to_device_content(bob_sas.user_id(), start_content))
.await
.unwrap();

let alice_sas = machine.get_sas(bob_sas.user_id(), bob_sas.flow_id().as_str()).unwrap();

// We're not yet cancelled.
assert!(!alice_sas.is_cancelled());

let second_transaction_id = TransactionId::new();
let (bob_sas, start_content) =
Sas::start(identities, second_transaction_id.clone(), true, None);
machine
.receive_any_event(&wrap_any_to_device_content(bob_sas.user_id(), start_content))
.await
.unwrap();

let second_sas = machine.get_sas(bob_sas.user_id(), bob_sas.flow_id().as_str()).unwrap();

// Make sure we fetched the new one.
assert_eq!(second_sas.flow_id().as_str(), second_transaction_id);

// Make sure both of them are cancelled.
assert!(alice_sas.is_cancelled());
assert!(second_sas.is_cancelled());
}

/// Test to ensure that we cancel both verification requests if a second one
/// gets started while another one is going on.
#[async_test]
async fn double_verification_request_cancellation() {
let (machine, bob_store) = verification_machine().await;

// Start the first verification request.
let flow_id = FlowId::ToDevice("TEST_FLOW_ID".into());

let bob_request = VerificationRequest::new(
VerificationCache::new(),
bob_store.clone(),
flow_id.clone(),
alice_id(),
vec![],
None,
);

let request = bob_request.request_to_device();
let content: OutgoingContent = request.try_into().unwrap();

machine
.receive_any_event(&wrap_any_to_device_content(bob_request.other_user(), content))
.await
.unwrap();

let alice_request =
machine.get_request(bob_request.other_user(), bob_request.flow_id().as_str()).unwrap();

// We're not yet cancelled.
assert!(!alice_request.is_cancelled());

let second_transaction_id = TransactionId::new();
let bob_request = VerificationRequest::new(
VerificationCache::new(),
bob_store,
second_transaction_id.clone().into(),
alice_id(),
vec![],
None,
);

let request = bob_request.request_to_device();
let content: OutgoingContent = request.try_into().unwrap();

machine
.receive_any_event(&wrap_any_to_device_content(bob_request.other_user(), content))
.await
.unwrap();

let second_request =
machine.get_request(bob_request.other_user(), bob_request.flow_id().as_str()).unwrap();

// Make sure we fetched the new one.
assert_eq!(second_request.flow_id().as_str(), second_transaction_id);

// Make sure both of them are cancelled.
assert!(alice_request.is_cancelled());
assert!(second_request.is_cancelled());
}
}
62 changes: 61 additions & 1 deletion crates/matrix-sdk-crypto/src/verification/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ use crate::{
olm::{PrivateCrossSigningIdentity, ReadOnlyAccount, Session},
store::{Changes, CryptoStore},
types::Signatures,
CryptoStoreError, LocalTrust, ReadOnlyDevice, ReadOnlyOwnUserIdentity, ReadOnlyUserIdentities,
CryptoStoreError, LocalTrust, OutgoingVerificationRequest, ReadOnlyDevice,
ReadOnlyOwnUserIdentity, ReadOnlyUserIdentities,
};

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -772,3 +773,62 @@ pub(crate) mod tests {
}
}
}

#[cfg(test)]
mod test {
use std::sync::Arc;

use matrix_sdk_common::locks::Mutex;
use ruma::{device_id, user_id, DeviceId, UserId};

use super::VerificationStore;
use crate::{
olm::PrivateCrossSigningIdentity, store::MemoryStore, ReadOnlyAccount, ReadOnlyDevice,
};

pub fn alice_id() -> &'static UserId {
user_id!("@alice:example.org")
}

pub fn alice_device_id() -> &'static DeviceId {
device_id!("JLAFKJWSCS")
}

pub fn bob_id() -> &'static UserId {
user_id!("@bob:example.org")
}

pub fn bob_device_id() -> &'static DeviceId {
device_id!("BOBDEVCIE")
}

pub(crate) async fn setup_stores() -> (VerificationStore, VerificationStore) {
let alice = ReadOnlyAccount::new(alice_id(), alice_device_id());
let alice_store = MemoryStore::new();
let alice_identity = Mutex::new(PrivateCrossSigningIdentity::empty(alice_id()));

let bob = ReadOnlyAccount::new(bob_id(), bob_device_id());
let bob_store = MemoryStore::new();
let bob_identity = Mutex::new(PrivateCrossSigningIdentity::empty(bob_id()));

let alice_device = ReadOnlyDevice::from_account(&alice).await;
let bob_device = ReadOnlyDevice::from_account(&bob).await;

alice_store.save_devices(vec![bob_device]).await;
bob_store.save_devices(vec![alice_device]).await;

let alice_store = VerificationStore {
account: alice,
inner: Arc::new(alice_store),
private_identity: alice_identity.into(),
};

let bob_store = VerificationStore {
account: bob.clone(),
inner: Arc::new(bob_store),
private_identity: bob_identity.into(),
};

(alice_store, bob_store)
}
}
59 changes: 3 additions & 56 deletions crates/matrix-sdk-crypto/src/verification/requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1213,73 +1213,20 @@ mod tests {

use std::convert::{TryFrom, TryInto};

use matrix_sdk_common::locks::Mutex;
use matrix_sdk_test::async_test;
use ruma::{device_id, event_id, room_id, user_id, DeviceId, UserId};
use ruma::{event_id, room_id};

use super::VerificationRequest;
use crate::{
olm::{PrivateCrossSigningIdentity, ReadOnlyAccount},
store::{Changes, CryptoStore, MemoryStore},
verification::{
cache::VerificationCache,
event_enums::{OutgoingContent, ReadyContent, RequestContent, StartContent},
FlowId, VerificationStore,
test::{alice_id, bob_id, setup_stores},
FlowId,
},
ReadOnlyDevice,
};

fn alice_id() -> &'static UserId {
user_id!("@alice:example.org")
}

fn alice_device_id() -> &'static DeviceId {
device_id!("JLAFKJWSCS")
}

fn bob_id() -> &'static UserId {
user_id!("@bob:example.org")
}

fn bob_device_id() -> &'static DeviceId {
device_id!("BOBDEVCIE")
}

async fn setup_stores() -> (VerificationStore, VerificationStore) {
let alice = ReadOnlyAccount::new(alice_id(), alice_device_id());
let alice_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new());
let alice_identity = Mutex::new(PrivateCrossSigningIdentity::empty(alice_id()));

let alice_store = VerificationStore {
account: alice,
inner: alice_store.into(),
private_identity: alice_identity.into(),
};

let bob = ReadOnlyAccount::new(bob_id(), bob_device_id());
let bob_store: Box<dyn CryptoStore> = Box::new(MemoryStore::new());
let bob_identity = Mutex::new(PrivateCrossSigningIdentity::empty(bob_id()));

let bob_store = VerificationStore {
account: bob.clone(),
inner: bob_store.into(),
private_identity: bob_identity.into(),
};

let alice_device = ReadOnlyDevice::from_account(&alice_store.account).await;
let bob_device = ReadOnlyDevice::from_account(&bob_store.account).await;

let mut changes = Changes::default();
changes.devices.new.push(bob_device.clone());
alice_store.save_changes(changes).await.unwrap();

let mut changes = Changes::default();
changes.devices.new.push(alice_device.clone());
bob_store.save_changes(changes).await.unwrap();

(alice_store, bob_store)
}

#[async_test]
async fn test_request_accepting() {
let event_id = event_id!("$1234localhost").to_owned();
Expand Down

0 comments on commit 1a162e5

Please sign in to comment.