From c03c90c1cfe813a2963e8881d2aaa6abd64f32b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 20 Oct 2022 18:17:37 +0200 Subject: [PATCH] feat(bindings)!: Allow passing the E2EE settings when sharing a room key --- bindings/matrix-sdk-crypto-ffi/src/lib.rs | 101 +++++++++++++++++- bindings/matrix-sdk-crypto-ffi/src/machine.rs | 14 +-- bindings/matrix-sdk-crypto-ffi/src/olm.udl | 26 ++++- 3 files changed, 128 insertions(+), 13 deletions(-) diff --git a/bindings/matrix-sdk-crypto-ffi/src/lib.rs b/bindings/matrix-sdk-crypto-ffi/src/lib.rs index e35c26ae0..a4b2381c4 100644 --- a/bindings/matrix-sdk-crypto-ffi/src/lib.rs +++ b/bindings/matrix-sdk-crypto-ffi/src/lib.rs @@ -16,7 +16,7 @@ mod uniffi_api; mod users; mod verification; -use std::{borrow::Borrow, collections::HashMap, str::FromStr, sync::Arc}; +use std::{borrow::Borrow, collections::HashMap, str::FromStr, sync::Arc, time::Duration}; pub use backup_recovery_key::{ BackupRecoveryKey, DecodeError, MegolmV1BackupKey, PassphraseInfo, PkDecryptionError, @@ -29,14 +29,17 @@ use js_int::UInt; pub use logger::{set_logger, Logger}; pub use machine::{KeyRequestPair, OlmMachine}; use matrix_sdk_crypto::{ - types::{EventEncryptionAlgorithm, SigningKey}, - LocalTrust, + types::{EventEncryptionAlgorithm as RustEventEncryptionAlgorithm, SigningKey}, + EncryptionSettings as RustEncryptionSettings, LocalTrust, }; pub use responses::{ BootstrapCrossSigningResult, DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType, SignatureUploadRequest, UploadSigningKeysRequest, }; -use ruma::{DeviceId, DeviceKeyAlgorithm, OwnedUserId, RoomId, SecondsSinceUnixEpoch, UserId}; +use ruma::{ + events::room::history_visibility::HistoryVisibility as RustHistoryVisibility, DeviceId, + DeviceKeyAlgorithm, OwnedUserId, RoomId, SecondsSinceUnixEpoch, UserId, +}; use serde::{Deserialize, Serialize}; pub use users::UserIdentity; pub use verification::{ @@ -275,7 +278,7 @@ pub fn migrate( imported: session.imported, backed_up: session.backed_up, history_visibility: None, - algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2, + algorithm: RustEventEncryptionAlgorithm::MegolmV1AesSha2, }; let session = matrix_sdk_crypto::olm::InboundGroupSession::from_pickle(pickle)?; @@ -350,6 +353,94 @@ impl ProgressListener for T { } } +/// An encryption algorithm to be used to encrypt messages sent to a room. +pub enum EventEncryptionAlgorithm { + /// Olm version 1 using Curve25519, AES-256, and SHA-256. + OlmV1Curve25519AesSha2, + /// Megolm version 1 using AES-256 and SHA-256. + MegolmV1AesSha2, +} + +impl From for RustEventEncryptionAlgorithm { + fn from(a: EventEncryptionAlgorithm) -> Self { + match a { + EventEncryptionAlgorithm::OlmV1Curve25519AesSha2 => { + RustEventEncryptionAlgorithm::OlmV1Curve25519AesSha2 + } + EventEncryptionAlgorithm::MegolmV1AesSha2 => { + RustEventEncryptionAlgorithm::MegolmV1AesSha2 + } + } + } +} + +/// Who can see a room's history. +pub enum HistoryVisibility { + /// Previous events are accessible to newly joined members from the point + /// they were invited onwards. + /// + /// Events stop being accessible when the member's state changes to + /// something other than *invite* or *join*. + Invited, + + /// Previous events are accessible to newly joined members from the point + /// they joined the room onwards. + /// Events stop being accessible when the member's state changes to + /// something other than *join*. + Joined, + + /// Previous events are always accessible to newly joined members. + /// + /// All events in the room are accessible, even those sent when the member + /// was not a part of the room. + Shared, + + /// All events while this is the `HistoryVisibility` value may be shared by + /// any participating homeserver with anyone, regardless of whether they + /// have ever joined the room. + WorldReadable, +} + +impl From 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, + } + } +} + +/// Settings for an encrypted room. +/// +/// This determines the algorithm and rotation periods of a group session. +pub struct EncryptionSettings { + /// The encryption algorithm that should be used in the room. + pub algorithm: EventEncryptionAlgorithm, + /// How long the session should be used before changing it. Time in seconds. + pub rotation_period: u64, + /// How many messages should be sent before changing the session. + pub rotation_period_msgs: u64, + /// The history visibility of the room when the session was created. + pub history_visibility: HistoryVisibility, + /// Should untrusted devices receive the room key, or should they be + /// excluded from the conversation. + pub only_allow_trusted_devices: bool, +} + +impl From for RustEncryptionSettings { + fn from(v: EncryptionSettings) -> Self { + RustEncryptionSettings { + algorithm: v.algorithm.into(), + rotation_period: Duration::from_secs(v.rotation_period), + rotation_period_msgs: v.rotation_period_msgs, + history_visibility: v.history_visibility.into(), + only_allow_trusted_devices: v.only_allow_trusted_devices, + } + } +} + /// An event that was successfully decrypted. pub struct DecryptedEvent { /// The decrypted version of the event. diff --git a/bindings/matrix-sdk-crypto-ffi/src/machine.rs b/bindings/matrix-sdk-crypto-ffi/src/machine.rs index bd662a831..3b9123730 100644 --- a/bindings/matrix-sdk-crypto-ffi/src/machine.rs +++ b/bindings/matrix-sdk-crypto-ffi/src/machine.rs @@ -11,9 +11,8 @@ use js_int::UInt; use matrix_sdk_common::deserialized_responses::AlgorithmInfo; use matrix_sdk_crypto::{ backups::MegolmV1BackupKey as RustBackupKey, decrypt_room_key_export, encrypt_room_key_export, - matrix_sdk_qrcode::QrVerificationData, olm::ExportedRoomKey, store::RecoveryKey, - EncryptionSettings, LocalTrust, OlmMachine as InnerMachine, UserIdentities, - Verification as RustVerification, + matrix_sdk_qrcode::QrVerificationData, olm::ExportedRoomKey, store::RecoveryKey, LocalTrust, + OlmMachine as InnerMachine, UserIdentities, Verification as RustVerification, }; use ruma::{ api::{ @@ -46,9 +45,9 @@ use crate::{ responses::{response_from_string, OutgoingVerificationRequest, OwnedResponse}, BackupKeys, BackupRecoveryKey, BootstrapCrossSigningResult, ConfirmVerificationResult, CrossSigningKeyExport, CrossSigningStatus, DecodeError, DecryptedEvent, Device, DeviceLists, - KeyImportError, KeysImportResult, MegolmV1BackupKey, ProgressListener, QrCode, Request, - RequestType, RequestVerificationResult, RoomKeyCounts, ScanResult, SignatureUploadRequest, - StartSasResult, UserIdentity, Verification, VerificationRequest, + EncryptionSettings, KeyImportError, KeysImportResult, MegolmV1BackupKey, ProgressListener, + QrCode, Request, RequestType, RequestVerificationResult, RoomKeyCounts, ScanResult, + SignatureUploadRequest, StartSasResult, UserIdentity, Verification, VerificationRequest, }; /// A high level state machine that handles E2EE for Matrix. @@ -521,6 +520,7 @@ impl OlmMachine { &self, room_id: &str, users: Vec, + settings: EncryptionSettings, ) -> Result, CryptoStoreError> { let users: Vec = users.into_iter().filter_map(|u| UserId::parse(u).ok()).collect(); @@ -529,7 +529,7 @@ impl OlmMachine { let requests = self.runtime.block_on(self.inner.share_room_key( &room_id, users.iter().map(Deref::deref), - EncryptionSettings::default(), + settings, ))?; Ok(requests.into_iter().map(|r| r.as_ref().into()).collect()) diff --git a/bindings/matrix-sdk-crypto-ffi/src/olm.udl b/bindings/matrix-sdk-crypto-ffi/src/olm.udl index 8432e36de..9044d09ec 100644 --- a/bindings/matrix-sdk-crypto-ffi/src/olm.udl +++ b/bindings/matrix-sdk-crypto-ffi/src/olm.udl @@ -254,6 +254,26 @@ enum LocalTrust { "Unset", }; +enum EventEncryptionAlgorithm { + "OlmV1Curve25519AesSha2", + "MegolmV1AesSha2", +}; + +enum HistoryVisibility { + "Invited", + "Joined", + "Shared", + "WorldReadable", +}; + +dictionary EncryptionSettings { + EventEncryptionAlgorithm algorithm; + u64 rotation_period; + u64 rotation_period_msgs; + HistoryVisibility history_visibility; + boolean only_allow_trusted_devices; +}; + interface OlmMachine { [Throws=CryptoStoreError] constructor( @@ -301,7 +321,11 @@ interface OlmMachine { [Throws=CryptoStoreError] Request? get_missing_sessions(sequence users); [Throws=CryptoStoreError] - sequence share_room_key([ByRef] string room_id, sequence users); + sequence share_room_key( + [ByRef] string room_id, + sequence users, + EncryptionSettings settings + ); [Throws=CryptoStoreError] void receive_unencrypted_verification_event([ByRef] string event, [ByRef] string room_id);