crypto: Fix the method to transition from a request into a SAS verification

master
Damir Jelić 2021-06-14 17:49:18 +02:00
parent 29bba0b2ca
commit c547f384bc
1 changed files with 77 additions and 25 deletions

View File

@ -368,21 +368,44 @@ impl VerificationRequest {
} }
} }
pub(crate) fn start( /// Transition from this verification request into a SAS verification flow.
pub async fn start_sas(
&self, &self,
device: ReadOnlyDevice, ) -> Result<Option<(Sas, OutgoingVerificationRequest)>, CryptoStoreError> {
user_identity: Option<UserIdentities>, let inner = self.inner.lock().unwrap().clone();
) -> Option<(Sas, OutgoingContent)> {
match &*self.inner.lock().unwrap() { Ok(match &inner {
InnerRequest::Ready(s) => Some(s.clone().start_sas( InnerRequest::Ready(s) => {
s.store.clone(), if let Some((sas, content)) = s
s.account.clone(), .clone()
s.private_cross_signing_identity.clone(), .start_sas(
device, s.store.clone(),
user_identity, s.account.clone(),
)), s.private_cross_signing_identity.clone(),
)
.await?
{
self.verification_cache.insert_sas(sas.clone());
let request = match content {
OutgoingContent::ToDevice(content) => ToDeviceRequest::new(
&self.other_user(),
inner.other_device_id(),
content,
)
.into(),
OutgoingContent::Room(room_id, content) => {
RoomMessageRequest { room_id, txn_id: Uuid::new_v4(), content }.into()
}
};
Some((sas, request))
} else {
None
}
}
_ => None, _ => None,
} })
} }
} }
@ -832,20 +855,39 @@ impl RequestState<Ready> {
Ok(()) Ok(())
} }
fn start_sas( async fn start_sas(
self, self,
store: Arc<dyn CryptoStore>, store: Arc<dyn CryptoStore>,
account: ReadOnlyAccount, account: ReadOnlyAccount,
private_identity: PrivateCrossSigningIdentity, private_identity: PrivateCrossSigningIdentity,
other_device: ReadOnlyDevice, ) -> Result<Option<(Sas, OutgoingContent)>, CryptoStoreError> {
other_identity: Option<UserIdentities>, if !self.state.their_methods.contains(&VerificationMethod::MSasV1) {
) -> (Sas, OutgoingContent) { return Ok(None);
match self.flow_id.as_ref() { }
// TODO signal why starting the sas flow doesn't work?
let other_identity = store.get_user_identity(&self.other_user_id).await?;
let device = if let Some(device) =
self.store.get_device(&self.other_user_id, &self.state.other_device_id).await?
{
device
} else {
warn!(
user_id = self.other_user_id.as_str(),
device_id = self.state.other_device_id.as_str(),
"Can't start the SAS verificaiton flow, the device that \
accepted the verification doesn't exist"
);
return Ok(None);
};
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, account,
private_identity, private_identity,
other_device, device,
store, store,
other_identity, other_identity,
Some(t.to_owned()), Some(t.to_owned()),
@ -858,13 +900,13 @@ impl RequestState<Ready> {
r.to_owned(), r.to_owned(),
account, account,
private_identity, private_identity,
other_device, device,
store, store,
other_identity, other_identity,
); );
(sas, content) (sas, content)
} }
} }))
} }
} }
@ -978,6 +1020,10 @@ mod test {
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();
let mut changes = Changes::default();
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());
let bob_request = VerificationRequest::new( let bob_request = VerificationRequest::new(
@ -1010,9 +1056,10 @@ mod test {
assert!(bob_request.is_ready()); assert!(bob_request.is_ready());
assert!(alice_request.is_ready()); assert!(alice_request.is_ready());
let (bob_sas, start_content) = bob_request.start(alice_device, None).unwrap(); let (bob_sas, request) = bob_request.start_sas().await.unwrap().unwrap();
let content = StartContent::try_from(&start_content).unwrap(); let content: OutgoingContent = request.into();
let content = StartContent::try_from(&content).unwrap();
let flow_id = content.flow_id().to_owned(); let flow_id = content.flow_id().to_owned();
alice_request.receive_start(bob_device.user_id(), &content).await.unwrap(); alice_request.receive_start(bob_device.user_id(), &content).await.unwrap();
let alice_sas = let alice_sas =
@ -1039,6 +1086,10 @@ mod test {
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();
let mut changes = Changes::default();
changes.devices.new.push(alice_device.clone());
bob_store.save_changes(changes).await.unwrap();
let bob_request = VerificationRequest::new_to_device( let bob_request = VerificationRequest::new_to_device(
VerificationCache::new(), VerificationCache::new(),
bob, bob,
@ -1068,9 +1119,10 @@ mod test {
assert!(bob_request.is_ready()); assert!(bob_request.is_ready());
assert!(alice_request.is_ready()); assert!(alice_request.is_ready());
let (bob_sas, start_content) = bob_request.start(alice_device, None).unwrap(); let (bob_sas, request) = bob_request.start_sas().await.unwrap().unwrap();
let content = StartContent::try_from(&start_content).unwrap(); let content: OutgoingContent = request.into();
let content = StartContent::try_from(&content).unwrap();
let flow_id = content.flow_id().to_owned(); let flow_id = content.flow_id().to_owned();
alice_request.receive_start(bob_device.user_id(), &content).await.unwrap(); alice_request.receive_start(bob_device.user_id(), &content).await.unwrap();
let alice_sas = let alice_sas =