crypto: WIP more work on in-room verifications now up to accepting them.
parent
5105629c08
commit
b6e28e2280
|
@ -45,7 +45,7 @@ use matrix_sdk_base::{BaseClient, BaseClientConfig, Room, Session, StateStore};
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
use matrix_sdk_base::crypto::{
|
use matrix_sdk_base::crypto::{
|
||||||
decrypt_key_export, encrypt_key_export, olm::InboundGroupSession, store::CryptoStoreError,
|
decrypt_key_export, encrypt_key_export, olm::InboundGroupSession, store::CryptoStoreError,
|
||||||
AttachmentEncryptor, OutgoingRequests, ToDeviceRequest,
|
AttachmentEncryptor, OutgoingRequests, RoomMessageRequest, ToDeviceRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Enum controlling if a loop running callbacks should continue or abort.
|
/// Enum controlling if a loop running callbacks should continue or abort.
|
||||||
|
@ -1160,6 +1160,17 @@ impl Client {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn room_send_helper(
|
||||||
|
&self,
|
||||||
|
request: &RoomMessageRequest,
|
||||||
|
) -> Result<send_message_event::Response> {
|
||||||
|
let content = request.content.clone();
|
||||||
|
let txn_id = request.txn_id.into();
|
||||||
|
let room_id = &request.room_id;
|
||||||
|
|
||||||
|
self.room_send(&room_id, content, Some(txn_id)).await
|
||||||
|
}
|
||||||
|
|
||||||
/// Send a room message to the homeserver.
|
/// Send a room message to the homeserver.
|
||||||
///
|
///
|
||||||
/// Returns the parsed response from the server.
|
/// Returns the parsed response from the server.
|
||||||
|
@ -1458,7 +1469,10 @@ impl Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
async fn send_to_device(&self, request: &ToDeviceRequest) -> Result<ToDeviceResponse> {
|
pub(crate) async fn send_to_device(
|
||||||
|
&self,
|
||||||
|
request: &ToDeviceRequest,
|
||||||
|
) -> Result<ToDeviceResponse> {
|
||||||
let txn_id_string = request.txn_id_string();
|
let txn_id_string = request.txn_id_string();
|
||||||
let request = RumaToDeviceRequest::new(
|
let request = RumaToDeviceRequest::new(
|
||||||
request.event_type.clone(),
|
request.event_type.clone(),
|
||||||
|
@ -1737,6 +1751,14 @@ impl Client {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
OutgoingRequests::RoomMessage(request) => {
|
||||||
|
if let Ok(resp) = self.room_send_helper(request).await {
|
||||||
|
self.base_client
|
||||||
|
.mark_request_as_sent(&r.request_id(), &resp)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1891,7 +1913,7 @@ impl Client {
|
||||||
.await
|
.await
|
||||||
.map(|sas| Sas {
|
.map(|sas| Sas {
|
||||||
inner: sas,
|
inner: sas,
|
||||||
http_client: self.http_client.clone(),
|
client: self.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1953,7 +1975,7 @@ impl Client {
|
||||||
|
|
||||||
Ok(device.map(|d| Device {
|
Ok(device.map(|d| Device {
|
||||||
inner: d,
|
inner: d,
|
||||||
http_client: self.http_client.clone(),
|
client: self.clone(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2070,7 +2092,7 @@ impl Client {
|
||||||
|
|
||||||
Ok(UserDevices {
|
Ok(UserDevices {
|
||||||
inner: devices,
|
inner: devices,
|
||||||
http_client: self.http_client.clone(),
|
client: self.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,18 +18,15 @@ use matrix_sdk_base::crypto::{
|
||||||
store::CryptoStoreError, Device as BaseDevice, LocalTrust, ReadOnlyDevice,
|
store::CryptoStoreError, Device as BaseDevice, LocalTrust, ReadOnlyDevice,
|
||||||
UserDevices as BaseUserDevices,
|
UserDevices as BaseUserDevices,
|
||||||
};
|
};
|
||||||
use matrix_sdk_common::{
|
use matrix_sdk_common::identifiers::{DeviceId, DeviceIdBox};
|
||||||
api::r0::to_device::send_event_to_device::Request as ToDeviceRequest,
|
|
||||||
identifiers::{DeviceId, DeviceIdBox},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{error::Result, http_client::HttpClient, Sas};
|
use crate::{error::Result, Client, Sas};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// A device represents a E2EE capable client of an user.
|
/// A device represents a E2EE capable client of an user.
|
||||||
pub struct Device {
|
pub struct Device {
|
||||||
pub(crate) inner: BaseDevice,
|
pub(crate) inner: BaseDevice,
|
||||||
pub(crate) http_client: HttpClient,
|
pub(crate) client: Client,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for Device {
|
impl Deref for Device {
|
||||||
|
@ -66,14 +63,11 @@ impl Device {
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn start_verification(&self) -> Result<Sas> {
|
pub async fn start_verification(&self) -> Result<Sas> {
|
||||||
let (sas, request) = self.inner.start_verification().await?;
|
let (sas, request) = self.inner.start_verification().await?;
|
||||||
let txn_id_string = request.txn_id_string();
|
self.client.send_to_device(&request).await?;
|
||||||
let request = ToDeviceRequest::new(request.event_type, &txn_id_string, request.messages);
|
|
||||||
|
|
||||||
self.http_client.send(request).await?;
|
|
||||||
|
|
||||||
Ok(Sas {
|
Ok(Sas {
|
||||||
inner: sas,
|
inner: sas,
|
||||||
http_client: self.http_client.clone(),
|
client: self.client.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +96,7 @@ impl Device {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UserDevices {
|
pub struct UserDevices {
|
||||||
pub(crate) inner: BaseUserDevices,
|
pub(crate) inner: BaseUserDevices,
|
||||||
pub(crate) http_client: HttpClient,
|
pub(crate) client: Client,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserDevices {
|
impl UserDevices {
|
||||||
|
@ -110,7 +104,7 @@ impl UserDevices {
|
||||||
pub fn get(&self, device_id: &DeviceId) -> Option<Device> {
|
pub fn get(&self, device_id: &DeviceId) -> Option<Device> {
|
||||||
self.inner.get(device_id).map(|d| Device {
|
self.inner.get(device_id).map(|d| Device {
|
||||||
inner: d,
|
inner: d,
|
||||||
http_client: self.http_client.clone(),
|
client: self.client.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,11 +115,11 @@ impl UserDevices {
|
||||||
|
|
||||||
/// Iterator over all the devices of the user devices.
|
/// Iterator over all the devices of the user devices.
|
||||||
pub fn devices(&self) -> impl Iterator<Item = Device> + '_ {
|
pub fn devices(&self) -> impl Iterator<Item = Device> + '_ {
|
||||||
let client = self.http_client.clone();
|
let client = self.client.clone();
|
||||||
|
|
||||||
self.inner.devices().map(move |d| Device {
|
self.inner.devices().map(move |d| Device {
|
||||||
inner: d,
|
inner: d,
|
||||||
http_client: client.clone(),
|
client: client.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,26 +12,27 @@
|
||||||
// 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 matrix_sdk_base::crypto::{ReadOnlyDevice, Sas as BaseSas};
|
use matrix_sdk_base::crypto::{OutgoingVerificationRequest, ReadOnlyDevice, Sas as BaseSas};
|
||||||
use matrix_sdk_common::api::r0::to_device::send_event_to_device::Request as ToDeviceRequest;
|
|
||||||
|
|
||||||
use crate::{error::Result, http_client::HttpClient};
|
use crate::{error::Result, Client};
|
||||||
|
|
||||||
/// An object controling the interactive verification flow.
|
/// An object controling the interactive verification flow.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Sas {
|
pub struct Sas {
|
||||||
pub(crate) inner: BaseSas,
|
pub(crate) inner: BaseSas,
|
||||||
pub(crate) http_client: HttpClient,
|
pub(crate) client: Client,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sas {
|
impl Sas {
|
||||||
/// Accept the interactive verification flow.
|
/// Accept the interactive verification flow.
|
||||||
pub async fn accept(&self) -> Result<()> {
|
pub async fn accept(&self) -> Result<()> {
|
||||||
if let Some(req) = self.inner.accept() {
|
if let Some(req) = self.inner.accept() {
|
||||||
let txn_id_string = req.txn_id_string();
|
match req {
|
||||||
let request = ToDeviceRequest::new(req.event_type, &txn_id_string, req.messages);
|
OutgoingVerificationRequest::ToDevice(r) => {
|
||||||
|
self.client.send_to_device(&r).await?;
|
||||||
self.http_client.send(request).await?;
|
}
|
||||||
|
OutgoingVerificationRequest::InRoom(_) => todo!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -40,15 +41,12 @@ impl Sas {
|
||||||
pub async fn confirm(&self) -> Result<()> {
|
pub async fn confirm(&self) -> Result<()> {
|
||||||
let (to_device, signature) = self.inner.confirm().await?;
|
let (to_device, signature) = self.inner.confirm().await?;
|
||||||
|
|
||||||
if let Some(req) = to_device {
|
if let Some(request) = to_device {
|
||||||
let txn_id_string = req.txn_id_string();
|
self.client.send_to_device(&request).await?;
|
||||||
let request = ToDeviceRequest::new(req.event_type, &txn_id_string, req.messages);
|
|
||||||
|
|
||||||
self.http_client.send(request).await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(s) = signature {
|
if let Some(s) = signature {
|
||||||
self.http_client.send(s).await?;
|
self.client.send(s).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -56,12 +54,10 @@ 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(req) = self.inner.cancel() {
|
if let Some(request) = self.inner.cancel() {
|
||||||
let txn_id_string = req.txn_id_string();
|
self.client.send_to_device(&request).await?;
|
||||||
let request = ToDeviceRequest::new(req.event_type, &txn_id_string, req.messages);
|
|
||||||
|
|
||||||
self.http_client.send(request).await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ use tracing::warn;
|
||||||
use crate::{
|
use crate::{
|
||||||
olm::{InboundGroupSession, PrivateCrossSigningIdentity, Session},
|
olm::{InboundGroupSession, PrivateCrossSigningIdentity, Session},
|
||||||
store::{Changes, DeviceChanges},
|
store::{Changes, DeviceChanges},
|
||||||
OutgoingRequest, OutgoingRequests,
|
OutgoingRequest, OutgoingRequests, OutgoingVerificationRequest,
|
||||||
};
|
};
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use crate::{OlmMachine, ReadOnlyAccount};
|
use crate::{OlmMachine, ReadOnlyAccount};
|
||||||
|
@ -97,7 +97,7 @@ impl Device {
|
||||||
.start_sas(self.inner.clone())
|
.start_sas(self.inner.clone())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if let OutgoingRequests::ToDeviceRequest(r) = request {
|
if let OutgoingVerificationRequest::ToDevice(r) = request {
|
||||||
Ok((sas, r))
|
Ok((sas, r))
|
||||||
} else {
|
} else {
|
||||||
panic!("Invalid verification request type");
|
panic!("Invalid verification request type");
|
||||||
|
|
|
@ -51,6 +51,7 @@ pub use machine::OlmMachine;
|
||||||
pub use olm::EncryptionSettings;
|
pub use olm::EncryptionSettings;
|
||||||
pub(crate) use olm::ReadOnlyAccount;
|
pub(crate) use olm::ReadOnlyAccount;
|
||||||
pub use requests::{
|
pub use requests::{
|
||||||
IncomingResponse, KeysQueryRequest, OutgoingRequest, OutgoingRequests, ToDeviceRequest,
|
IncomingResponse, KeysQueryRequest, OutgoingRequest, OutgoingRequests,
|
||||||
|
OutgoingVerificationRequest, RoomMessageRequest, ToDeviceRequest,
|
||||||
};
|
};
|
||||||
pub use verification::{Sas, VerificationRequest};
|
pub use verification::{Sas, VerificationRequest};
|
||||||
|
|
|
@ -322,6 +322,7 @@ impl OlmMachine {
|
||||||
}
|
}
|
||||||
|
|
||||||
requests.append(&mut self.outgoing_to_device_requests());
|
requests.append(&mut self.outgoing_to_device_requests());
|
||||||
|
requests.append(&mut self.verification_machine.outgoing_room_message_requests());
|
||||||
requests.append(&mut self.key_request_machine.outgoing_to_device_requests());
|
requests.append(&mut self.key_request_machine.outgoing_to_device_requests());
|
||||||
|
|
||||||
requests
|
requests
|
||||||
|
@ -360,6 +361,9 @@ impl OlmMachine {
|
||||||
IncomingResponse::SignatureUpload(_) => {
|
IncomingResponse::SignatureUpload(_) => {
|
||||||
self.verification_machine.mark_request_as_sent(request_id);
|
self.verification_machine.mark_request_as_sent(request_id);
|
||||||
}
|
}
|
||||||
|
IncomingResponse::RoomMessage(_) => {
|
||||||
|
self.verification_machine.mark_request_as_sent(request_id);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
// 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.
|
||||||
|
|
||||||
|
#![allow(missing_docs)]
|
||||||
|
|
||||||
use std::{collections::BTreeMap, sync::Arc, time::Duration};
|
use std::{collections::BTreeMap, sync::Arc, time::Duration};
|
||||||
|
|
||||||
use matrix_sdk_common::{
|
use matrix_sdk_common::{
|
||||||
|
@ -26,10 +28,11 @@ use matrix_sdk_common::{
|
||||||
upload_signing_keys::Response as SigningKeysUploadResponse,
|
upload_signing_keys::Response as SigningKeysUploadResponse,
|
||||||
CrossSigningKey,
|
CrossSigningKey,
|
||||||
},
|
},
|
||||||
|
message::send_message_event::Response as RoomMessageResponse,
|
||||||
to_device::{send_event_to_device::Response as ToDeviceResponse, DeviceIdOrAllDevices},
|
to_device::{send_event_to_device::Response as ToDeviceResponse, DeviceIdOrAllDevices},
|
||||||
},
|
},
|
||||||
events::EventType,
|
events::{AnyMessageEventContent, EventType},
|
||||||
identifiers::{DeviceIdBox, UserId},
|
identifiers::{DeviceIdBox, RoomId, UserId},
|
||||||
uuid::Uuid,
|
uuid::Uuid,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -120,6 +123,7 @@ pub enum OutgoingRequests {
|
||||||
/// Signature upload request, this request is used after a successful device
|
/// Signature upload request, this request is used after a successful device
|
||||||
/// or user verification is done.
|
/// or user verification is done.
|
||||||
SignatureUpload(SignatureUploadRequest),
|
SignatureUpload(SignatureUploadRequest),
|
||||||
|
RoomMessage(RoomMessageRequest),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -150,6 +154,12 @@ impl From<ToDeviceRequest> for OutgoingRequests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<RoomMessageRequest> for OutgoingRequests {
|
||||||
|
fn from(request: RoomMessageRequest) -> Self {
|
||||||
|
OutgoingRequests::RoomMessage(request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<SignatureUploadRequest> for OutgoingRequests {
|
impl From<SignatureUploadRequest> for OutgoingRequests {
|
||||||
fn from(request: SignatureUploadRequest) -> Self {
|
fn from(request: SignatureUploadRequest) -> Self {
|
||||||
OutgoingRequests::SignatureUpload(request)
|
OutgoingRequests::SignatureUpload(request)
|
||||||
|
@ -176,6 +186,7 @@ pub enum IncomingResponse<'a> {
|
||||||
/// The cross signing keys upload response, marking our private cross
|
/// The cross signing keys upload response, marking our private cross
|
||||||
/// signing identity as shared.
|
/// signing identity as shared.
|
||||||
SignatureUpload(&'a SignatureUploadResponse),
|
SignatureUpload(&'a SignatureUploadResponse),
|
||||||
|
RoomMessage(&'a RoomMessageResponse),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a KeysUploadResponse> for IncomingResponse<'a> {
|
impl<'a> From<&'a KeysUploadResponse> for IncomingResponse<'a> {
|
||||||
|
@ -196,6 +207,12 @@ impl<'a> From<&'a ToDeviceResponse> for IncomingResponse<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a RoomMessageResponse> for IncomingResponse<'a> {
|
||||||
|
fn from(response: &'a RoomMessageResponse) -> Self {
|
||||||
|
IncomingResponse::RoomMessage(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a KeysClaimResponse> for IncomingResponse<'a> {
|
impl<'a> From<&'a KeysClaimResponse> for IncomingResponse<'a> {
|
||||||
fn from(response: &'a KeysClaimResponse) -> Self {
|
fn from(response: &'a KeysClaimResponse) -> Self {
|
||||||
IncomingResponse::KeysClaim(response)
|
IncomingResponse::KeysClaim(response)
|
||||||
|
@ -230,3 +247,55 @@ impl OutgoingRequest {
|
||||||
&self.request
|
&self.request
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct RoomMessageRequest {
|
||||||
|
/// The room to send the event to.
|
||||||
|
pub room_id: RoomId,
|
||||||
|
|
||||||
|
/// The transaction ID for this event.
|
||||||
|
///
|
||||||
|
/// Clients should generate an ID unique across requests with the
|
||||||
|
/// same access token; it will be used by the server to ensure
|
||||||
|
/// idempotency of requests.
|
||||||
|
pub txn_id: Uuid,
|
||||||
|
|
||||||
|
/// The event content to send.
|
||||||
|
pub content: AnyMessageEventContent,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum OutgoingVerificationRequest {
|
||||||
|
ToDevice(ToDeviceRequest),
|
||||||
|
InRoom(RoomMessageRequest),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OutgoingVerificationRequest {
|
||||||
|
pub fn request_id(&self) -> Uuid {
|
||||||
|
match self {
|
||||||
|
OutgoingVerificationRequest::ToDevice(t) => t.txn_id,
|
||||||
|
OutgoingVerificationRequest::InRoom(r) => r.txn_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ToDeviceRequest> for OutgoingVerificationRequest {
|
||||||
|
fn from(r: ToDeviceRequest) -> Self {
|
||||||
|
OutgoingVerificationRequest::ToDevice(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<RoomMessageRequest> for OutgoingVerificationRequest {
|
||||||
|
fn from(r: RoomMessageRequest) -> Self {
|
||||||
|
OutgoingVerificationRequest::InRoom(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<OutgoingVerificationRequest> for OutgoingRequests {
|
||||||
|
fn from(request: OutgoingVerificationRequest) -> Self {
|
||||||
|
match request {
|
||||||
|
OutgoingVerificationRequest::ToDevice(r) => OutgoingRequests::ToDeviceRequest(r),
|
||||||
|
OutgoingVerificationRequest::InRoom(r) => OutgoingRequests::RoomMessage(r),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -37,7 +37,8 @@ use crate::{
|
||||||
olm::PrivateCrossSigningIdentity,
|
olm::PrivateCrossSigningIdentity,
|
||||||
requests::{OutgoingRequest, ToDeviceRequest},
|
requests::{OutgoingRequest, ToDeviceRequest},
|
||||||
store::{CryptoStore, CryptoStoreError},
|
store::{CryptoStore, CryptoStoreError},
|
||||||
OutgoingRequests, ReadOnlyAccount, ReadOnlyDevice,
|
OutgoingRequests, OutgoingVerificationRequest, ReadOnlyAccount, ReadOnlyDevice,
|
||||||
|
RoomMessageRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -49,6 +50,7 @@ pub struct VerificationMachine {
|
||||||
room_verifications: Arc<DashMap<EventId, Sas>>,
|
room_verifications: Arc<DashMap<EventId, Sas>>,
|
||||||
requests: Arc<DashMap<EventId, VerificationRequest>>,
|
requests: Arc<DashMap<EventId, VerificationRequest>>,
|
||||||
outgoing_to_device_messages: Arc<DashMap<Uuid, OutgoingRequest>>,
|
outgoing_to_device_messages: Arc<DashMap<Uuid, OutgoingRequest>>,
|
||||||
|
outgoing_room_messages: Arc<DashMap<Uuid, OutgoingRequest>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VerificationMachine {
|
impl VerificationMachine {
|
||||||
|
@ -65,13 +67,14 @@ impl VerificationMachine {
|
||||||
requests: DashMap::new().into(),
|
requests: DashMap::new().into(),
|
||||||
outgoing_to_device_messages: DashMap::new().into(),
|
outgoing_to_device_messages: DashMap::new().into(),
|
||||||
room_verifications: DashMap::new().into(),
|
room_verifications: DashMap::new().into(),
|
||||||
|
outgoing_room_messages: DashMap::new().into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start_sas(
|
pub async fn start_sas(
|
||||||
&self,
|
&self,
|
||||||
device: ReadOnlyDevice,
|
device: ReadOnlyDevice,
|
||||||
) -> Result<(Sas, OutgoingRequests), CryptoStoreError> {
|
) -> Result<(Sas, OutgoingVerificationRequest), CryptoStoreError> {
|
||||||
let identity = self.store.get_user_identity(device.user_id()).await?;
|
let identity = self.store.get_user_identity(device.user_id()).await?;
|
||||||
let private_identity = self.private_identity.lock().await.clone();
|
let private_identity = self.private_identity.lock().await.clone();
|
||||||
|
|
||||||
|
@ -83,8 +86,13 @@ impl VerificationMachine {
|
||||||
identity,
|
identity,
|
||||||
);
|
);
|
||||||
|
|
||||||
let request: OutgoingRequests = match content {
|
let request = match content {
|
||||||
OutgoingContent::Room(c) => todo!(),
|
OutgoingContent::Room(r, c) => RoomMessageRequest {
|
||||||
|
room_id: r,
|
||||||
|
txn_id: Uuid::new_v4(),
|
||||||
|
content: c,
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
OutgoingContent::ToDevice(c) => {
|
OutgoingContent::ToDevice(c) => {
|
||||||
let request = content_to_request(device.user_id(), device.device_id(), c);
|
let request = content_to_request(device.user_id(), device.device_id(), c);
|
||||||
|
|
||||||
|
@ -127,7 +135,23 @@ impl VerificationMachine {
|
||||||
self.outgoing_to_device_messages.insert(request_id, request);
|
self.outgoing_to_device_messages.insert(request_id, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
OutgoingContent::Room(c) => todo!(),
|
OutgoingContent::Room(r, c) => {
|
||||||
|
let request_id = Uuid::new_v4();
|
||||||
|
|
||||||
|
let request = OutgoingRequest {
|
||||||
|
request: Arc::new(
|
||||||
|
RoomMessageRequest {
|
||||||
|
room_id: r,
|
||||||
|
txn_id: request_id.clone(),
|
||||||
|
content: c,
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
request_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.outgoing_room_messages.insert(request_id, request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,9 +162,17 @@ impl VerificationMachine {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mark_request_as_sent(&self, uuid: &Uuid) {
|
pub fn mark_request_as_sent(&self, uuid: &Uuid) {
|
||||||
|
self.outgoing_room_messages.remove(uuid);
|
||||||
self.outgoing_to_device_messages.remove(uuid);
|
self.outgoing_to_device_messages.remove(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn outgoing_room_message_requests(&self) -> Vec<OutgoingRequest> {
|
||||||
|
self.outgoing_room_messages
|
||||||
|
.iter()
|
||||||
|
.map(|r| (*r).clone())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn outgoing_to_device_requests(&self) -> Vec<OutgoingRequest> {
|
pub fn outgoing_to_device_requests(&self) -> Vec<OutgoingRequest> {
|
||||||
#[allow(clippy::map_clone)]
|
#[allow(clippy::map_clone)]
|
||||||
self.outgoing_to_device_messages
|
self.outgoing_to_device_messages
|
||||||
|
@ -215,9 +247,23 @@ impl VerificationMachine {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
// TODO we need to queue up the accept event
|
// TODO we need to queue up the accept event
|
||||||
// here.
|
// here.
|
||||||
let accept_event = s.accept();
|
info!(
|
||||||
|
"Started a new SAS verification, \
|
||||||
|
automatically accepting because of in-room"
|
||||||
|
);
|
||||||
|
|
||||||
|
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(
|
||||||
|
accept_request.request_id(),
|
||||||
|
OutgoingRequest {
|
||||||
|
request_id: accept_request.request_id(),
|
||||||
|
request: Arc::new(accept_request.into()),
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Err(c) => {
|
Err(c) => {
|
||||||
warn!(
|
warn!(
|
||||||
|
|
|
@ -93,13 +93,15 @@ impl VerificationRequest {
|
||||||
) -> Result<Sas, OutgoingContent> {
|
) -> Result<Sas, OutgoingContent> {
|
||||||
match &*self.inner.lock().unwrap() {
|
match &*self.inner.lock().unwrap() {
|
||||||
InnerRequest::Ready(s) => s.into_started_sas(
|
InnerRequest::Ready(s) => s.into_started_sas(
|
||||||
event,
|
&event.clone().into_full_event(self.room_id().clone()),
|
||||||
self.store.clone(),
|
self.store.clone(),
|
||||||
self.account.clone(),
|
self.account.clone(),
|
||||||
self.private_cross_signing_identity.clone(),
|
self.private_cross_signing_identity.clone(),
|
||||||
device,
|
device,
|
||||||
user_identity,
|
user_identity,
|
||||||
),
|
),
|
||||||
|
// TODO cancel here since we got a missmatched message or do
|
||||||
|
// nothing?
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +130,7 @@ impl InnerRequest {
|
||||||
|
|
||||||
fn into_started_sas(
|
fn into_started_sas(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: &SyncMessageEvent<StartEventContent>,
|
event: &MessageEvent<StartEventContent>,
|
||||||
store: Arc<Box<dyn CryptoStore>>,
|
store: Arc<Box<dyn CryptoStore>>,
|
||||||
account: ReadOnlyAccount,
|
account: ReadOnlyAccount,
|
||||||
private_identity: PrivateCrossSigningIdentity,
|
private_identity: PrivateCrossSigningIdentity,
|
||||||
|
@ -299,7 +301,7 @@ struct Ready {
|
||||||
impl RequestState<Ready> {
|
impl RequestState<Ready> {
|
||||||
fn into_started_sas(
|
fn into_started_sas(
|
||||||
&self,
|
&self,
|
||||||
event: &SyncMessageEvent<StartEventContent>,
|
event: &MessageEvent<StartEventContent>,
|
||||||
store: Arc<Box<dyn CryptoStore>>,
|
store: Arc<Box<dyn CryptoStore>>,
|
||||||
account: ReadOnlyAccount,
|
account: ReadOnlyAccount,
|
||||||
private_identity: PrivateCrossSigningIdentity,
|
private_identity: PrivateCrossSigningIdentity,
|
||||||
|
@ -312,7 +314,7 @@ impl RequestState<Ready> {
|
||||||
other_device,
|
other_device,
|
||||||
store,
|
store,
|
||||||
&event.sender,
|
&event.sender,
|
||||||
event.content.clone(),
|
(event.room_id.clone(), event.content.clone()),
|
||||||
other_identity,
|
other_identity,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -325,13 +327,14 @@ impl RequestState<Ready> {
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<UserIdentities>,
|
||||||
) -> (Sas, OutgoingContent) {
|
) -> (Sas, OutgoingContent) {
|
||||||
Sas::start(
|
todo!()
|
||||||
account,
|
// Sas::start_in_room(
|
||||||
private_identity,
|
// account,
|
||||||
other_device,
|
// private_identity,
|
||||||
store,
|
// other_device,
|
||||||
other_identity,
|
// store,
|
||||||
)
|
// other_identity,
|
||||||
|
// )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,11 +19,13 @@ use std::convert::TryInto;
|
||||||
use matrix_sdk_common::{
|
use matrix_sdk_common::{
|
||||||
events::{
|
events::{
|
||||||
key::verification::{
|
key::verification::{
|
||||||
|
accept::{AcceptEventContent, AcceptToDeviceEventContent},
|
||||||
start::{StartEventContent, StartMethod, StartToDeviceEventContent},
|
start::{StartEventContent, StartMethod, StartToDeviceEventContent},
|
||||||
KeyAgreementProtocol,
|
KeyAgreementProtocol,
|
||||||
},
|
},
|
||||||
AnyMessageEventContent, AnyToDeviceEventContent, MessageEvent, ToDeviceEvent,
|
AnyMessageEventContent, AnyToDeviceEventContent, MessageEvent, ToDeviceEvent,
|
||||||
},
|
},
|
||||||
|
identifiers::RoomId,
|
||||||
CanonicalJsonValue,
|
CanonicalJsonValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,28 +34,28 @@ use super::FlowId;
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum StartContent {
|
pub enum StartContent {
|
||||||
ToDevice(StartToDeviceEventContent),
|
ToDevice(StartToDeviceEventContent),
|
||||||
Room(StartEventContent),
|
Room(RoomId, StartEventContent),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StartContent {
|
impl StartContent {
|
||||||
pub fn method(&self) -> &StartMethod {
|
pub fn method(&self) -> &StartMethod {
|
||||||
match self {
|
match self {
|
||||||
StartContent::ToDevice(c) => &c.method,
|
StartContent::ToDevice(c) => &c.method,
|
||||||
StartContent::Room(c) => &c.method,
|
StartContent::Room(_, c) => &c.method,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn flow_id(&self) -> FlowId {
|
pub fn flow_id(&self) -> FlowId {
|
||||||
match self {
|
match self {
|
||||||
StartContent::ToDevice(c) => FlowId::ToDevice(c.transaction_id.clone()),
|
StartContent::ToDevice(c) => FlowId::ToDevice(c.transaction_id.clone()),
|
||||||
StartContent::Room(c) => FlowId::InRoom(c.relation.event_id.clone()),
|
StartContent::Room(r, c) => FlowId::InRoom(r.clone(), c.relation.event_id.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_canonical_json(self) -> CanonicalJsonValue {
|
pub fn to_canonical_json(self) -> CanonicalJsonValue {
|
||||||
let content = match self {
|
let content = match self {
|
||||||
StartContent::Room(c) => serde_json::to_value(c),
|
|
||||||
StartContent::ToDevice(c) => serde_json::to_value(c),
|
StartContent::ToDevice(c) => serde_json::to_value(c),
|
||||||
|
StartContent::Room(_, c) => serde_json::to_value(c),
|
||||||
};
|
};
|
||||||
|
|
||||||
content
|
content
|
||||||
|
@ -63,9 +65,9 @@ impl StartContent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<StartEventContent> for StartContent {
|
impl From<(RoomId, StartEventContent)> for StartContent {
|
||||||
fn from(content: StartEventContent) -> Self {
|
fn from(tuple: (RoomId, StartEventContent)) -> Self {
|
||||||
StartContent::Room(content)
|
StartContent::Room(tuple.0, tuple.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,16 +77,34 @@ impl From<StartToDeviceEventContent> for StartContent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum AcceptContent {
|
||||||
|
ToDevice(AcceptToDeviceEventContent),
|
||||||
|
Room(RoomId, AcceptEventContent),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AcceptToDeviceEventContent> for AcceptContent {
|
||||||
|
fn from(content: AcceptToDeviceEventContent) -> Self {
|
||||||
|
AcceptContent::ToDevice(content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(RoomId, AcceptEventContent)> for AcceptContent {
|
||||||
|
fn from(content: (RoomId, AcceptEventContent)) -> Self {
|
||||||
|
AcceptContent::Room(content.0, content.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum OutgoingContent {
|
pub enum OutgoingContent {
|
||||||
Room(AnyMessageEventContent),
|
Room(RoomId, AnyMessageEventContent),
|
||||||
ToDevice(AnyToDeviceEventContent),
|
ToDevice(AnyToDeviceEventContent),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<StartContent> for OutgoingContent {
|
impl From<StartContent> for OutgoingContent {
|
||||||
fn from(content: StartContent) -> Self {
|
fn from(content: StartContent) -> Self {
|
||||||
match content {
|
match content {
|
||||||
StartContent::Room(c) => AnyMessageEventContent::KeyVerificationStart(c).into(),
|
StartContent::Room(r, c) => (r, AnyMessageEventContent::KeyVerificationStart(c)).into(),
|
||||||
StartContent::ToDevice(c) => AnyToDeviceEventContent::KeyVerificationStart(c).into(),
|
StartContent::ToDevice(c) => AnyToDeviceEventContent::KeyVerificationStart(c).into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,8 +116,8 @@ impl From<AnyToDeviceEventContent> for OutgoingContent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<AnyMessageEventContent> for OutgoingContent {
|
impl From<(RoomId, AnyMessageEventContent)> for OutgoingContent {
|
||||||
fn from(content: AnyMessageEventContent) -> Self {
|
fn from(content: (RoomId, AnyMessageEventContent)) -> Self {
|
||||||
OutgoingContent::Room(content)
|
OutgoingContent::Room(content.0, content.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ use matrix_sdk_common::{
|
||||||
},
|
},
|
||||||
AnyToDeviceEvent, AnyToDeviceEventContent, MessageEvent, ToDeviceEvent,
|
AnyToDeviceEvent, AnyToDeviceEventContent, MessageEvent, ToDeviceEvent,
|
||||||
},
|
},
|
||||||
identifiers::{EventId, UserId},
|
identifiers::{EventId, RoomId, UserId},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -36,7 +36,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
event_enums::OutgoingContent,
|
event_enums::{AcceptContent, 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,
|
||||||
|
@ -69,11 +69,18 @@ impl InnerSas {
|
||||||
|
|
||||||
pub fn start_in_room(
|
pub fn start_in_room(
|
||||||
event_id: EventId,
|
event_id: EventId,
|
||||||
|
room_id: RoomId,
|
||||||
account: ReadOnlyAccount,
|
account: ReadOnlyAccount,
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<UserIdentities>,
|
||||||
) -> (InnerSas, OutgoingContent) {
|
) -> (InnerSas, OutgoingContent) {
|
||||||
let sas = SasState::<Created>::new_in_room(event_id, account, other_device, other_identity);
|
let sas = SasState::<Created>::new_in_room(
|
||||||
|
room_id,
|
||||||
|
event_id,
|
||||||
|
account,
|
||||||
|
other_device,
|
||||||
|
other_identity,
|
||||||
|
);
|
||||||
let content = sas.as_content();
|
let content = sas.as_content();
|
||||||
(InnerSas::Created(sas), content)
|
(InnerSas::Created(sas), content)
|
||||||
}
|
}
|
||||||
|
@ -97,7 +104,7 @@ impl InnerSas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn accept(&self) -> Option<AcceptToDeviceEventContent> {
|
pub fn accept(&self) -> Option<AcceptContent> {
|
||||||
if let InnerSas::Started(s) = self {
|
if let InnerSas::Started(s) = self {
|
||||||
Some(s.as_content())
|
Some(s.as_content())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -20,6 +20,7 @@ mod sas_state;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use event_enums::AcceptContent;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use tracing::{error, info, trace, warn};
|
use tracing::{error, info, trace, warn};
|
||||||
|
|
||||||
|
@ -30,15 +31,18 @@ use matrix_sdk_common::{
|
||||||
cancel::CancelCode,
|
cancel::CancelCode,
|
||||||
start::{StartEventContent, StartToDeviceEventContent},
|
start::{StartEventContent, StartToDeviceEventContent},
|
||||||
},
|
},
|
||||||
AnyToDeviceEvent, AnyToDeviceEventContent, MessageEvent, ToDeviceEvent,
|
AnyMessageEventContent, AnyToDeviceEvent, AnyToDeviceEventContent, MessageEvent,
|
||||||
|
ToDeviceEvent,
|
||||||
},
|
},
|
||||||
identifiers::{DeviceId, EventId, RoomId, UserId},
|
identifiers::{DeviceId, EventId, RoomId, UserId},
|
||||||
|
uuid::Uuid,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::SignatureError,
|
error::SignatureError,
|
||||||
identities::{LocalTrust, ReadOnlyDevice, UserIdentities},
|
identities::{LocalTrust, ReadOnlyDevice, UserIdentities},
|
||||||
olm::PrivateCrossSigningIdentity,
|
olm::PrivateCrossSigningIdentity,
|
||||||
|
requests::{OutgoingVerificationRequest, RoomMessageRequest},
|
||||||
store::{Changes, CryptoStore, CryptoStoreError, DeviceChanges},
|
store::{Changes, CryptoStore, CryptoStoreError, DeviceChanges},
|
||||||
ReadOnlyAccount, ToDeviceRequest,
|
ReadOnlyAccount, ToDeviceRequest,
|
||||||
};
|
};
|
||||||
|
@ -189,6 +193,7 @@ impl Sas {
|
||||||
) -> (Sas, OutgoingContent) {
|
) -> (Sas, OutgoingContent) {
|
||||||
let (inner, content) = InnerSas::start_in_room(
|
let (inner, content) = InnerSas::start_in_room(
|
||||||
flow_id,
|
flow_id,
|
||||||
|
room_id,
|
||||||
account.clone(),
|
account.clone(),
|
||||||
other_device.clone(),
|
other_device.clone(),
|
||||||
other_identity.clone(),
|
other_identity.clone(),
|
||||||
|
@ -249,10 +254,18 @@ impl Sas {
|
||||||
///
|
///
|
||||||
/// This does nothing if the verification was already accepted, otherwise it
|
/// This does nothing if the verification was already accepted, otherwise it
|
||||||
/// returns an `AcceptEventContent` that needs to be sent out.
|
/// returns an `AcceptEventContent` that needs to be sent out.
|
||||||
pub fn accept(&self) -> Option<ToDeviceRequest> {
|
pub fn accept(&self) -> Option<OutgoingVerificationRequest> {
|
||||||
self.inner.lock().unwrap().accept().map(|c| {
|
self.inner.lock().unwrap().accept().map(|c| match c {
|
||||||
let content = AnyToDeviceEventContent::KeyVerificationAccept(c);
|
AcceptContent::ToDevice(c) => {
|
||||||
self.content_to_request(content)
|
let content = AnyToDeviceEventContent::KeyVerificationAccept(c);
|
||||||
|
self.content_to_request(content).into()
|
||||||
|
}
|
||||||
|
AcceptContent::Room(room_id, content) => RoomMessageRequest {
|
||||||
|
room_id,
|
||||||
|
txn_id: Uuid::new_v4(),
|
||||||
|
content: AnyMessageEventContent::KeyVerificationAccept(content),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
convert::TryFrom,
|
convert::TryFrom,
|
||||||
|
matches,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
@ -24,8 +25,8 @@ use matrix_sdk_common::{
|
||||||
events::{
|
events::{
|
||||||
key::verification::{
|
key::verification::{
|
||||||
accept::{
|
accept::{
|
||||||
AcceptMethod, AcceptToDeviceEventContent, MSasV1Content as AcceptV1Content,
|
AcceptEventContent, AcceptMethod, AcceptToDeviceEventContent,
|
||||||
MSasV1ContentInit as AcceptV1ContentInit,
|
MSasV1Content as AcceptV1Content, MSasV1ContentInit as AcceptV1ContentInit,
|
||||||
},
|
},
|
||||||
cancel::{CancelCode, CancelToDeviceEventContent},
|
cancel::{CancelCode, CancelToDeviceEventContent},
|
||||||
key::KeyToDeviceEventContent,
|
key::KeyToDeviceEventContent,
|
||||||
|
@ -39,13 +40,13 @@ use matrix_sdk_common::{
|
||||||
},
|
},
|
||||||
AnyMessageEventContent, AnyToDeviceEventContent, MessageEvent, ToDeviceEvent,
|
AnyMessageEventContent, AnyToDeviceEventContent, MessageEvent, ToDeviceEvent,
|
||||||
},
|
},
|
||||||
identifiers::{DeviceId, EventId, UserId},
|
identifiers::{DeviceId, EventId, RoomId, UserId},
|
||||||
uuid::Uuid,
|
uuid::Uuid,
|
||||||
};
|
};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
event_enums::{OutgoingContent, StartContent},
|
event_enums::{AcceptContent, 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,
|
||||||
},
|
},
|
||||||
|
@ -74,20 +75,28 @@ const MAX_EVENT_TIMEOUT: Duration = Duration::from_secs(60);
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum FlowId {
|
pub enum FlowId {
|
||||||
ToDevice(String),
|
ToDevice(String),
|
||||||
InRoom(EventId),
|
InRoom(RoomId, EventId),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlowId {
|
impl FlowId {
|
||||||
|
pub fn room_id(&self) -> Option<&RoomId> {
|
||||||
|
if let FlowId::InRoom(r, _) = &self {
|
||||||
|
Some(r)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_string(&self) -> String {
|
pub fn to_string(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
FlowId::InRoom(r) => r.to_string(),
|
FlowId::InRoom(_, r) => r.to_string(),
|
||||||
FlowId::ToDevice(t) => t.to_string(),
|
FlowId::ToDevice(t) => t.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_str(&self) -> &str {
|
pub fn as_str(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
FlowId::InRoom(r) => r.as_str(),
|
FlowId::InRoom(_, r) => r.as_str(),
|
||||||
FlowId::ToDevice(t) => t.as_str(),
|
FlowId::ToDevice(t) => t.as_str(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,12 +349,13 @@ impl SasState<Created> {
|
||||||
///
|
///
|
||||||
/// * `other_identity` - The identity of the other user if one exists.
|
/// * `other_identity` - The identity of the other user if one exists.
|
||||||
pub fn new_in_room(
|
pub fn new_in_room(
|
||||||
|
room_id: RoomId,
|
||||||
event_id: EventId,
|
event_id: EventId,
|
||||||
account: ReadOnlyAccount,
|
account: ReadOnlyAccount,
|
||||||
other_device: ReadOnlyDevice,
|
other_device: ReadOnlyDevice,
|
||||||
other_identity: Option<UserIdentities>,
|
other_identity: Option<UserIdentities>,
|
||||||
) -> SasState<Created> {
|
) -> SasState<Created> {
|
||||||
let flow_id = FlowId::InRoom(event_id);
|
let flow_id = FlowId::InRoom(room_id, event_id);
|
||||||
Self::new_helper(flow_id, account, other_device, other_identity)
|
Self::new_helper(flow_id, account, other_device, other_identity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +390,7 @@ impl SasState<Created> {
|
||||||
|
|
||||||
pub fn as_start_content(&self) -> StartContent {
|
pub fn as_start_content(&self) -> StartContent {
|
||||||
match self.verification_flow_id.as_ref() {
|
match self.verification_flow_id.as_ref() {
|
||||||
FlowId::ToDevice(s) => StartContent::ToDevice(StartToDeviceEventContent {
|
FlowId::ToDevice(_) => StartContent::ToDevice(StartToDeviceEventContent {
|
||||||
transaction_id: self.verification_flow_id.to_string(),
|
transaction_id: self.verification_flow_id.to_string(),
|
||||||
from_device: self.device_id().into(),
|
from_device: self.device_id().into(),
|
||||||
method: StartMethod::MSasV1(
|
method: StartMethod::MSasV1(
|
||||||
|
@ -388,16 +398,19 @@ impl SasState<Created> {
|
||||||
.expect("Invalid initial protocol definitions."),
|
.expect("Invalid initial protocol definitions."),
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
FlowId::InRoom(e) => StartContent::Room(StartEventContent {
|
FlowId::InRoom(r, e) => StartContent::Room(
|
||||||
from_device: self.device_id().into(),
|
r.clone(),
|
||||||
method: StartMethod::MSasV1(
|
StartEventContent {
|
||||||
MSasV1Content::new(self.state.protocol_definitions.clone())
|
from_device: self.device_id().into(),
|
||||||
.expect("Invalid initial protocol definitions."),
|
method: StartMethod::MSasV1(
|
||||||
),
|
MSasV1Content::new(self.state.protocol_definitions.clone())
|
||||||
relation: Relation {
|
.expect("Invalid initial protocol definitions."),
|
||||||
event_id: e.clone(),
|
),
|
||||||
|
relation: Relation {
|
||||||
|
event_id: e.clone(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,25 +571,40 @@ impl SasState<Started> {
|
||||||
/// This should be sent out automatically if the SAS verification flow has
|
/// This should be sent out automatically if the SAS verification flow has
|
||||||
/// been started because of a
|
/// been started because of a
|
||||||
/// m.key.verification.request -> m.key.verification.ready flow.
|
/// m.key.verification.request -> m.key.verification.ready flow.
|
||||||
pub fn as_content(&self) -> AcceptToDeviceEventContent {
|
pub fn as_content(&self) -> AcceptContent {
|
||||||
let accepted_protocols = AcceptedProtocols::default();
|
let accepted_protocols = AcceptedProtocols::default();
|
||||||
|
|
||||||
AcceptToDeviceEventContent {
|
let method = AcceptMethod::MSasV1(
|
||||||
transaction_id: self.verification_flow_id.to_string(),
|
AcceptV1ContentInit {
|
||||||
method: AcceptMethod::MSasV1(
|
commitment: self.state.commitment.clone(),
|
||||||
AcceptV1ContentInit {
|
hash: accepted_protocols.hash,
|
||||||
commitment: self.state.commitment.clone(),
|
key_agreement_protocol: accepted_protocols.key_agreement_protocol,
|
||||||
hash: accepted_protocols.hash,
|
message_authentication_code: accepted_protocols.message_auth_code,
|
||||||
key_agreement_protocol: accepted_protocols.key_agreement_protocol,
|
short_authentication_string: self
|
||||||
message_authentication_code: accepted_protocols.message_auth_code,
|
.state
|
||||||
short_authentication_string: self
|
.protocol_definitions
|
||||||
.state
|
.short_authentication_string
|
||||||
.protocol_definitions
|
.clone(),
|
||||||
.short_authentication_string
|
}
|
||||||
.clone(),
|
.into(),
|
||||||
}
|
);
|
||||||
|
|
||||||
|
match self.verification_flow_id.as_ref() {
|
||||||
|
FlowId::ToDevice(_) => AcceptToDeviceEventContent {
|
||||||
|
transaction_id: self.verification_flow_id.to_string(),
|
||||||
|
method,
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
FlowId::InRoom(r, e) => (
|
||||||
|
r.clone(),
|
||||||
|
AcceptEventContent {
|
||||||
|
method,
|
||||||
|
relation: Relation {
|
||||||
|
event_id: e.clone(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
.into(),
|
.into(),
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,7 +704,7 @@ impl SasState<Accepted> {
|
||||||
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) => {
|
FlowId::InRoom(_, r) => {
|
||||||
todo!("In-room verifications aren't implemented")
|
todo!("In-room verifications aren't implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue