crypto: Remember who cancelled the verification
This seems to be of limited use considering that people can just see the sender of the cancellation event or they perform the cancellation themselves using the cancel() method but EA seems to want this.master
parent
d4e80883dc
commit
af084528c8
|
@ -167,12 +167,13 @@ impl Done {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Cancelled {
|
||||
cancelled_by_us: bool,
|
||||
cancel_code: CancelCode,
|
||||
reason: &'static str,
|
||||
}
|
||||
|
||||
impl Cancelled {
|
||||
fn new(code: CancelCode) -> Self {
|
||||
fn new(cancelled_by_us: bool, code: CancelCode) -> Self {
|
||||
let reason = match code {
|
||||
CancelCode::Accepted => {
|
||||
"A m.key.verification.request was accepted by a different device."
|
||||
|
@ -192,7 +193,7 @@ impl Cancelled {
|
|||
_ => "Unknown cancel reason",
|
||||
};
|
||||
|
||||
Self { cancel_code: code, reason }
|
||||
Self { cancelled_by_us, cancel_code: code, reason }
|
||||
}
|
||||
|
||||
pub fn as_content(&self, flow_id: &FlowId) -> OutgoingContent {
|
||||
|
|
|
@ -210,7 +210,7 @@ impl QrVerification {
|
|||
}
|
||||
|
||||
fn cancel_with_code(&self, code: CancelCode) -> Option<OutgoingContent> {
|
||||
let new_state = QrState::<Cancelled>::new(code);
|
||||
let new_state = QrState::<Cancelled>::new(true, code);
|
||||
let content = new_state.as_content(self.flow_id());
|
||||
|
||||
let mut state = self.state.lock().unwrap();
|
||||
|
@ -243,7 +243,7 @@ impl QrVerification {
|
|||
match self.identities.mark_as_done(Some(&devices), Some(&identities)).await? {
|
||||
VerificationResult::Ok => (None, None),
|
||||
VerificationResult::Cancel(c) => {
|
||||
let canceled = QrState::<Cancelled>::new(c);
|
||||
let canceled = QrState::<Cancelled>::new(false, c);
|
||||
let content = canceled.as_content(self.flow_id());
|
||||
new_state = InnerState::Cancelled(canceled);
|
||||
(Some(content), None)
|
||||
|
@ -594,8 +594,8 @@ impl QrState<Scanned> {
|
|||
}
|
||||
|
||||
impl QrState<Cancelled> {
|
||||
fn new(cancel_code: CancelCode) -> Self {
|
||||
QrState { state: Cancelled::new(cancel_code) }
|
||||
fn new(cancelled_by_us: bool, cancel_code: CancelCode) -> Self {
|
||||
QrState { state: Cancelled::new(cancelled_by_us, cancel_code) }
|
||||
}
|
||||
|
||||
fn as_content(&self, flow_id: &FlowId) -> OutgoingContent {
|
||||
|
@ -614,10 +614,10 @@ impl QrState<Created> {
|
|||
if self.state.secret == m.secret {
|
||||
Ok(QrState { state: Scanned {} })
|
||||
} else {
|
||||
Err(QrState::<Cancelled>::new(CancelCode::KeyMismatch))
|
||||
Err(QrState::<Cancelled>::new(false, CancelCode::KeyMismatch))
|
||||
}
|
||||
}
|
||||
_ => Err(QrState::<Cancelled>::new(CancelCode::UnknownMethod)),
|
||||
_ => Err(QrState::<Cancelled>::new(false, CancelCode::UnknownMethod)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -376,7 +376,7 @@ impl VerificationRequest {
|
|||
/// Cancel the verification request
|
||||
pub fn cancel(&self) -> Option<OutgoingVerificationRequest> {
|
||||
let mut inner = self.inner.lock().unwrap();
|
||||
inner.cancel(&CancelCode::User);
|
||||
inner.cancel(true, &CancelCode::User);
|
||||
|
||||
let content = if let InnerRequest::Cancelled(c) = &*inner {
|
||||
Some(c.state.as_content(self.flow_id()))
|
||||
|
@ -436,7 +436,7 @@ impl VerificationRequest {
|
|||
pub(crate) fn receive_cancel(&self, sender: &UserId, content: &CancelContent<'_>) {
|
||||
if sender == self.other_user() {
|
||||
let mut inner = self.inner.lock().unwrap().clone();
|
||||
inner.cancel(content.cancel_code());
|
||||
inner.cancel(false, content.cancel_code());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -539,12 +539,12 @@ impl InnerRequest {
|
|||
})
|
||||
}
|
||||
|
||||
fn cancel(&mut self, cancel_code: &CancelCode) {
|
||||
fn cancel(&mut self, cancelled_by_us: bool, cancel_code: &CancelCode) {
|
||||
*self = InnerRequest::Cancelled(match self {
|
||||
InnerRequest::Created(s) => s.clone().into_canceled(cancel_code),
|
||||
InnerRequest::Requested(s) => s.clone().into_canceled(cancel_code),
|
||||
InnerRequest::Ready(s) => s.clone().into_canceled(cancel_code),
|
||||
InnerRequest::Passive(s) => s.clone().into_canceled(cancel_code),
|
||||
InnerRequest::Created(s) => s.clone().into_canceled(cancelled_by_us, cancel_code),
|
||||
InnerRequest::Requested(s) => s.clone().into_canceled(cancelled_by_us, cancel_code),
|
||||
InnerRequest::Ready(s) => s.clone().into_canceled(cancelled_by_us, cancel_code),
|
||||
InnerRequest::Passive(s) => s.clone().into_canceled(cancelled_by_us, cancel_code),
|
||||
InnerRequest::Done(_) => return,
|
||||
InnerRequest::Cancelled(_) => return,
|
||||
})
|
||||
|
@ -604,7 +604,11 @@ impl<S: Clone> RequestState<S> {
|
|||
}
|
||||
}
|
||||
|
||||
fn into_canceled(self, cancel_code: &CancelCode) -> RequestState<Cancelled> {
|
||||
fn into_canceled(
|
||||
self,
|
||||
cancelled_by_us: bool,
|
||||
cancel_code: &CancelCode,
|
||||
) -> RequestState<Cancelled> {
|
||||
RequestState::<Cancelled> {
|
||||
account: self.account,
|
||||
private_cross_signing_identity: self.private_cross_signing_identity,
|
||||
|
@ -612,7 +616,7 @@ impl<S: Clone> RequestState<S> {
|
|||
store: self.store,
|
||||
flow_id: self.flow_id,
|
||||
other_user_id: self.other_user_id,
|
||||
state: Cancelled::new(cancel_code.clone()),
|
||||
state: Cancelled::new(cancelled_by_us, cancel_code.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,13 +168,17 @@ impl InnerSas {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn cancel(self, code: CancelCode) -> (InnerSas, Option<OutgoingContent>) {
|
||||
pub fn cancel(
|
||||
self,
|
||||
cancelled_by_us: bool,
|
||||
code: CancelCode,
|
||||
) -> (InnerSas, Option<OutgoingContent>) {
|
||||
let sas = match self {
|
||||
InnerSas::Created(s) => s.cancel(code),
|
||||
InnerSas::Started(s) => s.cancel(code),
|
||||
InnerSas::Accepted(s) => s.cancel(code),
|
||||
InnerSas::KeyReceived(s) => s.cancel(code),
|
||||
InnerSas::MacReceived(s) => s.cancel(code),
|
||||
InnerSas::Created(s) => s.cancel(cancelled_by_us, code),
|
||||
InnerSas::Started(s) => s.cancel(cancelled_by_us, code),
|
||||
InnerSas::Accepted(s) => s.cancel(cancelled_by_us, code),
|
||||
InnerSas::KeyReceived(s) => s.cancel(cancelled_by_us, code),
|
||||
InnerSas::MacReceived(s) => s.cancel(cancelled_by_us, code),
|
||||
_ => return (self, None),
|
||||
};
|
||||
|
||||
|
@ -230,7 +234,7 @@ impl InnerSas {
|
|||
}
|
||||
}
|
||||
AnyVerificationContent::Cancel(c) => {
|
||||
let (sas, _) = self.cancel(c.cancel_code().to_owned());
|
||||
let (sas, _) = self.cancel(false, c.cancel_code().to_owned());
|
||||
(sas, None)
|
||||
}
|
||||
AnyVerificationContent::Key(c) => match self {
|
||||
|
@ -324,6 +328,14 @@ impl InnerSas {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn cancelled_by_us(&self) -> Option<bool> {
|
||||
if let InnerSas::Cancelled(c) = self {
|
||||
Some(c.state.cancelled_by_us)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn timed_out(&self) -> bool {
|
||||
match self {
|
||||
InnerSas::Created(s) => s.timed_out(),
|
||||
|
|
|
@ -115,6 +115,11 @@ impl Sas {
|
|||
self.inner.lock().unwrap().cancel_code()
|
||||
}
|
||||
|
||||
/// Has the verification flow been cancelled by us.
|
||||
pub fn cancelled_by_us(&self) -> Option<bool> {
|
||||
self.inner.lock().unwrap().cancelled_by_us()
|
||||
}
|
||||
|
||||
/// Did we initiate the verification flow.
|
||||
pub fn we_started(&self) -> bool {
|
||||
self.we_started
|
||||
|
@ -390,7 +395,7 @@ impl Sas {
|
|||
pub fn cancel_with_code(&self, code: CancelCode) -> Option<OutgoingVerificationRequest> {
|
||||
let mut guard = self.inner.lock().unwrap();
|
||||
let sas: InnerSas = (*guard).clone();
|
||||
let (sas, content) = sas.cancel(code);
|
||||
let (sas, content) = sas.cancel(true, code);
|
||||
*guard = sas;
|
||||
content.map(|c| match c {
|
||||
OutgoingContent::Room(room_id, content) => {
|
||||
|
|
|
@ -298,14 +298,14 @@ impl<S: Clone> SasState<S> {
|
|||
self.ids.other_device.clone()
|
||||
}
|
||||
|
||||
pub fn cancel(self, cancel_code: CancelCode) -> SasState<Cancelled> {
|
||||
pub fn cancel(self, cancelled_by_us: bool, cancel_code: CancelCode) -> SasState<Cancelled> {
|
||||
SasState {
|
||||
inner: self.inner,
|
||||
ids: self.ids,
|
||||
creation_time: self.creation_time,
|
||||
last_event_time: self.last_event_time,
|
||||
verification_flow_id: self.verification_flow_id,
|
||||
state: Arc::new(Cancelled::new(cancel_code)),
|
||||
state: Arc::new(Cancelled::new(cancelled_by_us, cancel_code)),
|
||||
started_from_request: self.started_from_request,
|
||||
}
|
||||
}
|
||||
|
@ -444,11 +444,11 @@ impl SasState<Created> {
|
|||
sender: &UserId,
|
||||
content: &AcceptContent,
|
||||
) -> Result<SasState<Accepted>, SasState<Cancelled>> {
|
||||
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(c))?;
|
||||
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(true, c))?;
|
||||
|
||||
if let AcceptMethod::SasV1(content) = content.method() {
|
||||
let accepted_protocols =
|
||||
AcceptedProtocols::try_from(content.clone()).map_err(|c| self.clone().cancel(c))?;
|
||||
let accepted_protocols = AcceptedProtocols::try_from(content.clone())
|
||||
.map_err(|c| self.clone().cancel(true, c))?;
|
||||
|
||||
let start_content = self.as_content().into();
|
||||
|
||||
|
@ -466,7 +466,7 @@ impl SasState<Created> {
|
|||
}),
|
||||
})
|
||||
} else {
|
||||
Err(self.cancel(CancelCode::UnknownMethod))
|
||||
Err(self.cancel(true, CancelCode::UnknownMethod))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -509,7 +509,7 @@ impl SasState<Started> {
|
|||
},
|
||||
|
||||
verification_flow_id: flow_id.clone(),
|
||||
state: Arc::new(Cancelled::new(CancelCode::UnknownMethod)),
|
||||
state: Arc::new(Cancelled::new(true, CancelCode::UnknownMethod)),
|
||||
};
|
||||
|
||||
if let StartMethod::SasV1(method_content) = content.method() {
|
||||
|
@ -600,7 +600,7 @@ impl SasState<Started> {
|
|||
sender: &UserId,
|
||||
content: &KeyContent,
|
||||
) -> Result<SasState<KeyReceived>, SasState<Cancelled>> {
|
||||
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(c))?;
|
||||
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(true, c))?;
|
||||
|
||||
let their_pubkey = content.public_key().to_owned();
|
||||
|
||||
|
@ -640,7 +640,7 @@ impl SasState<Accepted> {
|
|||
sender: &UserId,
|
||||
content: &KeyContent,
|
||||
) -> Result<SasState<KeyReceived>, SasState<Cancelled>> {
|
||||
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(c))?;
|
||||
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(true, c))?;
|
||||
|
||||
let commitment = calculate_commitment(
|
||||
content.public_key(),
|
||||
|
@ -648,7 +648,7 @@ impl SasState<Accepted> {
|
|||
);
|
||||
|
||||
if self.state.commitment != commitment {
|
||||
Err(self.cancel(CancelCode::InvalidMessage))
|
||||
Err(self.cancel(true, CancelCode::InvalidMessage))
|
||||
} else {
|
||||
let their_pubkey = content.public_key().to_owned();
|
||||
|
||||
|
@ -777,7 +777,7 @@ impl SasState<KeyReceived> {
|
|||
sender: &UserId,
|
||||
content: &MacContent,
|
||||
) -> Result<SasState<MacReceived>, SasState<Cancelled>> {
|
||||
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(c))?;
|
||||
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(true, c))?;
|
||||
|
||||
let (devices, master_keys) = receive_mac_event(
|
||||
&self.inner.lock().unwrap(),
|
||||
|
@ -786,7 +786,7 @@ impl SasState<KeyReceived> {
|
|||
sender,
|
||||
content,
|
||||
)
|
||||
.map_err(|c| self.clone().cancel(c))?;
|
||||
.map_err(|c| self.clone().cancel(true, c))?;
|
||||
|
||||
Ok(SasState {
|
||||
inner: self.inner,
|
||||
|
@ -837,7 +837,7 @@ impl SasState<Confirmed> {
|
|||
sender: &UserId,
|
||||
content: &MacContent,
|
||||
) -> Result<SasState<Done>, SasState<Cancelled>> {
|
||||
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(c))?;
|
||||
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(true, c))?;
|
||||
|
||||
let (devices, master_keys) = receive_mac_event(
|
||||
&self.inner.lock().unwrap(),
|
||||
|
@ -846,7 +846,7 @@ impl SasState<Confirmed> {
|
|||
sender,
|
||||
content,
|
||||
)
|
||||
.map_err(|c| self.clone().cancel(c))?;
|
||||
.map_err(|c| self.clone().cancel(true, c))?;
|
||||
|
||||
Ok(SasState {
|
||||
inner: self.inner,
|
||||
|
@ -877,7 +877,7 @@ impl SasState<Confirmed> {
|
|||
sender: &UserId,
|
||||
content: &MacContent,
|
||||
) -> Result<SasState<WaitingForDone>, SasState<Cancelled>> {
|
||||
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(c))?;
|
||||
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(true, c))?;
|
||||
|
||||
let (devices, master_keys) = receive_mac_event(
|
||||
&self.inner.lock().unwrap(),
|
||||
|
@ -886,7 +886,7 @@ impl SasState<Confirmed> {
|
|||
sender,
|
||||
content,
|
||||
)
|
||||
.map_err(|c| self.clone().cancel(c))?;
|
||||
.map_err(|c| self.clone().cancel(true, c))?;
|
||||
|
||||
Ok(SasState {
|
||||
inner: self.inner,
|
||||
|
@ -1032,7 +1032,7 @@ impl SasState<WaitingForDone> {
|
|||
sender: &UserId,
|
||||
content: &DoneContent,
|
||||
) -> Result<SasState<Done>, SasState<Cancelled>> {
|
||||
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(c))?;
|
||||
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(true, c))?;
|
||||
|
||||
Ok(SasState {
|
||||
inner: self.inner,
|
||||
|
|
Loading…
Reference in New Issue