Skip to content

feat(crypto): Support EncryptionInfo for olm encrypted messages when using add_event_handler #5099

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

Merged
merged 20 commits into from
Jun 13, 2025

Conversation

BillCarsonFr
Copy link
Member

@BillCarsonFr BillCarsonFr commented May 26, 2025

Main change

In event_handler/mod.rs there is a new method handle_sync_to_device_events(..) that will dispatch the to-device messages with the olm variant of EncryptionInfo.

The sync response struct SyncResponse now have pub to_device: Vec<ProcessedToDeviceEvent> instead of the old pub to_device: Vec<Raw<AnyToDeviceEvent>>

Context

It is now possible to get an Olm EncryptionInfo when register an event handler for to-device messages (previously the encryption_info was always None for to-device`.

        client.add_event_handler({
            move |ev: AnyToDeviceEvent, encryption_info: Option<EncryptionInfo>| {
                // If `encryption_info` is some, it was a successfully decrypted to-device message
                future::ready(())
            }
        });

Make it possible to make a difference between a plaintext and a successfully decrypted to-device message.
There is now a new variant of EncryptionInfo that will be passed to the to-device event handlers.

There might be a change that would be better to review alone 125aec6

=> I needed to move ProcessedToDeviceEvent from the crypto crate to the common crate. If not it was making it complex to compile with the e2e feature not enabled. This is the same reason why SyncTimelineEvent/UnableToDecryptReason/Encryption info are already in the common crate.

Based on #5074

  • Public API changes documented in changelogs (optional)

Signed-off-by:

Base automatically changed from valere/crypto/olm_encryption_info to main June 4, 2025 09:54
Copy link

codecov bot commented Jun 6, 2025

Codecov Report

Attention: Patch coverage is 68.29268% with 13 lines in your changes missing coverage. Please review.

Project coverage is 85.13%. Comparing base (6ab11a0) to head (d92eceb).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...sdk-base/src/response_processors/e2ee/to_device.rs 12.50% 7 Missing ⚠️
...es/matrix-sdk-common/src/deserialized_responses.rs 75.00% 3 Missing ⚠️
...ates/matrix-sdk/src/test_utils/mocks/encryption.rs 0.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5099      +/-   ##
==========================================
- Coverage   85.14%   85.13%   -0.01%     
==========================================
  Files         329      329              
  Lines       36912    36939      +27     
==========================================
+ Hits        31429    31449      +20     
- Misses       5483     5490       +7     

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@BillCarsonFr BillCarsonFr marked this pull request as ready for review June 6, 2025 08:30
@BillCarsonFr BillCarsonFr requested review from a team as code owners June 6, 2025 08:30
@BillCarsonFr BillCarsonFr requested review from Hywan and andybalaam and removed request for a team June 6, 2025 08:30
false // Exclude events with no type or encrypted
}
})
.map(matrix_sdk_common::deserialized_responses::ProcessedToDeviceEvent::PlainText)
Copy link
Member Author

Choose a reason for hiding this comment

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

When there is no encryption, to-device are not processed by the olm machine. There is no UnProcessed variant of ProcessedToDeviceEvent (not sure it would make sense :/).
So anyhow, we can just ignore the encrypted to-device as they are useless. So we can just map to PlainText variant?
I wonder if we should at some point remove the optional e2e-encryption feature flag

Copy link
Contributor

Choose a reason for hiding this comment

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

Huh, but how are events we fail to decrypt treated? Why not treat them just like that?

Copy link
Member

@andybalaam andybalaam left a comment

Choose a reason for hiding this comment

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

Looks sensible to me. A couple of optional minor comments.

let captured_info: Arc<Mutex<Option<EncryptionInfo>>> = Arc::new(Mutex::new(None));

client.add_event_handler({
let captured = captured_event.clone();
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer this to be called captured_event too.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thx @andybalam I updated the test 041e50d

let captured_info = captured_info.clone();
move |ev: AnyToDeviceEvent, encryption_info: Option<EncryptionInfo>| {
let mut captured_lock = captured.lock();
*captured_lock = Some(ev);
Copy link
Member

Choose a reason for hiding this comment

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

Can we lock and update in the same line of code? Might be nicer?

@Hywan Hywan removed their request for review June 6, 2025 13:02
@poljar poljar self-requested a review June 10, 2025 13:13
Copy link
Contributor

@poljar poljar left a comment

Choose a reason for hiding this comment

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

Alright, I think most of this looks good and makes sense.

I don't think we should completely filter out UTDs in case E2EE is disabled at compile time, the rest are small nits.

false // Exclude events with no type or encrypted
}
})
.map(matrix_sdk_common::deserialized_responses::ProcessedToDeviceEvent::PlainText)
Copy link
Contributor

Choose a reason for hiding this comment

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

Huh, but how are events we fail to decrypt treated? Why not treat them just like that?

.field(
"to_device",
&DebugListOfRawEventsNoId(
self.to_device.iter().map(|p| p.to_raw()).collect::<Vec<_>>().as_slice(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Feels a bit expensive to clone the whole thing for a debug output, can't we have an as_raw() that will borrow the thing instead?

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 did a similar thing to DebugListOfRawEventsNoId for list of processed to device 3eaaa30

@@ -120,6 +120,15 @@ impl MatrixMockServer {
alice_olm.update_tracked_users([bob_user_id.as_ref()]).await.unwrap();
}

// let bob be aware of Alice keys in order to be able to decrypt custom
// to-device (the device keys check are not delayed for non-crypto to-device
Copy link
Contributor

Choose a reason for hiding this comment

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

I think they are in fact only delayed or rather deferred for m.room.key events since dropping those would lead to a lot of UTDs.

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 clarified (I am not sure what is exactly done for key bundles, but no need to go in details here)

@BillCarsonFr BillCarsonFr requested a review from poljar June 12, 2025 14:42
Copy link
Contributor

@poljar poljar left a comment

Choose a reason for hiding this comment

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

I think this is now good to go, we just need to fix the changelog entry.

To double check, this isn't a breaking change, right? Existing event handlers will continue on working, they'll just ignore the new EncryptionInfo field.

Comment on lines 13 to 15
- `Client::add_event_handler`: Set `Option<EncryptionInfo>` in `EventHandlerData` for to-device messages.
If the to-device message was encrypted, the `EncryptionInfo` will be set. If it is `None` the message was sent in clear.
([#5099](https://github.com/matrix-org/matrix-rust-sdk/pull/5099))
Copy link
Contributor

Choose a reason for hiding this comment

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

This has been put in the wrong place, it's not part of the 0.12.0 release.

Copy link
Member Author

Choose a reason for hiding this comment

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

oh right, got hit by the merge. d92eceb

To double check, this isn't a breaking change, right? Existing event handlers will continue on working

Yes no change for existing event handlers.
Existing event handlers for to_device that requested the EncryptionInfo were always getting None, now they will get something if the event was encrypted.

Copy link
Contributor

@poljar poljar left a comment

Choose a reason for hiding this comment

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

Thanks, looks good now.

Should I just squash merge?

@poljar poljar merged commit 7126fc8 into main Jun 13, 2025
41 of 42 checks passed
@poljar poljar deleted the valere/crypto/receive_encrypted_to_device branch June 13, 2025 12:31
richvdh added a commit to matrix-org/matrix-sdk-crypto-wasm that referenced this pull request Jun 30, 2025
... which includes matrix-org/matrix-rust-sdk#5099,
which moves `ProcessedToDeviceEvent` to matrix-sdk-common.
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.

3 participants