diff --git a/crates/matrix-sdk-crypto/Cargo.toml b/crates/matrix-sdk-crypto/Cargo.toml index 9030ab5d2..a5bf126d3 100644 --- a/crates/matrix-sdk-crypto/Cargo.toml +++ b/crates/matrix-sdk-crypto/Cargo.toml @@ -72,6 +72,8 @@ http = "0.2.4" indoc = "1.0.3" matches = "0.1.8" matrix-sdk-test = { version = "0.4.0", path = "../matrix-sdk-test" } + +# This is needed for the benchmarks matrix-sdk-sled = { version = "0.1.0", path = "../matrix-sdk-sled", default-features = false, features = ["crypto-store"] } [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] criterion = { version = "0.3.4", features = [ diff --git a/crates/matrix-sdk-crypto/src/backups/keys/recovery.rs b/crates/matrix-sdk-crypto/src/backups/keys/recovery.rs index 10abfc74f..495558b39 100644 --- a/crates/matrix-sdk-crypto/src/backups/keys/recovery.rs +++ b/crates/matrix-sdk-crypto/src/backups/keys/recovery.rs @@ -22,12 +22,11 @@ use olm_rs::{ errors::OlmPkDecryptionError, pk::{OlmPkDecryption, PkMessage}, }; -use rand::{thread_rng, Error as RandomError, Fill}; use thiserror::Error; use zeroize::Zeroizing; use super::MegolmV1BackupKey; -use crate::{store::RecoveryKey, utilities::encode}; +use crate::store::RecoveryKey; /// Error type for the decoding of a RecoveryKey. #[derive(Debug, Error)] @@ -97,16 +96,6 @@ impl RecoveryKey { bytes.iter().fold(Self::PREFIX_PARITY, |acc, x| acc ^ x) } - /// Create a new random recovery key. - pub fn new() -> Result { - let mut rng = thread_rng(); - - let mut key = [0u8; Self::KEY_SIZE]; - key.try_fill(&mut rng)?; - - Ok(Self { inner: key }) - } - /// Create a new recovery key from the given byte array. /// /// **Warning**: You need to make sure that the byte array contains correct @@ -130,11 +119,6 @@ impl RecoveryKey { } } - /// Export the `RecoveryKey` as a base64 encoded string. - pub fn to_base64(&self) -> String { - encode(self.inner) - } - /// Try to create a [`RecoveryKey`] from a base58 export of a `RecoveryKey`. pub fn from_base58(value: &str) -> Result { // Remove any whitespace we might have diff --git a/crates/matrix-sdk-crypto/src/backups/mod.rs b/crates/matrix-sdk-crypto/src/backups/mod.rs index f3b9d7a46..f0fd48469 100644 --- a/crates/matrix-sdk-crypto/src/backups/mod.rs +++ b/crates/matrix-sdk-crypto/src/backups/mod.rs @@ -463,57 +463,4 @@ mod test { backup_flow(machine).await } - - #[async_test] - #[cfg(feature = "sled_cryptostore")] - async fn default_store_backups() -> Result<(), OlmError> { - use tempfile::tempdir; - - let tmpdir = tempdir().expect("Can't create a temporary dir"); - let machine = - OlmMachine::with_default_store(alice_id(), alice_device_id(), tmpdir.as_ref(), None) - .await?; - - backup_flow(machine).await - } - - #[async_test] - #[cfg(feature = "sled_cryptostore")] - async fn recovery_key_storing() -> Result<(), OlmError> { - use tempfile::tempdir; - - let tmpdir = tempdir().expect("Can't create a temporary dir"); - let machine = OlmMachine::with_default_store( - alice_id(), - alice_device_id(), - tmpdir.as_ref(), - Some("test"), - ) - .await?; - let backup_machine = machine.backup_machine(); - - let recovery_key = RecoveryKey::new().expect("Can't create new recovery key"); - let encoded_key = recovery_key.to_base64(); - - backup_machine.save_recovery_key(Some(recovery_key), Some("1".to_owned())).await?; - - let loded_backup = backup_machine.get_backup_keys().await?; - - assert_eq!( - encoded_key, - loded_backup - .recovery_key - .expect("The recovery key wasn't loaded from the store") - .to_base64(), - "The loaded key matches to the one we stored" - ); - - assert_eq!( - Some("1"), - loded_backup.backup_version.as_deref(), - "The loaded version matches to the one we stored" - ); - - Ok(()) - } } diff --git a/crates/matrix-sdk-crypto/src/machine.rs b/crates/matrix-sdk-crypto/src/machine.rs index 1ca7241fc..b24871923 100644 --- a/crates/matrix-sdk-crypto/src/machine.rs +++ b/crates/matrix-sdk-crypto/src/machine.rs @@ -261,27 +261,6 @@ impl OlmMachine { Ok(OlmMachine::new_helper(&user_id, device_id, store, account, identity)) } - /// Create a new machine with the default crypto store. - /// - /// The default store uses a Sled database to store the encryption keys. - /// - /// # Arguments - /// - /// * `user_id` - The unique id of the user that owns this machine. - /// - /// * `device_id` - The unique id of the device that owns this machine. - #[cfg(feature = "sled_cryptostore")] - pub async fn with_default_store( - user_id: &UserId, - device_id: &DeviceId, - path: impl AsRef, - passphrase: Option<&str>, - ) -> StoreResult { - let store = SledStore::open_with_passphrase(path, passphrase)?; - - OlmMachine::with_store(user_id.to_owned(), device_id.into(), Box::new(store)).await - } - /// The unique user id that owns this `OlmMachine` instance. pub fn user_id(&self) -> &UserId { &self.user_id @@ -2005,44 +1984,6 @@ pub(crate) mod test { } } - #[async_test] - #[cfg(feature = "sled_cryptostore")] - async fn test_machine_with_default_store() { - use tempfile::tempdir; - - let tmpdir = tempdir().unwrap(); - - let machine = OlmMachine::with_default_store( - user_id(), - alice_device_id(), - tmpdir.as_ref(), - Some("test"), - ) - .await - .unwrap(); - - let user_id = machine.user_id().to_owned(); - let device_id = machine.device_id().to_owned(); - let ed25519_key = machine.identity_keys().ed25519; - - machine.receive_keys_upload_response(&keys_upload_response()).await.unwrap(); - - drop(machine); - - let machine = OlmMachine::with_default_store( - &user_id, - alice_device_id(), - tmpdir.as_ref(), - Some("test"), - ) - .await - .unwrap(); - - assert_eq!(&user_id, machine.user_id()); - assert_eq!(&*device_id, machine.device_id()); - assert_eq!(ed25519_key, machine.identity_keys().ed25519); - } - #[async_test] async fn interactive_verification() { let (alice, bob) = get_machine_pair_with_setup_sessions().await; diff --git a/crates/matrix-sdk-crypto/src/store/integration_tests.rs b/crates/matrix-sdk-crypto/src/store/integration_tests.rs index 665c92f9d..56532ac1f 100644 --- a/crates/matrix-sdk-crypto/src/store/integration_tests.rs +++ b/crates/matrix-sdk-crypto/src/store/integration_tests.rs @@ -21,7 +21,7 @@ macro_rules! cryptostore_integration_tests { InboundGroupSession, OlmMessageHash, PrivateCrossSigningIdentity, ReadOnlyAccount, Session, }, - store::{CryptoStore, GossipRequest, Changes, DeviceChanges, IdentityChanges}, + store::{CryptoStore, GossipRequest, Changes, DeviceChanges, IdentityChanges, RecoveryKey}, }; fn alice_id() -> &'static UserId { @@ -575,6 +575,40 @@ macro_rules! cryptostore_integration_tests { assert_eq!(None, stored_request); assert!(store.get_unsent_secret_requests().await.unwrap().is_empty()); } + + #[async_test] + async fn recovery_key_saving() { + let dir = "recovery_key_saving".to_owned(); + let (account, store) = get_loaded_store(dir).await; + + let recovery_key = RecoveryKey::new().expect("Can't create new recovery key"); + let encoded_key = recovery_key.to_base64(); + + let changes = Changes { + recovery_key: Some(recovery_key), + backup_version: Some("1".to_owned()), + ..Default::default() + }; + + store.save_changes(changes).await.unwrap(); + + let loded_backup = store.load_backup_keys().await.unwrap(); + + assert_eq!( + encoded_key, + loded_backup + .recovery_key + .expect("The recovery key wasn't loaded from the store") + .to_base64(), + "The loaded key matches to the one we stored" + ); + + assert_eq!( + Some("1"), + loded_backup.backup_version.as_deref(), + "The loaded version matches to the one we stored" + ); + } } )* } diff --git a/crates/matrix-sdk-crypto/src/store/mod.rs b/crates/matrix-sdk-crypto/src/store/mod.rs index 401de834d..992226782 100644 --- a/crates/matrix-sdk-crypto/src/store/mod.rs +++ b/crates/matrix-sdk-crypto/src/store/mod.rs @@ -76,6 +76,7 @@ use crate::{ InboundGroupSession, OlmMessageHash, OutboundGroupSession, PrivateCrossSigningIdentity, ReadOnlyAccount, Session, }, + utilities::encode, verification::VerificationMachine, CrossSigningStatus, }; @@ -178,6 +179,21 @@ struct InnerPickle { impl RecoveryKey { /// The number of bytes the recovery key will hold. pub const KEY_SIZE: usize = 32; + + /// Create a new random recovery key. + pub fn new() -> Result { + let mut rng = rand::thread_rng(); + + let mut key = [0u8; Self::KEY_SIZE]; + rand::Fill::try_fill(&mut key, &mut rng)?; + + Ok(Self { inner: key }) + } + + /// Export the `RecoveryKey` as a base64 encoded string. + pub fn to_base64(&self) -> String { + encode(self.inner) + } } impl Debug for RecoveryKey {