Skip to content

Commit 7893e55

Browse files
committed
refactor(crypto): Make the room key importing logic more generic
1 parent c0e45a2 commit 7893e55

File tree

3 files changed

+85
-44
lines changed

3 files changed

+85
-44
lines changed

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ use crate::types::events::forwarded_room_key::ForwardedMegolmV2AesSha2Content;
3535
use crate::types::{
3636
deserialize_curve_key, deserialize_curve_key_vec,
3737
events::forwarded_room_key::{ForwardedMegolmV1AesSha2Content, ForwardedRoomKeyContent},
38-
serialize_curve_key, serialize_curve_key_vec, EventEncryptionAlgorithm, SigningKey,
39-
SigningKeys,
38+
serialize_curve_key, serialize_curve_key_vec, EventEncryptionAlgorithm, RoomKeyExport,
39+
SigningKey, SigningKeys,
4040
};
4141

4242
/// An error type for the creation of group sessions.
@@ -141,6 +141,20 @@ impl ExportedRoomKey {
141141
}
142142
}
143143

144+
impl RoomKeyExport for &ExportedRoomKey {
145+
fn room_id(&self) -> &ruma::RoomId {
146+
&self.room_id
147+
}
148+
149+
fn session_id(&self) -> &str {
150+
&self.session_id
151+
}
152+
153+
fn sender_key(&self) -> Curve25519PublicKey {
154+
self.sender_key
155+
}
156+
}
157+
144158
/// A backed up version of an [`InboundGroupSession`].
145159
///
146160
/// This can be used to back up the [`InboundGroupSession`] to the server using

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

Lines changed: 56 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ use crate::{
7474
},
7575
types::{
7676
events::room_key_withheld::RoomKeyWithheldEvent, BackupSecrets, CrossSigningSecrets,
77-
EventEncryptionAlgorithm, MegolmBackupV1Curve25519AesSha2Secrets, SecretsBundle,
77+
EventEncryptionAlgorithm, MegolmBackupV1Curve25519AesSha2Secrets, RoomKeyExport,
78+
SecretsBundle,
7879
},
7980
verification::VerificationMachine,
8081
CrossSigningStatus, OwnUserIdentityData, RoomKeyImportResult,
@@ -1832,6 +1833,54 @@ impl Store {
18321833
from_backup_version: Option<&str>,
18331834
progress_listener: impl Fn(usize, usize),
18341835
) -> Result<RoomKeyImportResult> {
1836+
let exported_keys: Vec<&ExportedRoomKey> = exported_keys.iter().collect();
1837+
self.import_sessions_impl(exported_keys, from_backup_version, progress_listener).await
1838+
}
1839+
1840+
/// Import the given room keys into our store.
1841+
///
1842+
/// # Arguments
1843+
///
1844+
/// * `exported_keys` - A list of previously exported keys that should be
1845+
/// imported into our store. If we already have a better version of a key
1846+
/// the key will *not* be imported.
1847+
///
1848+
/// Returns a tuple of numbers that represent the number of sessions that
1849+
/// were imported and the total number of sessions that were found in the
1850+
/// key export.
1851+
///
1852+
/// # Examples
1853+
///
1854+
/// ```no_run
1855+
/// # use std::io::Cursor;
1856+
/// # use matrix_sdk_crypto::{OlmMachine, decrypt_room_key_export};
1857+
/// # use ruma::{device_id, user_id};
1858+
/// # let alice = user_id!("@alice:example.org");
1859+
/// # async {
1860+
/// # let machine = OlmMachine::new(&alice, device_id!("DEVICEID")).await;
1861+
/// # let export = Cursor::new("".to_owned());
1862+
/// let exported_keys = decrypt_room_key_export(export, "1234").unwrap();
1863+
/// machine.store().import_exported_room_keys(exported_keys, |_, _| {}).await.unwrap();
1864+
/// # };
1865+
/// ```
1866+
pub async fn import_exported_room_keys(
1867+
&self,
1868+
exported_keys: Vec<ExportedRoomKey>,
1869+
progress_listener: impl Fn(usize, usize),
1870+
) -> Result<RoomKeyImportResult> {
1871+
self.import_room_keys(exported_keys, None, progress_listener).await
1872+
}
1873+
1874+
async fn import_sessions_impl<T>(
1875+
&self,
1876+
room_keys: Vec<T>,
1877+
from_backup_version: Option<&str>,
1878+
progress_listener: impl Fn(usize, usize),
1879+
) -> Result<RoomKeyImportResult>
1880+
where
1881+
T: TryInto<InboundGroupSession> + RoomKeyExport + Copy,
1882+
T::Error: Debug,
1883+
{
18351884
let mut sessions = Vec::new();
18361885

18371886
async fn new_session_better(
@@ -1845,11 +1894,11 @@ impl Store {
18451894
}
18461895
}
18471896

1848-
let total_count = exported_keys.len();
1897+
let total_count = room_keys.len();
18491898
let mut keys = BTreeMap::new();
18501899

1851-
for (i, key) in exported_keys.into_iter().enumerate() {
1852-
match InboundGroupSession::from_export(&key) {
1900+
for (i, key) in room_keys.into_iter().enumerate() {
1901+
match key.try_into() {
18531902
Ok(session) => {
18541903
let old_session = self
18551904
.inner
@@ -1875,9 +1924,9 @@ impl Store {
18751924
}
18761925
Err(e) => {
18771926
warn!(
1878-
sender_key= key.sender_key.to_base64(),
1879-
room_id = ?key.room_id,
1880-
session_id = key.session_id,
1927+
sender_key = key.sender_key().to_base64(),
1928+
room_id = ?key.room_id(),
1929+
session_id = key.session_id(),
18811930
error = ?e,
18821931
"Couldn't import a room key from a file export."
18831932
);
@@ -1896,40 +1945,6 @@ impl Store {
18961945
Ok(RoomKeyImportResult::new(imported_count, total_count, keys))
18971946
}
18981947

1899-
/// Import the given room keys into our store.
1900-
///
1901-
/// # Arguments
1902-
///
1903-
/// * `exported_keys` - A list of previously exported keys that should be
1904-
/// imported into our store. If we already have a better version of a key
1905-
/// the key will *not* be imported.
1906-
///
1907-
/// Returns a tuple of numbers that represent the number of sessions that
1908-
/// were imported and the total number of sessions that were found in the
1909-
/// key export.
1910-
///
1911-
/// # Examples
1912-
///
1913-
/// ```no_run
1914-
/// # use std::io::Cursor;
1915-
/// # use matrix_sdk_crypto::{OlmMachine, decrypt_room_key_export};
1916-
/// # use ruma::{device_id, user_id};
1917-
/// # let alice = user_id!("@alice:example.org");
1918-
/// # async {
1919-
/// # let machine = OlmMachine::new(&alice, device_id!("DEVICEID")).await;
1920-
/// # let export = Cursor::new("".to_owned());
1921-
/// let exported_keys = decrypt_room_key_export(export, "1234").unwrap();
1922-
/// machine.store().import_exported_room_keys(exported_keys, |_, _| {}).await.unwrap();
1923-
/// # };
1924-
/// ```
1925-
pub async fn import_exported_room_keys(
1926-
&self,
1927-
exported_keys: Vec<ExportedRoomKey>,
1928-
progress_listener: impl Fn(usize, usize),
1929-
) -> Result<RoomKeyImportResult> {
1930-
self.import_room_keys(exported_keys, None, progress_listener).await
1931-
}
1932-
19331948
pub(crate) fn crypto_store(&self) -> Arc<CryptoStoreWrapper> {
19341949
self.inner.store.clone()
19351950
}

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use matrix_sdk_common::deserialized_responses::PrivOwnedStr;
3838
use ruma::{
3939
events::AnyToDeviceEvent,
4040
serde::{Raw, StringEnum},
41-
DeviceKeyAlgorithm, DeviceKeyId, OwnedDeviceKeyId, OwnedUserId, UserId,
41+
DeviceKeyAlgorithm, DeviceKeyId, OwnedDeviceKeyId, OwnedUserId, RoomId, UserId,
4242
};
4343
use serde::{Deserialize, Deserializer, Serialize, Serializer};
4444
use vodozemac::{Curve25519PublicKey, Ed25519PublicKey, Ed25519Signature, KeyError};
@@ -660,3 +660,15 @@ impl ProcessedToDeviceEvent {
660660
}
661661
}
662662
}
663+
664+
/// Trait to express the various room key export formats we have in a unified
665+
/// manner.
666+
pub trait RoomKeyExport {
667+
/// The ID of the room where the exported room key was used.
668+
fn room_id(&self) -> &RoomId;
669+
/// The unique ID of the exported room key.
670+
fn session_id(&self) -> &str;
671+
/// The [Curve25519PublicKey] long-term identity key of the sender of this
672+
/// room key.
673+
fn sender_key(&self) -> Curve25519PublicKey;
674+
}

0 commit comments

Comments
 (0)