Skip to content

Commit

Permalink
Generic key-value API
Browse files Browse the repository at this point in the history
  • Loading branch information
Anderas committed Feb 24, 2023
1 parent d7fb36c commit 022028f
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 41 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/matrix-sdk-crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pbkdf2 = { version = "0.11.0", default-features = false }
rand = "0.8.5"
ruma = { workspace = true, features = ["rand", "canonical-json", "unstable-msc2677"] }
serde = { workspace = true, features = ["derive", "rc"] }
rmp-serde = "1.1.1"
serde_json = { workspace = true }
sha2 = "0.10.2"
thiserror = { workspace = true }
Expand Down
34 changes: 13 additions & 21 deletions crates/matrix-sdk-crypto/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

use std::{
collections::{BTreeMap, BTreeSet, HashMap, HashSet},
collections::{BTreeMap, BTreeSet, HashSet},
sync::Arc,
time::Duration,
};
Expand Down Expand Up @@ -511,8 +511,9 @@ impl OlmMachine {
&self,
room_id: &RoomId,
) -> StoreResult<Option<EncryptionSettings>> {
let settings = self.store.load_encryption_settings(room_id).await?;
Ok(settings)
let key = format!("encryption_settings-{room_id}");
let value = self.store.get_value(&key).await?;
Ok(value)
}

/// TODO: docs
Expand All @@ -521,35 +522,26 @@ impl OlmMachine {
room_id: &RoomId,
settings: EncryptionSettings,
) -> StoreResult<()> {
self.store
.save_changes(Changes {
encryption_settings: HashMap::from([(room_id.into(), settings)]),
..Default::default()
})
.await?;
let key = format!("encryption_settings-{room_id}");
self.store.set_value(&key, &settings).await?;
Ok(())
}

/// TODO: docs
pub async fn get_block_untrusted_devices_globally(&self) -> StoreResult<bool> {
let value = self.store.get_value("block_untrusted_devices").await?.unwrap_or_default();
Ok(value)
}

/// TODO: docs
pub async fn set_block_untrusted_devices_globally(
&self,
block_untrusted_devices: bool,
) -> StoreResult<()> {
self.store
.save_changes(Changes {
block_untrusted_devices_globally: Some(block_untrusted_devices),
..Default::default()
})
.await?;
self.store.set_value("block_untrusted_devices", &block_untrusted_devices).await?;
Ok(())
}

/// TODO: docs
pub async fn get_block_untrusted_devices_globally(&self) -> StoreResult<bool> {
let block = self.store.block_untrusted_devices_globally().await?;
Ok(block)
}

/// Receive a successful key claim response and create new Olm sessions with
/// the claimed keys.
///
Expand Down
26 changes: 12 additions & 14 deletions crates/matrix-sdk-crypto/src/session_manager/group_sessions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,29 +441,27 @@ impl GroupSessionManager {
self.sessions.clone()
}

/// TODO: Docs
pub async fn share_room_key(
&self,
room_id: &RoomId,
users: impl Iterator<Item = &UserId>,
) -> OlmResult<Vec<Arc<ToDeviceRequest>>> {
// Load settings from store or create new
let mut encryption_settings =
if let Some(settings) = self.store.load_encryption_settings(room_id).await? {
settings
} else {
let settings = EncryptionSettings::default();
let changes = Changes {
encryption_settings: HashMap::from([(room_id.into(), settings.clone())]),
..Default::default()
};
self.store.save_changes(changes).await?;
settings
};
let key = format!("encryption_settings-{room_id}");
let mut encryption_settings = if let Some(settings) = self.store.get_value(&key).await? {
settings
} else {
let settings = EncryptionSettings::default();
self.store.set_value(&key, &settings).await?;
settings
};

// Combine per-room and global unverified devices block
if !encryption_settings.only_allow_trusted_devices {
encryption_settings.only_allow_trusted_devices =
self.store.block_untrusted_devices_globally().await?;
let block_globally =
self.store.get_value("block_untrusted_devices").await?.unwrap_or_default();
encryption_settings.only_allow_trusted_devices = block_globally
}

self.share_room_key_with_settings(room_id, users, encryption_settings).await
Expand Down
10 changes: 9 additions & 1 deletion crates/matrix-sdk-crypto/src/store/memorystore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use crate::{
gossiping::{GossipRequest, SecretInfo},
identities::{ReadOnlyDevice, ReadOnlyUserIdentities},
olm::{OutboundGroupSession, PrivateCrossSigningIdentity},
EncryptionSettings, TrackedUser,
TrackedUser,
};

fn encode_key_info(info: &SecretInfo) -> String {
Expand Down Expand Up @@ -270,6 +270,14 @@ impl CryptoStore for MemoryStore {
async fn load_backup_keys(&self) -> Result<BackupKeys> {
Ok(BackupKeys::default())
}

async fn get_custom_value(&self, _key: &str) -> Result<Option<Vec<u8>>> {
Ok(None)
}

async fn set_custom_value(&self, _key: &str, _value: Vec<u8>) -> Result<()> {
Ok(())
}
}

#[cfg(test)]
Expand Down
30 changes: 29 additions & 1 deletion crates/matrix-sdk-crypto/src/store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ use atomic::Ordering;
use dashmap::DashSet;
use matrix_sdk_common::locks::Mutex;
use ruma::{events::secret::request::SecretName, DeviceId, OwnedDeviceId, OwnedUserId, UserId};
use serde::{Deserialize, Serialize};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use thiserror::Error;
use tracing::{info, warn};
use vodozemac::{megolm::SessionOrdering, Curve25519PublicKey};
Expand Down Expand Up @@ -697,6 +697,34 @@ impl Store {

Ok(self.tracked_users_cache.iter().map(|u| u.clone()).collect())
}

/// TODO: docs
pub async fn get_value<T: DeserializeOwned>(&self, key: &str) -> Result<Option<T>> {
let Some(value) = self.get_custom_value(key).await? else {
return Ok(None);
};
let deserialized = self.deserialize_value(&value)?;
Ok(Some(deserialized))
}

/// TODO: docs
pub async fn set_value(&self, key: &str, value: &impl Serialize) -> Result<()> {
let serialized = self.serialize_value(value)?;
self.set_custom_value(key, serialized).await?;
Ok(())
}

fn serialize_value(&self, value: &impl Serialize) -> Result<Vec<u8>> {
let serialized =
rmp_serde::to_vec_named(value).map_err(|x| CryptoStoreError::Backend(x.into()))?; // TODO: Serialization type
Ok(serialized)
}

fn deserialize_value<T: DeserializeOwned>(&self, value: &[u8]) -> Result<T> {
let deserialized =
rmp_serde::from_slice(value).map_err(|e| CryptoStoreError::Backend(e.into()))?;
Ok(deserialized)
}
}

impl Deref for Store {
Expand Down
24 changes: 24 additions & 0 deletions crates/matrix-sdk-crypto/src/store/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,22 @@ pub trait CryptoStore: AsyncTraitDeps {
&self,
request_id: &TransactionId,
) -> Result<(), Self::Error>;

/// Get arbitrary data from the store
///
/// # Arguments
///
/// * `key` - The key to fetch data for
async fn get_custom_value(&self, key: &str) -> Result<Option<Vec<u8>>, Self::Error>;

/// Put arbitrary data into the store
///
/// # Arguments
///
/// * `key` - The key to insert data into
///
/// * `value` - The value to insert
async fn set_custom_value(&self, key: &str, value: Vec<u8>) -> Result<(), Self::Error>;
}

#[repr(transparent)]
Expand Down Expand Up @@ -312,6 +328,14 @@ impl<T: CryptoStore> CryptoStore for EraseCryptoStoreError<T> {
async fn delete_outgoing_secret_requests(&self, request_id: &TransactionId) -> Result<()> {
self.0.delete_outgoing_secret_requests(request_id).await.map_err(Into::into)
}

async fn get_custom_value(&self, key: &str) -> Result<Option<Vec<u8>>, Self::Error> {
self.0.get_custom_value(key).await.map_err(Into::into)
}

async fn set_custom_value(&self, key: &str, value: Vec<u8>) -> Result<(), Self::Error> {
self.0.set_custom_value(key, value).await.map_err(Into::into)
}
}

/// A type-erased [`CryptoStore`].
Expand Down

This file was deleted.

26 changes: 26 additions & 0 deletions crates/matrix-sdk-sqlite/src/crypto_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,32 @@ impl CryptoStore for SqliteCryptoStore {
let request_id = self.encode_key("key_requests", request_id.as_bytes());
Ok(self.acquire().await?.delete_key_request(request_id).await?)
}

async fn get_custom_value(&self, key: &str) -> Result<Option<Vec<u8>>> {
let Some(serialized) = self.acquire().await?.get_kv(key).await? else {
return Ok(None);
};
let value = if let Some(cipher) = &self.store_cipher {
let encrypted = rmp_serde::from_slice(&serialized)?;
cipher.decrypt_value_data(encrypted)?
} else {
serialized
};

Ok(Some(value))
}

async fn set_custom_value(&self, key: &str, value: Vec<u8>) -> Result<()> {
let serialized = if let Some(cipher) = &self.store_cipher {
let encrypted = cipher.encrypt_value_data(value)?;
rmp_serde::to_vec_named(&encrypted)?
} else {
value
};

self.acquire().await?.set_kv(key, serialized).await?;
Ok(())
}
}

#[cfg(test)]
Expand Down

0 comments on commit 022028f

Please sign in to comment.