Skip to content

Commit 64f54e5

Browse files
committed
refactor(crypto): Use the DecryptedOlmV1Event type when encrypting to-device events
This ensures that new fields that are added to the `m.olm.v1.curve25519-aes-sha` content need to be added in a single place.
1 parent 3146be3 commit 64f54e5

File tree

2 files changed

+55
-17
lines changed

2 files changed

+55
-17
lines changed

crates/matrix-sdk-crypto/src/olm/session.rs

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::{fmt, sync::Arc};
1616

1717
use ruma::{serde::Raw, SecondsSinceUnixEpoch};
1818
use serde::{Deserialize, Serialize};
19-
use serde_json::json;
19+
use serde_json::Value;
2020
use tokio::sync::Mutex;
2121
use tracing::{debug, Span};
2222
use vodozemac::{
@@ -29,7 +29,11 @@ use crate::types::events::room::encrypted::OlmV2Curve25519AesSha2Content;
2929
use crate::{
3030
error::{EventError, OlmResult, SessionUnpickleError},
3131
types::{
32-
events::room::encrypted::{OlmV1Curve25519AesSha2Content, ToDeviceEncryptedEventContent},
32+
events::{
33+
olm_v1::DecryptedOlmV1Event,
34+
room::encrypted::{OlmV1Curve25519AesSha2Content, ToDeviceEncryptedEventContent},
35+
EventType,
36+
},
3337
DeviceKeys, EventEncryptionAlgorithm,
3438
},
3539
DeviceData,
@@ -146,26 +150,59 @@ impl Session {
146150
content: impl Serialize,
147151
message_id: Option<String>,
148152
) -> OlmResult<Raw<ToDeviceEncryptedEventContent>> {
153+
#[derive(Debug)]
154+
struct Content<'a> {
155+
event_type: &'a str,
156+
content: Raw<Value>,
157+
}
158+
159+
impl EventType for Content<'_> {
160+
// This is a bit of a hack, usually we just define the `EVENT_TYPE` and use the
161+
// default implementation of `event_type()`, we can't do this here
162+
// because the event type isn't static.
163+
//
164+
// So we just leave EVENT_TYPE out. This works because the serialization is
165+
// using `event_type()` and this type is contained to this function.
166+
const EVENT_TYPE: &'static str = "";
167+
168+
fn event_type(&self) -> &str {
169+
self.event_type
170+
}
171+
}
172+
173+
impl Serialize for Content<'_> {
174+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
175+
where
176+
S: serde::Serializer,
177+
{
178+
self.content.serialize(serializer)
179+
}
180+
}
181+
149182
let plaintext = {
183+
let content = serde_json::to_value(content)?;
184+
let content = Content { event_type, content: Raw::new(&content)? };
185+
150186
let recipient_signing_key =
151187
recipient_device.ed25519_key().ok_or(EventError::MissingSigningKey)?;
152188

153-
let payload = json!({
154-
"sender": &self.our_device_keys.user_id,
155-
"sender_device": &self.our_device_keys.device_id,
156-
"keys": {
157-
"ed25519": self.our_device_keys.ed25519_key().expect("Device doesn't have ed25519 key").to_base64(),
189+
let content = DecryptedOlmV1Event {
190+
sender: self.our_device_keys.user_id.clone(),
191+
recipient: recipient_device.user_id().into(),
192+
keys: crate::types::events::olm_v1::OlmV1Keys {
193+
ed25519: self
194+
.our_device_keys
195+
.ed25519_key()
196+
.expect("Our own device should have an Ed25519 public key"),
158197
},
159-
"org.matrix.msc4147.device_keys": self.our_device_keys,
160-
"recipient": recipient_device.user_id(),
161-
"recipient_keys": {
162-
"ed25519": recipient_signing_key.to_base64(),
198+
recipient_keys: crate::types::events::olm_v1::OlmV1Keys {
199+
ed25519: recipient_signing_key,
163200
},
164-
"type": event_type,
165-
"content": content,
166-
});
201+
sender_device_keys: Some(self.our_device_keys.clone()),
202+
content,
203+
};
167204

168-
serde_json::to_string(&payload)?
205+
serde_json::to_string(&content)?
169206
};
170207

171208
let ciphertext = self.encrypt_helper(&plaintext).await;

crates/matrix-sdk-crypto/src/types/events/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ pub trait EventType {
4040

4141
/// Get the event type of the event content.
4242
///
43-
/// **Note**: This should never be implemented manually, this takes the
44-
/// event type from the constant.
43+
/// **Note**: This usually doesn't need to be implemented. The default
44+
/// implementation will take the event type from the
45+
/// [`EventType::EVENT_TYPE`] constant.
4546
fn event_type(&self) -> &str {
4647
Self::EVENT_TYPE
4748
}

0 commit comments

Comments
 (0)