Skip to content

Commit 2241e6a

Browse files
committed
refactor!(crypto): Don't process in-room verification implicitly
1 parent 928871d commit 2241e6a

File tree

6 files changed

+102
-49
lines changed

6 files changed

+102
-49
lines changed

bindings/matrix-sdk-crypto-ffi/src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,6 @@ pub enum DecryptionError {
6161
Identifier(#[from] IdParseError),
6262
#[error(transparent)]
6363
Megolm(#[from] MegolmError),
64+
#[error(transparent)]
65+
Store(#[from] InnerStoreError),
6466
}

bindings/matrix-sdk-crypto-ffi/src/machine.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ use ruma::{
3434
},
3535
IncomingResponse,
3636
},
37-
events::{key::verification::VerificationMethod, AnySyncMessageLikeEvent},
37+
events::{
38+
key::verification::VerificationMethod, room::message::MessageType, AnyMessageLikeEvent,
39+
AnySyncMessageLikeEvent, AnyTimelineEvent, MessageLikeEvent,
40+
},
3841
serde::Raw,
3942
DeviceKeyAlgorithm, EventId, OwnedTransactionId, OwnedUserId, RoomId, UserId,
4043
};
@@ -635,6 +638,7 @@ impl OlmMachine {
635638
&self,
636639
event: &str,
637640
room_id: &str,
641+
handle_verification_events: bool,
638642
) -> Result<DecryptedEvent, DecryptionError> {
639643
// Element Android wants only the content and the type and will create a
640644
// decrypted event with those two itself, this struct makes sure we
@@ -652,6 +656,25 @@ impl OlmMachine {
652656

653657
let decrypted = self.runtime.block_on(self.inner.decrypt_room_event(&event, &room_id))?;
654658

659+
if handle_verification_events {
660+
if let Ok(AnyTimelineEvent::MessageLike(e)) = decrypted.event.deserialize() {
661+
match &e {
662+
AnyMessageLikeEvent::RoomMessage(MessageLikeEvent::Original(
663+
original_event,
664+
)) => {
665+
if let MessageType::VerificationRequest(_) = &original_event.content.msgtype
666+
{
667+
self.runtime.block_on(self.inner.receive_verification_event(&e))?;
668+
}
669+
}
670+
_ if e.event_type().to_string().starts_with("m.key.verification") => {
671+
self.runtime.block_on(self.inner.receive_verification_event(&e))?;
672+
}
673+
_ => (),
674+
}
675+
}
676+
}
677+
655678
let encryption_info =
656679
decrypted.encryption_info.expect("Decrypted event didn't contain any encryption info");
657680

@@ -816,13 +839,25 @@ impl OlmMachine {
816839
&self,
817840
event: &str,
818841
room_id: &str,
842+
) -> Result<(), CryptoStoreError> {
843+
self.receive_verification_event(event, room_id)
844+
}
845+
846+
/// Receive an verification event.
847+
///
848+
/// This method can be used to pass verification events that are happening
849+
/// in rooms to the `OlmMachine`.
850+
pub fn receive_verification_event(
851+
&self,
852+
event: &str,
853+
room_id: &str,
819854
) -> Result<(), CryptoStoreError> {
820855
let room_id = RoomId::parse(room_id)?;
821856
let event: AnySyncMessageLikeEvent = serde_json::from_str(event)?;
822857

823858
let event = event.into_full_event(room_id);
824859

825-
self.runtime.block_on(self.inner.receive_unencrypted_verification_event(&event))?;
860+
self.runtime.block_on(self.inner.receive_verification_event(&event))?;
826861

827862
Ok(())
828863
}

bindings/matrix-sdk-crypto-ffi/src/olm.udl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ enum DecryptionError {
5959
"Identifier",
6060
"Serialization",
6161
"Megolm",
62+
"Store",
6263
};
6364

6465
dictionary DeviceLists {
@@ -365,7 +366,7 @@ interface OlmMachine {
365366
);
366367

367368
[Throws=DecryptionError]
368-
DecryptedEvent decrypt_room_event([ByRef] string event, [ByRef] string room_id);
369+
DecryptedEvent decrypt_room_event([ByRef] string event, [ByRef] string room_id, boolean handle_verificaton_events);
369370
[Throws=CryptoStoreError]
370371
string encrypt([ByRef] string room_id, [ByRef] string event_type, [ByRef] string content);
371372

@@ -396,6 +397,8 @@ interface OlmMachine {
396397

397398
[Throws=CryptoStoreError]
398399
void receive_unencrypted_verification_event([ByRef] string event, [ByRef] string room_id);
400+
[Throws=CryptoStoreError]
401+
void receive_verification_event([ByRef] string event, [ByRef] string room_id);
399402
sequence<VerificationRequest> get_verification_requests([ByRef] string user_id);
400403
VerificationRequest? get_verification_request([ByRef] string user_id, [ByRef] string flow_id);
401404
Verification? get_verification([ByRef] string user_id, [ByRef] string flow_id);

bindings/matrix-sdk-crypto-js/src/machine.rs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -633,24 +633,17 @@ impl OlmMachine {
633633
.collect()
634634
}
635635

636-
/// Receive an unencrypted verification event.
636+
/// Receive a verification event.
637637
///
638638
/// This method can be used to pass verification events that are
639-
/// happening in unencrypted rooms to the `OlmMachine`.
640-
///
641-
/// Note: This does not need to be called for encrypted events
642-
/// since those will get passed to the `OlmMachine` during
643-
/// decryption.
644-
#[wasm_bindgen(js_name = "receiveUnencryptedVerificationEvent")]
645-
pub fn receive_unencrypted_verification_event(&self, event: &str) -> Result<Promise, JsError> {
639+
/// happening in rooms to the `OlmMachine`.
640+
#[wasm_bindgen(js_name = "receiveVerificationEvent")]
641+
pub fn receive_verification_event(&self, event: &str) -> Result<Promise, JsError> {
646642
let event: ruma::events::AnyMessageLikeEvent = serde_json::from_str(event)?;
647643
let me = self.inner.clone();
648644

649645
Ok(future_to_promise(async move {
650-
Ok(me
651-
.receive_unencrypted_verification_event(&event)
652-
.await
653-
.map(|_| JsValue::UNDEFINED)?)
646+
Ok(me.receive_verification_event(&event).await.map(|_| JsValue::UNDEFINED)?)
654647
}))
655648
}
656649

crates/matrix-sdk-base/src/client.rs

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ use matrix_sdk_crypto::{
3131
use once_cell::sync::OnceCell;
3232
#[cfg(feature = "e2e-encryption")]
3333
use ruma::events::{
34-
room::{history_visibility::HistoryVisibility, redaction::SyncRoomRedactionEvent},
34+
room::{
35+
history_visibility::HistoryVisibility, message::MessageType,
36+
redaction::SyncRoomRedactionEvent,
37+
},
3538
AnySyncMessageLikeEvent, SyncMessageLikeEvent,
3639
};
3740
use ruma::{
@@ -240,21 +243,49 @@ impl BaseClient {
240243
}
241244

242245
#[cfg(feature = "e2e-encryption")]
243-
async fn handle_unencrypted_verification_event(
246+
async fn handle_verification_event(
244247
&self,
245248
event: &AnySyncMessageLikeEvent,
246249
room_id: &RoomId,
247250
) -> Result<()> {
248251
if let Some(olm) = self.olm_machine() {
249-
olm.receive_unencrypted_verification_event(
250-
&event.clone().into_full_event(room_id.to_owned()),
251-
)
252-
.await?;
252+
olm.receive_verification_event(&event.clone().into_full_event(room_id.to_owned()))
253+
.await?;
253254
}
254255

255256
Ok(())
256257
}
257258

259+
#[cfg(feature = "e2e-encryption")]
260+
async fn decrypt_sync_room_event(
261+
&self,
262+
event: &Raw<AnySyncTimelineEvent>,
263+
room_id: &RoomId,
264+
) -> Result<Option<SyncTimelineEvent>> {
265+
let Some(olm) = self.olm_machine() else { return Ok(None) };
266+
267+
let event = olm.decrypt_room_event(event.cast_ref(), room_id).await.unwrap();
268+
let event: SyncTimelineEvent = event.into();
269+
270+
if let Ok(AnySyncTimelineEvent::MessageLike(e)) = event.event.deserialize() {
271+
match &e {
272+
AnySyncMessageLikeEvent::RoomMessage(SyncMessageLikeEvent::Original(
273+
original_event,
274+
)) => {
275+
if let MessageType::VerificationRequest(_) = &original_event.content.msgtype {
276+
self.handle_verification_event(&e, room_id).await?;
277+
}
278+
}
279+
_ if e.event_type().to_string().starts_with("m.key.verification") => {
280+
self.handle_verification_event(&e, room_id).await?;
281+
}
282+
_ => (),
283+
}
284+
}
285+
286+
Ok(Some(event))
287+
}
288+
258289
#[allow(clippy::too_many_arguments)]
259290
pub(crate) async fn handle_timeline(
260291
&self,
@@ -338,13 +369,10 @@ impl BaseClient {
338369
AnySyncMessageLikeEvent::RoomEncrypted(
339370
SyncMessageLikeEvent::Original(_),
340371
) => {
341-
if let Some(olm) = self.olm_machine() {
342-
if let Ok(decrypted) = olm
343-
.decrypt_room_event(event.event.cast_ref(), room_id)
344-
.await
345-
{
346-
event = decrypted.into();
347-
}
372+
if let Ok(Some(e)) =
373+
self.decrypt_sync_room_event(&event.event, room_id).await
374+
{
375+
event = e;
348376
}
349377
}
350378
AnySyncMessageLikeEvent::RoomMessage(
@@ -353,12 +381,12 @@ impl BaseClient {
353381
ruma::events::room::message::MessageType::VerificationRequest(
354382
_,
355383
) => {
356-
self.handle_unencrypted_verification_event(e, room_id).await?;
384+
self.handle_verification_event(e, room_id).await?;
357385
}
358386
_ => (),
359387
},
360388
_ if e.event_type().to_string().starts_with("m.key.verification") => {
361-
self.handle_unencrypted_verification_event(e, room_id).await?;
389+
self.handle_verification_event(e, room_id).await?;
362390
}
363391
_ => (),
364392
},

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

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,14 @@ use ruma::{
3535
},
3636
assign,
3737
events::{
38-
secret::request::SecretName, AnyMessageLikeEvent, AnyTimelineEvent, AnyToDeviceEvent,
39-
MessageLikeEventContent,
38+
secret::request::SecretName, AnyMessageLikeEvent, AnyToDeviceEvent, MessageLikeEventContent,
4039
},
4140
serde::Raw,
4241
DeviceId, DeviceKeyAlgorithm, OwnedDeviceId, OwnedDeviceKeyId, OwnedTransactionId, OwnedUserId,
4342
RoomId, TransactionId, UInt, UserId,
4443
};
4544
use serde_json::{value::to_raw_value, Value};
46-
use tracing::{debug, error, field::debug, info, instrument, trace, warn};
45+
use tracing::{debug, error, field::debug, info, instrument, warn};
4746
use vodozemac::{
4847
megolm::{DecryptionError, SessionOrdering},
4948
Curve25519PublicKey, Ed25519Signature,
@@ -731,13 +730,22 @@ impl OlmMachine {
731730
///
732731
/// **Note**: This does not need to be called for encrypted events since
733732
/// those will get passed to the `OlmMachine` during decryption.
733+
#[deprecated(note = "Use OlmMachine::receive_verification_event instead", since = "0.7.0")]
734734
pub async fn receive_unencrypted_verification_event(
735735
&self,
736736
event: &AnyMessageLikeEvent,
737737
) -> StoreResult<()> {
738738
self.verification_machine.receive_any_event(event).await
739739
}
740740

741+
/// Receive an verification event.
742+
///
743+
/// This method can be used to pass verification events that are happening
744+
/// in rooms to the `OlmMachine`.
745+
pub async fn receive_verification_event(&self, event: &AnyMessageLikeEvent) -> StoreResult<()> {
746+
self.verification_machine.receive_any_event(event).await
747+
}
748+
741749
/// Receive and properly handle a decrypted to-device event.
742750
///
743751
/// # Arguments
@@ -1127,22 +1135,6 @@ impl OlmMachine {
11271135

11281136
// TODO: check the message index.
11291137
let (decrypted_event, _) = session.decrypt(event).await?;
1130-
1131-
match decrypted_event.deserialize() {
1132-
Ok(e) => {
1133-
// TODO: log the event type once `AnyTimelineEvent` has the
1134-
// method as well
1135-
trace!("Successfully decrypted a room event");
1136-
1137-
if let AnyTimelineEvent::MessageLike(e) = e {
1138-
self.verification_machine.receive_any_event(&e).await?;
1139-
}
1140-
}
1141-
Err(e) => {
1142-
warn!("Event was successfully decrypted but has an invalid format: {e}");
1143-
}
1144-
}
1145-
11461138
let encryption_info = self.get_encryption_info(&session, &event.sender).await?;
11471139

11481140
Ok(TimelineEvent { encryption_info: Some(encryption_info), event: decrypted_event })

0 commit comments

Comments
 (0)