crypto: Handle all the cancel states.

master
Damir Jelić 2020-07-27 15:56:28 +02:00
parent 5471c07244
commit 6e67585bf6
1 changed files with 25 additions and 15 deletions

View File

@ -103,7 +103,7 @@ impl Sas {
account: Account, account: Account,
other_device: Device, other_device: Device,
event: &ToDeviceEvent<StartEventContent>, event: &ToDeviceEvent<StartEventContent>,
) -> Result<Sas, CancelEventContent> { ) -> Result<Sas, AnyToDeviceEventContent> {
let inner = InnerSas::from_start_event(account.clone(), other_device.clone(), event)?; let inner = InnerSas::from_start_event(account.clone(), other_device.clone(), event)?;
Ok(Sas { Ok(Sas {
inner: Arc::new(Mutex::new(inner)), inner: Arc::new(Mutex::new(inner)),
@ -177,7 +177,7 @@ impl InnerSas {
account: Account, account: Account,
other_device: Device, other_device: Device,
event: &ToDeviceEvent<StartEventContent>, event: &ToDeviceEvent<StartEventContent>,
) -> Result<InnerSas, CancelEventContent> { ) -> Result<InnerSas, AnyToDeviceEventContent> {
match SasState::<Started>::from_start_event(account, other_device, event) { match SasState::<Started>::from_start_event(account, other_device, event) {
Ok(s) => Ok(InnerSas::Started(s)), Ok(s) => Ok(InnerSas::Started(s)),
Err(s) => Err(s.as_content()), Err(s) => Err(s.as_content()),
@ -224,8 +224,7 @@ impl InnerSas {
) )
} }
Err(s) => { Err(s) => {
let content = let content = s.as_content();
AnyToDeviceEventContent::KeyVerificationCancel(s.as_content());
(InnerSas::Canceled(s), Some(content)) (InnerSas::Canceled(s), Some(content))
} }
} }
@ -236,7 +235,10 @@ impl InnerSas {
AnyToDeviceEvent::KeyVerificationKey(e) => match self { AnyToDeviceEvent::KeyVerificationKey(e) => match self {
InnerSas::Accepted(s) => match s.into_key_received(e) { InnerSas::Accepted(s) => match s.into_key_received(e) {
Ok(s) => (InnerSas::KeyRecieved(s), None), Ok(s) => (InnerSas::KeyRecieved(s), None),
Err(s) => (InnerSas::Canceled(s), None), Err(s) => {
let content = s.as_content();
(InnerSas::Canceled(s), Some(content))
}
}, },
InnerSas::Started(s) => match s.into_key_received(e) { InnerSas::Started(s) => match s.into_key_received(e) {
Ok(s) => { Ok(s) => {
@ -246,18 +248,27 @@ impl InnerSas {
Some(AnyToDeviceEventContent::KeyVerificationKey(content)), Some(AnyToDeviceEventContent::KeyVerificationKey(content)),
) )
} }
Err(s) => (InnerSas::Canceled(s), None), Err(s) => {
let content = s.as_content();
(InnerSas::Canceled(s), Some(content))
}
}, },
_ => (self, None), _ => (self, None),
}, },
AnyToDeviceEvent::KeyVerificationMac(e) => match self { AnyToDeviceEvent::KeyVerificationMac(e) => match self {
InnerSas::KeyRecieved(s) => match s.into_mac_received(e) { InnerSas::KeyRecieved(s) => match s.into_mac_received(e) {
Ok(s) => (InnerSas::MacReceived(s), None), Ok(s) => (InnerSas::MacReceived(s), None),
Err(s) => (InnerSas::Canceled(s), None), Err(s) => {
let content = s.as_content();
(InnerSas::Canceled(s), Some(content))
}
}, },
InnerSas::Confirmed(s) => match s.into_done(e) { InnerSas::Confirmed(s) => match s.into_done(e) {
Ok(s) => (InnerSas::Done(s), None), Ok(s) => (InnerSas::Done(s), None),
Err(s) => (InnerSas::Canceled(s), None), Err(s) => {
let content = s.as_content();
(InnerSas::Canceled(s), Some(content))
}
}, },
_ => (self, None), _ => (self, None),
}, },
@ -337,10 +348,6 @@ impl From<AcceptEventContent> for AcceptedProtocols {
} }
} }
// TODO each of our state transitions can fail and return a canceled state. We
// need to check the senders at each transition, the commitment, the
// verification flow id (transaction id).
/// A type level state machine modeling the Sas flow. /// A type level state machine modeling the Sas flow.
/// ///
/// This is the generic struc holding common data between the different states /// This is the generic struc holding common data between the different states
@ -708,6 +715,9 @@ impl SasState<Accepted> {
self, self,
event: &mut ToDeviceEvent<KeyEventContent>, event: &mut ToDeviceEvent<KeyEventContent>,
) -> Result<SasState<KeyReceived>, SasState<Canceled>> { ) -> Result<SasState<KeyReceived>, SasState<Canceled>> {
self.check_sender_and_txid(&event.sender, &event.content.transaction_id)
.map_err(|c| self.clone().cancel(c))?;
let utility = OlmUtility::new(); let utility = OlmUtility::new();
let commitment = utility.sha256_utf8_msg(&format!( let commitment = utility.sha256_utf8_msg(&format!(
"{}{}", "{}{}",
@ -975,12 +985,12 @@ impl Canceled {
} }
impl SasState<Canceled> { impl SasState<Canceled> {
fn as_content(&self) -> CancelEventContent { fn as_content(&self) -> AnyToDeviceEventContent {
CancelEventContent { AnyToDeviceEventContent::KeyVerificationCancel(CancelEventContent {
transaction_id: self.verification_flow_id.to_string(), transaction_id: self.verification_flow_id.to_string(),
reason: self.state.reason.to_string(), reason: self.state.reason.to_string(),
code: self.state.cancel_code.clone(), code: self.state.cancel_code.clone(),
} })
} }
} }