Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,53 @@
# UNRELEASED

**BREAKING CHANGES**

- The format for `EncryptionSettings.sharingStrategy` has changed. It must
now be created using the `CollectStrategy.deviceBasedStrategy(...)` or
`CollectStrategy.identityBasedStrategy()` functions.
([#141](https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/141))
- The `OlmMachine.decryptRoomEvent` has a new `DecryptionSettings` parameter
that allows specifying the required sender trust level. If the trust level
is not met, the decryption will fail. To replicate the old behaviour, use a
sender trust level of `TrustRequirement.Untrusted`.
([#141](https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/141))

**Security Fixes**

- Fix `UserIdentity.isVerified` to take into account our own identity
[#d8d9dae](https://github.com/matrix-org/matrix-rust-sdk/commit/d8d9dae9d77bee48a2591b9aad9bd2fa466354cc) (Moderate, [GHSA-4qg4-cvh2-crgg](https://github.com/matrix-org/matrix-rust-sdk/security/advisories/GHSA-4qg4-cvh2-crgg)).

**Other changes**

- Add `(Own)UserIdentity.wasPreviouslyVerified()`,
`(Own)UserIdentity.withdrawVerification()`, and
`(Own)UserIdentity.hasVerificationViolation()` to check and manage the state
of users who were previously verified but are no longer verified.
([#141](https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/141))
- Add `UserIdentity.pinCurrentMasterKey()` and
`UserInfo.identityNeedsUserApproval()` to manage user identity changes.
([#141](https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/141))
- `ShieldState` has a new `code` property that is set when the shield state is
not `None`.
([#141](https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/141))
- Add a new API `Device.encryptToDeviceEvent` to encrypt a to-device message using
Olm.
([#101](https://github.com/matrix-org/matrix-rust-sdk-crypto-wasm/pull/101))

- Update matrix-rust-sdk to `07aa6d7bc`, which includes:

- **NOTE**: this version causes changes to the format of the serialised
data in the CryptoStore, meaning that, once upgraded, it will not be
possible to roll back applications to earlier versions without breaking
user sessions.

- Miscellaneous improvements to logging for verification and
`OwnUserIdentity` updates.
([#3949](https://github.com/matrix-org/matrix-rust-sdk/pull/3949))

- Add message IDs to all outgoing encrypted to-device messages.
([#3776](https://github.com/matrix-org/matrix-rust-sdk/pull/3776))

# matrix-sdk-crypto-wasm v7.0.0

**BREAKING CHANGES**
Expand Down
39 changes: 13 additions & 26 deletions Cargo.lock

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

150 changes: 114 additions & 36 deletions src/encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use std::time::Duration;

use matrix_sdk_common::deserialized_responses::ShieldState as RustShieldState;
pub use matrix_sdk_common::deserialized_responses::ShieldStateCode;
use wasm_bindgen::prelude::*;

use crate::events;
Expand Down Expand Up @@ -119,50 +120,120 @@ impl From<matrix_sdk_crypto::types::EventEncryptionAlgorithm> for EncryptionAlgo
/// Strategy to collect the devices that should receive room keys for the
/// current discussion.
#[wasm_bindgen()]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CollectStrategy {
/// Device based sharing strategy, excluding devices that are not trusted.
/// A device is trusted if any of the following is true:
#[derive(Debug, Clone, PartialEq)]
pub struct CollectStrategy {
inner: matrix_sdk_crypto::CollectStrategy,
}

#[wasm_bindgen]
impl CollectStrategy {
/// Tests for equality between two [`CollecStrategy`]s.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CollecStrategy -> CollectStrategy

#[wasm_bindgen]
pub fn eq(&self, other: &CollectStrategy) -> bool {
self == other
}
}

impl From<CollectStrategy> for matrix_sdk_crypto::CollectStrategy {
fn from(value: CollectStrategy) -> Self {
value.inner
}
}

impl From<matrix_sdk_crypto::CollectStrategy> for CollectStrategy {
fn from(value: matrix_sdk_crypto::CollectStrategy) -> Self {
Self { inner: value }
}
}

#[wasm_bindgen]
impl CollectStrategy {
/// Device based sharing strategy.
///
/// If `only_allow_trusted_devices` is `true`, devices that are not trusted
/// will be excluded from the conversation. A device is trusted if any of
/// the following is true:
/// - It was manually marked as trusted.
/// - It was marked as verified via interactive verification.
/// - It is signed by its owner identity, and this identity has been
/// trusted via interactive verification.
/// - It is the current own device of the user.
DeviceBasedStrategyOnlyTrustedDevices,
/// Device based sharing strategy, including all devices.
DeviceBasedStrategyAllDevices,
///
/// If `error_on_verified_user` is `true`, and a verified user has an
/// unsigned device, key sharing will fail with an error.
///
/// If `error_on_verified_user` is `true`, and a verified user has replaced
/// their identity, key sharing will fail with an error.
///
/// Otherwise, keys are shared with unsigned devices as normal.
///
/// Once the problematic devices are blacklisted or whitelisted the
/// caller can retry to share a second time.
#[wasm_bindgen(js_name = "deviceBasedStrategy")]
pub fn device_based_strategy(
only_allow_trusted_devices: bool,
error_on_verified_user_problem: bool,
) -> CollectStrategy {
Self {
inner: matrix_sdk_crypto::CollectStrategy::DeviceBasedStrategy {
only_allow_trusted_devices,
error_on_verified_user_problem,
},
}
}

/// Share based on identity. Only distribute to devices signed by their
/// owner. If a user has no published identity he will not receive
/// any room keys.
IdentityBasedStrategy,
#[wasm_bindgen(js_name = "identityBasedStrategy")]
pub fn identity_based_strategy() -> CollectStrategy {
Self { inner: matrix_sdk_crypto::CollectStrategy::IdentityBasedStrategy }
}
}

impl From<CollectStrategy> for matrix_sdk_crypto::CollectStrategy {
fn from(value: CollectStrategy) -> Self {
/// The trust level required to decrypt an event
#[wasm_bindgen]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TrustRequirement {
/// Decrypt events from everyone regardless of trust
Untrusted,
/// Only decrypt events from cross-signed or legacy devices
CrossSignedOrLegacy,
/// Only decrypt events from cross-signed devices
CrossSigned,
}

impl From<TrustRequirement> for matrix_sdk_crypto::TrustRequirement {
fn from(value: TrustRequirement) -> Self {
match value {
CollectStrategy::DeviceBasedStrategyOnlyTrustedDevices => {
Self::DeviceBasedStrategy { only_allow_trusted_devices: true }
}
CollectStrategy::DeviceBasedStrategyAllDevices => {
Self::DeviceBasedStrategy { only_allow_trusted_devices: false }
}
CollectStrategy::IdentityBasedStrategy => Self::IdentityBasedStrategy,
TrustRequirement::Untrusted => Self::Untrusted,
TrustRequirement::CrossSignedOrLegacy => Self::CrossSignedOrLegacy,
TrustRequirement::CrossSigned => Self::CrossSigned,
}
}
}

impl From<matrix_sdk_crypto::CollectStrategy> for CollectStrategy {
fn from(value: matrix_sdk_crypto::CollectStrategy) -> Self {
match value {
matrix_sdk_crypto::CollectStrategy::DeviceBasedStrategy {
only_allow_trusted_devices: true,
} => Self::DeviceBasedStrategyOnlyTrustedDevices,
matrix_sdk_crypto::CollectStrategy::DeviceBasedStrategy {
only_allow_trusted_devices: false,
} => Self::DeviceBasedStrategyAllDevices,
matrix_sdk_crypto::CollectStrategy::IdentityBasedStrategy => {
Self::IdentityBasedStrategy
}
/// Settings for decrypting messages
#[wasm_bindgen(getter_with_clone)]
#[derive(Debug, Clone)]
pub struct DecryptionSettings {
/// The trust level required to decrypt the event
pub sender_device_trust_requirement: TrustRequirement,
}

#[wasm_bindgen]
impl DecryptionSettings {
/// Create a new `DecryptionSettings` with the given trust requirement.
#[wasm_bindgen(constructor)]
pub fn new(sender_device_trust_requirement: TrustRequirement) -> DecryptionSettings {
Self { sender_device_trust_requirement }
}
}

impl From<&DecryptionSettings> for matrix_sdk_crypto::DecryptionSettings {
fn from(value: &DecryptionSettings) -> Self {
Self {
sender_device_trust_requirement: value.sender_device_trust_requirement.clone().into(),
}
}
}
Expand All @@ -187,6 +258,9 @@ pub enum ShieldColor {
pub struct ShieldState {
/// The shield color
pub color: ShieldColor,
/// A machine-readable representation of the authenticity for a
/// `ShieldState`.
pub code: Option<ShieldStateCode>,
message: Option<String>,
}

Expand All @@ -202,13 +276,17 @@ impl ShieldState {
impl From<RustShieldState> for ShieldState {
fn from(value: RustShieldState) -> Self {
match value {
RustShieldState::Red { message } => {
Self { color: ShieldColor::Red, message: Some(message.to_owned()) }
}
RustShieldState::Grey { message } => {
Self { color: ShieldColor::Grey, message: Some(message.to_owned()) }
}
RustShieldState::None => Self { color: ShieldColor::None, message: None },
RustShieldState::Red { message, code } => Self {
color: ShieldColor::Red,
code: Some(code),
message: Some(message.to_owned()),
},
RustShieldState::Grey { message, code } => Self {
color: ShieldColor::Grey,
code: Some(code),
message: Some(message.to_owned()),
},
RustShieldState::None => Self { color: ShieldColor::None, code: None, message: None },
}
}
}
Expand Down
Loading