diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index e6799e9801..44f8daaf64 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -1,15 +1,29 @@ mod error; mod logger; mod machine; +mod responses; pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; pub use logger::{set_logger, Logger}; -pub use machine::{ - DecryptedEvent, Device, DeviceLists, KeysImportResult, OlmMachine, Request, RequestType, Sas, -}; +pub use machine::{Device, OlmMachine, Sas}; +pub use responses::{DeviceLists, KeysImportResult, Request, RequestType}; pub trait ProgressListener { fn on_progress(&self, progress: i32, total: i32); } +/// An event that was successfully decrypted. +pub struct DecryptedEvent { + /// The decrypted version of the event. + pub clear_event: String, + /// The claimed curve25519 key of the sender. + pub sender_curve25519_key: String, + /// The claimed ed25519 key of the sender. + pub claimed_ed25519_key: Option, + /// The curve25519 chain of the senders that forwarded the Megolm decryption + /// key to us. Is empty if the key came directly from the sender of the + /// event. + pub forwarding_curve25519_chain: Vec, +} + include!(concat!(env!("OUT_DIR"), "/olm.uniffi.rs")); diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 1ef9a30379..27bc93634b 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -4,7 +4,6 @@ use std::{ io::Cursor, }; -use http::Response; use serde_json::{json, value::RawValue}; use tokio::runtime::Runtime; @@ -17,7 +16,6 @@ use matrix_sdk_common::{ sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, to_device::send_event_to_device::Response as ToDeviceResponse, }, - assign, deserialized_responses::events::{AlgorithmInfo, SyncMessageEvent}, events::{room::encrypted::EncryptedEventContent, AnyMessageEventContent, EventContent}, identifiers::{DeviceKeyAlgorithm, RoomId, UserId}, @@ -26,109 +24,43 @@ use matrix_sdk_common::{ }; use matrix_sdk_crypto::{ - decrypt_key_export, encrypt_key_export, EncryptionSettings, IncomingResponse, - OlmMachine as InnerMachine, OutgoingRequest, ToDeviceRequest, + decrypt_key_export, encrypt_key_export, Device as InnerDevice, EncryptionSettings, + OlmMachine as InnerMachine, }; use crate::{ error::{CryptoStoreError, DecryptionError, MachineCreationError}, - KeyImportError, ProgressListener, + responses::{response_from_string, OwnedResponse}, + DecryptedEvent, DeviceLists, KeyImportError, KeysImportResult, ProgressListener, Request, + RequestType, }; +/// A high level state machine that handles E2EE for Matrix. pub struct OlmMachine { inner: InnerMachine, runtime: Runtime, } -pub struct DecryptedEvent { - pub clear_event: String, - pub sender_curve25519_key: String, - pub claimed_ed25519_key: Option, - pub forwarding_curve25519_chain: Vec, -} - -pub struct DeviceLists { - pub changed: Vec, - pub left: Vec, -} - -impl Into for DeviceLists { - fn into(self) -> RumaDeviceLists { - assign!(RumaDeviceLists::new(), { - changed: self - .changed - .into_iter() - .filter_map(|u| UserId::try_from(u).ok()) - .collect(), - left: self - .left - .into_iter() - .filter_map(|u| UserId::try_from(u).ok()) - .collect(), - }) - } -} - -pub struct KeysImportResult { - pub total: i32, - pub imported: i32, -} - -enum OwnedResponse { - KeysClaim(KeysClaimResponse), - KeysUpload(KeysUploadResponse), - KeysQuery(KeysQueryResponse), - ToDevice(ToDeviceResponse), -} - -impl From for OwnedResponse { - fn from(response: KeysClaimResponse) -> Self { - OwnedResponse::KeysClaim(response) - } -} - -impl From for OwnedResponse { - fn from(response: KeysQueryResponse) -> Self { - OwnedResponse::KeysQuery(response) - } -} - -impl From for OwnedResponse { - fn from(response: KeysUploadResponse) -> Self { - OwnedResponse::KeysUpload(response) - } -} - -impl From for OwnedResponse { - fn from(response: ToDeviceResponse) -> Self { - OwnedResponse::ToDevice(response) - } -} - -impl<'a> Into> for &'a OwnedResponse { - fn into(self) -> IncomingResponse<'a> { - match self { - OwnedResponse::KeysClaim(r) => IncomingResponse::KeysClaim(r), - OwnedResponse::KeysQuery(r) => IncomingResponse::KeysQuery(r), - OwnedResponse::KeysUpload(r) => IncomingResponse::KeysUpload(r), - OwnedResponse::ToDevice(r) => IncomingResponse::ToDevice(r), - } - } -} - -pub enum RequestType { - KeysQuery, - KeysClaim, - KeysUpload, - ToDevice, -} - pub struct Device { pub user_id: String, pub device_id: String, pub keys: HashMap, } +impl From for Device { + fn from(d: InnerDevice) -> Self { + Device { + user_id: d.user_id().to_string(), + device_id: d.device_id().to_string(), + keys: d + .keys() + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + } + } +} + pub struct Sas { pub other_user_id: String, pub other_device_id: String, @@ -136,84 +68,6 @@ pub struct Sas { pub request: Request, } -pub enum Request { - ToDevice { - request_id: String, - event_type: String, - body: String, - }, - KeysUpload { - request_id: String, - body: String, - }, - KeysQuery { - request_id: String, - users: Vec, - }, - KeysClaim { - request_id: String, - one_time_keys: HashMap>, - }, -} - -impl From for Request { - fn from(r: OutgoingRequest) -> Self { - use matrix_sdk_crypto::OutgoingRequests::*; - - match r.request() { - KeysUpload(u) => { - let body = json!({ - "device_keys": u.device_keys, - "one_time_keys": u.one_time_keys, - }); - - Request::KeysUpload { - request_id: r.request_id().to_string(), - body: serde_json::to_string(&body) - .expect("Can't serialize keys upload request"), - } - } - KeysQuery(k) => { - let users: Vec = k.device_keys.keys().map(|u| u.to_string()).collect(); - Request::KeysQuery { - request_id: r.request_id().to_string(), - users, - } - } - ToDeviceRequest(t) => Request::from(t), - SignatureUpload(_) => todo!(), - RoomMessage(_) => todo!(), - } - } -} - -impl From for Request { - fn from(r: ToDeviceRequest) -> Self { - Request::ToDevice { - request_id: r.txn_id_string(), - event_type: r.event_type.to_string(), - body: serde_json::to_string(&r.messages).unwrap(), - } - } -} - -impl From<&ToDeviceRequest> for Request { - fn from(r: &ToDeviceRequest) -> Self { - Request::ToDevice { - request_id: r.txn_id_string(), - event_type: r.event_type.to_string(), - body: serde_json::to_string(&r.messages).unwrap(), - } - } -} - -fn response_from_string(body: &str) -> Response> { - Response::builder() - .status(200) - .body(body.as_bytes().to_vec()) - .expect("Can't create HTTP response") -} - impl OlmMachine { pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { let user_id = UserId::try_from(user_id)?; @@ -242,15 +96,7 @@ impl OlmMachine { self.runtime .block_on(self.inner.get_device(&user_id, device_id.into())) .unwrap() - .map(|d| Device { - user_id: d.user_id().to_string(), - device_id: d.device_id().to_string(), - keys: d - .keys() - .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - }) + .map(|d| d.into()) } pub fn get_user_devices(&self, user_id: &str) -> Vec { @@ -259,15 +105,7 @@ impl OlmMachine { .block_on(self.inner.get_user_devices(&user_id)) .unwrap() .devices() - .map(|d| Device { - user_id: d.user_id().to_string(), - device_id: d.device_id().to_string(), - keys: d - .keys() - .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - }) + .map(|d| d.into()) .collect() } diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs new file mode 100644 index 0000000000..4861920598 --- /dev/null +++ b/rust-sdk/src/responses.rs @@ -0,0 +1,179 @@ +use std::{ + collections::HashMap, + convert::TryFrom, +}; + +use http::Response; +use serde_json::json; + +use matrix_sdk_common::{ + api::r0::{ + keys::{ + claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, + upload_keys::Response as KeysUploadResponse, + }, + sync::sync_events::DeviceLists as RumaDeviceLists, + to_device::send_event_to_device::Response as ToDeviceResponse, + }, + assign, + identifiers::UserId, +}; + +use matrix_sdk_crypto::{ + IncomingResponse, OutgoingRequest, ToDeviceRequest, +}; + +pub enum Request { + ToDevice { + request_id: String, + event_type: String, + body: String, + }, + KeysUpload { + request_id: String, + body: String, + }, + KeysQuery { + request_id: String, + users: Vec, + }, + KeysClaim { + request_id: String, + one_time_keys: HashMap>, + }, +} + +impl From for Request { + fn from(r: OutgoingRequest) -> Self { + use matrix_sdk_crypto::OutgoingRequests::*; + + match r.request() { + KeysUpload(u) => { + let body = json!({ + "device_keys": u.device_keys, + "one_time_keys": u.one_time_keys, + }); + + Request::KeysUpload { + request_id: r.request_id().to_string(), + body: serde_json::to_string(&body) + .expect("Can't serialize keys upload request"), + } + } + KeysQuery(k) => { + let users: Vec = k.device_keys.keys().map(|u| u.to_string()).collect(); + Request::KeysQuery { + request_id: r.request_id().to_string(), + users, + } + } + ToDeviceRequest(t) => Request::from(t), + SignatureUpload(_) => todo!(), + RoomMessage(_) => todo!(), + } + } +} + +impl From for Request { + fn from(r: ToDeviceRequest) -> Self { + Request::ToDevice { + request_id: r.txn_id_string(), + event_type: r.event_type.to_string(), + body: serde_json::to_string(&r.messages).unwrap(), + } + } +} + +impl From<&ToDeviceRequest> for Request { + fn from(r: &ToDeviceRequest) -> Self { + Request::ToDevice { + request_id: r.txn_id_string(), + event_type: r.event_type.to_string(), + body: serde_json::to_string(&r.messages).unwrap(), + } + } +} + +pub(crate) fn response_from_string(body: &str) -> Response> { + Response::builder() + .status(200) + .body(body.as_bytes().to_vec()) + .expect("Can't create HTTP response") +} + + +pub enum RequestType { + KeysQuery, + KeysClaim, + KeysUpload, + ToDevice, +} + +pub struct DeviceLists { + pub changed: Vec, + pub left: Vec, +} + +impl Into for DeviceLists { + fn into(self) -> RumaDeviceLists { + assign!(RumaDeviceLists::new(), { + changed: self + .changed + .into_iter() + .filter_map(|u| UserId::try_from(u).ok()) + .collect(), + left: self + .left + .into_iter() + .filter_map(|u| UserId::try_from(u).ok()) + .collect(), + }) + } +} + +pub struct KeysImportResult { + pub total: i32, + pub imported: i32, +} + +pub(crate) enum OwnedResponse { + KeysClaim(KeysClaimResponse), + KeysUpload(KeysUploadResponse), + KeysQuery(KeysQueryResponse), + ToDevice(ToDeviceResponse), +} + +impl From for OwnedResponse { + fn from(response: KeysClaimResponse) -> Self { + OwnedResponse::KeysClaim(response) + } +} + +impl From for OwnedResponse { + fn from(response: KeysQueryResponse) -> Self { + OwnedResponse::KeysQuery(response) + } +} + +impl From for OwnedResponse { + fn from(response: KeysUploadResponse) -> Self { + OwnedResponse::KeysUpload(response) + } +} + +impl From for OwnedResponse { + fn from(response: ToDeviceResponse) -> Self { + OwnedResponse::ToDevice(response) + } +} + +impl<'a> Into> for &'a OwnedResponse { + fn into(self) -> IncomingResponse<'a> { + match self { + OwnedResponse::KeysClaim(r) => IncomingResponse::KeysClaim(r), + OwnedResponse::KeysQuery(r) => IncomingResponse::KeysQuery(r), + OwnedResponse::KeysUpload(r) => IncomingResponse::KeysUpload(r), + OwnedResponse::ToDevice(r) => IncomingResponse::ToDevice(r), + } + } +}