Skip to content

Commit

Permalink
Store encryption settings
Browse files Browse the repository at this point in the history
  • Loading branch information
Anderas committed Feb 24, 2023
1 parent e162c99 commit d7fb36c
Show file tree
Hide file tree
Showing 8 changed files with 214 additions and 27 deletions.
50 changes: 40 additions & 10 deletions bindings/matrix-sdk-crypto-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,12 +382,18 @@ pub enum EventEncryptionAlgorithm {
impl From<EventEncryptionAlgorithm> for RustEventEncryptionAlgorithm {
fn from(a: EventEncryptionAlgorithm) -> Self {
match a {
EventEncryptionAlgorithm::OlmV1Curve25519AesSha2 => {
RustEventEncryptionAlgorithm::OlmV1Curve25519AesSha2
}
EventEncryptionAlgorithm::MegolmV1AesSha2 => {
RustEventEncryptionAlgorithm::MegolmV1AesSha2
}
EventEncryptionAlgorithm::OlmV1Curve25519AesSha2 => Self::OlmV1Curve25519AesSha2,
EventEncryptionAlgorithm::MegolmV1AesSha2 => Self::MegolmV1AesSha2,
}
}
}

impl From<RustEventEncryptionAlgorithm> for EventEncryptionAlgorithm {
fn from(value: RustEventEncryptionAlgorithm) -> Self {
match value {
RustEventEncryptionAlgorithm::OlmV1Curve25519AesSha2 => Self::OlmV1Curve25519AesSha2,
RustEventEncryptionAlgorithm::MegolmV1AesSha2 => Self::MegolmV1AesSha2,
_ => todo!(),
}
}
}
Expand Down Expand Up @@ -422,10 +428,22 @@ pub enum HistoryVisibility {
impl From<HistoryVisibility> for RustHistoryVisibility {
fn from(h: HistoryVisibility) -> Self {
match h {
HistoryVisibility::Invited => RustHistoryVisibility::Invited,
HistoryVisibility::Joined => RustHistoryVisibility::Joined,
HistoryVisibility::Shared => RustHistoryVisibility::Shared,
HistoryVisibility::WorldReadable => RustHistoryVisibility::Shared,
HistoryVisibility::Invited => Self::Invited,
HistoryVisibility::Joined => Self::Joined,
HistoryVisibility::Shared => Self::Shared,
HistoryVisibility::WorldReadable => Self::Shared,
}
}
}

impl From<RustHistoryVisibility> for HistoryVisibility {
fn from(h: RustHistoryVisibility) -> Self {
match h {
RustHistoryVisibility::Invited => Self::Invited,
RustHistoryVisibility::Joined => Self::Joined,
RustHistoryVisibility::Shared => Self::Shared,
RustHistoryVisibility::WorldReadable => Self::WorldReadable,
_ => todo!(),
}
}
}
Expand Down Expand Up @@ -464,6 +482,18 @@ impl From<EncryptionSettings> for RustEncryptionSettings {
}
}

impl From<RustEncryptionSettings> for EncryptionSettings {
fn from(value: RustEncryptionSettings) -> Self {
EncryptionSettings {
algorithm: value.algorithm.into(),
rotation_period: value.rotation_period.as_secs(),
rotation_period_msgs: value.rotation_period_msgs,
history_visibility: value.history_visibility.into(),
only_allow_trusted_devices: value.only_allow_trusted_devices,
}
}
}

/// An event that was successfully decrypted.
pub struct DecryptedEvent {
/// The decrypted version of the event.
Expand Down
74 changes: 65 additions & 9 deletions bindings/matrix-sdk-crypto-ffi/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ use crate::{
responses::{response_from_string, OwnedResponse},
BackupKeys, BackupRecoveryKey, BootstrapCrossSigningResult, CrossSigningKeyExport,
CrossSigningStatus, DecodeError, DecryptedEvent, Device, DeviceLists, EncryptionSettings,
KeyImportError, KeysImportResult, MegolmV1BackupKey, ProgressListener, Request, RequestType,
RequestVerificationResult, RoomKeyCounts, Sas, SignatureUploadRequest, StartSasResult,
UserIdentity, Verification, VerificationRequest,
EventEncryptionAlgorithm, KeyImportError, KeysImportResult, MegolmV1BackupKey,
ProgressListener, Request, RequestType, RequestVerificationResult, RoomKeyCounts, Sas,
SignatureUploadRequest, StartSasResult, UserIdentity, Verification, VerificationRequest,
};

/// A high level state machine that handles E2EE for Matrix.
Expand Down Expand Up @@ -560,6 +560,65 @@ impl OlmMachine {
.map(|r| r.into()))
}

/// TODO: docs
pub fn get_encryption_settings(
&self,
room_id: &str,
) -> Result<Option<EncryptionSettings>, CryptoStoreError> {
let room_id = RoomId::parse(room_id)?;
let settings =
self.runtime.block_on(self.inner.get_encryption_settings(&room_id))?.map(|v| v.into());
Ok(settings)
}

/// TODO: docs
pub fn set_event_encryption_algorithm(
&self,
room_id: &str,
algorithm: EventEncryptionAlgorithm,
) -> Result<(), CryptoStoreError> {
let room_id = RoomId::parse(room_id)?;
self.runtime.block_on(async move {
let mut settings =
self.inner.get_encryption_settings(&room_id).await?.unwrap_or_default();
settings.algorithm = algorithm.into();
self.inner.set_encryption_settings(&room_id, settings).await?;
Ok(())
})
}

/// TODO: docs
pub fn set_block_untrusted_devices_per_room(
&self,
room_id: &str,
block_untrusted_devices: bool,
) -> Result<(), CryptoStoreError> {
let room_id = RoomId::parse(room_id)?;
self.runtime.block_on(async move {
let mut settings =
self.inner.get_encryption_settings(&room_id).await?.unwrap_or_default();
settings.only_allow_trusted_devices = block_untrusted_devices;
self.inner.set_encryption_settings(&room_id, settings).await?;
Ok(())
})
}

/// TODO: docs
pub fn set_block_untrusted_devices_globally(
&self,
block_untrusted_devices: bool,
) -> Result<(), CryptoStoreError> {
self.runtime
.block_on(self.inner.set_block_untrusted_devices_globally(block_untrusted_devices))?;
Ok(())
}

/// TODO: docs
pub fn is_blocking_untrusted_devices_globally(&self) -> Result<bool, CryptoStoreError> {
let block = self.runtime.block_on(self.inner.get_block_untrusted_devices_globally())?;
Ok(block)
}

/// Share a room key with the given list of users for the given room.
///
/// After the request was sent out and a successful response was received
Expand All @@ -583,17 +642,14 @@ impl OlmMachine {
&self,
room_id: &str,
users: Vec<String>,
settings: EncryptionSettings,
) -> Result<Vec<Request>, CryptoStoreError> {
let users: Vec<OwnedUserId> =
users.into_iter().filter_map(|u| UserId::parse(u).ok()).collect();

let room_id = RoomId::parse(room_id)?;
let requests = self.runtime.block_on(self.inner.share_room_key(
&room_id,
users.iter().map(Deref::deref),
settings,
))?;
let requests = self
.runtime
.block_on(self.inner.share_room_key(&room_id, users.iter().map(Deref::deref)))?;

Ok(requests.into_iter().map(|r| r.as_ref().into()).collect())
}
Expand Down
19 changes: 17 additions & 2 deletions bindings/matrix-sdk-crypto-ffi/src/olm.udl
Original file line number Diff line number Diff line change
Expand Up @@ -385,11 +385,26 @@ interface OlmMachine {
void update_tracked_users(sequence<string> users);
[Throws=CryptoStoreError]
Request? get_missing_sessions(sequence<string> users);

[Throws=CryptoStoreError]
EncryptionSettings? get_encryption_settings([ByRef] string room_id);

[Throws=CryptoStoreError]
void set_event_encryption_algorithm([ByRef] string room_id, EventEncryptionAlgorithm algorithm);

[Throws=CryptoStoreError]
void set_block_untrusted_devices_per_room([ByRef] string room_id, boolean block_untrusted_devices);

[Throws=CryptoStoreError]
void set_block_untrusted_devices_globally(boolean block_untrusted_devices);

[Throws=CryptoStoreError]
boolean is_blocking_untrusted_devices_globally();

[Throws=CryptoStoreError]
sequence<Request> share_room_key(
[ByRef] string room_id,
sequence<string> users,
EncryptionSettings settings
sequence<string> users
);

[Throws=CryptoStoreError]
Expand Down
3 changes: 2 additions & 1 deletion crates/matrix-sdk-base/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1067,7 +1067,8 @@ impl BaseClient {
let settings = settings.ok_or(Error::EncryptionNotEnabled)?;
let settings = EncryptionSettings::new(settings, history_visibility, false);

Ok(o.share_room_key(room_id, members.map(Deref::deref), settings).await?)
Ok(o.share_room_key_with_settings(room_id, members.map(Deref::deref), settings)
.await?)
}
None => panic!("Olm machine wasn't started"),
}
Expand Down
59 changes: 56 additions & 3 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, HashSet},
collections::{BTreeMap, BTreeSet, HashMap, HashSet},
sync::Arc,
time::Duration,
};
Expand Down Expand Up @@ -506,6 +506,50 @@ impl OlmMachine {
self.session_manager.get_missing_sessions(users).await
}

/// TODO: docs
pub async fn get_encryption_settings(
&self,
room_id: &RoomId,
) -> StoreResult<Option<EncryptionSettings>> {
let settings = self.store.load_encryption_settings(room_id).await?;
Ok(settings)
}

/// TODO: docs
pub async fn set_encryption_settings(
&self,
room_id: &RoomId,
settings: EncryptionSettings,
) -> StoreResult<()> {
self.store
.save_changes(Changes {
encryption_settings: HashMap::from([(room_id.into(), settings)]),
..Default::default()
})
.await?;
Ok(())
}

/// 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?;
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 Expand Up @@ -749,9 +793,18 @@ impl OlmMachine {
&self,
room_id: &RoomId,
users: impl Iterator<Item = &UserId>,
encryption_settings: impl Into<EncryptionSettings>,
) -> OlmResult<Vec<Arc<ToDeviceRequest>>> {
self.group_session_manager.share_room_key(room_id, users, encryption_settings).await
self.group_session_manager.share_room_key(room_id, users).await
}

/// TODO: docs
pub async fn share_room_key_with_settings(
&self,
room_id: &RoomId,
users: impl Iterator<Item = &UserId>,
settings: impl Into<EncryptionSettings>,
) -> OlmResult<Vec<Arc<ToDeviceRequest>>> {
self.group_session_manager.share_room_key_with_settings(room_id, users, settings).await
}

/// Receive an unencrypted verification event.
Expand Down
30 changes: 29 additions & 1 deletion crates/matrix-sdk-crypto/src/session_manager/group_sessions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,34 @@ impl GroupSessionManager {
self.sessions.clone()
}

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
};

// 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?;
}

self.share_room_key_with_settings(room_id, users, encryption_settings).await
}

/// Get to-device requests to share a room key with users in a room.
///
/// # Arguments
Expand All @@ -451,7 +479,7 @@ impl GroupSessionManager {
///
/// `encryption_settings` - The settings that should be used for
/// the room key.
pub async fn share_room_key(
pub async fn share_room_key_with_settings(
&self,
room_id: &RoomId,
users: impl Iterator<Item = &UserId>,
Expand Down
2 changes: 1 addition & 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},
TrackedUser,
EncryptionSettings, TrackedUser,
};

fn encode_key_info(info: &SecretInfo) -> String {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CREATE TABLE "encryption_settings"(
"room_id" BLOB PRIMARY KEY NOT NULL,
"data" BLOB NOT NULL
);

0 comments on commit d7fb36c

Please sign in to comment.