Skip to content

Commit c7608f4

Browse files
committed
feat: Append withheld info from room key bundle to store.
1 parent 2ea3646 commit c7608f4

File tree

1 file changed

+124
-8
lines changed
  • crates/matrix-sdk-crypto/src/store

1 file changed

+124
-8
lines changed

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

Lines changed: 124 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ use crate::{
7777
Session, StaticAccountData,
7878
},
7979
types::{
80-
BackupSecrets, CrossSigningSecrets, MegolmBackupV1Curve25519AesSha2Secrets, RoomKeyExport,
81-
SecretsBundle,
80+
events::room_key_withheld::MegolmV1AesSha2WithheldContent, BackupSecrets,
81+
CrossSigningSecrets, MegolmBackupV1Curve25519AesSha2Secrets, RoomKeyExport, SecretsBundle,
8282
},
8383
verification::VerificationMachine,
8484
CrossSigningStatus, OwnUserIdentityData, RoomKeyImportResult,
@@ -1632,12 +1632,11 @@ impl Store {
16321632

16331633
tracing::Span::current().record("sender_data", tracing::field::debug(&sender_data));
16341634

1635-
match sender_data {
1635+
match &sender_data {
16361636
SenderData::UnknownDevice { .. }
16371637
| SenderData::VerificationViolation(_)
16381638
| SenderData::DeviceInfo { .. } => {
16391639
warn!("Not accepting a historic room key bundle due to insufficient trust in the sender");
1640-
Ok(())
16411640
}
16421641
SenderData::SenderUnverified(_) | SenderData::SenderVerified(_) => {
16431642
let (good, bad): (Vec<_>, Vec<_>) = bundle.room_keys.iter().partition_map(|key| {
@@ -1681,10 +1680,28 @@ impl Store {
16811680
self.import_sessions_impl(good, None, progress_listener).await?;
16821681
}
16831682
}
1683+
}
1684+
}
16841685

1685-
Ok(())
1686+
let mut changes = Changes::default();
1687+
for withheld in &bundle.withheld {
1688+
if let RoomKeyWithheldContent::MegolmV1AesSha2(
1689+
MegolmV1AesSha2WithheldContent::BlackListed(c)
1690+
| MegolmV1AesSha2WithheldContent::Unverified(c)
1691+
| MegolmV1AesSha2WithheldContent::Unauthorised(c)
1692+
| MegolmV1AesSha2WithheldContent::Unavailable(c),
1693+
) = withheld
1694+
{
1695+
changes
1696+
.withheld_session_info
1697+
.entry(c.room_id.to_owned())
1698+
.or_default()
1699+
.insert(c.session_id.to_owned(), withheld.to_owned().into());
16861700
}
16871701
}
1702+
self.save_changes(changes).await?;
1703+
1704+
Ok(())
16881705
}
16891706
}
16901707

@@ -1717,17 +1734,32 @@ impl matrix_sdk_common::cross_process_lock::TryLock for LockableCryptoStore {
17171734
mod tests {
17181735
use std::pin::pin;
17191736

1737+
use assert_matches2::assert_matches;
17201738
use futures_util::StreamExt;
17211739
use insta::{_macro_support::Content, assert_json_snapshot, internals::ContentPath};
17221740
use matrix_sdk_test::async_test;
1723-
use ruma::{device_id, room_id, user_id, RoomId};
1741+
use ruma::{
1742+
device_id,
1743+
events::room::{EncryptedFileInit, JsonWebKeyInit},
1744+
owned_mxc_uri, room_id,
1745+
serde::Base64,
1746+
user_id, RoomId,
1747+
};
17241748
use vodozemac::megolm::SessionKey;
17251749

17261750
use crate::{
17271751
machine::test_helpers::get_machine_pair,
17281752
olm::{InboundGroupSession, SenderData},
1729-
store::types::DehydratedDeviceKey,
1730-
types::EventEncryptionAlgorithm,
1753+
store::types::{DehydratedDeviceKey, StoredRoomKeyBundleData},
1754+
types::{
1755+
events::{
1756+
room_key_bundle::RoomKeyBundleContent,
1757+
room_key_withheld::{
1758+
MegolmV1AesSha2WithheldContent, RoomKeyWithheldContent, RoomKeyWithheldEntry,
1759+
},
1760+
},
1761+
EventEncryptionAlgorithm,
1762+
},
17311763
OlmMachine,
17321764
};
17331765

@@ -1969,6 +2001,90 @@ mod tests {
19692001
});
19702002
}
19712003

2004+
#[async_test]
2005+
async fn test_receive_room_key_bundle() {
2006+
let alice = OlmMachine::new(user_id!("@a:s.co"), device_id!("ALICE")).await;
2007+
let alice_key = alice.identity_keys().curve25519;
2008+
let bob = OlmMachine::new(user_id!("@b:s.co"), device_id!("BOB")).await;
2009+
2010+
let room_id = room_id!("!room1:localhost");
2011+
2012+
let session_key1 = "AgAAAAC2XHVzsMBKs4QCRElJ92CJKyGtknCSC8HY7cQ7UYwndMKLQAejXLh5UA0l6s736mgctcUMNvELScUWrObdflrHo+vth/gWreXOaCnaSxmyjjKErQwyIYTkUfqbHy40RJfEesLwnN23on9XAkch/iy8R2+Jz7B8zfG01f2Ow2SxPQFnAndcO1ZSD2GmXgedy6n4B20MWI1jGP2wiexOWbFSya8DO/VxC9m5+/mF+WwYqdpKn9g4Y05Yw4uz7cdjTc3rXm7xK+8E7hI//5QD1nHPvuKYbjjM9u2JSL+Bzp61Cw";
2013+
let session_key2 = "AgAAAAC1BXreFTUQQSBGekTEuYxhdytRKyv4JgDGcG+VOBYdPNGgs807SdibCGJky4lJ3I+7ZDGHoUzZPZP/4ogGu4kxni0PWdtWuN7+5zsuamgoFF/BkaGeUUGv6kgIkx8pyPpM5SASTUEP9bN2loDSpUPYwfiIqz74DgC4WQ4435sTBctYvKz8n+TDJwdLXpyT6zKljuqADAioud+s/iqx9LYn9HpbBfezZcvbg67GtE113pLrvde3IcPI5s6dNHK2onGO2B2eoaobcen18bbEDnlUGPeIivArLya7Da6us14jBQ";
2014+
2015+
let sessions = [
2016+
create_inbound_group_session_with_visibility(
2017+
&alice,
2018+
room_id,
2019+
&SessionKey::from_base64(session_key1).unwrap(),
2020+
true,
2021+
),
2022+
create_inbound_group_session_with_visibility(
2023+
&alice,
2024+
room_id,
2025+
&SessionKey::from_base64(session_key2).unwrap(),
2026+
false,
2027+
),
2028+
];
2029+
2030+
alice.store().save_inbound_group_sessions(&sessions).await.unwrap();
2031+
let bundle = alice.store().build_room_key_bundle(room_id).await.unwrap();
2032+
2033+
bob.store()
2034+
.receive_room_key_bundle(
2035+
&StoredRoomKeyBundleData {
2036+
sender_user: alice.user_id().to_owned(),
2037+
sender_key: alice_key.clone(),
2038+
sender_data: SenderData::sender_verified(
2039+
alice.user_id(),
2040+
device_id!("ALICE"),
2041+
alice.identity_keys().ed25519,
2042+
),
2043+
2044+
bundle_data: RoomKeyBundleContent {
2045+
room_id: room_id.to_owned(),
2046+
// This isn't used at all in the method call, so we can fill it with
2047+
// garbage.
2048+
file: EncryptedFileInit {
2049+
url: owned_mxc_uri!("mxc://example.com/0"),
2050+
key: JsonWebKeyInit {
2051+
kty: "oct".to_string(),
2052+
key_ops: vec!["encrypt".to_string(), "decrypt".to_string()],
2053+
alg: "A256CTR.".to_string(),
2054+
k: Base64::new(vec![0u8; 128]),
2055+
ext: true,
2056+
}
2057+
.into(),
2058+
iv: Base64::new(vec![0u8; 128]),
2059+
hashes: vec![("sha256".to_string(), Base64::new(vec![0u8; 128]))]
2060+
.into_iter()
2061+
.collect(),
2062+
v: "v2".to_string(),
2063+
}
2064+
.into(),
2065+
},
2066+
},
2067+
bundle,
2068+
|_, _| {},
2069+
)
2070+
.await
2071+
.unwrap();
2072+
2073+
// The room key should be imported successfully
2074+
let imported_sessions =
2075+
bob.store().get_inbound_group_sessions_by_room_id(room_id).await.unwrap();
2076+
2077+
assert_eq!(imported_sessions.len(), 1);
2078+
assert_eq!(imported_sessions[0].room_id(), room_id);
2079+
2080+
assert_matches!(
2081+
bob.store().get_withheld_info(room_id, sessions[1].session_id()).await.unwrap(),
2082+
Some(RoomKeyWithheldEntry::Bundle(RoomKeyWithheldContent::MegolmV1AesSha2(
2083+
MegolmV1AesSha2WithheldContent::Unauthorised(_)
2084+
)))
2085+
);
2086+
}
2087+
19722088
/// Create an inbound Megolm session for the given room.
19732089
///
19742090
/// `olm_machine` is used to set the `sender_key` and `signing_key`

0 commit comments

Comments
 (0)