Skip to content

Commit 822b1c9

Browse files
committed
crypto: replace uses of compare_group_session
... with `merge_received_group_session`. `merge_received_group_session` expands the logic of `compare_group_session` to handle the fact that there is more than one axis of "better" or "worse" and we may need to take the best bits of two copies of the session.
1 parent 52344fa commit 822b1c9

File tree

4 files changed

+15
-93
lines changed

4 files changed

+15
-93
lines changed

crates/matrix-sdk-crypto/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file.
88

99
### Features
1010

11+
- When we receive an inbound Megolm session from two different sources, merge the two copies together to get the best of both.
12+
([#5865](https://github.com/matrix-org/matrix-rust-sdk/pull/5865)
1113
- When constructing a key bundle for history sharing, if we had received a key bundle ourselves, in which one or more sessions was marked as "history not shared", pass that on to the new user.
1214
([#5820](https://github.com/matrix-org/matrix-rust-sdk/pull/5820)
1315
- Expose new method `CryptoStore::get_withheld_sessions_by_room_id`.

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

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use ruma::{
3939
TransactionId, UserId,
4040
};
4141
use tracing::{debug, field::debug, info, instrument, trace, warn, Span};
42-
use vodozemac::{megolm::SessionOrdering, Curve25519PublicKey};
42+
use vodozemac::Curve25519PublicKey;
4343

4444
use super::{GossipRequest, GossippedSecret, RequestEvent, RequestInfo, SecretInfo, WaitQueue};
4545
use crate::{
@@ -964,6 +964,7 @@ impl GossipMachine {
964964
Ok(name)
965965
}
966966

967+
#[tracing::instrument(skip_all)]
967968
async fn accept_forwarded_room_key(
968969
&self,
969970
info: &GossipRequest,
@@ -972,33 +973,11 @@ impl GossipMachine {
972973
) -> Result<Option<InboundGroupSession>, CryptoStoreError> {
973974
match InboundGroupSession::try_from(event) {
974975
Ok(session) => {
975-
if self.inner.store.compare_group_session(&session).await?
976-
== SessionOrdering::Better
977-
{
976+
let new_session = self.inner.store.merge_received_group_session(session).await?;
977+
if new_session.is_some() {
978978
self.mark_as_done(info).await?;
979-
980-
info!(
981-
?sender_key,
982-
claimed_sender_key = ?session.sender_key(),
983-
room_id = ?session.room_id(),
984-
session_id = session.session_id(),
985-
algorithm = ?session.algorithm(),
986-
"Received a forwarded room key",
987-
);
988-
989-
Ok(Some(session))
990-
} else {
991-
info!(
992-
?sender_key,
993-
claimed_sender_key = ?session.sender_key(),
994-
room_id = ?session.room_id(),
995-
session_id = session.session_id(),
996-
algorithm = ?session.algorithm(),
997-
"Received a forwarded room key but we already have a better version of it",
998-
);
999-
1000-
Ok(None)
1001979
}
980+
Ok(new_session)
1002981
}
1003982
Err(e) => {
1004983
warn!(?sender_key, "Couldn't create a group session from a received room key");

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

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,7 @@ use tracing::{
6262
field::{debug, display},
6363
info, instrument, trace, warn, Span,
6464
};
65-
use vodozemac::{
66-
megolm::{DecryptionError, SessionOrdering},
67-
Curve25519PublicKey, Ed25519Signature,
68-
};
65+
use vodozemac::{megolm::DecryptionError, Curve25519PublicKey, Ed25519Signature};
6966

7067
#[cfg(feature = "experimental-send-custom-to-device")]
7168
use crate::session_manager::split_devices_for_share_strategy;
@@ -916,25 +913,9 @@ impl OlmMachine {
916913
let sender_data =
917914
SenderDataFinder::find_using_event(self.store(), sender_key, event, &session)
918915
.await?;
919-
920916
session.sender_data = sender_data;
921917

922-
match self.store().compare_group_session(&session).await? {
923-
SessionOrdering::Better => {
924-
info!("Received a new megolm room key");
925-
926-
Ok(Some(session))
927-
}
928-
comparison_result => {
929-
warn!(
930-
?comparison_result,
931-
"Received a megolm room key that we already have a better version \
932-
of, discarding"
933-
);
934-
935-
Ok(None)
936-
}
937-
}
918+
Ok(self.store().merge_received_group_session(session).await?)
938919
}
939920
Err(e) => {
940921
Span::current().record("session_id", &content.session_id);

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

Lines changed: 6 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -634,29 +634,6 @@ impl Store {
634634
self.inner.store.save_changes(changes).await
635635
}
636636

637-
/// Compare the given `InboundGroupSession` with an existing session we have
638-
/// in the store.
639-
///
640-
/// This method returns `SessionOrdering::Better` if the given session is
641-
/// better than the one we already have or if we don't have such a
642-
/// session in the store.
643-
pub(crate) async fn compare_group_session(
644-
&self,
645-
session: &InboundGroupSession,
646-
) -> Result<SessionOrdering> {
647-
let old_session = self
648-
.inner
649-
.store
650-
.get_inbound_group_session(session.room_id(), session.session_id())
651-
.await?;
652-
653-
Ok(if let Some(old_session) = old_session {
654-
session.compare(&old_session).await
655-
} else {
656-
SessionOrdering::Better
657-
})
658-
}
659-
660637
/// Given an `InboundGroupSession` which we have just received, see if we
661638
/// have a matching session already in the store, and determine how to
662639
/// handle it.
@@ -1526,43 +1503,26 @@ impl Store {
15261503
{
15271504
let mut sessions = Vec::new();
15281505

1529-
async fn new_session_better(
1530-
session: &InboundGroupSession,
1531-
old_session: Option<InboundGroupSession>,
1532-
) -> bool {
1533-
if let Some(old_session) = &old_session {
1534-
session.compare(old_session).await == SessionOrdering::Better
1535-
} else {
1536-
true
1537-
}
1538-
}
1539-
15401506
let total_count = room_keys.len();
15411507
let mut keys = BTreeMap::new();
15421508

15431509
for (i, key) in room_keys.into_iter().enumerate() {
15441510
match key.try_into() {
15451511
Ok(session) => {
1546-
let old_session = self
1547-
.inner
1548-
.store
1549-
.get_inbound_group_session(session.room_id(), session.session_id())
1550-
.await?;
1551-
15521512
// Only import the session if we didn't have this session or
15531513
// if it's a better version of the same session.
1554-
if new_session_better(&session, old_session).await {
1514+
if let Some(merged) = self.merge_received_group_session(session).await? {
15551515
if from_backup_version.is_some() {
1556-
session.mark_as_backed_up();
1516+
merged.mark_as_backed_up();
15571517
}
15581518

1559-
keys.entry(session.room_id().to_owned())
1519+
keys.entry(merged.room_id().to_owned())
15601520
.or_insert_with(BTreeMap::new)
1561-
.entry(session.sender_key().to_base64())
1521+
.entry(merged.sender_key().to_base64())
15621522
.or_insert_with(BTreeSet::new)
1563-
.insert(session.session_id().to_owned());
1523+
.insert(merged.session_id().to_owned());
15641524

1565-
sessions.push(session);
1525+
sessions.push(merged);
15661526
}
15671527
}
15681528
Err(e) => {

0 commit comments

Comments
 (0)