crypto: Move the CancelContent generation out of the sas module

master
Damir Jelić 2021-05-26 11:54:22 +02:00
parent 300189bb37
commit 0e514b755f
7 changed files with 107 additions and 94 deletions

View File

@ -133,8 +133,8 @@ impl Sas {
} }
/// Is the verification process canceled. /// Is the verification process canceled.
pub fn is_canceled(&self) -> bool { pub fn is_cancelled(&self) -> bool {
self.inner.is_canceled() self.inner.is_cancelled()
} }
/// Get the other users device that we're veryfying. /// Get the other users device that we're veryfying.

View File

@ -61,8 +61,8 @@ impl VerificationCache {
} }
pub fn garbage_collect(&self) -> Vec<OutgoingRequest> { pub fn garbage_collect(&self) -> Vec<OutgoingRequest> {
self.sas_verification.retain(|_, s| !(s.is_done() || s.is_canceled())); self.sas_verification.retain(|_, s| !(s.is_done() || s.is_cancelled()));
self.room_sas_verifications.retain(|_, s| !(s.is_done() || s.is_canceled())); self.room_sas_verifications.retain(|_, s| !(s.is_done() || s.is_cancelled()));
let mut requests: Vec<OutgoingRequest> = self let mut requests: Vec<OutgoingRequest> = self
.sas_verification .sas_verification

View File

@ -17,10 +17,70 @@ mod requests;
mod sas; mod sas;
pub use machine::{VerificationCache, VerificationMachine}; pub use machine::{VerificationCache, VerificationMachine};
use matrix_sdk_common::identifiers::{EventId, RoomId}; use matrix_sdk_common::{
events::key::verification::{
cancel::{CancelCode, CancelEventContent, CancelToDeviceEventContent},
Relation,
},
identifiers::{EventId, RoomId},
};
pub use requests::VerificationRequest; pub use requests::VerificationRequest;
pub use sas::{AcceptSettings, Sas, VerificationResult}; pub use sas::{AcceptSettings, Sas, VerificationResult};
use self::sas::CancelContent;
#[derive(Clone, Debug)]
pub struct Cancelled {
cancel_code: CancelCode,
reason: &'static str,
}
impl Cancelled {
fn new(code: CancelCode) -> Self {
let reason = match code {
CancelCode::Accepted => {
"A m.key.verification.request was accepted by a different device."
}
CancelCode::InvalidMessage => "The received message was invalid.",
CancelCode::KeyMismatch => "The expected key did not match the verified one",
CancelCode::Timeout => "The verification process timed out.",
CancelCode::UnexpectedMessage => "The device received an unexpected message.",
CancelCode::UnknownMethod => {
"The device does not know how to handle the requested method."
}
CancelCode::UnknownTransaction => {
"The device does not know about the given transaction ID."
}
CancelCode::User => "The user cancelled the verification.",
CancelCode::UserMismatch => "The expected user did not match the verified user",
_ => unimplemented!(),
};
Self { cancel_code: code, reason }
}
pub fn as_content(&self, flow_id: &FlowId) -> CancelContent {
match flow_id {
FlowId::ToDevice(s) => CancelToDeviceEventContent::new(
s.clone(),
self.reason.to_string(),
self.cancel_code.clone(),
)
.into(),
FlowId::InRoom(r, e) => (
r.clone(),
CancelEventContent::new(
self.reason.to_string(),
self.cancel_code.clone(),
Relation::new(e.clone()),
),
)
.into(),
}
}
}
#[derive(Clone, Debug, Hash, PartialEq, PartialOrd)] #[derive(Clone, Debug, Hash, PartialEq, PartialOrd)]
pub enum FlowId { pub enum FlowId {
ToDevice(String), ToDevice(String),

View File

@ -848,7 +848,7 @@ mod test {
let content = StartContent::try_from(&start_content).unwrap(); let content = StartContent::try_from(&start_content).unwrap();
let alice_sas = alice_request.into_started_sas(content, bob_device, None).unwrap(); let alice_sas = alice_request.into_started_sas(content, bob_device, None).unwrap();
assert!(!bob_sas.is_canceled()); assert!(!bob_sas.is_cancelled());
assert!(!alice_sas.is_canceled()); assert!(!alice_sas.is_cancelled());
} }
} }

View File

@ -27,13 +27,14 @@ use matrix_sdk_common::{
use super::{ use super::{
event_enums::{AcceptContent, CancelContent, MacContent, OutgoingContent}, event_enums::{AcceptContent, CancelContent, MacContent, OutgoingContent},
sas_state::{ sas_state::{
Accepted, Canceled, Confirmed, Created, Done, KeyReceived, MacReceived, SasState, Started, Accepted, Confirmed, Created, Done, KeyReceived, MacReceived, SasState, Started,
WaitingForDone, WaitingForDone,
}, },
FlowId, StartContent, FlowId, StartContent,
}; };
use crate::{ use crate::{
identities::{ReadOnlyDevice, UserIdentities}, identities::{ReadOnlyDevice, UserIdentities},
verification::Cancelled,
ReadOnlyAccount, ReadOnlyAccount,
}; };
@ -48,7 +49,7 @@ pub enum InnerSas {
WaitingForDone(SasState<WaitingForDone>), WaitingForDone(SasState<WaitingForDone>),
WaitingForDoneUnconfirmed(SasState<WaitingForDone>), WaitingForDoneUnconfirmed(SasState<WaitingForDone>),
Done(SasState<Done>), Done(SasState<Done>),
Canceled(SasState<Canceled>), Cancelled(SasState<Cancelled>),
} }
impl InnerSas { impl InnerSas {
@ -90,7 +91,7 @@ impl InnerSas {
InnerSas::WaitingForDone(_) => false, InnerSas::WaitingForDone(_) => false,
InnerSas::WaitingForDoneUnconfirmed(_) => false, InnerSas::WaitingForDoneUnconfirmed(_) => false,
InnerSas::Done(_) => false, InnerSas::Done(_) => false,
InnerSas::Canceled(_) => false, InnerSas::Cancelled(_) => false,
} }
} }
@ -139,7 +140,7 @@ impl InnerSas {
match self { match self {
InnerSas::Created(s) => s.set_creation_time(time), InnerSas::Created(s) => s.set_creation_time(time),
InnerSas::Started(s) => s.set_creation_time(time), InnerSas::Started(s) => s.set_creation_time(time),
InnerSas::Canceled(s) => s.set_creation_time(time), InnerSas::Cancelled(s) => s.set_creation_time(time),
InnerSas::Accepted(s) => s.set_creation_time(time), InnerSas::Accepted(s) => s.set_creation_time(time),
InnerSas::KeyRecieved(s) => s.set_creation_time(time), InnerSas::KeyRecieved(s) => s.set_creation_time(time),
InnerSas::Confirmed(s) => s.set_creation_time(time), InnerSas::Confirmed(s) => s.set_creation_time(time),
@ -162,7 +163,7 @@ impl InnerSas {
let content = sas.as_content(); let content = sas.as_content();
(InnerSas::Canceled(sas), Some(content)) (InnerSas::Cancelled(sas), Some(content))
} }
pub fn confirm(self) -> (InnerSas, Option<MacContent>) { pub fn confirm(self) -> (InnerSas, Option<MacContent>) {
@ -201,7 +202,7 @@ impl InnerSas {
Ok(s) => (InnerSas::KeyRecieved(s), None), Ok(s) => (InnerSas::KeyRecieved(s), None),
Err(s) => { Err(s) => {
let content = s.as_content(); let content = s.as_content();
(InnerSas::Canceled(s), Some(content.into())) (InnerSas::Cancelled(s), Some(content.into()))
} }
} }
} }
@ -213,7 +214,7 @@ impl InnerSas {
} }
Err(s) => { Err(s) => {
let content = s.as_content(); let content = s.as_content();
(InnerSas::Canceled(s), Some(content.into())) (InnerSas::Cancelled(s), Some(content.into()))
} }
} }
} }
@ -226,7 +227,7 @@ impl InnerSas {
Ok(s) => (InnerSas::MacReceived(s), None), Ok(s) => (InnerSas::MacReceived(s), None),
Err(s) => { Err(s) => {
let content = s.as_content(); let content = s.as_content();
(InnerSas::Canceled(s), Some(content.into())) (InnerSas::Cancelled(s), Some(content.into()))
} }
} }
} }
@ -239,7 +240,7 @@ impl InnerSas {
} }
Err(s) => { Err(s) => {
let content = s.as_content(); let content = s.as_content();
(InnerSas::Canceled(s), Some(content.into())) (InnerSas::Cancelled(s), Some(content.into()))
} }
} }
} }
@ -251,7 +252,7 @@ impl InnerSas {
Ok(s) => (InnerSas::Done(s), None), Ok(s) => (InnerSas::Done(s), None),
Err(s) => { Err(s) => {
let content = s.as_content(); let content = s.as_content();
(InnerSas::Canceled(s), Some(content.into())) (InnerSas::Cancelled(s), Some(content.into()))
} }
} }
} }
@ -263,7 +264,7 @@ impl InnerSas {
} }
Err(s) => { Err(s) => {
let content = s.as_content(); let content = s.as_content();
(InnerSas::Canceled(s), Some(content.into())) (InnerSas::Cancelled(s), Some(content.into()))
} }
} }
} }
@ -285,7 +286,7 @@ impl InnerSas {
} }
Err(s) => { Err(s) => {
let content = s.as_content(); let content = s.as_content();
(InnerSas::Canceled(s), Some(content.into())) (InnerSas::Cancelled(s), Some(content.into()))
} }
} }
} else { } else {
@ -297,7 +298,7 @@ impl InnerSas {
Ok(s) => (InnerSas::KeyRecieved(s), None), Ok(s) => (InnerSas::KeyRecieved(s), None),
Err(s) => { Err(s) => {
let content = s.as_content(); let content = s.as_content();
(InnerSas::Canceled(s), Some(content.into())) (InnerSas::Cancelled(s), Some(content.into()))
} }
}, },
InnerSas::Started(s) => match s.into_key_received(&e.sender, e.content.clone()) { InnerSas::Started(s) => match s.into_key_received(&e.sender, e.content.clone()) {
@ -307,7 +308,7 @@ impl InnerSas {
} }
Err(s) => { Err(s) => {
let content = s.as_content(); let content = s.as_content();
(InnerSas::Canceled(s), Some(content.into())) (InnerSas::Cancelled(s), Some(content.into()))
} }
}, },
_ => (self, None), _ => (self, None),
@ -318,7 +319,7 @@ impl InnerSas {
Ok(s) => (InnerSas::MacReceived(s), None), Ok(s) => (InnerSas::MacReceived(s), None),
Err(s) => { Err(s) => {
let content = s.as_content(); let content = s.as_content();
(InnerSas::Canceled(s), Some(content.into())) (InnerSas::Cancelled(s), Some(content.into()))
} }
} }
} }
@ -326,7 +327,7 @@ impl InnerSas {
Ok(s) => (InnerSas::Done(s), None), Ok(s) => (InnerSas::Done(s), None),
Err(s) => { Err(s) => {
let content = s.as_content(); let content = s.as_content();
(InnerSas::Canceled(s), Some(content.into())) (InnerSas::Cancelled(s), Some(content.into()))
} }
}, },
_ => (self, None), _ => (self, None),
@ -343,15 +344,15 @@ impl InnerSas {
matches!(self, InnerSas::Done(_)) matches!(self, InnerSas::Done(_))
} }
pub fn is_canceled(&self) -> bool { pub fn is_cancelled(&self) -> bool {
matches!(self, InnerSas::Canceled(_)) matches!(self, InnerSas::Cancelled(_))
} }
pub fn timed_out(&self) -> bool { pub fn timed_out(&self) -> bool {
match self { match self {
InnerSas::Created(s) => s.timed_out(), InnerSas::Created(s) => s.timed_out(),
InnerSas::Started(s) => s.timed_out(), InnerSas::Started(s) => s.timed_out(),
InnerSas::Canceled(s) => s.timed_out(), InnerSas::Cancelled(s) => s.timed_out(),
InnerSas::Accepted(s) => s.timed_out(), InnerSas::Accepted(s) => s.timed_out(),
InnerSas::KeyRecieved(s) => s.timed_out(), InnerSas::KeyRecieved(s) => s.timed_out(),
InnerSas::Confirmed(s) => s.timed_out(), InnerSas::Confirmed(s) => s.timed_out(),
@ -366,7 +367,7 @@ impl InnerSas {
match self { match self {
InnerSas::Created(s) => s.verification_flow_id.clone(), InnerSas::Created(s) => s.verification_flow_id.clone(),
InnerSas::Started(s) => s.verification_flow_id.clone(), InnerSas::Started(s) => s.verification_flow_id.clone(),
InnerSas::Canceled(s) => s.verification_flow_id.clone(), InnerSas::Cancelled(s) => s.verification_flow_id.clone(),
InnerSas::Accepted(s) => s.verification_flow_id.clone(), InnerSas::Accepted(s) => s.verification_flow_id.clone(),
InnerSas::KeyRecieved(s) => s.verification_flow_id.clone(), InnerSas::KeyRecieved(s) => s.verification_flow_id.clone(),
InnerSas::Confirmed(s) => s.verification_flow_id.clone(), InnerSas::Confirmed(s) => s.verification_flow_id.clone(),

View File

@ -559,7 +559,7 @@ impl Sas {
} }
pub(crate) fn cancel_if_timed_out(&self) -> Option<OutgoingVerificationRequest> { pub(crate) fn cancel_if_timed_out(&self) -> Option<OutgoingVerificationRequest> {
if self.is_canceled() || self.is_done() { if self.is_cancelled() || self.is_done() {
None None
} else if self.timed_out() { } else if self.timed_out() {
let mut guard = self.inner.lock().unwrap(); let mut guard = self.inner.lock().unwrap();
@ -598,8 +598,8 @@ impl Sas {
} }
/// Is the SAS flow canceled. /// Is the SAS flow canceled.
pub fn is_canceled(&self) -> bool { pub fn is_cancelled(&self) -> bool {
self.inner.lock().unwrap().is_canceled() self.inner.lock().unwrap().is_cancelled()
} }
/// Get the emoji version of the short auth string. /// Get the emoji version of the short auth string.

View File

@ -25,7 +25,7 @@ use matrix_sdk_common::{
AcceptEventContent, AcceptMethod, AcceptToDeviceEventContent, AcceptEventContent, AcceptMethod, AcceptToDeviceEventContent,
SasV1Content as AcceptV1Content, SasV1ContentInit as AcceptV1ContentInit, SasV1Content as AcceptV1Content, SasV1ContentInit as AcceptV1ContentInit,
}, },
cancel::{CancelCode, CancelEventContent, CancelToDeviceEventContent}, cancel::CancelCode,
done::DoneEventContent, done::DoneEventContent,
key::{KeyEventContent, KeyToDeviceEventContent}, key::{KeyEventContent, KeyToDeviceEventContent},
start::{ start::{
@ -52,7 +52,7 @@ use super::{
}; };
use crate::{ use crate::{
identities::{ReadOnlyDevice, UserIdentities}, identities::{ReadOnlyDevice, UserIdentities},
verification::FlowId, verification::{Cancelled, FlowId},
ReadOnlyAccount, ReadOnlyAccount,
}; };
@ -281,12 +281,6 @@ pub struct Done {
verified_master_keys: Arc<[UserIdentities]>, verified_master_keys: Arc<[UserIdentities]>,
} }
#[derive(Clone, Debug)]
pub struct Canceled {
cancel_code: CancelCode,
reason: &'static str,
}
impl<S: Clone> SasState<S> { impl<S: Clone> SasState<S> {
/// Get our own user id. /// Get our own user id.
#[cfg(test)] #[cfg(test)]
@ -304,14 +298,14 @@ impl<S: Clone> SasState<S> {
self.ids.other_device.clone() self.ids.other_device.clone()
} }
pub fn cancel(self, cancel_code: CancelCode) -> SasState<Canceled> { pub fn cancel(self, cancel_code: CancelCode) -> SasState<Cancelled> {
SasState { SasState {
inner: self.inner, inner: self.inner,
ids: self.ids, ids: self.ids,
creation_time: self.creation_time, creation_time: self.creation_time,
last_event_time: self.last_event_time, last_event_time: self.last_event_time,
verification_flow_id: self.verification_flow_id, verification_flow_id: self.verification_flow_id,
state: Arc::new(Canceled::new(cancel_code)), state: Arc::new(Cancelled::new(cancel_code)),
} }
} }
@ -448,7 +442,7 @@ impl SasState<Created> {
self, self,
sender: &UserId, sender: &UserId,
content: impl Into<AcceptContent>, content: impl Into<AcceptContent>,
) -> Result<SasState<Accepted>, SasState<Canceled>> { ) -> Result<SasState<Accepted>, SasState<Cancelled>> {
let content = content.into(); let content = content.into();
self.check_event(&sender, content.flow_id().as_str()) self.check_event(&sender, content.flow_id().as_str())
.map_err(|c| self.clone().cancel(c))?; .map_err(|c| self.clone().cancel(c))?;
@ -496,7 +490,7 @@ impl SasState<Started> {
other_device: ReadOnlyDevice, other_device: ReadOnlyDevice,
other_identity: Option<UserIdentities>, other_identity: Option<UserIdentities>,
content: impl Into<StartContent>, content: impl Into<StartContent>,
) -> Result<SasState<Started>, SasState<Canceled>> { ) -> Result<SasState<Started>, SasState<Cancelled>> {
Self::from_start_helper(account, other_device, other_identity, &content.into()) Self::from_start_helper(account, other_device, other_identity, &content.into())
} }
@ -505,7 +499,7 @@ impl SasState<Started> {
other_device: ReadOnlyDevice, other_device: ReadOnlyDevice,
other_identity: Option<UserIdentities>, other_identity: Option<UserIdentities>,
content: &StartContent, content: &StartContent,
) -> Result<SasState<Started>, SasState<Canceled>> { ) -> Result<SasState<Started>, SasState<Cancelled>> {
let canceled = || SasState { let canceled = || SasState {
inner: Arc::new(Mutex::new(OlmSas::new())), inner: Arc::new(Mutex::new(OlmSas::new())),
@ -519,7 +513,7 @@ impl SasState<Started> {
}, },
verification_flow_id: content.flow_id().into(), verification_flow_id: content.flow_id().into(),
state: Arc::new(Canceled::new(CancelCode::UnknownMethod)), state: Arc::new(Cancelled::new(CancelCode::UnknownMethod)),
}; };
if let StartMethod::SasV1(method_content) = content.method() { if let StartMethod::SasV1(method_content) = content.method() {
@ -608,7 +602,7 @@ impl SasState<Started> {
self, self,
sender: &UserId, sender: &UserId,
content: impl Into<KeyContent>, content: impl Into<KeyContent>,
) -> Result<SasState<KeyReceived>, SasState<Canceled>> { ) -> Result<SasState<KeyReceived>, SasState<Cancelled>> {
let content = content.into(); let content = content.into();
self.check_event(&sender, &content.flow_id().as_str()) self.check_event(&sender, &content.flow_id().as_str())
@ -650,7 +644,7 @@ impl SasState<Accepted> {
self, self,
sender: &UserId, sender: &UserId,
content: impl Into<KeyContent>, content: impl Into<KeyContent>,
) -> Result<SasState<KeyReceived>, SasState<Canceled>> { ) -> Result<SasState<KeyReceived>, SasState<Cancelled>> {
let content = content.into(); let content = content.into();
self.check_event(&sender, content.flow_id().as_str()) self.check_event(&sender, content.flow_id().as_str())
@ -783,7 +777,7 @@ impl SasState<KeyReceived> {
self, self,
sender: &UserId, sender: &UserId,
content: impl Into<MacContent>, content: impl Into<MacContent>,
) -> Result<SasState<MacReceived>, SasState<Canceled>> { ) -> Result<SasState<MacReceived>, SasState<Cancelled>> {
let content = content.into(); let content = content.into();
self.check_event(&sender, content.flow_id().as_str()) self.check_event(&sender, content.flow_id().as_str())
@ -844,7 +838,7 @@ impl SasState<Confirmed> {
self, self,
sender: &UserId, sender: &UserId,
content: impl Into<MacContent>, content: impl Into<MacContent>,
) -> Result<SasState<Done>, SasState<Canceled>> { ) -> Result<SasState<Done>, SasState<Cancelled>> {
let content = content.into(); let content = content.into();
self.check_event(&sender, &content.flow_id().as_str()) self.check_event(&sender, &content.flow_id().as_str())
@ -886,7 +880,7 @@ impl SasState<Confirmed> {
self, self,
sender: &UserId, sender: &UserId,
content: impl Into<MacContent>, content: impl Into<MacContent>,
) -> Result<SasState<WaitingForDone>, SasState<Canceled>> { ) -> Result<SasState<WaitingForDone>, SasState<Cancelled>> {
let content = content.into(); let content = content.into();
self.check_event(&sender, &content.flow_id().as_str()) self.check_event(&sender, &content.flow_id().as_str())
@ -1036,7 +1030,7 @@ impl SasState<WaitingForDone> {
self, self,
sender: &UserId, sender: &UserId,
content: impl Into<DoneContent>, content: impl Into<DoneContent>,
) -> Result<SasState<Done>, SasState<Canceled>> { ) -> Result<SasState<Done>, SasState<Cancelled>> {
let content = content.into(); let content = content.into();
self.check_event(&sender, &content.flow_id().as_str()) self.check_event(&sender, &content.flow_id().as_str())
@ -1088,51 +1082,9 @@ impl SasState<Done> {
} }
} }
impl Canceled { impl SasState<Cancelled> {
fn new(code: CancelCode) -> Canceled {
let reason = match code {
CancelCode::Accepted => {
"A m.key.verification.request was accepted by a different device."
}
CancelCode::InvalidMessage => "The received message was invalid.",
CancelCode::KeyMismatch => "The expected key did not match the verified one",
CancelCode::Timeout => "The verification process timed out.",
CancelCode::UnexpectedMessage => "The device received an unexpected message.",
CancelCode::UnknownMethod => {
"The device does not know how to handle the requested method."
}
CancelCode::UnknownTransaction => {
"The device does not know about the given transaction ID."
}
CancelCode::User => "The user cancelled the verification.",
CancelCode::UserMismatch => "The expected user did not match the verified user",
_ => unimplemented!(),
};
Canceled { cancel_code: code, reason }
}
}
impl SasState<Canceled> {
pub fn as_content(&self) -> CancelContent { pub fn as_content(&self) -> CancelContent {
match self.verification_flow_id.as_ref() { self.state.as_content(&self.verification_flow_id)
FlowId::ToDevice(s) => CancelToDeviceEventContent::new(
s.clone(),
self.state.reason.to_string(),
self.state.cancel_code.clone(),
)
.into(),
FlowId::InRoom(r, e) => (
r.clone(),
CancelEventContent::new(
self.state.reason.to_string(),
self.state.cancel_code.clone(),
Relation::new(e.clone()),
),
)
.into(),
}
} }
} }