Skip to content

Commit 42bada0

Browse files
committed
feat(sdk): condition encryption on room settings
Signed-off-by: Skye Elliot <[email protected]>
1 parent 7898a1a commit 42bada0

File tree

7 files changed

+76
-46
lines changed

7 files changed

+76
-46
lines changed

crates/matrix-sdk-crypto/src/machine/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ use ruma::{
4545
},
4646
assign,
4747
events::{
48+
room::encrypted::unstable_state::StateRoomEncryptedEventContent,
4849
secret::request::SecretName, AnyMessageLikeEvent, AnyMessageLikeEventContent,
4950
AnyStateEventContent, AnyToDeviceEvent, MessageLikeEventContent, StateEventContent,
5051
},
@@ -1117,7 +1118,7 @@ impl OlmMachine {
11171118
room_id: &RoomId,
11181119
content: C,
11191120
state_key: K,
1120-
) -> MegolmResult<Raw<RoomEncryptedEventContent>>
1121+
) -> MegolmResult<Raw<StateRoomEncryptedEventContent>>
11211122
where
11221123
C: StateEventContent,
11231124
C::StateKey: Borrow<K>,
@@ -1149,7 +1150,7 @@ impl OlmMachine {
11491150
event_type: &str,
11501151
state_key: &str,
11511152
content: &Raw<AnyStateEventContent>,
1152-
) -> MegolmResult<Raw<RoomEncryptedEventContent>> {
1153+
) -> MegolmResult<Raw<StateRoomEncryptedEventContent>> {
11531154
self.inner
11541155
.group_session_manager
11551156
.encrypt_state(room_id, event_type, state_key, content)

crates/matrix-sdk-crypto/src/machine/tests/room_settings.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ async fn test_stores_and_returns_room_settings() {
2323

2424
let settings = RoomSettings {
2525
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
26+
encrypt_state_events: false,
2627
only_allow_trusted_devices: true,
2728
session_rotation_period: Some(Duration::from_secs(10)),
2829
session_rotation_period_messages: Some(1234),

crates/matrix-sdk-crypto/src/olm/group_sessions/outbound.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ use std::{
2727
use matrix_sdk_common::{deserialized_responses::WithheldCode, locks::RwLock as StdRwLock};
2828
use ruma::{
2929
events::{
30-
room::{encryption::RoomEncryptionEventContent, history_visibility::HistoryVisibility},
30+
room::{
31+
encrypted::unstable_state::StateRoomEncryptedEventContent,
32+
encryption::RoomEncryptionEventContent, history_visibility::HistoryVisibility,
33+
},
3134
AnyMessageLikeEventContent, AnyStateEventContent,
3235
},
3336
serde::Raw,
@@ -543,7 +546,7 @@ impl OutboundGroupSession {
543546
event_type: &str,
544547
state_key: &str,
545548
content: &Raw<AnyStateEventContent>,
546-
) -> Raw<RoomEncryptedEventContent> {
549+
) -> Raw<StateRoomEncryptedEventContent> {
547550
#[derive(Serialize)]
548551
struct Payload<'a> {
549552
#[serde(rename = "type")]
@@ -557,10 +560,6 @@ impl OutboundGroupSession {
557560
let payload_json =
558561
serde_json::to_string(&payload).expect("payload serialization never fails");
559562

560-
let relates_to = content
561-
.get_field::<serde_json::Value>("m.relates_to")
562-
.expect("serde_json::Value deserialization with valid JSON input never fails");
563-
564563
let ciphertext = self.encrypt_helper(payload_json).await;
565564
let scheme: RoomEventEncryptionScheme = match self.settings.algorithm {
566565
EventEncryptionAlgorithm::MegolmV1AesSha2 => MegolmV1AesSha2Content {
@@ -580,9 +579,12 @@ impl OutboundGroupSession {
580579
),
581580
};
582581

583-
let content = RoomEncryptedEventContent { scheme, relates_to, other: Default::default() };
582+
let content =
583+
RoomEncryptedEventContent { scheme, relates_to: None, other: Default::default() };
584584

585-
Raw::new(&content).expect("m.room.encrypted event content can always be serialized")
585+
Raw::new(&content)
586+
.expect("m.room.encrypted event content can always be serialized")
587+
.cast_unchecked()
586588
}
587589

588590
fn elapsed(&self) -> bool {

crates/matrix-sdk-crypto/src/session_manager/group_sessions/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use matrix_sdk_common::{
2929
};
3030
use ruma::{
3131
events::{
32+
room::encrypted::unstable_state::StateRoomEncryptedEventContent,
3233
AnyMessageLikeEventContent, AnyStateEventContent, AnyToDeviceEventContent,
3334
ToDeviceEventType,
3435
},
@@ -233,7 +234,7 @@ impl GroupSessionManager {
233234
event_type: &str,
234235
state_key: &str,
235236
content: &Raw<AnyStateEventContent>,
236-
) -> MegolmResult<Raw<RoomEncryptedEventContent>> {
237+
) -> MegolmResult<Raw<StateRoomEncryptedEventContent>> {
237238
let session =
238239
self.sessions.get_or_load(room_id).await.expect("Session wasn't created nor shared");
239240

crates/matrix-sdk-crypto/src/store/integration_tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,7 @@ macro_rules! cryptostore_integration_tests {
11631163
let room_1 = room_id!("!test_1:localhost");
11641164
let settings_1 = RoomSettings {
11651165
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
1166+
encrypt_state_events: true,
11661167
only_allow_trusted_devices: true,
11671168
session_rotation_period: Some(Duration::from_secs(10)),
11681169
session_rotation_period_messages: Some(123),

crates/matrix-sdk-crypto/src/store/types.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,9 @@ pub struct RoomSettings {
411411
/// The encryption algorithm that should be used in the room.
412412
pub algorithm: EventEncryptionAlgorithm,
413413

414+
/// Whether this room supports encrypted state events.
415+
pub encrypt_state_events: bool,
416+
414417
/// Should untrusted devices receive the room key, or should they be
415418
/// excluded from the conversation.
416419
pub only_allow_trusted_devices: bool,
@@ -428,6 +431,7 @@ impl Default for RoomSettings {
428431
fn default() -> Self {
429432
Self {
430433
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
434+
encrypt_state_events: false,
431435
only_allow_trusted_devices: false,
432436
session_rotation_period: None,
433437
session_rotation_period_messages: None,

crates/matrix-sdk/src/room/futures.rs

Lines changed: 55 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,41 @@ impl<'a> SendStateEventRaw<'a> {
405405
self.request_config = Some(request_config);
406406
self
407407
}
408+
409+
/// Returns `true` if the inner event should be encrypted.
410+
async fn should_encrypt(room: &Room, event_type: &str) -> bool {
411+
let olm = room.client.olm_machine().await;
412+
let olm = olm.as_ref().expect("Olm machine was not started.");
413+
414+
// Lookup room settings and check encryptiong state.
415+
let Ok(Some(settings)) = olm.room_settings(room.room_id()).await else {
416+
trace!("Sending plaintext event as the room is NOT encrypted.");
417+
return false;
418+
};
419+
if !settings.encrypt_state_events {
420+
trace!("Sending plaintext event as the room does NOT support encrypted state events.");
421+
return false;
422+
}
423+
424+
// Check the event is not critical.
425+
if matches!(
426+
event_type,
427+
"m.room.create"
428+
| "m.room.member"
429+
| "m.room.join_rules"
430+
| "m.room.power_levels"
431+
| "m.room.third_party_invite"
432+
| "m.room.history_visibility"
433+
| "m.room.guest_access"
434+
| "m.room.encryption"
435+
| "m.space.child"
436+
| "m.space.parent"
437+
) {
438+
return false;
439+
}
440+
441+
true
442+
}
408443
}
409444

410445
impl<'a> IntoFuture for SendStateEventRaw<'a> {
@@ -420,47 +455,32 @@ impl<'a> IntoFuture for SendStateEventRaw<'a> {
420455
let mut state_key = state_key.to_owned();
421456

422457
#[cfg(feature = "e2e-encryption")]
423-
if room.latest_encryption_state().await?.is_state_encrypted() {
424-
if matches!(
425-
event_type,
426-
"m.room.create"
427-
| "m.room.member"
428-
| "m.room.join_rules"
429-
| "m.room.power_levels"
430-
| "m.room.third_party_invite"
431-
| "m.room.history_visibility"
432-
| "m.room.guest_access"
433-
| "m.room.encryption"
434-
| "m.space.child"
435-
| "m.space.parent"
436-
) {
437-
trace!("Sending plaintext event because of the event type.");
438-
} else {
439-
trace!(
440-
room_id = ?room.room_id(),
441-
"Sending encrypted event because the room is encrypted.",
442-
);
458+
if Self::should_encrypt(room, event_type).await {
459+
Span::current().record("is_room_encrypted", true);
460+
trace!(
461+
room_id = ?room.room_id(),
462+
"Sending encrypted event because the room is encrypted.",
463+
);
443464

444-
if !room.are_members_synced() {
445-
room.sync_members().await?;
446-
}
465+
if !room.are_members_synced() {
466+
room.sync_members().await?;
467+
}
447468

448-
room.query_keys_for_untracked_or_dirty_users().await?;
449-
room.preshare_room_key().await?;
469+
room.query_keys_for_untracked_or_dirty_users().await?;
470+
room.preshare_room_key().await?;
450471

451-
let olm = room.client.olm_machine().await;
452-
let olm = olm.as_ref().expect("Olm machine wasn't started");
472+
let olm = room.client.olm_machine().await;
473+
let olm = olm.as_ref().expect("Olm machine wasn't started");
453474

454-
content = olm
455-
.encrypt_state_event_raw(room.room_id(), event_type, &state_key, &content)
456-
.await?
457-
.cast_unchecked();
458-
state_key = format!("{event_type}:{state_key}");
459-
event_type = "m.room.encrypted";
460-
}
475+
content = olm
476+
.encrypt_state_event_raw(room.room_id(), event_type, &state_key, &content)
477+
.await?
478+
.cast_unchecked();
479+
480+
state_key = format!("{event_type}:{state_key}");
481+
event_type = "m.room.encrypted";
461482
} else {
462483
Span::current().record("is_room_encrypted", false);
463-
trace!("Sending plaintext event because the room is NOT encrypted.");
464484
}
465485

466486
let request = send_state_event::v3::Request::new_raw(

0 commit comments

Comments
 (0)