diff --git a/crates/matrix-sdk-crypto/src/olm/session.rs b/crates/matrix-sdk-crypto/src/olm/session.rs index a51fbaa9d..59290bbd3 100644 --- a/crates/matrix-sdk-crypto/src/olm/session.rs +++ b/crates/matrix-sdk-crypto/src/olm/session.rs @@ -16,7 +16,7 @@ use std::{fmt, sync::Arc}; use ruma::{serde::Raw, SecondsSinceUnixEpoch}; use serde::{Deserialize, Serialize}; -use serde_json::json; +use serde_json::Value; use tokio::sync::Mutex; use tracing::{debug, Span}; use vodozemac::{ @@ -29,7 +29,11 @@ use crate::types::events::room::encrypted::OlmV2Curve25519AesSha2Content; use crate::{ error::{EventError, OlmResult, SessionUnpickleError}, types::{ - events::room::encrypted::{OlmV1Curve25519AesSha2Content, ToDeviceEncryptedEventContent}, + events::{ + olm_v1::DecryptedOlmV1Event, + room::encrypted::{OlmV1Curve25519AesSha2Content, ToDeviceEncryptedEventContent}, + EventType, + }, DeviceKeys, EventEncryptionAlgorithm, }, DeviceData, @@ -146,26 +150,59 @@ impl Session { content: impl Serialize, message_id: Option, ) -> OlmResult> { + #[derive(Debug)] + struct Content<'a> { + event_type: &'a str, + content: Raw, + } + + impl EventType for Content<'_> { + // This is a bit of a hack, usually we just define the `EVENT_TYPE` and use the + // default implementation of `event_type()`, we can't do this here + // because the event type isn't static. + // + // So we just leave EVENT_TYPE out. This works because the serialization is + // using `event_type()` and this type is contained to this function. + const EVENT_TYPE: &'static str = ""; + + fn event_type(&self) -> &str { + self.event_type + } + } + + impl Serialize for Content<'_> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.content.serialize(serializer) + } + } + let plaintext = { + let content = serde_json::to_value(content)?; + let content = Content { event_type, content: Raw::new(&content)? }; + let recipient_signing_key = recipient_device.ed25519_key().ok_or(EventError::MissingSigningKey)?; - let payload = json!({ - "sender": &self.our_device_keys.user_id, - "sender_device": &self.our_device_keys.device_id, - "keys": { - "ed25519": self.our_device_keys.ed25519_key().expect("Device doesn't have ed25519 key").to_base64(), + let content = DecryptedOlmV1Event { + sender: self.our_device_keys.user_id.clone(), + recipient: recipient_device.user_id().into(), + keys: crate::types::events::olm_v1::OlmV1Keys { + ed25519: self + .our_device_keys + .ed25519_key() + .expect("Our own device should have an Ed25519 public key"), }, - "org.matrix.msc4147.device_keys": self.our_device_keys, - "recipient": recipient_device.user_id(), - "recipient_keys": { - "ed25519": recipient_signing_key.to_base64(), + recipient_keys: crate::types::events::olm_v1::OlmV1Keys { + ed25519: recipient_signing_key, }, - "type": event_type, - "content": content, - }); + sender_device_keys: Some(self.our_device_keys.clone()), + content, + }; - serde_json::to_string(&payload)? + serde_json::to_string(&content)? }; let ciphertext = self.encrypt_helper(&plaintext).await; diff --git a/crates/matrix-sdk-crypto/src/types/events/mod.rs b/crates/matrix-sdk-crypto/src/types/events/mod.rs index a4fe78ec6..bb9618d89 100644 --- a/crates/matrix-sdk-crypto/src/types/events/mod.rs +++ b/crates/matrix-sdk-crypto/src/types/events/mod.rs @@ -40,8 +40,9 @@ pub trait EventType { /// Get the event type of the event content. /// - /// **Note**: This should never be implemented manually, this takes the - /// event type from the constant. + /// **Note**: This usually doesn't need to be implemented. The default + /// implementation will take the event type from the + /// [`EventType::EVENT_TYPE`] constant. fn event_type(&self) -> &str { Self::EVENT_TYPE }