Skip to content

feat(sdk): Rename (export|import)_keys to (export|import)_room_keys #1058

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Sep 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bindings/matrix-sdk-crypto-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ mod test {
"JGgPQRuYj3ScMdPS+A0P+k/1qS9Hr3qeKXLscI+hS78"
);

let room_keys = machine.runtime.block_on(machine.inner.export_keys(|_| true))?;
let room_keys = machine.runtime.block_on(machine.inner.export_room_keys(|_| true))?;
assert_eq!(room_keys.len(), 2);

let cross_signing_status = machine.cross_signing_status();
Expand Down
29 changes: 17 additions & 12 deletions bindings/matrix-sdk-crypto-ffi/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use base64::{decode_config, encode, STANDARD_NO_PAD};
use js_int::UInt;
use matrix_sdk_common::deserialized_responses::AlgorithmInfo;
use matrix_sdk_crypto::{
backups::MegolmV1BackupKey as RustBackupKey, decrypt_key_export, encrypt_key_export,
backups::MegolmV1BackupKey as RustBackupKey, decrypt_room_key_export, encrypt_room_key_export,
matrix_sdk_qrcode::QrVerificationData, olm::ExportedRoomKey, store::RecoveryKey,
EncryptionSettings, LocalTrust, OlmMachine as InnerMachine, UserIdentities,
Verification as RustVerification,
Expand Down Expand Up @@ -658,16 +658,20 @@ impl OlmMachine {
///
/// * `rounds` - The number of rounds that should be used when expanding the
/// passphrase into an key.
pub fn export_keys(&self, passphrase: &str, rounds: i32) -> Result<String, CryptoStoreError> {
let keys = self.runtime.block_on(self.inner.export_keys(|_| true))?;
pub fn export_room_keys(
&self,
passphrase: &str,
rounds: i32,
) -> Result<String, CryptoStoreError> {
let keys = self.runtime.block_on(self.inner.export_room_keys(|_| true))?;

let encrypted = encrypt_key_export(&keys, passphrase, rounds as u32)
let encrypted = encrypt_room_key_export(&keys, passphrase, rounds as u32)
.map_err(CryptoStoreError::Serialization)?;

Ok(encrypted)
}

fn import_keys_helper(
fn import_room_keys_helper(
&self,
keys: Vec<ExportedRoomKey>,
from_backup: bool,
Expand All @@ -677,7 +681,8 @@ impl OlmMachine {
progress_listener.on_progress(progress as i32, total as i32)
};

let result = self.runtime.block_on(self.inner.import_keys(keys, from_backup, listener))?;
let result =
self.runtime.block_on(self.inner.import_room_keys(keys, from_backup, listener))?;

Ok(KeysImportResult {
imported: result.imported_count as i64,
Expand Down Expand Up @@ -705,20 +710,20 @@ impl OlmMachine {
///
/// * `progress_listener` - A callback that can be used to introspect the
/// progress of the key import.
pub fn import_keys(
pub fn import_room_keys(
&self,
keys: &str,
passphrase: &str,
progress_listener: Box<dyn ProgressListener>,
) -> Result<KeysImportResult, KeyImportError> {
let keys = Cursor::new(keys);
let keys = decrypt_key_export(keys, passphrase)?;
self.import_keys_helper(keys, false, progress_listener)
let keys = decrypt_room_key_export(keys, passphrase)?;
self.import_room_keys_helper(keys, false, progress_listener)
}

/// Import room keys from the given serialized unencrypted key export.
///
/// This method is the same as [`OlmMachine::import_keys`] but the
/// This method is the same as [`OlmMachine::import_room_keys`] but the
/// decryption step is skipped and should be performed by the caller. This
/// should be used if the room keys are coming from the server-side backup,
/// the method will mark all imported room keys as backed up.
Expand All @@ -729,7 +734,7 @@ impl OlmMachine {
///
/// * `progress_listener` - A callback that can be used to introspect the
/// progress of the key import.
pub fn import_decrypted_keys(
pub fn import_decrypted_room_keys(
&self,
keys: &str,
progress_listener: Box<dyn ProgressListener>,
Expand All @@ -738,7 +743,7 @@ impl OlmMachine {

let keys = keys.into_iter().map(serde_json::from_value).filter_map(|k| k.ok()).collect();

self.import_keys_helper(keys, true, progress_listener)
self.import_room_keys_helper(keys, true, progress_listener)
}

/// Discard the currently active room key for the given room if there is
Expand Down
6 changes: 3 additions & 3 deletions bindings/matrix-sdk-crypto-ffi/src/olm.udl
Original file line number Diff line number Diff line change
Expand Up @@ -358,15 +358,15 @@ interface OlmMachine {
KeyRequestPair request_room_key([ByRef] string event, [ByRef] string room_id);

[Throws=CryptoStoreError]
string export_keys([ByRef] string passphrase, i32 rounds);
string export_room_keys([ByRef] string passphrase, i32 rounds);
[Throws=KeyImportError]
KeysImportResult import_keys(
KeysImportResult import_room_keys(
[ByRef] string keys,
[ByRef] string passphrase,
ProgressListener progress_listener
);
[Throws=KeyImportError]
KeysImportResult import_decrypted_keys(
KeysImportResult import_decrypted_room_keys(
[ByRef] string keys,
ProgressListener progress_listener
);
Expand Down
41 changes: 22 additions & 19 deletions crates/matrix-sdk-crypto/src/file_encryption/key_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,18 @@ pub enum KeyExportError {
/// # Examples
/// ```no_run
/// # use std::io::Cursor;
/// # use matrix_sdk_crypto::{OlmMachine, decrypt_key_export};
/// # use matrix_sdk_crypto::{OlmMachine, decrypt_room_key_export};
/// # use ruma::{device_id, user_id};
/// # use futures::executor::block_on;
/// # let alice = user_id!("@alice:example.org");
/// # block_on(async {
/// # let machine = OlmMachine::new(&alice, device_id!("DEVICEID")).await;
/// # let export = Cursor::new("".to_owned());
/// let exported_keys = decrypt_key_export(export, "1234").unwrap();
/// machine.import_keys(exported_keys, false, |_, _| {}).await.unwrap();
/// let exported_keys = decrypt_room_key_export(export, "1234").unwrap();
/// machine.import_room_keys(exported_keys, false, |_, _| {}).await.unwrap();
/// # });
/// ```
pub fn decrypt_key_export(
pub fn decrypt_room_key_export(
mut input: impl Read,
passphrase: &str,
) -> Result<Vec<ExportedRoomKey>, KeyExportError> {
Expand Down Expand Up @@ -125,7 +125,7 @@ pub fn decrypt_key_export(
/// * `rounds` - The number of rounds that should be used for the key
/// derivation when the passphrase gets turned into an AES key. More rounds are
/// increasingly computationally intensive and as such help against brute-force
/// attacks. Should be at least `10000`, while values in the `100000` ranges
/// attacks. Should be at least `10_000`, while values in the `100_000` ranges
/// should be preferred.
///
/// # Panics
Expand All @@ -135,18 +135,18 @@ pub fn decrypt_key_export(
///
/// # Examples
/// ```no_run
/// # use matrix_sdk_crypto::{OlmMachine, encrypt_key_export};
/// # use matrix_sdk_crypto::{OlmMachine, encrypt_room_key_export};
/// # use ruma::{device_id, user_id, room_id};
/// # use futures::executor::block_on;
/// # let alice = user_id!("@alice:example.org");
/// # block_on(async {
/// # let machine = OlmMachine::new(&alice, device_id!("DEVICEID")).await;
/// let room_id = room_id!("!test:localhost");
/// let exported_keys = machine.export_keys(|s| s.room_id() == room_id).await.unwrap();
/// let encrypted_export = encrypt_key_export(&exported_keys, "1234", 1);
/// let exported_keys = machine.export_room_keys(|s| s.room_id() == room_id).await.unwrap();
/// let encrypted_export = encrypt_room_key_export(&exported_keys, "1234", 1);
/// # });
/// ```
pub fn encrypt_key_export(
pub fn encrypt_room_key_export(
keys: &[ExportedRoomKey],
passphrase: &str,
rounds: u32,
Expand Down Expand Up @@ -283,7 +283,9 @@ mod tests {
use matrix_sdk_test::async_test;
use ruma::room_id;

use super::{decode, decrypt_helper, decrypt_key_export, encrypt_helper, encrypt_key_export};
use super::{
decode, decrypt_helper, decrypt_room_key_export, encrypt_helper, encrypt_room_key_export,
};
use crate::{error::OlmResult, machine::tests::get_prepared_machine, RoomKeyImportResult};

const PASSPHRASE: &str = "1234";
Expand Down Expand Up @@ -332,19 +334,19 @@ mod tests {
let room_id = room_id!("!test:localhost");

machine.create_outbound_group_session_with_defaults(room_id).await.unwrap();
let export = machine.export_keys(|s| s.room_id() == room_id).await.unwrap();
let export = machine.export_room_keys(|s| s.room_id() == room_id).await.unwrap();

assert!(!export.is_empty());

let encrypted = encrypt_key_export(&export, "1234", 1).unwrap();
let decrypted = decrypt_key_export(Cursor::new(encrypted), "1234").unwrap();
let encrypted = encrypt_room_key_export(&export, "1234", 1).unwrap();
let decrypted = decrypt_room_key_export(Cursor::new(encrypted), "1234").unwrap();

for (exported, decrypted) in export.iter().zip(decrypted.iter()) {
assert_eq!(exported.session_key.to_base64(), decrypted.session_key.to_base64());
}

assert_eq!(
machine.import_keys(decrypted, false, |_, _| {}).await.unwrap(),
machine.import_room_keys(decrypted, false, |_, _| {}).await.unwrap(),
RoomKeyImportResult::new(0, 1, BTreeMap::new())
);
}
Expand All @@ -369,17 +371,17 @@ mod tests {
)]),
);

assert_eq!(machine.import_keys(export, false, |_, _| {}).await?, keys);
assert_eq!(machine.import_room_keys(export, false, |_, _| {}).await?, keys);

let export = vec![session.export_at_index(10).await];
assert_eq!(
machine.import_keys(export, false, |_, _| {}).await?,
machine.import_room_keys(export, false, |_, _| {}).await?,
RoomKeyImportResult::new(0, 1, BTreeMap::new())
);

let better_export = vec![session.export().await];

assert_eq!(machine.import_keys(better_export, false, |_, _| {}).await?, keys);
assert_eq!(machine.import_room_keys(better_export, false, |_, _| {}).await?, keys);

let another_session = machine.create_inbound_session(room_id).await?;
let export = vec![another_session.export_at_index(10).await];
Expand All @@ -396,15 +398,16 @@ mod tests {
)]),
);

assert_eq!(machine.import_keys(export, false, |_, _| {}).await?, keys);
assert_eq!(machine.import_room_keys(export, false, |_, _| {}).await?, keys);

Ok(())
}

#[test]
fn test_real_decrypt() {
let reader = Cursor::new(TEST_EXPORT);
let imported = decrypt_key_export(reader, PASSPHRASE).expect("Can't decrypt key export");
let imported =
decrypt_room_key_export(reader, PASSPHRASE).expect("Can't decrypt key export");
assert!(!imported.is_empty())
}
}
2 changes: 1 addition & 1 deletion crates/matrix-sdk-crypto/src/file_encryption/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ mod key_export;
pub use attachments::{
AttachmentDecryptor, AttachmentEncryptor, DecryptorError, MediaEncryptionInfo,
};
pub use key_export::{decrypt_key_export, encrypt_key_export, KeyExportError};
pub use key_export::{decrypt_room_key_export, encrypt_room_key_export, KeyExportError};
2 changes: 1 addition & 1 deletion crates/matrix-sdk-crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl RoomKeyImportResult {

pub use error::{EventError, MegolmError, OlmError, SessionCreationError, SignatureError};
pub use file_encryption::{
decrypt_key_export, encrypt_key_export, AttachmentDecryptor, AttachmentEncryptor,
decrypt_room_key_export, encrypt_room_key_export, AttachmentDecryptor, AttachmentEncryptor,
DecryptorError, KeyExportError, MediaEncryptionInfo,
};
pub use gossiping::GossipRequest;
Expand Down
16 changes: 8 additions & 8 deletions crates/matrix-sdk-crypto/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1330,18 +1330,18 @@ impl OlmMachine {
/// # Examples
/// ```no_run
/// # use std::io::Cursor;
/// # use matrix_sdk_crypto::{OlmMachine, decrypt_key_export};
/// # use matrix_sdk_crypto::{OlmMachine, decrypt_room_key_export};
/// # use ruma::{device_id, user_id};
/// # use futures::executor::block_on;
/// # let alice = user_id!("@alice:example.org");
/// # block_on(async {
/// # let machine = OlmMachine::new(&alice, device_id!("DEVICEID")).await;
/// # let export = Cursor::new("".to_owned());
/// let exported_keys = decrypt_key_export(export, "1234").unwrap();
/// machine.import_keys(exported_keys, false, |_, _| {}).await.unwrap();
/// let exported_keys = decrypt_room_key_export(export, "1234").unwrap();
/// machine.import_room_keys(exported_keys, false, |_, _| {}).await.unwrap();
/// # });
/// ```
pub async fn import_keys(
pub async fn import_room_keys(
&self,
exported_keys: Vec<ExportedRoomKey>,
#[allow(unused_variables)] from_backup: bool,
Expand Down Expand Up @@ -1434,18 +1434,18 @@ impl OlmMachine {
/// # Examples
///
/// ```no_run
/// # use matrix_sdk_crypto::{OlmMachine, encrypt_key_export};
/// # use matrix_sdk_crypto::{OlmMachine, encrypt_room_key_export};
/// # use ruma::{device_id, user_id, room_id};
/// # use futures::executor::block_on;
/// # let alice = user_id!("@alice:example.org");
/// # block_on(async {
/// # let machine = OlmMachine::new(&alice, device_id!("DEVICEID")).await;
/// let room_id = room_id!("!test:localhost");
/// let exported_keys = machine.export_keys(|s| s.room_id() == room_id).await.unwrap();
/// let encrypted_export = encrypt_key_export(&exported_keys, "1234", 1);
/// let exported_keys = machine.export_room_keys(|s| s.room_id() == room_id).await.unwrap();
/// let encrypted_export = encrypt_room_key_export(&exported_keys, "1234", 1);
/// # });
/// ```
pub async fn export_keys(
pub async fn export_room_keys(
&self,
mut predicate: impl FnMut(&InboundGroupSession) -> bool,
) -> StoreResult<Vec<ExportedRoomKey>> {
Expand Down
4 changes: 2 additions & 2 deletions crates/matrix-sdk/src/docs/encryption.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ comes first.

Since room keys get relatively often rotated, each room key will need to be
stored, otherwise we won't be able to decrypt historical messages. The SDK
stores all room keys locally in a encrypted manner.
stores all room keys locally in an encrypted manner.

Besides storing them as part of the SDK store, users can export room keys
using the [`Encryption::export_keys`] method.
using the [`Encryption::export_room_keys`] method.

# Verification

Expand Down
18 changes: 9 additions & 9 deletions crates/matrix-sdk/src/encryption/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ impl Encryption {
/// // Export all room keys.
/// client
/// .encryption()
/// .export_keys(path, "secret-passphrase", |_| true)
/// .export_room_keys(path, "secret-passphrase", |_| true)
/// .await?;
///
/// // Export only the room keys for a certain room.
Expand All @@ -725,25 +725,25 @@ impl Encryption {
///
/// client
/// .encryption()
/// .export_keys(path, "secret-passphrase", |s| s.room_id() == room_id)
/// .export_room_keys(path, "secret-passphrase", |s| s.room_id() == room_id)
/// .await?;
/// # anyhow::Ok(()) });
/// ```
#[cfg(not(target_arch = "wasm32"))]
pub async fn export_keys(
pub async fn export_room_keys(
&self,
path: PathBuf,
passphrase: &str,
predicate: impl FnMut(&matrix_sdk_base::crypto::olm::InboundGroupSession) -> bool,
) -> Result<()> {
let olm = self.client.olm_machine().ok_or(Error::AuthenticationRequired)?;

let keys = olm.export_keys(predicate).await?;
let keys = olm.export_room_keys(predicate).await?;
let passphrase = zeroize::Zeroizing::new(passphrase.to_owned());

let encrypt = move || -> Result<()> {
let export: String =
matrix_sdk_base::crypto::encrypt_key_export(&keys, &passphrase, 500_000)?;
matrix_sdk_base::crypto::encrypt_room_key_export(&keys, &passphrase, 500_000)?;
let mut file = std::fs::File::create(path)?;
file.write_all(&export.into_bytes())?;
Ok(())
Expand Down Expand Up @@ -783,7 +783,7 @@ impl Encryption {
/// # let mut client = Client::new(homeserver).await?;
/// let path = PathBuf::from("/home/example/e2e-keys.txt");
/// let result =
/// client.encryption().import_keys(path, "secret-passphrase").await?;
/// client.encryption().import_room_keys(path, "secret-passphrase").await?;
///
/// println!(
/// "Imported {} room keys out of {}",
Expand All @@ -792,7 +792,7 @@ impl Encryption {
/// # anyhow::Ok(()) });
/// ```
#[cfg(not(target_arch = "wasm32"))]
pub async fn import_keys(
pub async fn import_room_keys(
&self,
path: PathBuf,
passphrase: &str,
Expand All @@ -802,13 +802,13 @@ impl Encryption {

let decrypt = move || {
let file = std::fs::File::open(path)?;
matrix_sdk_base::crypto::decrypt_key_export(file, &passphrase)
matrix_sdk_base::crypto::decrypt_room_key_export(file, &passphrase)
};

let task = tokio::task::spawn_blocking(decrypt);
let import = task.await.expect("Task join error")?;

Ok(olm.import_keys(import, false, |_, _| {}).await?)
Ok(olm.import_room_keys(import, false, |_, _| {}).await?)
}
}

Expand Down