Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable sender trust checking on decrypting #3701

Closed
wants to merge 41 commits into from

Conversation

uhoreg
Copy link
Member

@uhoreg uhoreg commented Jul 15, 2024

  • Public API changes documented in changelogs (optional)

Signed-off-by:

@BillCarsonFr BillCarsonFr force-pushed the valere/invisible_crypto/identity_sharing_with_pin branch from 8fbd9a4 to e309219 Compare July 23, 2024 08:46
@uhoreg uhoreg marked this pull request as ready for review July 24, 2024 14:59
@uhoreg uhoreg requested a review from a team as a code owner July 24, 2024 14:59
@uhoreg uhoreg requested review from jmartinesp and removed request for a team July 24, 2024 14:59
@uhoreg
Copy link
Member Author

uhoreg commented Jul 24, 2024

I'm not sure how to handle the higher levels. It seems like we should be storing the setting in some struct so that, e.g. messages that come down /sync get decrypted with the right setting, but I'm not sure where it should go. I don't see a relevant struct that has settings, so there isn't a clear place to put the setting.

@jmartinesp
Copy link
Contributor

Sorry, I don't have much experience with the SDK and much less with the crypto part of it. Maybe someone else from the team can answer your questions? @poljar , @andybalaam?

@poljar poljar requested review from poljar and removed request for jmartinesp July 25, 2024 07:43
@uhoreg uhoreg requested a review from BillCarsonFr August 9, 2024 00:51
@@ -74,6 +74,9 @@ pub enum SenderData {
/// If false, we had simply accepted the key as this user's latest
/// key.
master_key_verified: bool,

#[serde(default)]
identity_needs_user_approval: bool,
Copy link
Member Author

Choose a reason for hiding this comment

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

I added this so that session_data_finder can find this information, so that the trust level can be calculated. But I think that it would be better to combine this with the master_key_verified field, and make them into a new master_key_status field that is an enum with Unverified, NeedsApproval, and Verified options. Maybe we should even add another option for the case where the user's previous identity was verified, but they rotated their identity. Maybe something like PreviousIdentityVerified.

What do you think?

(If you think it's better to keep it as-is, then I'll write documentation for this field, but I didn't want to write it if I was going to remove it right away.)

Copy link
Member

Choose a reason for hiding this comment

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

You've asked me for my opinion on this question, but this change doesn't seem to appear anywhere in the PR, so I don't think I have enough context on the change to form a sensible opinion.

@uhoreg
Copy link
Member Author

uhoreg commented Aug 9, 2024

I believe the tests fail because get_encryption_info now updates the sender_data, so I'll need to poke more things into the database so that it updates to the right thing. Aside from that, I think that this is ready for re-review.

@uhoreg uhoreg requested a review from poljar August 9, 2024 01:46
@richvdh
Copy link
Member

richvdh commented Aug 12, 2024

Discussion: should we throw an error when an identity has been rotated?

  • For a TOFU user, we should definitely just decrypt as normal (for symmetry with encryption)
  • For a verified user, we will throw an error on decryption if the identity is replaced (an expected UTD). The application can try to re-decrypt after the user re-verifies/reverts to unverified.

@richvdh
Copy link
Member

richvdh commented Aug 12, 2024

@uhoreg will update this PR a bit and then get @richvdh to review

Copy link

codecov bot commented Aug 15, 2024

Codecov Report

Attention: Patch coverage is 91.30435% with 4 lines in your changes missing coverage. Please review.

Project coverage is 84.09%. Comparing base (6becbf6) to head (0e9b581).
Report is 106 commits behind head on main.

Files Patch % Lines
crates/matrix-sdk-crypto/src/machine/mod.rs 87.50% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3701      +/-   ##
==========================================
- Coverage   84.11%   84.09%   -0.02%     
==========================================
  Files         262      262              
  Lines       27599    27628      +29     
==========================================
+ Hits        23214    23235      +21     
- Misses       4385     4393       +8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@uhoreg uhoreg requested a review from richvdh August 15, 2024 20:37
@uhoreg
Copy link
Member Author

uhoreg commented Aug 15, 2024

@richvdh I think this is ready for review. I do have one question that I'd like an opinion on.

The commit history is a big mess, partially due to being based on a branch that got force-pushed at some point, so this PR should probably get squash-merged.

Copy link
Member

@richvdh richvdh left a comment

Choose a reason for hiding this comment

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

Some initial thoughts.

I'm really struggling to follow this as one big diff. +600 lines isn't huge, but there is actually quite a lot changing here, and following the logic though everywhere is hard.

I think it might be better to start again on the commit history, and break it into smaller changes. For example - let's separate the changes to SenderData from the changes to decryption. Then add the DecryptionSettings parameter without actually implementing it, so that we can see the real changes without all the noise from that.

@@ -32,6 +32,9 @@ Changes:

Breaking changes:

- `OlmMachine::decrypt_room_event` now takes an `EncryptionSettings` argument.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
- `OlmMachine::decrypt_room_event` now takes an `EncryptionSettings` argument.
- `OlmMachine::decrypt_room_event` now takes a `DecryptionSettings` argument.

Copy link
Member

Choose a reason for hiding this comment

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

we should probably also document some of the changes to publicly-visible types (MegolmError, VerificationLevel, etc)

@@ -115,6 +116,10 @@ pub enum MegolmError {
/// The storage layer returned an error.
#[error(transparent)]
Store(#[from] CryptoStoreError),

/// The sender's cross-signing identity isn't trusted
#[error("message quarantined because sender's cross-signing identity is not trusted: {0}")]
Copy link
Member

Choose a reason for hiding this comment

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

what does "quarantined" mean here? Is it stored somewhere within the store?


/// The sender's cross-signing identity isn't trusted
#[error("message quarantined because sender's cross-signing identity is not trusted: {0}")]
SenderIdentity(#[from] VerificationLevel),
Copy link
Member

Choose a reason for hiding this comment

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

SenderIdentity feels like it doesn't quite describe the problem here.

Suggested change
SenderIdentity(#[from] VerificationLevel),
SenderIdentityNotTrusted(#[from] VerificationLevel),

@@ -115,6 +116,10 @@ pub enum MegolmError {
/// The storage layer returned an error.
#[error(transparent)]
Store(#[from] CryptoStoreError),

/// The sender's cross-signing identity isn't trusted
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// The sender's cross-signing identity isn't trusted
/// An encrypted message wasn't decrypted, because the sender's cross-signing identity isn't trusted.

(This should maybe also link to DecryptionSettings and say that it only happens under some conditions)

Copy link
Member

Choose a reason for hiding this comment

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

Actually, isn't it more "because the message could not be linked to a verified device" than specific to the sender's identity?

pub enum TrustRequirement {
/// Decrypt events from everyone regardless of trust.
Untrusted,
/// Only decrypt events from cross-signed or legacy sessions (Megolm
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// Only decrypt events from cross-signed or legacy sessions (Megolm
/// Only decrypt events from cross-signed devices or legacy sessions (Megolm

Comment on lines +82 to +83
/// TODO: should this be merged with the master_key_verified field and
/// turned into an enum?
Copy link
Member

Choose a reason for hiding this comment

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

Short answer: yes, this really feels like it ought to be a tri-state.

(#3846 added an OwnUserIdentityVerifiedState enum for a similar reason; not sure we should reuse that, but I think it's a pattern we should follow)

A downside is that it breaks backwards-compatibility for the crypto store :/

///
/// This is used by `check_sender_trust_requirement`, and ensures that the
/// sending device is cross-signed.
fn check_sender_trusted(&self, encryption_info: &EncryptionInfo) -> MegolmResult<()> {
Copy link
Member

Choose a reason for hiding this comment

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

per a discussion today in #matrix-rust-sdk-dev, helper functions should probably come after the functions they help.

Comment on lines +384 to +385
// Helper function that encrypts a message and shares the Megolm session
// with a recipient
Copy link
Member

Choose a reason for hiding this comment

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

helpers after the functions they help, please

Comment on lines +79 to +80
/// Whether the user's master key was previously verified, but the
/// current master key is not.
Copy link
Member

Choose a reason for hiding this comment

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

if this is the actual behaviour (and I'm not sure that it is), it needs a name that reflects it.

@@ -74,6 +74,9 @@ pub enum SenderData {
/// If false, we had simply accepted the key as this user's latest
/// key.
master_key_verified: bool,

#[serde(default)]
identity_needs_user_approval: bool,
Copy link
Member

Choose a reason for hiding this comment

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

You've asked me for my opinion on this question, but this change doesn't seem to appear anywhere in the PR, so I don't think I have enough context on the change to form a sensible opinion.

@uhoreg
Copy link
Member Author

uhoreg commented Aug 28, 2024

replaced by #3899

@uhoreg uhoreg closed this Aug 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants