From 1cdde23bc46e206aa5e7aeea4c782d69170ec3f1 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Tue, 12 Apr 2022 16:50:58 +0200 Subject: [PATCH] replace storeky with storecipher in wasm --- .../matrix-sdk-indexeddb/src/state_store.rs | 65 ++++++++----------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/crates/matrix-sdk-indexeddb/src/state_store.rs b/crates/matrix-sdk-indexeddb/src/state_store.rs index 5fbaafbb7..d386ab3c5 100644 --- a/crates/matrix-sdk-indexeddb/src/state_store.rs +++ b/crates/matrix-sdk-indexeddb/src/state_store.rs @@ -21,11 +21,12 @@ use matrix_sdk_base::{ deserialized_responses::{MemberEvent, SyncRoomEvent}, media::{MediaRequest, UniqueKey}, store::{ - store_key::{self, EncryptedEvent, StoreKey}, BoxStream, Result as StoreResult, StateChanges, StateStore, StoreError, }, RoomInfo, }; +use matrix_sdk_store_encryption::{StoreCipher, Error as EncryptionError}; + use matrix_sdk_common::{ async_trait, ruma::{ @@ -49,18 +50,15 @@ use wasm_bindgen::JsValue; use crate::safe_encode::SafeEncode; -#[derive(Debug, Serialize, Deserialize)] -pub enum DatabaseType { - Unencrypted, - Encrypted(store_key::EncryptedStoreKey), -} +#[derive(Clone, Serialize, Deserialize)] +struct StoreKeyWrapper(Vec); #[derive(Debug, thiserror::Error)] pub enum SerializationError { #[error(transparent)] Json(#[from] serde_json::Error), #[error(transparent)] - Encryption(#[from] store_key::Error), + Encryption(#[from] EncryptionError), #[error("DomException {name} ({code}): {message}")] DomException { name: String, message: String, code: u16 }, #[error(transparent)] @@ -83,9 +81,11 @@ impl From for StoreError { SerializationError::Json(e) => StoreError::Json(e), SerializationError::StoreError(e) => e, SerializationError::Encryption(e) => match e { - store_key::Error::Random(e) => StoreError::Encryption(e.to_string()), - store_key::Error::Serialization(e) => StoreError::Json(e), - store_key::Error::Encryption(e) => StoreError::Encryption(e), + EncryptionError::Random(e) => StoreError::Encryption(e.to_string()), + EncryptionError::Serialization(e) => StoreError::Json(e), + EncryptionError::Encryption(e) => StoreError::Encryption(e.to_string()), + EncryptionError::Version(found, expected) => StoreError::Encryption(format!("Bad Database Encryption Version: expected {} found {}", expected, found)), + EncryptionError::Length(found, expected) => StoreError::Encryption(format!("The database key an invalid length: expected {} found {}", expected, found)), }, _ => StoreError::Backend(anyhow!(e)), } @@ -135,7 +135,7 @@ mod KEYS { pub struct IndexeddbStore { name: String, pub(crate) inner: IdbDatabase, - store_key: Option, + store_cipher: Option, } impl std::fmt::Debug for IndexeddbStore { @@ -147,7 +147,7 @@ impl std::fmt::Debug for IndexeddbStore { type Result = std::result::Result; impl IndexeddbStore { - async fn open_helper(name: String, store_key: Option) -> Result { + async fn open_helper(name: String, store_cipher: Option) -> Result { // Open my_db v1 let mut db_req: OpenDbRequest = IdbDatabase::open_f64(&name, 1.0)?; db_req.set_on_upgrade_needed(Some(|evt: &IdbVersionChangeEvent| -> Result<(), JsValue> { @@ -190,7 +190,7 @@ impl IndexeddbStore { let db: IdbDatabase = db_req.into_future().await?; - Ok(Self { name, inner: db, store_key }) + Ok(Self { name, inner: db, store_cipher }) } #[allow(dead_code)] @@ -200,7 +200,7 @@ impl IndexeddbStore { #[allow(dead_code)] pub(crate) async fn open_encrypted() -> StoreResult { - let key = StoreKey::new().map_err::(|e| e.into())?; + let key = StoreCipher::new().map_err::(|e| e.into())?; Ok(IndexeddbStore::open_helper("state_encrypted".to_owned(), Some(key)).await?) } @@ -228,33 +228,25 @@ impl IndexeddbStore { db.transaction_on_one_with_mode("matrix-sdk-state", IdbTransactionMode::Readwrite)?; let ob = tx.object_store("matrix-sdk-state")?; - let store_key: Option = ob + let cipher = if let Some(StoreKeyWrapper(inner)) = ob .get(&JsValue::from_str(KEYS::STORE_KEY))? .await? - .map(|k| k.into_serde()) - .transpose()?; - - let store_key = if let Some(key) = store_key { - if let DatabaseType::Encrypted(k) = key { - StoreKey::import(passphrase, k).map_err(|_| StoreError::StoreLocked)? - } else { - return Err(StoreError::UnencryptedStore.into()); - } + .map(|v| v.into_serde()) + .transpose()? + { + StoreCipher::import(passphrase, &inner)? } else { - let key = StoreKey::new().map_err::(|e| e.into())?; - let encrypted_key = DatabaseType::Encrypted( - key.export(passphrase).map_err::(|e| e.into())?, - ); + let ciph = StoreCipher::new()?; ob.put_key_val( &JsValue::from_str(KEYS::STORE_KEY), - &JsValue::from_serde(&encrypted_key)?, + &JsValue::from_serde(&StoreKeyWrapper(ciph.export(passphrase)?))?, )?; - key + ciph }; tx.await.into_result()?; - IndexeddbStore::open_helper(name, Some(store_key)).await + IndexeddbStore::open_helper(name, Some(cipher)).await } pub async fn open_with_name(name: String) -> StoreResult { @@ -265,8 +257,8 @@ impl IndexeddbStore { &self, event: &impl Serialize, ) -> std::result::Result { - Ok(match self.store_key { - Some(ref key) => JsValue::from_serde(&key.encrypt(event)?)?, + Ok(match self.store_cipher { + Some(ref cipher) => JsValue::from_serde(&cipher.encrypt_value_typed(event)?)?, None => JsValue::from_serde(event)?, }) } @@ -275,11 +267,8 @@ impl IndexeddbStore { &self, event: JsValue, ) -> std::result::Result { - match self.store_key { - Some(ref key) => { - let encrypted: EncryptedEvent = event.into_serde()?; - Ok(key.decrypt(encrypted)?) - } + match self.store_cipher { + Some(ref cipher) => Ok(cipher.decrypt_value_typed(event.into_serde()?)?), None => Ok(event.into_serde()?), } }