fix(indexeddb): Don't derive a StoreCipher twice if we're reusing the db

This commit is contained in:
Damir Jelić
2022-04-26 18:34:44 +02:00
parent 742c1944eb
commit 6e89ecfbf0
3 changed files with 17 additions and 13 deletions

View File

@@ -73,7 +73,7 @@ pub struct IndexeddbStore {
name: String,
pub(crate) inner: IdbDatabase,
store_cipher: Arc<Option<StoreCipher>>,
store_cipher: Option<Arc<StoreCipher>>,
session_cache: SessionStore,
tracked_users_cache: Arc<DashSet<OwnedUserId>>,
@@ -133,7 +133,10 @@ pub struct AccountInfo {
}
impl IndexeddbStore {
async fn open_helper(prefix: String, store_cipher: Option<StoreCipher>) -> Result<Self> {
pub(crate) async fn open_with_store_cipher(
prefix: String,
store_cipher: Option<Arc<StoreCipher>>,
) -> Result<Self> {
let name = format!("{:0}::matrix-sdk-crypto", prefix);
// Open my_db v1
@@ -167,7 +170,7 @@ impl IndexeddbStore {
name,
session_cache,
inner: db,
store_cipher: store_cipher.into(),
store_cipher,
account_info: RwLock::new(None).into(),
tracked_users_cache: DashSet::new().into(),
users_for_key_query_cache: DashSet::new().into(),
@@ -176,7 +179,7 @@ impl IndexeddbStore {
/// Open a new IndexeddbStore with default name and no passphrase
pub async fn open() -> Result<Self> {
IndexeddbStore::open_helper("crypto".to_owned(), None).await
IndexeddbStore::open_with_store_cipher("crypto".to_owned(), None).await
}
/// Open a new IndexeddbStore with given name and passphrase
@@ -229,16 +232,16 @@ impl IndexeddbStore {
}
};
IndexeddbStore::open_helper(prefix, Some(store_cipher)).await
IndexeddbStore::open_with_store_cipher(prefix, Some(store_cipher.into())).await
}
/// Open a new IndexeddbStore with given name and no passphrase
pub async fn open_with_name(name: String) -> Result<Self> {
IndexeddbStore::open_helper(name, None).await
IndexeddbStore::open_with_store_cipher(name, None).await
}
fn serialize_value(&self, value: &impl Serialize) -> Result<JsValue, CryptoStoreError> {
if let Some(key) = &*self.store_cipher {
if let Some(key) = &self.store_cipher {
let value =
key.encrypt_value(value).map_err(|e| CryptoStoreError::Backend(anyhow!(e)))?;
@@ -252,7 +255,7 @@ impl IndexeddbStore {
&self,
value: JsValue,
) -> Result<T, CryptoStoreError> {
if let Some(key) = &*self.store_cipher {
if let Some(key) = &self.store_cipher {
let value: Vec<u8> = value.into_serde()?;
key.decrypt_value(&value).map_err(|e| CryptoStoreError::Backend(anyhow!(e)))
} else {

View File

@@ -33,7 +33,8 @@ async fn open_stores_with_name(
if let Some(passphrase) = passphrase {
let state_store = StateStore::open_with_passphrase(name.clone(), passphrase).await?;
let crypto_store = CryptoStore::open_with_passphrase(name, passphrase).await?;
let crypto_store =
CryptoStore::open_with_store_cipher(name, state_store.store_cipher.clone()).await?;
Ok((Box::new(state_store), Box::new(crypto_store)))
} else {
let state_store = StateStore::open_with_name(name.clone()).await?;

View File

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::collections::BTreeSet;
use std::{collections::BTreeSet, sync::Arc};
use anyhow::anyhow;
use futures_util::stream;
@@ -140,7 +140,7 @@ mod KEYS {
pub struct IndexeddbStore {
name: String,
pub(crate) inner: IdbDatabase,
store_cipher: Option<StoreCipher>,
pub(crate) store_cipher: Option<Arc<StoreCipher>>,
}
impl std::fmt::Debug for IndexeddbStore {
@@ -152,7 +152,7 @@ impl std::fmt::Debug for IndexeddbStore {
type Result<A, E = SerializationError> = std::result::Result<A, E>;
impl IndexeddbStore {
async fn open_helper(name: String, store_cipher: Option<StoreCipher>) -> Result<Self> {
async fn open_helper(name: String, store_cipher: Option<Arc<StoreCipher>>) -> Result<Self> {
// 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> {
@@ -245,7 +245,7 @@ impl IndexeddbStore {
tx.await.into_result()?;
IndexeddbStore::open_helper(name, Some(cipher)).await
IndexeddbStore::open_helper(name, Some(cipher.into())).await
}
pub async fn open_with_name(name: String) -> StoreResult<Self> {