matrix-sdk: Update ruma

Co-authored-by: Damir Jelić <poljar@termina.org.uk>
This commit is contained in:
Jonas Platte 2021-06-20 01:35:28 +02:00 committed by Damir Jelić
parent bdd35206e8
commit 43e213fd67
30 changed files with 369 additions and 362 deletions

View file

@ -20,5 +20,5 @@ byteorder = "1.4.3"
image = { version = "0.23.14", optional = true }
qrcode = { version = "0.12.0", default-features = false }
rqrr = { version = "0.3.2" , optional = true }
ruma-identifiers = "0.19.1"
ruma-identifiers = { version = "0.19.3", git = "https://github.com/ruma/ruma", rev = "d73ab8add" }
thiserror = "1.0.24"

View file

@ -56,6 +56,8 @@ default_features = false
[dependencies.ruma]
version = "0.1.2"
git = "https://github.com/ruma/ruma"
rev = "d73ab8add"
features = ["client-api-c", "compat", "unstable-pre-spec"]
[dependencies.tokio-stream]

View file

@ -142,7 +142,7 @@ async fn login(
if let Some(Verification::SasV1(sas)) = client
.get_verification(
&e.sender,
e.content.relation.event_id.as_str(),
e.content.relates_to.event_id.as_str(),
)
.await
{
@ -153,7 +153,7 @@ async fn login(
if let Some(Verification::SasV1(sas)) = client
.get_verification(
&e.sender,
e.content.relation.event_id.as_str(),
e.content.relates_to.event_id.as_str(),
)
.await
{

View file

@ -1786,8 +1786,8 @@ impl Client {
request: &ToDeviceRequest,
) -> Result<ToDeviceResponse> {
let txn_id_string = request.txn_id_string();
let request = RumaToDeviceRequest::new(
request.event_type.clone(),
let request = RumaToDeviceRequest::new_raw(
request.event_type.as_str(),
&txn_id_string,
request.messages.clone(),
);

View file

@ -47,6 +47,7 @@ use ruma::{
GlobalAccountDataEvent, RoomAccountDataEvent, StrippedStateEvent, SyncEphemeralRoomEvent,
SyncMessageEvent, SyncStateEvent,
},
serde::Raw,
RoomId,
};
use serde_json::value::RawValue as RawJsonValue;
@ -89,14 +90,24 @@ impl Handler {
self.handle_room_account_data_event(room.clone(), &event).await;
}
for event in room_info.state.events.iter().filter_map(|e| e.deserialize().ok()) {
self.handle_state_event(room.clone(), &event).await;
for (raw_event, event) in room_info.state.events.iter().filter_map(|e| {
if let Ok(d) = e.deserialize() {
Some((e, d))
} else {
None
}
}) {
self.handle_state_event(room.clone(), &event, raw_event).await;
}
for event in
room_info.timeline.events.iter().filter_map(|e| e.event.deserialize().ok())
{
self.handle_timeline_event(room.clone(), &event).await;
for (raw_event, event) in room_info.timeline.events.iter().filter_map(|e| {
if let Ok(d) = e.event.deserialize() {
Some((&e.event, d))
} else {
None
}
}) {
self.handle_timeline_event(room.clone(), &event, raw_event).await;
}
}
}
@ -109,14 +120,24 @@ impl Handler {
self.handle_room_account_data_event(room.clone(), &event).await;
}
for event in room_info.state.events.iter().filter_map(|e| e.deserialize().ok()) {
self.handle_state_event(room.clone(), &event).await;
for (raw_event, event) in room_info.state.events.iter().filter_map(|e| {
if let Ok(d) = e.deserialize() {
Some((e, d))
} else {
None
}
}) {
self.handle_state_event(room.clone(), &event, raw_event).await;
}
for event in
room_info.timeline.events.iter().filter_map(|e| e.event.deserialize().ok())
{
self.handle_timeline_event(room.clone(), &event).await;
for (raw_event, event) in room_info.timeline.events.iter().filter_map(|e| {
if let Ok(d) = e.event.deserialize() {
Some((&e.event, d))
} else {
None
}
}) {
self.handle_timeline_event(room.clone(), &event, raw_event).await;
}
}
}
@ -144,7 +165,12 @@ impl Handler {
}
}
async fn handle_timeline_event(&self, room: Room, event: &AnySyncRoomEvent) {
async fn handle_timeline_event(
&self,
room: Room,
event: &AnySyncRoomEvent,
raw_event: &Raw<AnySyncRoomEvent>,
) {
match event {
AnySyncRoomEvent::State(event) => match event {
AnySyncStateEvent::RoomMember(e) => self.on_room_member(room, e).await,
@ -157,10 +183,25 @@ impl Handler {
AnySyncStateEvent::RoomPowerLevels(e) => self.on_room_power_levels(room, e).await,
AnySyncStateEvent::RoomTombstone(e) => self.on_room_tombstone(room, e).await,
AnySyncStateEvent::RoomJoinRules(e) => self.on_room_join_rules(room, e).await,
AnySyncStateEvent::Custom(e) => {
self.on_custom_event(room, &CustomEvent::State(e)).await
AnySyncStateEvent::PolicyRuleRoom(_)
| AnySyncStateEvent::PolicyRuleServer(_)
| AnySyncStateEvent::PolicyRuleUser(_)
| AnySyncStateEvent::RoomCreate(_)
| AnySyncStateEvent::RoomEncryption(_)
| AnySyncStateEvent::RoomGuestAccess(_)
| AnySyncStateEvent::RoomHistoryVisibility(_)
| AnySyncStateEvent::RoomPinnedEvents(_)
| AnySyncStateEvent::RoomServerAcl(_)
| AnySyncStateEvent::RoomThirdPartyInvite(_)
| AnySyncStateEvent::RoomTopic(_)
| AnySyncStateEvent::SpaceChild(_)
| AnySyncStateEvent::SpaceParent(_) => {}
_ => {
if let Ok(e) = raw_event.deserialize_as::<SyncStateEvent<CustomEventContent>>()
{
self.on_custom_event(room, &CustomEvent::State(&e)).await;
}
}
_ => {}
},
AnySyncRoomEvent::Message(event) => match event {
AnySyncMessageEvent::RoomMessage(e) => self.on_room_message(room, e).await,
@ -169,23 +210,40 @@ impl Handler {
}
AnySyncMessageEvent::RoomRedaction(e) => self.on_room_redaction(room, e).await,
AnySyncMessageEvent::Reaction(e) => self.on_room_reaction(room, e).await,
AnySyncMessageEvent::Custom(e) => {
self.on_custom_event(room, &CustomEvent::Message(e)).await
}
AnySyncMessageEvent::CallInvite(e) => self.on_room_call_invite(room, e).await,
AnySyncMessageEvent::CallAnswer(e) => self.on_room_call_answer(room, e).await,
AnySyncMessageEvent::CallCandidates(e) => {
self.on_room_call_candidates(room, e).await
}
AnySyncMessageEvent::CallHangup(e) => self.on_room_call_hangup(room, e).await,
_ => {}
AnySyncMessageEvent::KeyVerificationReady(_)
| AnySyncMessageEvent::KeyVerificationStart(_)
| AnySyncMessageEvent::KeyVerificationCancel(_)
| AnySyncMessageEvent::KeyVerificationAccept(_)
| AnySyncMessageEvent::KeyVerificationKey(_)
| AnySyncMessageEvent::KeyVerificationMac(_)
| AnySyncMessageEvent::KeyVerificationDone(_)
| AnySyncMessageEvent::RoomEncrypted(_)
| AnySyncMessageEvent::Sticker(_) => {}
_ => {
if let Ok(e) =
raw_event.deserialize_as::<SyncMessageEvent<CustomEventContent>>()
{
self.on_custom_event(room, &CustomEvent::Message(&e)).await;
}
}
},
AnySyncRoomEvent::RedactedState(_event) => {}
AnySyncRoomEvent::RedactedMessage(_event) => {}
}
}
async fn handle_state_event(&self, room: Room, event: &AnySyncStateEvent) {
async fn handle_state_event(
&self,
room: Room,
event: &AnySyncStateEvent,
raw_event: &Raw<AnySyncStateEvent>,
) {
match event {
AnySyncStateEvent::RoomMember(member) => self.on_state_member(room, member).await,
AnySyncStateEvent::RoomName(name) => self.on_state_name(room, name).await,
@ -202,10 +260,24 @@ impl Handler {
// TODO make `on_state_tombstone` method
self.on_room_tombstone(room, tomb).await
}
AnySyncStateEvent::Custom(custom) => {
self.on_custom_event(room, &CustomEvent::State(custom)).await
AnySyncStateEvent::PolicyRuleRoom(_)
| AnySyncStateEvent::PolicyRuleServer(_)
| AnySyncStateEvent::PolicyRuleUser(_)
| AnySyncStateEvent::RoomCreate(_)
| AnySyncStateEvent::RoomEncryption(_)
| AnySyncStateEvent::RoomGuestAccess(_)
| AnySyncStateEvent::RoomHistoryVisibility(_)
| AnySyncStateEvent::RoomPinnedEvents(_)
| AnySyncStateEvent::RoomServerAcl(_)
| AnySyncStateEvent::RoomThirdPartyInvite(_)
| AnySyncStateEvent::RoomTopic(_)
| AnySyncStateEvent::SpaceChild(_)
| AnySyncStateEvent::SpaceParent(_) => {}
_ => {
if let Ok(e) = raw_event.deserialize_as::<SyncStateEvent<CustomEventContent>>() {
self.on_custom_event(room, &CustomEvent::State(&e)).await;
}
}
_ => {}
}
}

View file

@ -33,6 +33,8 @@ matrix-sdk = { version = "0.2", path = "../matrix_sdk", default-features = false
[dependencies.ruma]
version = "0.1.2"
git = "https://github.com/ruma/ruma"
rev = "d73ab8add"
features = ["client-api-c", "appservice-api-s", "unstable-pre-spec"]
[dev-dependencies]

View file

@ -26,7 +26,7 @@ docs = ["encryption", "sled_cryptostore"]
[dependencies]
dashmap = "4.0.2"
lru = "0.6.5"
ruma = { version = "0.1.2", features = ["client-api-c", "unstable-pre-spec"] }
ruma = { version = "0.1.2", features = ["client-api-c", "unstable-pre-spec"], git = "https://github.com/ruma/ruma", rev = "d73ab8add" }
serde = { version = "1.0.122", features = ["rc"] }
serde_json = "1.0.61"
tracing = "0.1.22"

View file

@ -13,7 +13,7 @@ version = "0.2.0"
[dependencies]
async-trait = "0.1.42"
instant = { version = "0.1.9", features = ["wasm-bindgen", "now"] }
ruma = { version = "0.1.2", features = ["client-api-c"] }
ruma = { version = "0.1.2", features = ["client-api-c"], git = "https://github.com/ruma/ruma", rev = "d73ab8add" }
serde = "1.0.122"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]

View file

@ -22,7 +22,7 @@ docs = ["sled_cryptostore"]
[dependencies]
matrix-qrcode = { version = "0.1.0", path = "../matrix_qrcode" }
matrix-sdk-common = { version = "0.2.0", path = "../matrix_sdk_common" }
ruma = { version = "0.1.2", features = ["client-api-c", "unstable-pre-spec"] }
ruma = { version = "0.1.2", features = ["client-api-c", "unstable-pre-spec"], git = "https://github.com/ruma/ruma", rev = "d73ab8add" }
olm-rs = { version = "1.0.0", features = ["serde"] }
getrandom = "0.2.2"

View file

@ -25,11 +25,10 @@ use std::{
use atomic::Atomic;
use matrix_sdk_common::locks::Mutex;
use ruma::{
api::client::r0::keys::SignedKey,
encryption::DeviceKeys,
encryption::{DeviceKeys, SignedKey},
events::{
forwarded_room_key::ForwardedRoomKeyToDeviceEventContent,
room::encrypted::EncryptedEventContent, EventType,
room::encrypted::EncryptedEventContent, AnyToDeviceEventContent,
},
identifiers::{
DeviceId, DeviceIdBox, DeviceKeyAlgorithm, DeviceKeyId, EventEncryptionAlgorithm, UserId,
@ -176,15 +175,12 @@ impl Device {
///
/// # Arguments
///
/// * `event_type` - The type of the event.
///
/// * `content` - The content of the event that should be encrypted.
pub(crate) async fn encrypt(
&self,
event_type: EventType,
content: Value,
content: AnyToDeviceEventContent,
) -> OlmResult<(Session, EncryptedEventContent)> {
self.inner.encrypt(&*self.verification_machine.store, event_type, content).await
self.inner.encrypt(&*self.verification_machine.store, content).await
}
/// Encrypt the given inbound group session as a forwarded room key for this
@ -213,8 +209,7 @@ impl Device {
);
};
let content = serde_json::to_value(content)?;
self.encrypt(EventType::ForwardedRoomKey, content).await
self.encrypt(AnyToDeviceEventContent::ForwardedRoomKey(content)).await
}
}
@ -421,8 +416,7 @@ impl ReadOnlyDevice {
pub(crate) async fn encrypt(
&self,
store: &dyn CryptoStore,
event_type: EventType,
content: Value,
content: AnyToDeviceEventContent,
) -> OlmResult<(Session, EncryptedEventContent)> {
let sender_key = if let Some(k) = self.get_key(DeviceKeyAlgorithm::Curve25519) {
k
@ -455,7 +449,7 @@ impl ReadOnlyDevice {
return Err(OlmError::MissingSession);
};
let message = session.encrypt(self, event_type, content).await?;
let message = session.encrypt(self, content).await?;
Ok((session, message))
}

View file

@ -22,7 +22,7 @@ use std::{
};
use ruma::{
api::client::r0::keys::{CrossSigningKey, KeyUsage},
encryption::{CrossSigningKey, KeyUsage},
DeviceKeyId, UserId,
};
use serde::{Deserialize, Serialize};

View file

@ -20,21 +20,20 @@
// If we don't trust the device store an object that remembers the request and
// let the users introspect that object.
use std::{collections::BTreeMap, sync::Arc};
use std::sync::Arc;
use dashmap::{mapref::entry::Entry, DashMap, DashSet};
use matrix_sdk_common::uuid::Uuid;
use ruma::{
api::client::r0::to_device::DeviceIdOrAllDevices,
events::{
forwarded_room_key::ForwardedRoomKeyToDeviceEventContent,
room_key_request::{Action, RequestedKeyInfo, RoomKeyRequestToDeviceEventContent},
AnyToDeviceEvent, EventType, ToDeviceEvent,
AnyToDeviceEvent, AnyToDeviceEventContent, ToDeviceEvent,
},
identifiers::{DeviceId, DeviceIdBox, EventEncryptionAlgorithm, RoomId, UserId},
to_device::DeviceIdOrAllDevices,
};
use serde::{Deserialize, Serialize};
use serde_json::value::to_raw_value;
use thiserror::Error;
use tracing::{error, info, trace, warn};
@ -150,7 +149,7 @@ pub struct OutgoingKeyRequest {
}
impl OutgoingKeyRequest {
fn to_request(&self, own_device_id: &DeviceId) -> Result<OutgoingRequest, serde_json::Error> {
fn to_request(&self, own_device_id: &DeviceId) -> OutgoingRequest {
let content = RoomKeyRequestToDeviceEventContent::new(
Action::Request,
Some(self.info.clone()),
@ -158,13 +157,17 @@ impl OutgoingKeyRequest {
self.request_id.to_string(),
);
wrap_key_request_content(self.request_recipient.clone(), self.request_id, &content)
let request = ToDeviceRequest::new_with_id(
&self.request_recipient,
DeviceIdOrAllDevices::AllDevices,
AnyToDeviceEventContent::RoomKeyRequest(content),
self.request_id,
);
OutgoingRequest { request_id: request.txn_id, request: Arc::new(request.into()) }
}
fn to_cancellation(
&self,
own_device_id: &DeviceId,
) -> Result<OutgoingRequest, serde_json::Error> {
fn to_cancellation(&self, own_device_id: &DeviceId) -> OutgoingRequest {
let content = RoomKeyRequestToDeviceEventContent::new(
Action::CancelRequest,
None,
@ -172,8 +175,13 @@ impl OutgoingKeyRequest {
self.request_id.to_string(),
);
let id = Uuid::new_v4();
wrap_key_request_content(self.request_recipient.clone(), id, &content)
let request = ToDeviceRequest::new(
&self.request_recipient,
DeviceIdOrAllDevices::AllDevices,
AnyToDeviceEventContent::RoomKeyRequest(content),
);
OutgoingRequest { request_id: request.txn_id, request: Arc::new(request.into()) }
}
}
@ -187,26 +195,6 @@ impl PartialEq for OutgoingKeyRequest {
}
}
fn wrap_key_request_content(
recipient: UserId,
id: Uuid,
content: &RoomKeyRequestToDeviceEventContent,
) -> Result<OutgoingRequest, serde_json::Error> {
let mut messages = BTreeMap::new();
messages
.entry(recipient)
.or_insert_with(BTreeMap::new)
.insert(DeviceIdOrAllDevices::AllDevices, to_raw_value(content)?);
Ok(OutgoingRequest {
request_id: id,
request: Arc::new(
ToDeviceRequest { event_type: EventType::RoomKeyRequest, txn_id: id, messages }.into(),
),
})
}
impl KeyRequestMachine {
pub fn new(
user_id: Arc<UserId>,
@ -229,13 +217,14 @@ impl KeyRequestMachine {
/// Load stored outgoing requests that were not yet sent out.
async fn load_outgoing_requests(&self) -> Result<Vec<OutgoingRequest>, CryptoStoreError> {
self.store
Ok(self
.store
.get_unsent_key_requests()
.await?
.into_iter()
.filter(|i| !i.sent_out)
.map(|info| info.to_request(self.device_id()).map_err(CryptoStoreError::from))
.collect()
.map(|info| info.to_request(self.device_id()))
.collect())
}
/// Our own user id.
@ -448,23 +437,15 @@ impl KeyRequestMachine {
let (used_session, content) =
device.encrypt_session(session.clone(), message_index).await?;
let id = Uuid::new_v4();
let mut messages = BTreeMap::new();
messages.entry(device.user_id().to_owned()).or_insert_with(BTreeMap::new).insert(
DeviceIdOrAllDevices::DeviceId(device.device_id().into()),
to_raw_value(&content)?,
let request = ToDeviceRequest::new(
device.user_id(),
device.device_id().to_owned(),
AnyToDeviceEventContent::RoomEncrypted(content),
);
let request = OutgoingRequest {
request_id: id,
request: Arc::new(
ToDeviceRequest { event_type: EventType::RoomEncrypted, txn_id: id, messages }
.into(),
),
};
self.outgoing_to_device_requests.insert(id, request);
let request =
OutgoingRequest { request_id: request.txn_id, request: Arc::new(request.into()) };
self.outgoing_to_device_requests.insert(request.request_id, request);
Ok(used_session)
}
@ -594,8 +575,8 @@ impl KeyRequestMachine {
let request = self.store.get_key_request_by_info(&key_info).await?;
if let Some(request) = request {
let cancel = request.to_cancellation(self.device_id())?;
let request = request.to_request(self.device_id())?;
let cancel = request.to_cancellation(self.device_id());
let request = request.to_request(self.device_id());
Ok((Some(cancel), request))
} else {
@ -618,7 +599,7 @@ impl KeyRequestMachine {
sent_out: false,
};
let outgoing_request = request.to_request(self.device_id())?;
let outgoing_request = request.to_request(self.device_id());
self.save_outgoing_key_info(request).await?;
Ok(outgoing_request)
@ -717,7 +698,7 @@ impl KeyRequestMachine {
// can delete it in one transaction.
self.delete_key_info(&key_info).await?;
let request = key_info.to_cancellation(self.device_id())?;
let request = key_info.to_cancellation(self.device_id());
self.outgoing_to_device_requests.insert(request.request_id, request);
Ok(())
@ -789,13 +770,14 @@ mod test {
use matrix_sdk_common::locks::Mutex;
use matrix_sdk_test::async_test;
use ruma::{
api::client::r0::to_device::DeviceIdOrAllDevices,
events::{
forwarded_room_key::ForwardedRoomKeyToDeviceEventContent,
room::encrypted::EncryptedEventContent,
room_key_request::RoomKeyRequestToDeviceEventContent, AnyToDeviceEvent, ToDeviceEvent,
},
room_id, user_id, DeviceIdBox, RoomId, UserId,
room_id,
to_device::DeviceIdOrAllDevices,
user_id, DeviceIdBox, RoomId, UserId,
};
use super::{KeyRequestMachine, KeyshareDecision};
@ -1203,8 +1185,7 @@ mod test {
.unwrap()
.get(&DeviceIdOrAllDevices::AllDevices)
.unwrap();
let content: RoomKeyRequestToDeviceEventContent =
serde_json::from_str(content.get()).unwrap();
let content: RoomKeyRequestToDeviceEventContent = content.deserialize_as().unwrap();
alice_machine.mark_outgoing_request_as_sent(id).await.unwrap();
@ -1233,7 +1214,7 @@ mod test {
.unwrap()
.get(&DeviceIdOrAllDevices::DeviceId(alice_device_id()))
.unwrap();
let content: EncryptedEventContent = serde_json::from_str(content.get()).unwrap();
let content: EncryptedEventContent = content.deserialize_as().unwrap();
bob_machine.mark_outgoing_request_as_sent(id).await.unwrap();
@ -1336,8 +1317,7 @@ mod test {
.unwrap()
.get(&DeviceIdOrAllDevices::AllDevices)
.unwrap();
let content: RoomKeyRequestToDeviceEventContent =
serde_json::from_str(content.get()).unwrap();
let content: RoomKeyRequestToDeviceEventContent = content.deserialize_as().unwrap();
alice_machine.mark_outgoing_request_as_sent(id).await.unwrap();
@ -1382,7 +1362,7 @@ mod test {
.unwrap()
.get(&DeviceIdOrAllDevices::DeviceId(alice_device_id()))
.unwrap();
let content: EncryptedEventContent = serde_json::from_str(content.get()).unwrap();
let content: EncryptedEventContent = content.deserialize_as().unwrap();
bob_machine.mark_outgoing_request_as_sent(id).await.unwrap();

View file

@ -755,11 +755,11 @@ impl OlmMachine {
| AnyToDeviceEvent::KeyVerificationStart(..) => {
self.handle_verification_event(event).await;
}
AnyToDeviceEvent::Dummy(_) => {}
AnyToDeviceEvent::RoomKey(_) => {}
AnyToDeviceEvent::ForwardedRoomKey(_) => {}
AnyToDeviceEvent::RoomEncrypted(_) => {}
AnyToDeviceEvent::Custom(_) => {}
AnyToDeviceEvent::Dummy(_)
| AnyToDeviceEvent::RoomKey(_)
| AnyToDeviceEvent::ForwardedRoomKey(_)
| AnyToDeviceEvent::RoomEncrypted(_) => {}
_ => {}
}
}
@ -1231,21 +1231,22 @@ pub(crate) mod test {
use matrix_sdk_test::test_json;
use ruma::{
api::{
client::r0::keys::{claim_keys, get_keys, upload_keys, OneTimeKey},
client::r0::keys::{claim_keys, get_keys, upload_keys},
IncomingResponse,
},
encryption::OneTimeKey,
events::{
dummy::DummyToDeviceEventContent,
room::{
encrypted::EncryptedEventContent,
message::{MessageEventContent, MessageType},
},
AnyMessageEventContent, AnySyncMessageEvent, AnySyncRoomEvent, AnyToDeviceEvent,
EventType, SyncMessageEvent, ToDeviceEvent, Unsigned,
AnyToDeviceEventContent, SyncMessageEvent, ToDeviceEvent, Unsigned,
},
identifiers::{
event_id, room_id, user_id, DeviceId, DeviceKeyAlgorithm, DeviceKeyId, UserId,
},
serde::Raw,
uint, MilliSecondsSinceUnixEpoch,
};
use serde_json::json;
@ -1291,12 +1292,16 @@ pub(crate) mod test {
fn to_device_requests_to_content(requests: Vec<Arc<ToDeviceRequest>>) -> EncryptedEventContent {
let to_device_request = &requests[0];
let content: Raw<EncryptedEventContent> = serde_json::from_str(
to_device_request.messages.values().next().unwrap().values().next().unwrap().get(),
)
.unwrap();
content.deserialize().unwrap()
to_device_request
.messages
.values()
.next()
.unwrap()
.values()
.next()
.unwrap()
.deserialize_as()
.unwrap()
}
pub(crate) async fn get_prepared_machine() -> (OlmMachine, OneTimeKeys) {
@ -1358,7 +1363,10 @@ pub(crate) mod test {
let bob_device = alice.get_device(&bob.user_id, &bob.device_id).await.unwrap().unwrap();
let (session, content) = bob_device.encrypt(EventType::Dummy, json!({})).await.unwrap();
let (session, content) = bob_device
.encrypt(AnyToDeviceEventContent::Dummy(DummyToDeviceEventContent::new()))
.await
.unwrap();
alice.store.save_sessions(&[session]).await.unwrap();
let event = ToDeviceEvent { sender: alice.user_id().clone(), content };
@ -1593,7 +1601,11 @@ pub(crate) mod test {
let event = ToDeviceEvent {
sender: alice.user_id().clone(),
content: bob_device.encrypt(EventType::Dummy, json!({})).await.unwrap().1,
content: bob_device
.encrypt(AnyToDeviceEventContent::Dummy(DummyToDeviceEventContent::new()))
.await
.unwrap()
.1,
};
let event = bob.decrypt_to_device_event(&event).await.unwrap().event.deserialize().unwrap();

View file

@ -30,13 +30,9 @@ use olm_rs::{
session::{OlmMessage, PreKeyMessage},
PicklingMode,
};
#[cfg(test)]
use ruma::events::EventType;
use ruma::{
api::client::r0::keys::{
upload_keys, upload_signatures::Request as SignatureUploadRequest, OneTimeKey, SignedKey,
},
encryption::DeviceKeys,
api::client::r0::keys::{upload_keys, upload_signatures::Request as SignatureUploadRequest},
encryption::{DeviceKeys, OneTimeKey, SignedKey},
events::{
room::encrypted::{EncryptedEventContent, EncryptedEventScheme},
AnyToDeviceEvent, ToDeviceEvent,
@ -993,6 +989,8 @@ impl ReadOnlyAccount {
#[cfg(test)]
pub(crate) async fn create_session_for(&self, other: &ReadOnlyAccount) -> (Session, Session) {
use ruma::events::{dummy::DummyToDeviceEventContent, AnyToDeviceEventContent};
other.generate_one_time_keys_helper(1).await;
let one_time = other.signed_one_time_keys().await.unwrap();
@ -1003,7 +1001,10 @@ impl ReadOnlyAccount {
other.mark_keys_as_published().await;
let message = our_session.encrypt(&device, EventType::Dummy, json!({})).await.unwrap();
let message = our_session
.encrypt(&device, AnyToDeviceEventContent::Dummy(DummyToDeviceEventContent::new()))
.await
.unwrap();
let content = if let EncryptedEventScheme::OlmV1Curve25519AesSha2(c) = message.scheme {
c
} else {

View file

@ -320,11 +320,9 @@ impl InboundGroupSession {
decrypted_object.get_mut("content").map(|c| c.as_object_mut()).flatten()
{
if !decrypted_content.contains_key("m.relates_to") {
if let Some(relation) = &event.content.relates_to {
decrypted_content.insert(
"m.relates_to".to_owned(),
serde_json::to_value(relation).unwrap_or_default(),
);
let content = serde_json::to_value(&event.content)?;
if let Some(relation) = content.as_object().and_then(|o| o.get("m.relates_to")) {
decrypted_content.insert("m.relates_to".to_owned(), relation.to_owned());
}
}
}

View file

@ -34,20 +34,20 @@ use olm_rs::{
errors::OlmGroupSessionError, outbound_group_session::OlmOutboundGroupSession, PicklingMode,
};
use ruma::{
api::client::r0::to_device::DeviceIdOrAllDevices,
events::{
room::{
encrypted::{EncryptedEventContent, EncryptedEventScheme, MegolmV1AesSha2ContentInit},
encryption::EncryptionEventContent,
history_visibility::HistoryVisibility,
message::Relation,
},
AnyMessageEventContent, EventContent,
room_key::RoomKeyToDeviceEventContent,
AnyMessageEventContent, AnyToDeviceEventContent, EventContent,
},
to_device::DeviceIdOrAllDevices,
DeviceId, DeviceIdBox, EventEncryptionAlgorithm, RoomId, UserId,
};
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use serde_json::json;
use tracing::{debug, error, trace};
use super::{
@ -277,13 +277,8 @@ impl OutboundGroupSession {
"type": content.event_type(),
});
let relates_to: Option<Relation> = json_content
.get("content")
.map(|c| c.get("m.relates_to").cloned().map(|r| serde_json::from_value(r).ok()))
.flatten()
.flatten();
let plaintext = json_content.to_string();
let relation = content.relation();
let ciphertext = self.encrypt_helper(plaintext).await;
@ -297,7 +292,7 @@ impl OutboundGroupSession {
EncryptedEventContent::new(
EncryptedEventScheme::MegolmV1AesSha2(encrypted_content),
relates_to,
relation,
)
}
@ -361,16 +356,15 @@ impl OutboundGroupSession {
session.session_message_index()
}
/// Get the outbound group session key as a json value that can be sent as a
/// m.room_key.
pub async fn as_json(&self) -> Value {
json!({
"algorithm": EventEncryptionAlgorithm::MegolmV1AesSha2,
"room_id": &*self.room_id,
"session_id": &*self.session_id,
"session_key": self.session_key().await,
"chain_index": self.message_index().await,
})
pub(crate) async fn as_content(&self) -> AnyToDeviceEventContent {
let session_key = self.session_key().await;
AnyToDeviceEventContent::RoomKey(RoomKeyToDeviceEventContent::new(
EventEncryptionAlgorithm::MegolmV1AesSha2,
self.room_id().to_owned(),
self.session_id().to_owned(),
session_key.0.clone(),
))
}
/// Has or will the session be shared with the given user/device pair.

View file

@ -63,9 +63,8 @@ pub(crate) mod test {
use olm_rs::session::OlmMessage;
use ruma::{
api::client::r0::keys::SignedKey,
events::forwarded_room_key::ForwardedRoomKeyToDeviceEventContent, room_id, user_id,
DeviceId, UserId,
encryption::SignedKey, events::forwarded_room_key::ForwardedRoomKeyToDeviceEventContent,
room_id, user_id, DeviceId, UserId,
};
use crate::olm::{InboundGroupSession, ReadOnlyAccount, Session};

View file

@ -26,12 +26,12 @@ use ruma::{
CiphertextInfo, EncryptedEventContent, EncryptedEventScheme,
OlmV1Curve25519AesSha2Content,
},
EventType,
AnyToDeviceEventContent, EventContent,
},
identifiers::{DeviceId, DeviceKeyAlgorithm, UserId},
};
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use serde_json::json;
use super::{deserialize_instant, serialize_instant, IdentityKeys};
use crate::{
@ -105,21 +105,17 @@ impl Session {
/// encrypted, this needs to be the device that was used to create this
/// session with.
///
/// * `event_type` - The type of the event.
///
/// * `content` - The content of the event.
pub async fn encrypt(
&mut self,
recipient_device: &ReadOnlyDevice,
event_type: EventType,
content: Value,
content: AnyToDeviceEventContent,
) -> OlmResult<EncryptedEventContent> {
let recipient_signing_key = recipient_device
.get_key(DeviceKeyAlgorithm::Ed25519)
.ok_or(EventError::MissingSigningKey)?;
let relates_to =
content.get("m.relates_to").cloned().and_then(|v| serde_json::from_value(v).ok());
let event_type = content.event_type();
let payload = json!({
"sender": self.user_id.as_str(),
@ -149,7 +145,7 @@ impl Session {
content,
self.our_identity_keys.curve25519().to_string(),
)),
relates_to,
None,
))
}

View file

@ -25,8 +25,8 @@ use std::{
use matrix_sdk_common::locks::Mutex;
use pk_signing::{MasterSigning, PickledSignings, SelfSigning, Signing, SigningError, UserSigning};
use ruma::{
api::client::r0::keys::{upload_signatures::Request as SignatureUploadRequest, KeyUsage},
encryption::DeviceKeys,
api::client::r0::keys::upload_signatures::Request as SignatureUploadRequest,
encryption::{DeviceKeys, KeyUsage},
DeviceKeyAlgorithm, DeviceKeyId, UserId,
};
use serde::{Deserialize, Serialize};
@ -403,7 +403,7 @@ mod test {
use std::{collections::BTreeMap, sync::Arc};
use matrix_sdk_test::async_test;
use ruma::{api::client::r0::keys::CrossSigningKey, user_id, UserId};
use ruma::{encryption::CrossSigningKey, user_id, UserId};
use super::{PrivateCrossSigningIdentity, Signing};
use crate::{

View file

@ -24,8 +24,7 @@ use olm_rs::pk::OlmPkSigning;
#[cfg(test)]
use olm_rs::{errors::OlmUtilityError, utility::OlmUtility};
use ruma::{
api::client::r0::keys::{CrossSigningKey, KeyUsage},
encryption::DeviceKeys,
encryption::{CrossSigningKey, DeviceKeys, KeyUsage},
serde::CanonicalJsonValue,
DeviceKeyAlgorithm, DeviceKeyId, UserId,
};

View file

@ -25,16 +25,17 @@ use ruma::{
Request as SignatureUploadRequest, Response as SignatureUploadResponse,
},
upload_signing_keys::Response as SigningKeysUploadResponse,
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,
},
encryption::CrossSigningKey,
events::{AnyMessageEventContent, AnyToDeviceEventContent, EventContent, EventType},
serde::Raw,
to_device::DeviceIdOrAllDevices,
DeviceIdBox, RoomId, UserId,
};
use serde::{Deserialize, Serialize};
use serde_json::value::RawValue as RawJsonValue;
/// Customized version of
/// `ruma_client_api::r0::to_device::send_event_to_device::Request`,
@ -54,7 +55,7 @@ pub struct ToDeviceRequest {
/// The content's type for this field will be updated in a future
/// release, until then you can create a value using
/// `serde_json::value::to_raw_value`.
pub messages: BTreeMap<UserId, BTreeMap<DeviceIdOrAllDevices, Box<RawJsonValue>>>,
pub messages: BTreeMap<UserId, BTreeMap<DeviceIdOrAllDevices, Raw<AnyToDeviceEventContent>>>,
}
impl ToDeviceRequest {
@ -73,18 +74,24 @@ impl ToDeviceRequest {
recipient: &UserId,
recipient_device: impl Into<DeviceIdOrAllDevices>,
content: AnyToDeviceEventContent,
) -> Self {
Self::new_with_id(recipient, recipient_device, content, Uuid::new_v4())
}
pub(crate) fn new_with_id(
recipient: &UserId,
recipient_device: impl Into<DeviceIdOrAllDevices>,
content: AnyToDeviceEventContent,
txn_id: Uuid,
) -> Self {
let mut messages = BTreeMap::new();
let mut user_messages = BTreeMap::new();
user_messages.insert(
recipient_device.into(),
serde_json::value::to_raw_value(&content).expect("Can't serialize to-device content"),
);
messages.insert(recipient.clone(), user_messages);
let event_type = EventType::from(content.event_type());
ToDeviceRequest { txn_id: Uuid::new_v4(), event_type, messages }
user_messages.insert(recipient_device.into(), Raw::from(content));
messages.insert(recipient.clone(), user_messages);
ToDeviceRequest { event_type, txn_id, messages }
}
/// Gets the transaction ID as a string.

View file

@ -21,14 +21,14 @@ use dashmap::DashMap;
use futures::future::join_all;
use matrix_sdk_common::{executor::spawn, uuid::Uuid};
use ruma::{
api::client::r0::to_device::DeviceIdOrAllDevices,
events::{
room::{encrypted::EncryptedEventContent, history_visibility::HistoryVisibility},
AnyMessageEventContent, EventType,
AnyMessageEventContent, AnyToDeviceEventContent, EventType,
},
serde::Raw,
to_device::DeviceIdOrAllDevices,
DeviceId, DeviceIdBox, RoomId, UserId,
};
use serde_json::Value;
use tracing::{debug, info, trace};
use crate::{
@ -224,22 +224,22 @@ impl GroupSessionManager {
/// Encrypt the given content for the given devices and create a to-device
/// requests that sends the encrypted content to them.
async fn encrypt_session_for(
content: Value,
content: AnyToDeviceEventContent,
devices: Vec<Device>,
) -> OlmResult<(Uuid, ToDeviceRequest, Vec<Session>)> {
let mut messages = BTreeMap::new();
let mut changed_sessions = Vec::new();
let encrypt = |device: Device, content: Value| async move {
let encrypt = |device: Device, content: AnyToDeviceEventContent| async move {
let mut message = BTreeMap::new();
let encrypted = device.encrypt(EventType::RoomKey, content.clone()).await;
let encrypted = device.encrypt(content.clone()).await;
let used_session = match encrypted {
Ok((session, encrypted)) => {
message.entry(device.user_id().clone()).or_insert_with(BTreeMap::new).insert(
DeviceIdOrAllDevices::DeviceId(device.device_id().into()),
serde_json::value::to_raw_value(&encrypted)?,
Raw::from(AnyToDeviceEventContent::RoomEncrypted(encrypted)),
);
Some(session)
}
@ -375,7 +375,7 @@ impl GroupSessionManager {
pub async fn encrypt_request(
chunk: Vec<Device>,
content: Value,
content: AnyToDeviceEventContent,
outbound: OutboundGroupSession,
message_index: u32,
being_shared: Arc<DashMap<Uuid, OutboundGroupSession>>,
@ -466,7 +466,7 @@ impl GroupSessionManager {
.flatten()
.collect();
let key_content = outbound.as_json().await;
let key_content = outbound.as_content().await;
let message_index = outbound.message_index().await;
if !devices.is_empty() {

View file

@ -17,15 +17,13 @@ use std::{collections::BTreeMap, sync::Arc, time::Duration};
use dashmap::{DashMap, DashSet};
use matrix_sdk_common::uuid::Uuid;
use ruma::{
api::client::r0::{
keys::claim_keys::{Request as KeysClaimRequest, Response as KeysClaimResponse},
to_device::DeviceIdOrAllDevices,
api::client::r0::keys::claim_keys::{
Request as KeysClaimRequest, Response as KeysClaimResponse,
},
assign,
events::EventType,
events::{dummy::DummyToDeviceEventContent, AnyToDeviceEventContent},
DeviceId, DeviceIdBox, DeviceKeyAlgorithm, UserId,
};
use serde_json::{json, value::to_raw_value};
use tracing::{error, info, warn};
use crate::{
@ -118,28 +116,21 @@ impl SessionManager {
async fn check_if_unwedged(&self, user_id: &UserId, device_id: &DeviceId) -> OlmResult<()> {
if self.wedged_devices.get(user_id).map(|d| d.remove(device_id)).flatten().is_some() {
if let Some(device) = self.store.get_device(user_id, device_id).await? {
let (_, content) = device.encrypt(EventType::Dummy, json!({})).await?;
let id = Uuid::new_v4();
let mut messages = BTreeMap::new();
let content = AnyToDeviceEventContent::Dummy(DummyToDeviceEventContent::new());
let (_, content) = device.encrypt(content).await?;
messages.entry(device.user_id().to_owned()).or_insert_with(BTreeMap::new).insert(
DeviceIdOrAllDevices::DeviceId(device.device_id().into()),
to_raw_value(&content)?,
let request = ToDeviceRequest::new(
device.user_id(),
device.device_id().to_owned(),
AnyToDeviceEventContent::RoomEncrypted(content),
);
let request = OutgoingRequest {
request_id: id,
request: Arc::new(
ToDeviceRequest {
event_type: EventType::RoomEncrypted,
txn_id: id,
messages,
}
.into(),
),
request_id: request.txn_id,
request: Arc::new(request.into()),
};
self.outgoing_to_device_requests.insert(id, request);
self.outgoing_to_device_requests.insert(request.request_id, request);
}
}

View file

@ -757,7 +757,7 @@ mod test {
use matrix_sdk_test::async_test;
use olm_rs::outbound_group_session::OlmOutboundGroupSession;
use ruma::{
api::client::r0::keys::SignedKey,
encryption::SignedKey,
events::room_key_request::RequestedKeyInfo,
identifiers::{room_id, user_id, DeviceId, EventEncryptionAlgorithm, UserId},
};

View file

@ -79,8 +79,7 @@ impl AnyEvent<'_> {
| AnyMessageEvent::RoomEncrypted(_)
| AnyMessageEvent::RoomMessageFeedback(_)
| AnyMessageEvent::RoomRedaction(_)
| AnyMessageEvent::Sticker(_)
| AnyMessageEvent::Custom(_) => None,
| AnyMessageEvent::Sticker(_) => None,
AnyMessageEvent::RoomMessage(m) => {
if let MessageType::VerificationRequest(v) = &m.content.msgtype {
Some(RequestContent::from(v).into())
@ -105,14 +104,14 @@ impl AnyEvent<'_> {
AnyMessageEvent::KeyVerificationDone(e) => {
Some(DoneContent::from(&e.content).into())
}
_ => None,
},
AnyEvent::ToDevice(e) => match e {
AnyToDeviceEvent::Dummy(_)
| AnyToDeviceEvent::RoomKey(_)
| AnyToDeviceEvent::RoomKeyRequest(_)
| AnyToDeviceEvent::ForwardedRoomKey(_)
| AnyToDeviceEvent::RoomEncrypted(_)
| AnyToDeviceEvent::Custom(_) => None,
| AnyToDeviceEvent::RoomEncrypted(_) => None,
AnyToDeviceEvent::KeyVerificationRequest(e) => {
Some(RequestContent::from(&e.content).into())
}
@ -137,6 +136,7 @@ impl AnyEvent<'_> {
AnyToDeviceEvent::KeyVerificationDone(e) => {
Some(DoneContent::from(&e.content).into())
}
_ => None,
},
}
}
@ -178,30 +178,30 @@ impl TryFrom<&AnyMessageEvent> for FlowId {
| AnyMessageEvent::RoomEncrypted(_)
| AnyMessageEvent::RoomMessageFeedback(_)
| AnyMessageEvent::RoomRedaction(_)
| AnyMessageEvent::Sticker(_)
| AnyMessageEvent::Custom(_) => Err(()),
| AnyMessageEvent::Sticker(_) => Err(()),
AnyMessageEvent::KeyVerificationReady(e) => {
Ok(FlowId::from((&e.room_id, &e.content.relation.event_id)))
Ok(FlowId::from((&e.room_id, &e.content.relates_to.event_id)))
}
AnyMessageEvent::RoomMessage(e) => Ok(FlowId::from((&e.room_id, &e.event_id))),
AnyMessageEvent::KeyVerificationStart(e) => {
Ok(FlowId::from((&e.room_id, &e.content.relation.event_id)))
Ok(FlowId::from((&e.room_id, &e.content.relates_to.event_id)))
}
AnyMessageEvent::KeyVerificationCancel(e) => {
Ok(FlowId::from((&e.room_id, &e.content.relation.event_id)))
Ok(FlowId::from((&e.room_id, &e.content.relates_to.event_id)))
}
AnyMessageEvent::KeyVerificationAccept(e) => {
Ok(FlowId::from((&e.room_id, &e.content.relation.event_id)))
Ok(FlowId::from((&e.room_id, &e.content.relates_to.event_id)))
}
AnyMessageEvent::KeyVerificationKey(e) => {
Ok(FlowId::from((&e.room_id, &e.content.relation.event_id)))
Ok(FlowId::from((&e.room_id, &e.content.relates_to.event_id)))
}
AnyMessageEvent::KeyVerificationMac(e) => {
Ok(FlowId::from((&e.room_id, &e.content.relation.event_id)))
Ok(FlowId::from((&e.room_id, &e.content.relates_to.event_id)))
}
AnyMessageEvent::KeyVerificationDone(e) => {
Ok(FlowId::from((&e.room_id, &e.content.relation.event_id)))
Ok(FlowId::from((&e.room_id, &e.content.relates_to.event_id)))
}
_ => Err(()),
}
}
}
@ -215,8 +215,7 @@ impl TryFrom<&AnyToDeviceEvent> for FlowId {
| AnyToDeviceEvent::RoomKey(_)
| AnyToDeviceEvent::RoomKeyRequest(_)
| AnyToDeviceEvent::ForwardedRoomKey(_)
| AnyToDeviceEvent::RoomEncrypted(_)
| AnyToDeviceEvent::Custom(_) => Err(()),
| AnyToDeviceEvent::RoomEncrypted(_) => Err(()),
AnyToDeviceEvent::KeyVerificationRequest(e) => {
Ok(FlowId::from(e.content.transaction_id.to_owned()))
}
@ -241,6 +240,7 @@ impl TryFrom<&AnyToDeviceEvent> for FlowId {
AnyToDeviceEvent::KeyVerificationDone(e) => {
Ok(FlowId::from(e.content.transaction_id.to_owned()))
}
_ => Err(()),
}
}
}
@ -397,7 +397,7 @@ impl<'a> StartContent<'a> {
pub fn flow_id(&self) -> &str {
match self {
Self::ToDevice(c) => &c.transaction_id,
Self::Room(c) => c.relation.event_id.as_str(),
Self::Room(c) => c.relates_to.event_id.as_str(),
}
}
@ -449,7 +449,7 @@ impl<'a> DoneContent<'a> {
pub fn flow_id(&self) -> &str {
match self {
Self::ToDevice(c) => &c.transaction_id,
Self::Room(c) => c.relation.event_id.as_str(),
Self::Room(c) => c.relates_to.event_id.as_str(),
}
}
}
@ -464,7 +464,7 @@ impl AcceptContent<'_> {
pub fn flow_id(&self) -> &str {
match self {
Self::ToDevice(c) => &c.transaction_id,
Self::Room(c) => c.relation.event_id.as_str(),
Self::Room(c) => c.relates_to.event_id.as_str(),
}
}
@ -495,7 +495,7 @@ impl KeyContent<'_> {
pub fn flow_id(&self) -> &str {
match self {
Self::ToDevice(c) => &c.transaction_id,
Self::Room(c) => c.relation.event_id.as_str(),
Self::Room(c) => c.relates_to.event_id.as_str(),
}
}
@ -517,7 +517,7 @@ impl MacContent<'_> {
pub fn flow_id(&self) -> &str {
match self {
Self::ToDevice(c) => &c.transaction_id,
Self::Room(c) => c.relation.event_id.as_str(),
Self::Room(c) => c.relates_to.event_id.as_str(),
}
}
@ -582,7 +582,7 @@ impl OwnedStartContent {
pub fn flow_id(&self) -> FlowId {
match self {
Self::ToDevice(c) => FlowId::ToDevice(c.transaction_id.clone()),
Self::Room(r, c) => FlowId::InRoom(r.clone(), c.relation.event_id.clone()),
Self::Room(r, c) => FlowId::InRoom(r.clone(), c.relates_to.event_id.clone()),
}
}
@ -688,72 +688,65 @@ impl From<RoomMessageRequest> for OutgoingContent {
#[cfg(test)]
impl TryFrom<ToDeviceRequest> for OutgoingContent {
type Error = ();
type Error = String;
fn try_from(value: ToDeviceRequest) -> Result<Self, Self::Error> {
fn try_from(request: ToDeviceRequest) -> Result<Self, Self::Error> {
use ruma::events::EventType;
use serde_json::Value;
let json: Value = serde_json::from_str(
value
request
.messages
.values()
.next()
.and_then(|m| m.values().next().map(|j| j.get()))
.ok_or(())?,
.and_then(|m| m.values().next())
.map(|c| c.json().get())
.ok_or_else(|| "Content is missing from the request".to_owned())?,
)
.map_err(|_| ())?;
.map_err(|e| e.to_string())?;
match value.event_type {
EventType::KeyVerificationRequest => {
Ok(AnyToDeviceEventContent::KeyVerificationRequest(
serde_json::from_value(json).map_err(|_| ())?,
)
.into())
}
EventType::KeyVerificationReady => Ok(AnyToDeviceEventContent::KeyVerificationReady(
serde_json::from_value(json).map_err(|_| ())?,
)
.into()),
EventType::KeyVerificationDone => Ok(AnyToDeviceEventContent::KeyVerificationDone(
serde_json::from_value(json).map_err(|_| ())?,
)
.into()),
EventType::KeyVerificationStart => Ok(AnyToDeviceEventContent::KeyVerificationStart(
serde_json::from_value(json).map_err(|_| ())?,
)
.into()),
EventType::KeyVerificationKey => Ok(AnyToDeviceEventContent::KeyVerificationKey(
serde_json::from_value(json).map_err(|_| ())?,
)
.into()),
EventType::KeyVerificationAccept => Ok(AnyToDeviceEventContent::KeyVerificationAccept(
serde_json::from_value(json).map_err(|_| ())?,
)
.into()),
EventType::KeyVerificationMac => Ok(AnyToDeviceEventContent::KeyVerificationMac(
serde_json::from_value(json).map_err(|_| ())?,
)
.into()),
EventType::KeyVerificationCancel => Ok(AnyToDeviceEventContent::KeyVerificationCancel(
serde_json::from_value(json).map_err(|_| ())?,
)
.into()),
_ => Err(()),
}
let content = match request.event_type {
EventType::KeyVerificationStart => AnyToDeviceEventContent::KeyVerificationStart(
serde_json::from_value(json).map_err(|e| e.to_string())?,
),
EventType::KeyVerificationKey => AnyToDeviceEventContent::KeyVerificationKey(
serde_json::from_value(json).map_err(|e| e.to_string())?,
),
EventType::KeyVerificationAccept => AnyToDeviceEventContent::KeyVerificationAccept(
serde_json::from_value(json).map_err(|e| e.to_string())?,
),
EventType::KeyVerificationMac => AnyToDeviceEventContent::KeyVerificationMac(
serde_json::from_value(json).map_err(|e| e.to_string())?,
),
EventType::KeyVerificationCancel => AnyToDeviceEventContent::KeyVerificationCancel(
serde_json::from_value(json).map_err(|e| e.to_string())?,
),
EventType::KeyVerificationReady => AnyToDeviceEventContent::KeyVerificationReady(
serde_json::from_value(json).map_err(|e| e.to_string())?,
),
EventType::KeyVerificationDone => AnyToDeviceEventContent::KeyVerificationDone(
serde_json::from_value(json).map_err(|e| e.to_string())?,
),
EventType::KeyVerificationRequest => AnyToDeviceEventContent::KeyVerificationRequest(
serde_json::from_value(json).map_err(|e| e.to_string())?,
),
e => return Err(format!("Unsupported event type {}", e)),
};
Ok(content.into())
}
}
#[cfg(test)]
impl TryFrom<OutgoingRequest> for OutgoingContent {
type Error = ();
type Error = String;
fn try_from(value: OutgoingRequest) -> Result<Self, ()> {
fn try_from(value: OutgoingRequest) -> Result<Self, Self::Error> {
match value.request() {
crate::OutgoingRequests::KeysUpload(_) => Err(()),
crate::OutgoingRequests::KeysQuery(_) => Err(()),
crate::OutgoingRequests::KeysUpload(_) => Err("Invalid request type".to_owned()),
crate::OutgoingRequests::KeysQuery(_) => Err("Invalid request type".to_owned()),
crate::OutgoingRequests::ToDeviceRequest(r) => Self::try_from(r.clone()),
crate::OutgoingRequests::SignatureUpload(_) => Err(()),
crate::OutgoingRequests::SignatureUpload(_) => Err("Invalid request type".to_owned()),
crate::OutgoingRequests::RoomMessage(r) => Ok(Self::from(r.clone())),
}
}

View file

@ -525,10 +525,9 @@ impl IdentitiesBeingVerified {
#[cfg(test)]
pub(crate) mod test {
use ruma::{
events::{AnyToDeviceEvent, AnyToDeviceEventContent, EventType, ToDeviceEvent},
events::{AnyToDeviceEvent, AnyToDeviceEventContent, ToDeviceEvent},
UserId,
};
use serde_json::Value;
use super::event_enums::OutgoingContent;
use crate::{
@ -540,7 +539,7 @@ pub(crate) mod test {
sender: &UserId,
request: &OutgoingVerificationRequest,
) -> AnyToDeviceEvent {
let content = get_content_from_request(request);
let content = request.to_owned().into();
wrap_any_to_device_content(sender, content)
}
@ -589,36 +588,4 @@ pub(crate) mod test {
_ => unreachable!(),
}
}
pub(crate) fn get_content_from_request(
request: &OutgoingVerificationRequest,
) -> OutgoingContent {
let request =
if let OutgoingVerificationRequest::ToDevice(r) = request { r } else { unreachable!() };
let json: Value = serde_json::from_str(
request.messages.values().next().unwrap().values().next().unwrap().get(),
)
.unwrap();
match request.event_type {
EventType::KeyVerificationStart => {
AnyToDeviceEventContent::KeyVerificationStart(serde_json::from_value(json).unwrap())
}
EventType::KeyVerificationKey => {
AnyToDeviceEventContent::KeyVerificationKey(serde_json::from_value(json).unwrap())
}
EventType::KeyVerificationAccept => AnyToDeviceEventContent::KeyVerificationAccept(
serde_json::from_value(json).unwrap(),
),
EventType::KeyVerificationMac => {
AnyToDeviceEventContent::KeyVerificationMac(serde_json::from_value(json).unwrap())
}
EventType::KeyVerificationCancel => AnyToDeviceEventContent::KeyVerificationCancel(
serde_json::from_value(json).unwrap(),
),
_ => unreachable!(),
}
.into()
}
}

View file

@ -19,7 +19,6 @@ use std::sync::{Arc, Mutex};
use matrix_qrcode::QrVerificationData;
use matrix_sdk_common::uuid::Uuid;
use ruma::{
api::client::r0::to_device::DeviceIdOrAllDevices,
events::{
key::verification::{
cancel::CancelCode,
@ -31,6 +30,7 @@ use ruma::{
room::message::KeyVerificationRequestEventContent,
AnyMessageEventContent, AnyToDeviceEventContent,
},
to_device::DeviceIdOrAllDevices,
DeviceId, DeviceIdBox, DeviceKeyAlgorithm, EventId, MilliSecondsSinceUnixEpoch, RoomId, UserId,
};
use tracing::{info, trace, warn};
@ -51,9 +51,9 @@ use crate::{
};
const SUPPORTED_METHODS: &[VerificationMethod] = &[
VerificationMethod::MSasV1,
VerificationMethod::MQrCodeShowV1,
VerificationMethod::MReciprocateV1,
VerificationMethod::SasV1,
VerificationMethod::QrCodeShowV1,
VerificationMethod::ReciprocateV1,
];
/// An object controlling key verification requests.
@ -780,8 +780,8 @@ impl RequestState<Ready> {
// If we didn't state that we support showing QR codes or if the other
// side doesn't support scanning QR codes bail early.
if !self.state.our_methods.contains(&VerificationMethod::MQrCodeShowV1)
|| !self.state.their_methods.contains(&VerificationMethod::MQrScanShowV1)
if !self.state.our_methods.contains(&VerificationMethod::QrCodeShowV1)
|| !self.state.their_methods.contains(&VerificationMethod::QrCodeScanV1)
{
return Ok(None);
}
@ -942,7 +942,7 @@ impl RequestState<Ready> {
account: ReadOnlyAccount,
private_identity: PrivateCrossSigningIdentity,
) -> Result<Option<(Sas, OutgoingContent)>, CryptoStoreError> {
if !self.state.their_methods.contains(&VerificationMethod::MSasV1) {
if !self.state.their_methods.contains(&VerificationMethod::SasV1) {
return Ok(None);
}

View file

@ -476,12 +476,12 @@ impl AcceptSettings {
fn apply(self, mut content: OwnedAcceptContent) -> OwnedAcceptContent {
match &mut content {
OwnedAcceptContent::ToDevice(AcceptToDeviceEventContent {
method: AcceptMethod::MSasV1(c),
method: AcceptMethod::SasV1(c),
..
})
| OwnedAcceptContent::Room(
_,
AcceptEventContent { method: AcceptMethod::MSasV1(c), .. },
AcceptEventContent { method: AcceptMethod::SasV1(c), .. },
) => {
c.short_authentication_string.retain(|sas| self.allowed_methods.contains(sas));
content

View file

@ -102,7 +102,7 @@ impl TryFrom<AcceptV1Content> for AcceptedProtocols {
Err(CancelCode::UnknownMethod)
} else {
Ok(Self {
method: VerificationMethod::MSasV1,
method: VerificationMethod::SasV1,
hash: content.hash,
key_agreement_protocol: content.key_agreement_protocol,
message_auth_code: content.message_authentication_code,
@ -149,7 +149,7 @@ impl TryFrom<&SasV1Content> for AcceptedProtocols {
}
Ok(Self {
method: VerificationMethod::MSasV1,
method: VerificationMethod::SasV1,
hash: HashAlgorithm::Sha256,
key_agreement_protocol: KeyAgreementProtocol::Curve25519HkdfSha256,
message_auth_code: MessageAuthenticationCode::HkdfHmacSha256,
@ -163,7 +163,7 @@ impl TryFrom<&SasV1Content> for AcceptedProtocols {
impl Default for AcceptedProtocols {
fn default() -> Self {
AcceptedProtocols {
method: VerificationMethod::MSasV1,
method: VerificationMethod::SasV1,
hash: HashAlgorithm::Sha256,
key_agreement_protocol: KeyAgreementProtocol::Curve25519HkdfSha256,
message_auth_code: MessageAuthenticationCode::HkdfHmacSha256,
@ -450,7 +450,7 @@ impl SasState<Created> {
) -> Result<SasState<Accepted>, SasState<Cancelled>> {
self.check_event(sender, content.flow_id()).map_err(|c| self.clone().cancel(c))?;
if let AcceptMethod::MSasV1(content) = content.method() {
if let AcceptMethod::SasV1(content) = content.method() {
let accepted_protocols =
AcceptedProtocols::try_from(content.clone()).map_err(|c| self.clone().cancel(c))?;
@ -560,7 +560,7 @@ impl SasState<Started> {
/// been started because of a
/// m.key.verification.request -> m.key.verification.ready flow.
pub fn as_content(&self) -> OwnedAcceptContent {
let method = AcceptMethod::MSasV1(
let method = AcceptMethod::SasV1(
AcceptV1ContentInit {
commitment: self.state.commitment.clone(),
hash: self.state.accepted_protocols.hash.clone(),
@ -684,10 +684,10 @@ impl SasState<Accepted> {
pub fn as_content(&self) -> OutgoingContent {
match &*self.verification_flow_id {
FlowId::ToDevice(s) => {
AnyToDeviceEventContent::KeyVerificationKey(KeyToDeviceEventContent {
transaction_id: s.to_string(),
key: self.inner.lock().unwrap().public_key(),
})
AnyToDeviceEventContent::KeyVerificationKey(KeyToDeviceEventContent::new(
s.to_string(),
self.inner.lock().unwrap().public_key(),
))
.into()
}
FlowId::InRoom(r, e) => (
@ -710,10 +710,10 @@ impl SasState<KeyReceived> {
pub fn as_content(&self) -> OutgoingContent {
match &*self.verification_flow_id {
FlowId::ToDevice(s) => {
AnyToDeviceEventContent::KeyVerificationKey(KeyToDeviceEventContent {
transaction_id: s.to_string(),
key: self.inner.lock().unwrap().public_key(),
})
AnyToDeviceEventContent::KeyVerificationKey(KeyToDeviceEventContent::new(
s.to_string(),
self.inner.lock().unwrap().public_key(),
))
.into()
}
FlowId::InRoom(r, e) => (
@ -1090,11 +1090,12 @@ mod test {
use ruma::{
events::key::verification::{
accept::{AcceptMethod, CustomContent},
start::{CustomContent as CustomStartContent, StartMethod},
accept::{AcceptMethod, AcceptToDeviceEventContent},
start::{StartMethod, StartToDeviceEventContent},
},
DeviceId, UserId,
};
use serde_json::json;
use super::{Accepted, Created, SasState, Started};
use crate::{
@ -1227,7 +1228,7 @@ mod test {
let mut method = content.method_mut();
match &mut method {
AcceptMethod::MSasV1(ref mut c) => {
AcceptMethod::SasV1(ref mut c) => {
c.commitment = "".to_string();
}
_ => panic!("Unknown accept event content"),
@ -1266,7 +1267,7 @@ mod test {
let mut method = content.method_mut();
match &mut method {
AcceptMethod::MSasV1(ref mut c) => {
AcceptMethod::SasV1(ref mut c) => {
c.short_authentication_string = vec![];
}
_ => panic!("Unknown accept event content"),
@ -1283,14 +1284,13 @@ mod test {
async fn sas_unknown_method() {
let (alice, bob) = get_sas_pair().await;
let mut content = bob.as_content();
let method = content.method_mut();
*method = AcceptMethod::Custom(CustomContent {
method: "m.sas.custom".to_string(),
data: Default::default(),
let content = json!({
"method": "m.sas.custom",
"method_data": "something",
"transaction_id": "some_id",
});
let content: AcceptToDeviceEventContent = serde_json::from_value(content).unwrap();
let content = AcceptContent::from(&content);
alice
@ -1331,22 +1331,22 @@ mod test {
)
.expect_err("Didn't cancel on invalid MAC method");
let mut start_content = alice_sas.as_content();
let method = start_content.method_mut();
*method = StartMethod::Custom(CustomStartContent {
method: "m.sas.custom".to_string(),
data: Default::default(),
let content = json!({
"method": "m.sas.custom",
"from_device": "DEVICEID",
"method_data": "something",
"transaction_id": "some_id",
});
let flow_id = start_content.flow_id();
let content = StartContent::from(&start_content);
let content: StartToDeviceEventContent = serde_json::from_value(content).unwrap();
let content = StartContent::from(&content);
let flow_id = content.flow_id().to_owned();
SasState::<Started>::from_start_event(
bob.clone(),
alice_device,
None,
flow_id,
flow_id.into(),
&content,
false,
)

View file

@ -18,6 +18,6 @@ http = "0.2.3"
lazy_static = "1.4.0"
matrix-sdk-common = { version = "0.2.0", path = "../matrix_sdk_common" }
matrix-sdk-test-macros = { version = "0.1.0", path = "../matrix_sdk_test_macros" }
ruma = { version = "0.1.2", features = ["client-api-c"] }
ruma = { version = "0.1.2", features = ["client-api-c"], git = "https://github.com/ruma/ruma", rev = "d73ab8add" }
serde = "1.0.122"
serde_json = "1.0.61"