Skip to content

Commit

Permalink
crypto: Expose a method to pin a user's identity
Browse files Browse the repository at this point in the history
  • Loading branch information
andybalaam committed Oct 3, 2024
1 parent a695e29 commit db420e4
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 3 deletions.
1 change: 1 addition & 0 deletions bindings/matrix-sdk-ffi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ Breaking changes:

Additions:

- Add `Room::pin_user_identity`
- Add `ClientBuilder::room_key_recipient_strategy`
4 changes: 4 additions & 0 deletions bindings/matrix-sdk-ffi/src/room.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,10 @@ impl Room {
})))
}

pub fn pin_user_identity(&self, user_id: &str) -> Result<(), ClientError> {
Ok(self.inner.pin_user_identity(user_id.try_into()?))
}

/// Set (or unset) a flag on the room to indicate that the user has
/// explicitly marked it as unread.
pub async fn set_unread_flag(&self, new_value: bool) -> Result<(), ClientError> {
Expand Down
16 changes: 16 additions & 0 deletions crates/matrix-sdk-crypto/src/identities/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,22 @@ impl UserIdentity {
}
}

/// Consider this identity to be trusted.
///
/// Resets this identity to the same "pinned" state assigned the first time
/// a user is encountered, where we follow "trust on first use" and
/// consider it trusted.
pub async fn pin(&self) -> Result<(), CryptoStoreError> {
match self {
UserIdentity::Own(_) => {
// Nothing to be done for our own identity: we already
// consider it trusted in this sense.
Ok(())
}
UserIdentity::Other(u) => u.pin_current_master_key().await,
}
}

/// Was this identity previously verified, and is no longer?
pub fn has_verification_violation(&self) -> bool {
match self {
Expand Down
1 change: 1 addition & 0 deletions crates/matrix-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Breaking changes:

Additions:

- new `Room::pin_user_identity` method.
- new `ClientBuilder::with_decryption_trust_requirement` method.
- new `ClientBuilder::with_room_key_recipient_strategy` method
- new `Room.set_account_data` and `Room.set_account_data_raw` RoomAccountData setters, analogous to the GlobalAccountData
Expand Down
9 changes: 9 additions & 0 deletions crates/matrix-sdk/src/encryption/identities/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,15 @@ impl UserIdentity {
self.inner.withdraw_verification().await
}

/// Consider this identity to be trusted.
///
/// Resets this identity to the same "pinned" state assigned the first time
/// a user is encountered, where we follow "trust on first use" and
/// consider it trusted.
pub async fn pin(&self) -> Result<(), CryptoStoreError> {
self.inner.pin().await
}

/// Get the public part of the Master key of this user identity.
///
/// The public part of the Master key is usually used to uniquely identify
Expand Down
4 changes: 4 additions & 0 deletions crates/matrix-sdk/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,10 @@ pub enum Error {
/// Backups are not enabled
#[error("backups are not enabled")]
BackupNotEnabled,

/// The user was not found
#[error("user was not found")]
UserNotFound,
}

#[rustfmt::skip] // stop rustfmt breaking the `<code>` in docs across multiple lines
Expand Down
5 changes: 2 additions & 3 deletions crates/matrix-sdk/src/room/identity_status_changes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,9 +430,8 @@ mod tests {
);

// Pin it
self.crypto_other_identity()
.await
.pin_current_master_key()
self.room
.pin_user_identity(self.user_id())
.await
.expect("Should not fail to pin");
} else {
Expand Down
14 changes: 14 additions & 0 deletions crates/matrix-sdk/src/room/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,20 @@ impl Room {
IdentityStatusChanges::create_stream(self.clone()).await
}

/// Mark this user as "pinned" meaning that we have seen their cryptographic
/// identity before.
#[cfg(feature = "e2e-encryption")]
pub async fn pin_user_identity(&self, user_id: &UserId) -> Result<()> {
Ok(self
.client
.encryption()
.get_user_identity(user_id)
.await?
.ok_or(Error::UserNotFound)?
.pin()
.await?)
}

/// Returns a wrapping `TimelineEvent` for the input `AnyTimelineEvent`,
/// decrypted if needs be.
///
Expand Down

0 comments on commit db420e4

Please sign in to comment.