crypto: Make the cancelations output only CancelContents.
parent
b6e28e2280
commit
79102b3390
|
@ -135,19 +135,42 @@ async fn login(
|
||||||
if !initial.load(Ordering::SeqCst) {
|
if !initial.load(Ordering::SeqCst) {
|
||||||
for (_room_id, room_info) in response.rooms.join {
|
for (_room_id, room_info) in response.rooms.join {
|
||||||
for event in room_info.timeline.events {
|
for event in room_info.timeline.events {
|
||||||
if let Ok(AnySyncRoomEvent::Message(AnySyncMessageEvent::RoomMessage(m))) =
|
if let AnySyncRoomEvent::Message(event) = event.deserialize().unwrap() {
|
||||||
event.deserialize()
|
match event {
|
||||||
{
|
AnySyncMessageEvent::RoomMessage(m) => {
|
||||||
if let MessageEventContent::VerificationRequest(_) = &m.content {
|
if let MessageEventContent::VerificationRequest(_) = &m.content
|
||||||
let request = client
|
{
|
||||||
.get_verification_request(&m.event_id)
|
let request = client
|
||||||
.await
|
.get_verification_request(&m.event_id)
|
||||||
.expect("Request object wasn't created");
|
.await
|
||||||
|
.expect("Request object wasn't created");
|
||||||
|
|
||||||
request
|
request
|
||||||
.accept()
|
.accept()
|
||||||
.await
|
.await
|
||||||
.expect("Can't accept verification request");
|
.expect("Can't accept verification request");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AnySyncMessageEvent::KeyVerificationKey(e) => {
|
||||||
|
let sas = client
|
||||||
|
.get_verification(&e.content.relation.event_id.as_str())
|
||||||
|
.await
|
||||||
|
.expect("Sas object wasn't created");
|
||||||
|
|
||||||
|
tokio::spawn(wait_for_confirmation((*client).clone(), sas));
|
||||||
|
}
|
||||||
|
AnySyncMessageEvent::KeyVerificationMac(e) => {
|
||||||
|
let sas = client
|
||||||
|
.get_verification(&e.content.relation.event_id.as_str())
|
||||||
|
.await
|
||||||
|
.expect("Sas object wasn't created");
|
||||||
|
|
||||||
|
if sas.is_done() {
|
||||||
|
print_result(&sas);
|
||||||
|
print_devices(&e.sender, &client).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1160,7 +1160,7 @@ impl Client {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn room_send_helper(
|
pub(crate) async fn room_send_helper(
|
||||||
&self,
|
&self,
|
||||||
request: &RoomMessageRequest,
|
request: &RoomMessageRequest,
|
||||||
) -> Result<send_message_event::Response> {
|
) -> Result<send_message_event::Response> {
|
||||||
|
|
|
@ -39,10 +39,18 @@ impl Sas {
|
||||||
|
|
||||||
/// Confirm that the short auth strings match on both sides.
|
/// Confirm that the short auth strings match on both sides.
|
||||||
pub async fn confirm(&self) -> Result<()> {
|
pub async fn confirm(&self) -> Result<()> {
|
||||||
let (to_device, signature) = self.inner.confirm().await?;
|
let (request, signature) = self.inner.confirm().await?;
|
||||||
|
|
||||||
if let Some(request) = to_device {
|
match request {
|
||||||
self.client.send_to_device(&request).await?;
|
Some(OutgoingVerificationRequest::InRoom(r)) => {
|
||||||
|
self.client.room_send_helper(&r).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(OutgoingVerificationRequest::ToDevice(r)) => {
|
||||||
|
self.client.send_to_device(&r).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
None => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(s) = signature {
|
if let Some(s) = signature {
|
||||||
|
@ -55,7 +63,14 @@ impl Sas {
|
||||||
/// Cancel the interactive verification flow.
|
/// Cancel the interactive verification flow.
|
||||||
pub async fn cancel(&self) -> Result<()> {
|
pub async fn cancel(&self) -> Result<()> {
|
||||||
if let Some(request) = self.inner.cancel() {
|
if let Some(request) = self.inner.cancel() {
|
||||||
self.client.send_to_device(&request).await?;
|
match request {
|
||||||
|
OutgoingVerificationRequest::ToDevice(r) => {
|
||||||
|
self.client.send_to_device(&r).await?;
|
||||||
|
}
|
||||||
|
OutgoingVerificationRequest::InRoom(r) => {
|
||||||
|
self.client.room_send_helper(&r).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -166,6 +166,24 @@ impl From<SignatureUploadRequest> for OutgoingRequests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<OutgoingVerificationRequest> for OutgoingRequest {
|
||||||
|
fn from(r: OutgoingVerificationRequest) -> Self {
|
||||||
|
Self {
|
||||||
|
request_id: r.request_id(),
|
||||||
|
request: Arc::new(r.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SignatureUploadRequest> for OutgoingRequest {
|
||||||
|
fn from(r: SignatureUploadRequest) -> Self {
|
||||||
|
Self {
|
||||||
|
request_id: Uuid::new_v4(),
|
||||||
|
request: Arc::new(r.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Enum over all the incoming responses we need to receive.
|
/// Enum over all the incoming responses we need to receive.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum IncomingResponse<'a> {
|
pub enum IncomingResponse<'a> {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::{convert::TryFrom, sync::Arc};
|
||||||
|
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ use tracing::{info, trace, warn};
|
||||||
|
|
||||||
use matrix_sdk_common::{
|
use matrix_sdk_common::{
|
||||||
events::{
|
events::{
|
||||||
room::message::MessageEventContent, AnySyncMessageEvent, AnySyncRoomEvent,
|
room::message::MessageEventContent, AnyMessageEvent, AnySyncMessageEvent, AnySyncRoomEvent,
|
||||||
AnyToDeviceEvent, AnyToDeviceEventContent,
|
AnyToDeviceEvent, AnyToDeviceEventContent,
|
||||||
},
|
},
|
||||||
identifiers::{DeviceId, EventId, RoomId, UserId},
|
identifiers::{DeviceId, EventId, RoomId, UserId},
|
||||||
|
@ -112,8 +112,19 @@ impl VerificationMachine {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_sas(&self, transaction_id: &str) -> Option<Sas> {
|
pub fn get_sas(&self, transaction_id: &str) -> Option<Sas> {
|
||||||
#[allow(clippy::map_clone)]
|
let sas = if let Ok(e) = EventId::try_from(transaction_id) {
|
||||||
self.verifications.get(transaction_id).map(|s| s.clone())
|
#[allow(clippy::map_clone)]
|
||||||
|
self.room_verifications.get(&e).map(|s| s.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
if sas.is_some() {
|
||||||
|
sas
|
||||||
|
} else {
|
||||||
|
#[allow(clippy::map_clone)]
|
||||||
|
self.verifications.get(transaction_id).map(|s| s.clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn queue_up_content(
|
fn queue_up_content(
|
||||||
|
@ -155,6 +166,13 @@ impl VerificationMachine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn receive_room_event_helper(&self, sas: &Sas, event: &AnyMessageEvent) {
|
||||||
|
if let Some(c) = sas.receive_room_event(event) {
|
||||||
|
self.queue_up_content(sas.other_user_id(), sas.other_device_id(), c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn receive_event_helper(&self, sas: &Sas, event: &AnyToDeviceEvent) {
|
fn receive_event_helper(&self, sas: &Sas, event: &AnyToDeviceEvent) {
|
||||||
if let Some(c) = sas.receive_event(event) {
|
if let Some(c) = sas.receive_event(event) {
|
||||||
self.queue_up_content(sas.other_user_id(), sas.other_device_id(), c);
|
self.queue_up_content(sas.other_user_id(), sas.other_device_id(), c);
|
||||||
|
@ -188,9 +206,9 @@ impl VerificationMachine {
|
||||||
for sas in self.verifications.iter() {
|
for sas in self.verifications.iter() {
|
||||||
if let Some(r) = sas.cancel_if_timed_out() {
|
if let Some(r) = sas.cancel_if_timed_out() {
|
||||||
self.outgoing_to_device_messages.insert(
|
self.outgoing_to_device_messages.insert(
|
||||||
r.txn_id,
|
r.request_id(),
|
||||||
OutgoingRequest {
|
OutgoingRequest {
|
||||||
request_id: r.txn_id,
|
request_id: r.request_id(),
|
||||||
request: Arc::new(r.into()),
|
request: Arc::new(r.into()),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -204,6 +222,12 @@ impl VerificationMachine {
|
||||||
event: &AnySyncRoomEvent,
|
event: &AnySyncRoomEvent,
|
||||||
) -> Result<(), CryptoStoreError> {
|
) -> Result<(), CryptoStoreError> {
|
||||||
if let AnySyncRoomEvent::Message(m) = event {
|
if let AnySyncRoomEvent::Message(m) = event {
|
||||||
|
// Since this are room events we will get events that we send out on
|
||||||
|
// our own as well.
|
||||||
|
if m.sender() == self.account.user_id() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
match m {
|
match m {
|
||||||
AnySyncMessageEvent::RoomMessage(m) => {
|
AnySyncMessageEvent::RoomMessage(m) => {
|
||||||
if let MessageEventContent::VerificationRequest(r) = &m.content {
|
if let MessageEventContent::VerificationRequest(r) = &m.content {
|
||||||
|
@ -245,25 +269,19 @@ impl VerificationMachine {
|
||||||
self.store.get_user_identity(&e.sender).await?,
|
self.store.get_user_identity(&e.sender).await?,
|
||||||
) {
|
) {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
// TODO we need to queue up the accept event
|
|
||||||
// here.
|
|
||||||
info!(
|
info!(
|
||||||
"Started a new SAS verification, \
|
"Started a new SAS verification, \
|
||||||
automatically accepting because of in-room"
|
automatically accepting because of in-room"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// TODO remove this unwrap
|
||||||
let accept_request = s.accept().unwrap();
|
let accept_request = s.accept().unwrap();
|
||||||
|
|
||||||
self.room_verifications
|
self.room_verifications
|
||||||
.insert(e.content.relation.event_id.clone(), s);
|
.insert(e.content.relation.event_id.clone(), s);
|
||||||
|
|
||||||
self.outgoing_room_messages.insert(
|
self.outgoing_room_messages
|
||||||
accept_request.request_id(),
|
.insert(accept_request.request_id(), accept_request.into());
|
||||||
OutgoingRequest {
|
|
||||||
request_id: accept_request.request_id(),
|
|
||||||
request: Arc::new(accept_request.into()),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Err(c) => {
|
Err(c) => {
|
||||||
warn!(
|
warn!(
|
||||||
|
@ -276,6 +294,38 @@ impl VerificationMachine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AnySyncMessageEvent::KeyVerificationKey(e) => {
|
||||||
|
if let Some(s) = self.room_verifications.get(&e.content.relation.event_id) {
|
||||||
|
self.receive_room_event_helper(
|
||||||
|
&s,
|
||||||
|
&m.clone().into_full_event(room_id.clone()),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
AnySyncMessageEvent::KeyVerificationMac(e) => {
|
||||||
|
if let Some(s) = self.room_verifications.get(&e.content.relation.event_id) {
|
||||||
|
self.receive_room_event_helper(
|
||||||
|
&s,
|
||||||
|
&m.clone().into_full_event(room_id.clone()),
|
||||||
|
);
|
||||||
|
|
||||||
|
if s.is_done() {
|
||||||
|
match s.mark_as_done().await? {
|
||||||
|
VerificationResult::Ok => (),
|
||||||
|
VerificationResult::Cancel(r) => {
|
||||||
|
self.outgoing_to_device_messages
|
||||||
|
.insert(r.request_id(), r.into());
|
||||||
|
}
|
||||||
|
VerificationResult::SignatureUpload(r) => {
|
||||||
|
let request: OutgoingRequest = r.into();
|
||||||
|
|
||||||
|
self.outgoing_to_device_messages
|
||||||
|
.insert(request.request_id, request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -350,9 +400,9 @@ impl VerificationMachine {
|
||||||
VerificationResult::Ok => (),
|
VerificationResult::Ok => (),
|
||||||
VerificationResult::Cancel(r) => {
|
VerificationResult::Cancel(r) => {
|
||||||
self.outgoing_to_device_messages.insert(
|
self.outgoing_to_device_messages.insert(
|
||||||
r.txn_id,
|
r.request_id(),
|
||||||
OutgoingRequest {
|
OutgoingRequest {
|
||||||
request_id: r.txn_id,
|
request_id: r.request_id(),
|
||||||
request: Arc::new(r.into()),
|
request: Arc::new(r.into()),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -14,16 +14,18 @@
|
||||||
|
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use std::convert::TryInto;
|
use std::{collections::BTreeMap, convert::TryInto};
|
||||||
|
|
||||||
use matrix_sdk_common::{
|
use matrix_sdk_common::{
|
||||||
events::{
|
events::{
|
||||||
key::verification::{
|
key::verification::{
|
||||||
accept::{AcceptEventContent, AcceptToDeviceEventContent},
|
accept::{AcceptEventContent, AcceptToDeviceEventContent},
|
||||||
|
cancel::{CancelEventContent, CancelToDeviceEventContent},
|
||||||
|
key::{KeyEventContent, KeyToDeviceEventContent},
|
||||||
|
mac::{MacEventContent, MacToDeviceEventContent},
|
||||||
start::{StartEventContent, StartMethod, StartToDeviceEventContent},
|
start::{StartEventContent, StartMethod, StartToDeviceEventContent},
|
||||||
KeyAgreementProtocol,
|
|
||||||
},
|
},
|
||||||
AnyMessageEventContent, AnyToDeviceEventContent, MessageEvent, ToDeviceEvent,
|
AnyMessageEventContent, AnyToDeviceEventContent,
|
||||||
},
|
},
|
||||||
identifiers::RoomId,
|
identifiers::RoomId,
|
||||||
CanonicalJsonValue,
|
CanonicalJsonValue,
|
||||||
|
@ -95,6 +97,96 @@ impl From<(RoomId, AcceptEventContent)> for AcceptContent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum KeyContent {
|
||||||
|
ToDevice(KeyToDeviceEventContent),
|
||||||
|
Room(RoomId, KeyEventContent),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyContent {
|
||||||
|
pub fn flow_id(&self) -> FlowId {
|
||||||
|
match self {
|
||||||
|
KeyContent::ToDevice(c) => FlowId::ToDevice(c.transaction_id.clone()),
|
||||||
|
KeyContent::Room(r, c) => FlowId::InRoom(r.clone(), c.relation.event_id.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn public_key(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
KeyContent::ToDevice(c) => &c.key,
|
||||||
|
KeyContent::Room(_, c) => &c.key,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<KeyToDeviceEventContent> for KeyContent {
|
||||||
|
fn from(content: KeyToDeviceEventContent) -> Self {
|
||||||
|
KeyContent::ToDevice(content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(RoomId, KeyEventContent)> for KeyContent {
|
||||||
|
fn from(content: (RoomId, KeyEventContent)) -> Self {
|
||||||
|
KeyContent::Room(content.0, content.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum MacContent {
|
||||||
|
ToDevice(MacToDeviceEventContent),
|
||||||
|
Room(RoomId, MacEventContent),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MacContent {
|
||||||
|
pub fn flow_id(&self) -> FlowId {
|
||||||
|
match self {
|
||||||
|
MacContent::ToDevice(c) => FlowId::ToDevice(c.transaction_id.clone()),
|
||||||
|
MacContent::Room(r, c) => FlowId::InRoom(r.clone(), c.relation.event_id.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mac(&self) -> &BTreeMap<String, String> {
|
||||||
|
match self {
|
||||||
|
MacContent::ToDevice(c) => &c.mac,
|
||||||
|
MacContent::Room(_, c) => &c.mac,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn keys(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
MacContent::ToDevice(c) => &c.keys,
|
||||||
|
MacContent::Room(_, c) => &c.keys,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<MacToDeviceEventContent> for MacContent {
|
||||||
|
fn from(content: MacToDeviceEventContent) -> Self {
|
||||||
|
MacContent::ToDevice(content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(RoomId, MacEventContent)> for MacContent {
|
||||||
|
fn from(content: (RoomId, MacEventContent)) -> Self {
|
||||||
|
MacContent::Room(content.0, content.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum CancelContent {
|
||||||
|
ToDevice(CancelToDeviceEventContent),
|
||||||
|
Room(RoomId, CancelEventContent),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(RoomId, CancelEventContent)> for CancelContent {
|
||||||
|
fn from(content: (RoomId, CancelEventContent)) -> Self {
|
||||||
|
CancelContent::Room(content.0, content.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<CancelToDeviceEventContent> for CancelContent {
|
||||||
|
fn from(content: CancelToDeviceEventContent) -> Self {
|
||||||
|
CancelContent::ToDevice(content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum OutgoingContent {
|
pub enum OutgoingContent {
|
||||||
Room(RoomId, AnyMessageEventContent),
|
Room(RoomId, AnyMessageEventContent),
|
||||||
|
@ -110,6 +202,26 @@ impl From<StartContent> for OutgoingContent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<CancelContent> for OutgoingContent {
|
||||||
|
fn from(content: CancelContent) -> Self {
|
||||||
|
match content {
|
||||||
|
CancelContent::Room(r, c) => {
|
||||||
|
(r, AnyMessageEventContent::KeyVerificationCancel(c)).into()
|
||||||
|
}
|
||||||
|
CancelContent::ToDevice(c) => AnyToDeviceEventContent::KeyVerificationCancel(c).into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<KeyContent> for OutgoingContent {
|
||||||
|
fn from(content: KeyContent) -> Self {
|
||||||
|
match content {
|
||||||
|
KeyContent::Room(r, c) => (r, AnyMessageEventContent::KeyVerificationKey(c)).into(),
|
||||||
|
KeyContent::ToDevice(c) => AnyToDeviceEventContent::KeyVerificationKey(c).into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<AnyToDeviceEventContent> for OutgoingContent {
|
impl From<AnyToDeviceEventContent> for OutgoingContent {
|
||||||
fn from(content: AnyToDeviceEventContent) -> Self {
|
fn from(content: AnyToDeviceEventContent) -> Self {
|
||||||
OutgoingContent::ToDevice(content)
|
OutgoingContent::ToDevice(content)
|
||||||
|
|
|
@ -23,7 +23,10 @@ use matrix_sdk_common::{
|
||||||
api::r0::to_device::DeviceIdOrAllDevices,
|
api::r0::to_device::DeviceIdOrAllDevices,
|
||||||
events::{
|
events::{
|
||||||
key::verification::{
|
key::verification::{
|
||||||
cancel::CancelCode, mac::MacToDeviceEventContent, start::StartToDeviceEventContent,
|
cancel::CancelCode,
|
||||||
|
mac::{MacEventContent, MacToDeviceEventContent},
|
||||||
|
start::StartToDeviceEventContent,
|
||||||
|
Relation,
|
||||||
},
|
},
|
||||||
AnyToDeviceEventContent, EventType, ToDeviceEvent,
|
AnyToDeviceEventContent, EventType, ToDeviceEvent,
|
||||||
},
|
},
|
||||||
|
@ -38,7 +41,10 @@ use crate::{
|
||||||
ReadOnlyAccount, ToDeviceRequest,
|
ReadOnlyAccount, ToDeviceRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{event_enums::StartContent, sas_state::FlowId};
|
use super::{
|
||||||
|
event_enums::{MacContent, StartContent},
|
||||||
|
sas_state::FlowId,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SasIds {
|
pub struct SasIds {
|
||||||
|
@ -186,7 +192,8 @@ pub fn receive_mac_event(
|
||||||
sas: &OlmSas,
|
sas: &OlmSas,
|
||||||
ids: &SasIds,
|
ids: &SasIds,
|
||||||
flow_id: &str,
|
flow_id: &str,
|
||||||
event: &ToDeviceEvent<MacToDeviceEventContent>,
|
sender: &UserId,
|
||||||
|
content: &MacContent,
|
||||||
) -> Result<(Vec<ReadOnlyDevice>, Vec<UserIdentities>), CancelCode> {
|
) -> Result<(Vec<ReadOnlyDevice>, Vec<UserIdentities>), CancelCode> {
|
||||||
let mut verified_devices = Vec::new();
|
let mut verified_devices = Vec::new();
|
||||||
let mut verified_identities = Vec::new();
|
let mut verified_identities = Vec::new();
|
||||||
|
@ -195,25 +202,25 @@ pub fn receive_mac_event(
|
||||||
|
|
||||||
trace!(
|
trace!(
|
||||||
"Received a key.verification.mac event from {} {}",
|
"Received a key.verification.mac event from {} {}",
|
||||||
event.sender,
|
sender,
|
||||||
ids.other_device.device_id()
|
ids.other_device.device_id()
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut keys = event.content.mac.keys().cloned().collect::<Vec<String>>();
|
let mut keys = content.mac().keys().cloned().collect::<Vec<String>>();
|
||||||
keys.sort();
|
keys.sort();
|
||||||
let keys = sas
|
let keys = sas
|
||||||
.calculate_mac(&keys.join(","), &format!("{}KEY_IDS", &info))
|
.calculate_mac(&keys.join(","), &format!("{}KEY_IDS", &info))
|
||||||
.expect("Can't calculate SAS MAC");
|
.expect("Can't calculate SAS MAC");
|
||||||
|
|
||||||
if keys != event.content.keys {
|
if keys != content.keys() {
|
||||||
return Err(CancelCode::KeyMismatch);
|
return Err(CancelCode::KeyMismatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (key_id, key_mac) in &event.content.mac {
|
for (key_id, key_mac) in content.mac() {
|
||||||
trace!(
|
trace!(
|
||||||
"Checking MAC for the key id {} from {} {}",
|
"Checking MAC for the key id {} from {} {}",
|
||||||
key_id,
|
key_id,
|
||||||
event.sender,
|
sender,
|
||||||
ids.other_device.device_id()
|
ids.other_device.device_id()
|
||||||
);
|
);
|
||||||
let key_id: DeviceKeyId = match key_id.as_str().try_into() {
|
let key_id: DeviceKeyId = match key_id.as_str().try_into() {
|
||||||
|
@ -227,6 +234,12 @@ pub fn receive_mac_event(
|
||||||
.calculate_mac(key, &format!("{}{}", info, key_id))
|
.calculate_mac(key, &format!("{}{}", info, key_id))
|
||||||
.expect("Can't calculate SAS MAC")
|
.expect("Can't calculate SAS MAC")
|
||||||
{
|
{
|
||||||
|
trace!(
|
||||||
|
"Successfully verified the device key {} from {}",
|
||||||
|
key_id,
|
||||||
|
sender
|
||||||
|
);
|
||||||
|
|
||||||
verified_devices.push(ids.other_device.clone());
|
verified_devices.push(ids.other_device.clone());
|
||||||
} else {
|
} else {
|
||||||
return Err(CancelCode::KeyMismatch);
|
return Err(CancelCode::KeyMismatch);
|
||||||
|
@ -243,7 +256,7 @@ pub fn receive_mac_event(
|
||||||
trace!(
|
trace!(
|
||||||
"Successfully verified the master key {} from {}",
|
"Successfully verified the master key {} from {}",
|
||||||
key_id,
|
key_id,
|
||||||
event.sender
|
sender
|
||||||
);
|
);
|
||||||
verified_identities.push(identity.clone())
|
verified_identities.push(identity.clone())
|
||||||
} else {
|
} else {
|
||||||
|
@ -255,7 +268,7 @@ pub fn receive_mac_event(
|
||||||
"Key ID {} in MAC event from {} {} doesn't belong to any device \
|
"Key ID {} in MAC event from {} {} doesn't belong to any device \
|
||||||
or user identity",
|
or user identity",
|
||||||
key_id,
|
key_id,
|
||||||
event.sender,
|
sender,
|
||||||
ids.other_device.device_id()
|
ids.other_device.device_id()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -297,7 +310,7 @@ fn extra_mac_info_send(ids: &SasIds, flow_id: &str) -> String {
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// This will panic if the public key of the other side wasn't set.
|
/// This will panic if the public key of the other side wasn't set.
|
||||||
pub fn get_mac_content(sas: &OlmSas, ids: &SasIds, flow_id: &FlowId) -> MacToDeviceEventContent {
|
pub fn get_mac_content(sas: &OlmSas, ids: &SasIds, flow_id: &FlowId) -> MacContent {
|
||||||
let mut mac: BTreeMap<String, String> = BTreeMap::new();
|
let mut mac: BTreeMap<String, String> = BTreeMap::new();
|
||||||
|
|
||||||
let key_id = DeviceKeyId::from_parts(DeviceKeyAlgorithm::Ed25519, ids.account.device_id());
|
let key_id = DeviceKeyId::from_parts(DeviceKeyAlgorithm::Ed25519, ids.account.device_id());
|
||||||
|
@ -323,8 +336,19 @@ pub fn get_mac_content(sas: &OlmSas, ids: &SasIds, flow_id: &FlowId) -> MacToDev
|
||||||
transaction_id: s.to_string(),
|
transaction_id: s.to_string(),
|
||||||
keys,
|
keys,
|
||||||
mac,
|
mac,
|
||||||
},
|
}
|
||||||
_ => todo!(),
|
.into(),
|
||||||
|
FlowId::InRoom(r, e) => (
|
||||||
|
r.clone(),
|
||||||
|
MacEventContent {
|
||||||
|
mac,
|
||||||
|
keys,
|
||||||
|
relation: Relation {
|
||||||
|
event_id: e.clone(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,8 @@ use matrix_sdk_common::{
|
||||||
mac::MacToDeviceEventContent,
|
mac::MacToDeviceEventContent,
|
||||||
start::{StartEventContent, StartToDeviceEventContent},
|
start::{StartEventContent, StartToDeviceEventContent},
|
||||||
},
|
},
|
||||||
AnyToDeviceEvent, AnyToDeviceEventContent, MessageEvent, ToDeviceEvent,
|
AnyMessageEvent, AnyMessageEventContent, AnySyncMessageEvent, AnyToDeviceEvent,
|
||||||
|
AnyToDeviceEventContent, MessageEvent, ToDeviceEvent,
|
||||||
},
|
},
|
||||||
identifiers::{EventId, RoomId, UserId},
|
identifiers::{EventId, RoomId, UserId},
|
||||||
};
|
};
|
||||||
|
@ -36,7 +37,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
event_enums::{AcceptContent, OutgoingContent},
|
event_enums::{AcceptContent, CancelContent, MacContent, OutgoingContent},
|
||||||
sas_state::{
|
sas_state::{
|
||||||
Accepted, Canceled, Confirmed, Created, Done, FlowId, KeyReceived, MacReceived, SasState,
|
Accepted, Canceled, Confirmed, Created, Done, FlowId, KeyReceived, MacReceived, SasState,
|
||||||
Started,
|
Started,
|
||||||
|
@ -91,7 +92,7 @@ impl InnerSas {
|
||||||
sender: &UserId,
|
sender: &UserId,
|
||||||
content: impl Into<StartContent>,
|
content: impl Into<StartContent>,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<UserIdentities>,
|
||||||
) -> Result<InnerSas, OutgoingContent> {
|
) -> Result<InnerSas, CancelContent> {
|
||||||
match SasState::<Started>::from_start_event(
|
match SasState::<Started>::from_start_event(
|
||||||
account,
|
account,
|
||||||
other_device,
|
other_device,
|
||||||
|
@ -127,7 +128,7 @@ impl InnerSas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cancel(self, code: CancelCode) -> (InnerSas, Option<OutgoingContent>) {
|
pub fn cancel(self, code: CancelCode) -> (InnerSas, Option<CancelContent>) {
|
||||||
let sas = match self {
|
let sas = match self {
|
||||||
InnerSas::Created(s) => s.cancel(code),
|
InnerSas::Created(s) => s.cancel(code),
|
||||||
InnerSas::Started(s) => s.cancel(code),
|
InnerSas::Started(s) => s.cancel(code),
|
||||||
|
@ -142,7 +143,7 @@ impl InnerSas {
|
||||||
(InnerSas::Canceled(sas), Some(content))
|
(InnerSas::Canceled(sas), Some(content))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn confirm(self) -> (InnerSas, Option<MacToDeviceEventContent>) {
|
pub fn confirm(self) -> (InnerSas, Option<MacContent>) {
|
||||||
match self {
|
match self {
|
||||||
InnerSas::KeyRecieved(s) => {
|
InnerSas::KeyRecieved(s) => {
|
||||||
let sas = s.confirm();
|
let sas = s.confirm();
|
||||||
|
@ -158,6 +159,62 @@ impl InnerSas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn receive_room_event(
|
||||||
|
self,
|
||||||
|
event: &AnyMessageEvent,
|
||||||
|
) -> (InnerSas, Option<OutgoingContent>) {
|
||||||
|
match event {
|
||||||
|
AnyMessageEvent::KeyVerificationKey(e) => match self {
|
||||||
|
InnerSas::Accepted(s) => {
|
||||||
|
match s.into_key_received(&e.sender, (e.room_id.clone(), e.content.clone())) {
|
||||||
|
Ok(s) => (InnerSas::KeyRecieved(s), None),
|
||||||
|
Err(s) => {
|
||||||
|
let content = s.as_content();
|
||||||
|
(InnerSas::Canceled(s), Some(content.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InnerSas::Started(s) => {
|
||||||
|
match s.into_key_received(&e.sender, (e.room_id.clone(), e.content.clone())) {
|
||||||
|
Ok(s) => {
|
||||||
|
let content = s.as_content();
|
||||||
|
(InnerSas::KeyRecieved(s), Some(content.into()))
|
||||||
|
}
|
||||||
|
Err(s) => {
|
||||||
|
let content = s.as_content();
|
||||||
|
(InnerSas::Canceled(s), Some(content.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => (self, None),
|
||||||
|
},
|
||||||
|
AnyMessageEvent::KeyVerificationMac(e) => match self {
|
||||||
|
InnerSas::KeyRecieved(s) => {
|
||||||
|
match s.into_mac_received(&e.sender, (e.room_id.clone(), e.content.clone())) {
|
||||||
|
Ok(s) => (InnerSas::MacReceived(s), None),
|
||||||
|
Err(s) => {
|
||||||
|
let content = s.as_content();
|
||||||
|
(InnerSas::Canceled(s), Some(content.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InnerSas::Confirmed(s) => {
|
||||||
|
match s.into_done(&e.sender, (e.room_id.clone(), e.content.clone())) {
|
||||||
|
Ok(s) => (InnerSas::Done(s), None),
|
||||||
|
Err(s) => {
|
||||||
|
let content = s.as_content();
|
||||||
|
(InnerSas::Canceled(s), Some(content.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (self, None),
|
||||||
|
},
|
||||||
|
_ => (self, None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn receive_event(self, event: &AnyToDeviceEvent) -> (InnerSas, Option<OutgoingContent>) {
|
pub fn receive_event(self, event: &AnyToDeviceEvent) -> (InnerSas, Option<OutgoingContent>) {
|
||||||
match event {
|
match event {
|
||||||
AnyToDeviceEvent::KeyVerificationAccept(e) => {
|
AnyToDeviceEvent::KeyVerificationAccept(e) => {
|
||||||
|
@ -165,14 +222,11 @@ impl InnerSas {
|
||||||
match s.into_accepted(e) {
|
match s.into_accepted(e) {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
let content = s.as_content();
|
let content = s.as_content();
|
||||||
(
|
(InnerSas::Accepted(s), Some(content.into()))
|
||||||
InnerSas::Accepted(s),
|
|
||||||
Some(AnyToDeviceEventContent::KeyVerificationKey(content).into()),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Err(s) => {
|
Err(s) => {
|
||||||
let content = s.as_content();
|
let content = s.as_content();
|
||||||
(InnerSas::Canceled(s), Some(content))
|
(InnerSas::Canceled(s), Some(content.into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -180,41 +234,39 @@ 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.sender, e.content.clone()) {
|
||||||
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))
|
(InnerSas::Canceled(s), Some(content.into()))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InnerSas::Started(s) => match s.into_key_received(e) {
|
InnerSas::Started(s) => match s.into_key_received(&e.sender, e.content.clone()) {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
let content = s.as_content();
|
let content = s.as_content();
|
||||||
(
|
(InnerSas::KeyRecieved(s), Some(content.into()))
|
||||||
InnerSas::KeyRecieved(s),
|
|
||||||
Some(AnyToDeviceEventContent::KeyVerificationKey(content).into()),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Err(s) => {
|
Err(s) => {
|
||||||
let content = s.as_content();
|
let content = s.as_content();
|
||||||
(InnerSas::Canceled(s), Some(content))
|
(InnerSas::Canceled(s), Some(content.into()))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => (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.sender, e.content.clone())
|
||||||
|
{
|
||||||
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))
|
(InnerSas::Canceled(s), Some(content.into()))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
InnerSas::Confirmed(s) => match s.into_done(e) {
|
InnerSas::Confirmed(s) => match s.into_done(&e.sender, e.content.clone()) {
|
||||||
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))
|
(InnerSas::Canceled(s), Some(content.into()))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => (self, None),
|
_ => (self, None),
|
||||||
|
|
|
@ -31,8 +31,8 @@ use matrix_sdk_common::{
|
||||||
cancel::CancelCode,
|
cancel::CancelCode,
|
||||||
start::{StartEventContent, StartToDeviceEventContent},
|
start::{StartEventContent, StartToDeviceEventContent},
|
||||||
},
|
},
|
||||||
AnyMessageEventContent, AnyToDeviceEvent, AnyToDeviceEventContent, MessageEvent,
|
AnyMessageEvent, AnyMessageEventContent, AnySyncMessageEvent, AnyToDeviceEvent,
|
||||||
ToDeviceEvent,
|
AnyToDeviceEventContent, MessageEvent, ToDeviceEvent,
|
||||||
},
|
},
|
||||||
identifiers::{DeviceId, EventId, RoomId, UserId},
|
identifiers::{DeviceId, EventId, RoomId, UserId},
|
||||||
uuid::Uuid,
|
uuid::Uuid,
|
||||||
|
@ -53,13 +53,15 @@ pub use sas_state::FlowId;
|
||||||
|
|
||||||
pub use event_enums::{OutgoingContent, StartContent};
|
pub use event_enums::{OutgoingContent, StartContent};
|
||||||
|
|
||||||
|
use self::event_enums::CancelContent;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// A result of a verification flow.
|
/// A result of a verification flow.
|
||||||
pub enum VerificationResult {
|
pub enum VerificationResult {
|
||||||
/// The verification succeeded, nothing needs to be done.
|
/// The verification succeeded, nothing needs to be done.
|
||||||
Ok,
|
Ok,
|
||||||
/// The verification was canceled.
|
/// The verification was canceled.
|
||||||
Cancel(ToDeviceRequest),
|
Cancel(OutgoingVerificationRequest),
|
||||||
/// The verification is done and has signatures that need to be uploaded.
|
/// The verification is done and has signatures that need to be uploaded.
|
||||||
SignatureUpload(SignatureUploadRequest),
|
SignatureUpload(SignatureUploadRequest),
|
||||||
}
|
}
|
||||||
|
@ -278,7 +280,13 @@ impl Sas {
|
||||||
/// the server.
|
/// the server.
|
||||||
pub async fn confirm(
|
pub async fn confirm(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<(Option<ToDeviceRequest>, Option<SignatureUploadRequest>), CryptoStoreError> {
|
) -> Result<
|
||||||
|
(
|
||||||
|
Option<OutgoingVerificationRequest>,
|
||||||
|
Option<SignatureUploadRequest>,
|
||||||
|
),
|
||||||
|
CryptoStoreError,
|
||||||
|
> {
|
||||||
let (content, done) = {
|
let (content, done) = {
|
||||||
let mut guard = self.inner.lock().unwrap();
|
let mut guard = self.inner.lock().unwrap();
|
||||||
let sas: InnerSas = (*guard).clone();
|
let sas: InnerSas = (*guard).clone();
|
||||||
|
@ -288,8 +296,17 @@ impl Sas {
|
||||||
(content, guard.is_done())
|
(content, guard.is_done())
|
||||||
};
|
};
|
||||||
|
|
||||||
let mac_request = content
|
let mac_request = content.map(|c| match c {
|
||||||
.map(|c| self.content_to_request(AnyToDeviceEventContent::KeyVerificationMac(c)));
|
event_enums::MacContent::ToDevice(c) => self
|
||||||
|
.content_to_request(AnyToDeviceEventContent::KeyVerificationMac(c))
|
||||||
|
.into(),
|
||||||
|
event_enums::MacContent::Room(r, c) => RoomMessageRequest {
|
||||||
|
room_id: r,
|
||||||
|
txn_id: Uuid::new_v4(),
|
||||||
|
content: AnyMessageEventContent::KeyVerificationMac(c),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
});
|
||||||
|
|
||||||
if done {
|
if done {
|
||||||
match self.mark_as_done().await? {
|
match self.mark_as_done().await? {
|
||||||
|
@ -530,22 +547,26 @@ impl Sas {
|
||||||
///
|
///
|
||||||
/// Returns None if the `Sas` object is already in a canceled state,
|
/// Returns None if the `Sas` object is already in a canceled state,
|
||||||
/// otherwise it returns a request that needs to be sent out.
|
/// otherwise it returns a request that needs to be sent out.
|
||||||
pub fn cancel(&self) -> Option<ToDeviceRequest> {
|
pub fn cancel(&self) -> Option<OutgoingVerificationRequest> {
|
||||||
let mut guard = self.inner.lock().unwrap();
|
let mut guard = self.inner.lock().unwrap();
|
||||||
let sas: InnerSas = (*guard).clone();
|
let sas: InnerSas = (*guard).clone();
|
||||||
let (sas, content) = sas.cancel(CancelCode::User);
|
let (sas, content) = sas.cancel(CancelCode::User);
|
||||||
*guard = sas;
|
*guard = sas;
|
||||||
|
|
||||||
content.map(|c| {
|
content.map(|c| match c {
|
||||||
if let OutgoingContent::ToDevice(c) = c {
|
CancelContent::Room(room_id, content) => RoomMessageRequest {
|
||||||
self.content_to_request(c)
|
room_id,
|
||||||
} else {
|
txn_id: Uuid::new_v4(),
|
||||||
todo!()
|
content: AnyMessageEventContent::KeyVerificationCancel(content),
|
||||||
}
|
}
|
||||||
|
.into(),
|
||||||
|
CancelContent::ToDevice(c) => self
|
||||||
|
.content_to_request(AnyToDeviceEventContent::KeyVerificationCancel(c))
|
||||||
|
.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn cancel_if_timed_out(&self) -> Option<ToDeviceRequest> {
|
pub(crate) fn cancel_if_timed_out(&self) -> Option<OutgoingVerificationRequest> {
|
||||||
if self.is_canceled() || self.is_done() {
|
if self.is_canceled() || self.is_done() {
|
||||||
None
|
None
|
||||||
} else if self.timed_out() {
|
} else if self.timed_out() {
|
||||||
|
@ -553,12 +574,16 @@ impl Sas {
|
||||||
let sas: InnerSas = (*guard).clone();
|
let sas: InnerSas = (*guard).clone();
|
||||||
let (sas, content) = sas.cancel(CancelCode::Timeout);
|
let (sas, content) = sas.cancel(CancelCode::Timeout);
|
||||||
*guard = sas;
|
*guard = sas;
|
||||||
content.map(|c| {
|
content.map(|c| match c {
|
||||||
if let OutgoingContent::ToDevice(c) = c {
|
CancelContent::Room(room_id, content) => RoomMessageRequest {
|
||||||
self.content_to_request(c)
|
room_id,
|
||||||
} else {
|
txn_id: Uuid::new_v4(),
|
||||||
todo!()
|
content: AnyMessageEventContent::KeyVerificationCancel(content),
|
||||||
}
|
}
|
||||||
|
.into(),
|
||||||
|
CancelContent::ToDevice(c) => self
|
||||||
|
.content_to_request(AnyToDeviceEventContent::KeyVerificationCancel(c))
|
||||||
|
.into(),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -602,6 +627,15 @@ impl Sas {
|
||||||
self.inner.lock().unwrap().decimals()
|
self.inner.lock().unwrap().decimals()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn receive_room_event(&self, event: &AnyMessageEvent) -> Option<OutgoingContent> {
|
||||||
|
let mut guard = self.inner.lock().unwrap();
|
||||||
|
let sas: InnerSas = (*guard).clone();
|
||||||
|
let (sas, content) = sas.receive_room_event(event);
|
||||||
|
*guard = sas;
|
||||||
|
|
||||||
|
content
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn receive_event(&self, event: &AnyToDeviceEvent) -> Option<OutgoingContent> {
|
pub(crate) fn receive_event(&self, event: &AnyToDeviceEvent) -> Option<OutgoingContent> {
|
||||||
let mut guard = self.inner.lock().unwrap();
|
let mut guard = self.inner.lock().unwrap();
|
||||||
let sas: InnerSas = (*guard).clone();
|
let sas: InnerSas = (*guard).clone();
|
||||||
|
|
|
@ -28,8 +28,8 @@ use matrix_sdk_common::{
|
||||||
AcceptEventContent, AcceptMethod, AcceptToDeviceEventContent,
|
AcceptEventContent, AcceptMethod, AcceptToDeviceEventContent,
|
||||||
MSasV1Content as AcceptV1Content, MSasV1ContentInit as AcceptV1ContentInit,
|
MSasV1Content as AcceptV1Content, MSasV1ContentInit as AcceptV1ContentInit,
|
||||||
},
|
},
|
||||||
cancel::{CancelCode, CancelToDeviceEventContent},
|
cancel::{CancelCode, CancelEventContent, CancelToDeviceEventContent},
|
||||||
key::KeyToDeviceEventContent,
|
key::{KeyEventContent, KeyToDeviceEventContent},
|
||||||
mac::MacToDeviceEventContent,
|
mac::MacToDeviceEventContent,
|
||||||
start::{
|
start::{
|
||||||
MSasV1Content, MSasV1ContentInit, StartEventContent, StartMethod,
|
MSasV1Content, MSasV1ContentInit, StartEventContent, StartMethod,
|
||||||
|
@ -46,7 +46,9 @@ use matrix_sdk_common::{
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
event_enums::{AcceptContent, OutgoingContent, StartContent},
|
event_enums::{
|
||||||
|
AcceptContent, CancelContent, KeyContent, MacContent, OutgoingContent, StartContent,
|
||||||
|
},
|
||||||
helpers::{
|
helpers::{
|
||||||
calculate_commitment, get_decimal, get_emoji, get_mac_content, receive_mac_event, SasIds,
|
calculate_commitment, get_decimal, get_emoji, get_mac_content, receive_mac_event, SasIds,
|
||||||
},
|
},
|
||||||
|
@ -618,14 +620,17 @@ impl SasState<Started> {
|
||||||
/// anymore.
|
/// anymore.
|
||||||
pub fn into_key_received(
|
pub fn into_key_received(
|
||||||
self,
|
self,
|
||||||
event: &ToDeviceEvent<KeyToDeviceEventContent>,
|
sender: &UserId,
|
||||||
|
content: impl Into<KeyContent>,
|
||||||
) -> Result<SasState<KeyReceived>, SasState<Canceled>> {
|
) -> Result<SasState<KeyReceived>, SasState<Canceled>> {
|
||||||
self.check_event(&event.sender, &event.content.transaction_id)
|
let content = content.into();
|
||||||
|
|
||||||
|
self.check_event(&sender, &content.flow_id().as_str())
|
||||||
.map_err(|c| self.clone().cancel(c))?;
|
.map_err(|c| self.clone().cancel(c))?;
|
||||||
|
|
||||||
let accepted_protocols = AcceptedProtocols::default();
|
let accepted_protocols = AcceptedProtocols::default();
|
||||||
|
|
||||||
let their_pubkey = event.content.key.clone();
|
let their_pubkey = content.public_key().to_owned();
|
||||||
|
|
||||||
self.inner
|
self.inner
|
||||||
.lock()
|
.lock()
|
||||||
|
@ -659,20 +664,23 @@ impl SasState<Accepted> {
|
||||||
/// anymore.
|
/// anymore.
|
||||||
pub fn into_key_received(
|
pub fn into_key_received(
|
||||||
self,
|
self,
|
||||||
event: &ToDeviceEvent<KeyToDeviceEventContent>,
|
sender: &UserId,
|
||||||
|
content: impl Into<KeyContent>,
|
||||||
) -> Result<SasState<KeyReceived>, SasState<Canceled>> {
|
) -> Result<SasState<KeyReceived>, SasState<Canceled>> {
|
||||||
self.check_event(&event.sender, &event.content.transaction_id)
|
let content = content.into();
|
||||||
|
|
||||||
|
self.check_event(&sender, content.flow_id().as_str())
|
||||||
.map_err(|c| self.clone().cancel(c))?;
|
.map_err(|c| self.clone().cancel(c))?;
|
||||||
|
|
||||||
let commitment = calculate_commitment(
|
let commitment = calculate_commitment(
|
||||||
&event.content.key,
|
content.public_key(),
|
||||||
self.state.start_content.as_ref().clone(),
|
self.state.start_content.as_ref().clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if self.state.commitment != commitment {
|
if self.state.commitment != commitment {
|
||||||
Err(self.cancel(CancelCode::InvalidMessage))
|
Err(self.cancel(CancelCode::InvalidMessage))
|
||||||
} else {
|
} else {
|
||||||
let their_pubkey = event.content.key.clone();
|
let their_pubkey = content.public_key().to_owned();
|
||||||
|
|
||||||
self.inner
|
self.inner
|
||||||
.lock()
|
.lock()
|
||||||
|
@ -698,15 +706,23 @@ impl SasState<Accepted> {
|
||||||
/// Get the content for the key event.
|
/// Get the content for the key event.
|
||||||
///
|
///
|
||||||
/// The content needs to be automatically sent to the other side.
|
/// The content needs to be automatically sent to the other side.
|
||||||
pub fn as_content(&self) -> KeyToDeviceEventContent {
|
pub fn as_content(&self) -> OutgoingContent {
|
||||||
match &*self.verification_flow_id {
|
match &*self.verification_flow_id {
|
||||||
FlowId::ToDevice(s) => KeyToDeviceEventContent {
|
FlowId::ToDevice(s) => KeyContent::ToDevice(KeyToDeviceEventContent {
|
||||||
transaction_id: s.to_string(),
|
transaction_id: s.to_string(),
|
||||||
key: self.inner.lock().unwrap().public_key(),
|
key: self.inner.lock().unwrap().public_key(),
|
||||||
},
|
})
|
||||||
FlowId::InRoom(_, r) => {
|
.into(),
|
||||||
todo!("In-room verifications aren't implemented")
|
FlowId::InRoom(r, e) => KeyContent::Room(
|
||||||
}
|
r.clone(),
|
||||||
|
KeyEventContent {
|
||||||
|
key: self.inner.lock().unwrap().public_key(),
|
||||||
|
relation: Relation {
|
||||||
|
event_id: e.clone(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -716,13 +732,23 @@ impl SasState<KeyReceived> {
|
||||||
///
|
///
|
||||||
/// The content needs to be automatically sent to the other side if and only
|
/// The content needs to be automatically sent to the other side if and only
|
||||||
/// if we_started is false.
|
/// if we_started is false.
|
||||||
pub fn as_content(&self) -> KeyToDeviceEventContent {
|
pub fn as_content(&self) -> KeyContent {
|
||||||
match self.verification_flow_id.as_ref() {
|
match &*self.verification_flow_id {
|
||||||
FlowId::ToDevice(s) => KeyToDeviceEventContent {
|
FlowId::ToDevice(s) => KeyContent::ToDevice(KeyToDeviceEventContent {
|
||||||
transaction_id: s.to_string(),
|
transaction_id: s.to_string(),
|
||||||
key: self.inner.lock().unwrap().public_key(),
|
key: self.inner.lock().unwrap().public_key(),
|
||||||
},
|
})
|
||||||
_ => todo!(),
|
.into(),
|
||||||
|
FlowId::InRoom(r, e) => KeyContent::Room(
|
||||||
|
r.clone(),
|
||||||
|
KeyEventContent {
|
||||||
|
key: self.inner.lock().unwrap().public_key(),
|
||||||
|
relation: Relation {
|
||||||
|
event_id: e.clone(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,16 +789,20 @@ impl SasState<KeyReceived> {
|
||||||
/// the other side.
|
/// the other side.
|
||||||
pub fn into_mac_received(
|
pub fn into_mac_received(
|
||||||
self,
|
self,
|
||||||
event: &ToDeviceEvent<MacToDeviceEventContent>,
|
sender: &UserId,
|
||||||
|
content: impl Into<MacContent>,
|
||||||
) -> Result<SasState<MacReceived>, SasState<Canceled>> {
|
) -> Result<SasState<MacReceived>, SasState<Canceled>> {
|
||||||
self.check_event(&event.sender, &event.content.transaction_id)
|
let content = content.into();
|
||||||
|
|
||||||
|
self.check_event(&sender, content.flow_id().as_str())
|
||||||
.map_err(|c| self.clone().cancel(c))?;
|
.map_err(|c| self.clone().cancel(c))?;
|
||||||
|
|
||||||
let (devices, master_keys) = receive_mac_event(
|
let (devices, master_keys) = receive_mac_event(
|
||||||
&self.inner.lock().unwrap(),
|
&self.inner.lock().unwrap(),
|
||||||
&self.ids,
|
&self.ids,
|
||||||
self.verification_flow_id.as_str(),
|
self.verification_flow_id.as_str(),
|
||||||
event,
|
sender,
|
||||||
|
&content,
|
||||||
)
|
)
|
||||||
.map_err(|c| self.clone().cancel(c))?;
|
.map_err(|c| self.clone().cancel(c))?;
|
||||||
|
|
||||||
|
@ -819,16 +849,20 @@ impl SasState<Confirmed> {
|
||||||
/// the other side.
|
/// the other side.
|
||||||
pub fn into_done(
|
pub fn into_done(
|
||||||
self,
|
self,
|
||||||
event: &ToDeviceEvent<MacToDeviceEventContent>,
|
sender: &UserId,
|
||||||
|
content: impl Into<MacContent>,
|
||||||
) -> Result<SasState<Done>, SasState<Canceled>> {
|
) -> Result<SasState<Done>, SasState<Canceled>> {
|
||||||
self.check_event(&event.sender, &event.content.transaction_id)
|
let content = content.into();
|
||||||
|
|
||||||
|
self.check_event(&sender, &content.flow_id().as_str())
|
||||||
.map_err(|c| self.clone().cancel(c))?;
|
.map_err(|c| self.clone().cancel(c))?;
|
||||||
|
|
||||||
let (devices, master_keys) = receive_mac_event(
|
let (devices, master_keys) = receive_mac_event(
|
||||||
&self.inner.lock().unwrap(),
|
&self.inner.lock().unwrap(),
|
||||||
&self.ids,
|
&self.ids,
|
||||||
&self.verification_flow_id.as_str(),
|
&self.verification_flow_id.as_str(),
|
||||||
event,
|
sender,
|
||||||
|
&content,
|
||||||
)
|
)
|
||||||
.map_err(|c| self.clone().cancel(c))?;
|
.map_err(|c| self.clone().cancel(c))?;
|
||||||
|
|
||||||
|
@ -849,7 +883,7 @@ impl SasState<Confirmed> {
|
||||||
/// Get the content for the mac event.
|
/// Get the content for the mac event.
|
||||||
///
|
///
|
||||||
/// The content needs to be automatically sent to the other side.
|
/// The content needs to be automatically sent to the other side.
|
||||||
pub fn as_content(&self) -> MacToDeviceEventContent {
|
pub fn as_content(&self) -> MacContent {
|
||||||
get_mac_content(
|
get_mac_content(
|
||||||
&self.inner.lock().unwrap(),
|
&self.inner.lock().unwrap(),
|
||||||
&self.ids,
|
&self.ids,
|
||||||
|
@ -911,7 +945,7 @@ impl SasState<Done> {
|
||||||
///
|
///
|
||||||
/// The content needs to be automatically sent to the other side if it
|
/// The content needs to be automatically sent to the other side if it
|
||||||
/// wasn't already sent.
|
/// wasn't already sent.
|
||||||
pub fn as_content(&self) -> MacToDeviceEventContent {
|
pub fn as_content(&self) -> MacContent {
|
||||||
get_mac_content(
|
get_mac_content(
|
||||||
&self.inner.lock().unwrap(),
|
&self.inner.lock().unwrap(),
|
||||||
&self.ids,
|
&self.ids,
|
||||||
|
@ -959,17 +993,26 @@ impl Canceled {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SasState<Canceled> {
|
impl SasState<Canceled> {
|
||||||
pub fn as_content(&self) -> OutgoingContent {
|
pub fn as_content(&self) -> CancelContent {
|
||||||
match self.verification_flow_id.as_ref() {
|
match self.verification_flow_id.as_ref() {
|
||||||
FlowId::ToDevice(s) => {
|
FlowId::ToDevice(s) => CancelToDeviceEventContent {
|
||||||
AnyToDeviceEventContent::KeyVerificationCancel(CancelToDeviceEventContent {
|
transaction_id: s.clone(),
|
||||||
transaction_id: self.verification_flow_id.to_string(),
|
reason: self.state.reason.to_string(),
|
||||||
|
code: self.state.cancel_code.clone(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
|
||||||
|
FlowId::InRoom(r, e) => (
|
||||||
|
r.clone(),
|
||||||
|
CancelEventContent {
|
||||||
reason: self.state.reason.to_string(),
|
reason: self.state.reason.to_string(),
|
||||||
code: self.state.cancel_code.clone(),
|
code: self.state.cancel_code.clone(),
|
||||||
})
|
relation: Relation {
|
||||||
.into()
|
event_id: e.clone(),
|
||||||
}
|
},
|
||||||
_ => todo!(),
|
},
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue