Skip to content

crypto: support for building key bundles #4775

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 2 commits into from
Mar 17, 2025

Conversation

richvdh
Copy link
Member

@richvdh richvdh commented Mar 10, 2025

Add a method to CryptoStore which will construct a key bundle, ready for encrypting and sharing with invited users.

Fixes #4504.

@richvdh richvdh force-pushed the rav/history_sharing/room_key_bundle branch 3 times, most recently from 2098247 to 1faf406 Compare March 10, 2025 15:22
Copy link

codecov bot commented Mar 10, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 86.12%. Comparing base (3d653d3) to head (a870c02).
Report is 113 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4775   +/-   ##
=======================================
  Coverage   86.11%   86.12%           
=======================================
  Files         292      293    +1     
  Lines       34369    34397   +28     
=======================================
+ Hits        29596    29623   +27     
- Misses       4773     4774    +1     

☔ 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.

@richvdh richvdh marked this pull request as ready for review March 11, 2025 10:09
@richvdh richvdh requested review from a team as code owners March 11, 2025 10:09
@richvdh richvdh requested review from stefanceriu and poljar and removed request for a team March 11, 2025 10:09
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.

Looks good minus some nits about type names and documentation.

Mainly requesting changes to see what you'll decide to do with the tests.

@@ -1987,6 +1992,36 @@ impl Store {
Ok(futures_util::stream::iter(sessions.into_iter().filter(predicate))
.then(|session| async move { session.export().await }))
}

/// Assemble a room key bundle for sharing encrypted history, as per
/// MSC4268.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we please link to the MSC if we mention it. I have some scripts that find the PR just from MSCXXXX but other people might not have such advanced technology in their IDE.

Copy link
Member Author

Choose a reason for hiding this comment

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

yup. Done in 89dee25.

// We sort the sessions in the bundle, so that the snapshot is stable.
bundle.room_keys.sort_by_key(|session| session.session_id.clone());
insta::with_settings!({ sort_maps => true }, {
assert_json_snapshot!(bundle);
Copy link
Contributor

Choose a reason for hiding this comment

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

An alternative to this might be to "redact" or rather replace the random bytes in the snapshot with something stable like I did in c1e28aa:

assert_json_snapshot!(pickle, {
".pickle.initial_ratchet.inner" => "[ratchet]",
".pickle.signing_key" => "[signing_key]",
".sender_key" => "[sender_key]",
".signing_key.ed25519" => "[ed25519_key]",
});

That would avoid having all the test data here as well as in the snapshot.

Copy link
Member Author

Choose a reason for hiding this comment

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

Unfortunately, this doesn't work very well here. Because there are several sessions, and we want to check which end up in which section of the output, the redactions get very fiddly. If we wanted to go down that route, it would be simpler to write out the test code by hand.

What does work quite well is a halfway house: we can generate the OlmMachines dynamically whilst still hardcoding the megolm sessions.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done in 6515b6f.

limitations under the License.
*/

//! Types for sharing encrypted room history, per MSC4268
Copy link
Contributor

Choose a reason for hiding this comment

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

Link to the MSC pretty please.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

pub withheld: Vec<RoomKeyWithheldContent>,
}

/// An [`InboundGroupSession`] for sharing as part of the key bundle.
Copy link
Contributor

Choose a reason for hiding this comment

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

We should probably describe how this differs from other 4 different room key types we have.

Would be neat to document the dangers of accepting such a room key and that they need to be treated somewhat specially, i.e. they will never be fully trusted like the room keys we receive directly from the creator.

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've added a bunch of documentation which I hope will help, in 27bfeb8


/// An [`InboundGroupSession`] for sharing as part of the key bundle.
#[derive(Deserialize, Serialize)]
pub struct SharedRoomKey {
Copy link
Contributor

Choose a reason for hiding this comment

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

I find that this name doesn't tell me much, every room key has been shared with you or you're going to share it.

Perhaps we could rename the type and the whole concept as something like a HistoricRoomKey, which would fit to the planned UI description of "History shared as presented by".

Copy link
Member Author

Choose a reason for hiding this comment

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

Renamed to HistoricRoomKey

Comment on lines 69 to 91
impl Debug for SharedRoomKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SharedRoomKey")
.field("algorithm", &self.algorithm)
.field("room_id", &self.room_id)
.field("sender_key", &self.sender_key)
.field("session_id", &self.session_id)
.field("sender_claimed_keys", &self.sender_claimed_keys)
.finish_non_exhaustive()
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Might make sense to add a snapshot test for this using assert_debug_snapshot!().

Copy link
Member Author

Choose a reason for hiding this comment

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

done in 36f74ed

@stefanceriu stefanceriu removed their request for review March 14, 2025 07:24
@richvdh richvdh requested a review from poljar March 14, 2025 16:11
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 for adding so many docs for the different room key types, this is a much needed overview.

Comment on lines +145 to +148
/// 3. [`ExportedRoomKey`] is very similar to `ForwardedRoomKeyContent`. The
/// only difference is that the original sender's Ed25519 key is embedded in
/// a `sender_claimed_keys` map rather than a top-level
/// `sender_claimed_ed25519_key` field.
Copy link
Contributor

Choose a reason for hiding this comment

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

I almost forgot about this, now I'm sad again.

richvdh added 2 commits March 17, 2025 11:24
Add a method to CryptoStore which will construct a key bundle, ready for
encrypting and sharing with invited users.

Part of #4504
@richvdh richvdh force-pushed the rav/history_sharing/room_key_bundle branch from 36f74ed to a870c02 Compare March 17, 2025 11:24
@richvdh richvdh enabled auto-merge March 17, 2025 11:25
@richvdh richvdh merged commit ad0223c into main Mar 17, 2025
43 checks passed
@richvdh richvdh deleted the rav/history_sharing/room_key_bundle branch March 17, 2025 11:45
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.

crypto: Add support for building a bundle of room keys, for sharing with other users
2 participants