Skip to content

Commit 27bfeb8

Browse files
committed
fixup! crypto: support for building key bundles
improve docuemntation and rename struct
1 parent 89dee25 commit 27bfeb8

File tree

5 files changed

+99
-17
lines changed

5 files changed

+99
-17
lines changed

crates/matrix-sdk-crypto/src/olm/group_sessions/inbound.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ use super::{
4040
BackedUpRoomKey, ExportedRoomKey, OutboundGroupSession, SenderData, SenderDataType,
4141
SessionCreationError, SessionKey,
4242
};
43+
#[cfg(doc)]
44+
use crate::types::{events::room_key::RoomKeyContent, room_history::HistoricRoomKey};
4345
use crate::{
4446
error::{EventError, MegolmResult},
4547
types::{
@@ -107,6 +109,60 @@ pub(crate) struct SessionCreatorInfo {
107109
/// access of the vodozemac type.
108110
///
109111
/// [vodozemac]: https://matrix-org.github.io/vodozemac/vodozemac/index.html
112+
///
113+
/// ## Structures representing serialised versions of an `InboundGroupSession`
114+
///
115+
/// This crate contains a number of structures which are used for exporting or
116+
/// sharing `InboundGroupSession` between users or devices, in different
117+
/// circumstances. The following is an attempt to catalogue them.
118+
///
119+
/// 1. First, we have the contents of an `m.room_key` to-device message (i.e., a
120+
/// [`RoomKeyContent`]. `RoomKeyContent` is unusual in that it can be created
121+
/// only by the original creator of the session (i.e., someone in possession
122+
/// of the corresponding [`OutboundGroupSession`]), since the embedded
123+
/// `session_key` is self-signed.
124+
///
125+
/// `RoomKeyContent` does **not** include any information about the creator
126+
/// of the session (such as the creator's public device keys), since it is
127+
/// assumed that the original creator of the session is the same as the
128+
/// device sending the to-device message; it is therefore implied by the Olm
129+
/// channel used to send the message.
130+
///
131+
/// All the other structs in this list include a `sender_key` field which
132+
/// contains the Curve25519 key belonging to the device which created the
133+
/// Megolm session (at least, according to the creator of the struct); they
134+
/// also include the Ed25519 key, though the exact serialisation mechanism
135+
/// varies.
136+
///
137+
/// 2. Next, we have the contents of an `m.forwarded_room_key` message (i.e. a
138+
/// [`ForwardedRoomKeyContent`]). This modifies `RoomKeyContent` by (a) using
139+
/// a `session_key` which is not self-signed, (b) adding a `sender_key` field
140+
/// as mentioned above, (c) adding a `sender_claimed_ed25519_key` field
141+
/// containing the original sender's Ed25519 key; (d) adding a
142+
/// `forwarding_curve25519_key_chain` field, which is intended to be used
143+
/// when the key is re-forwarded, but in practice is of little use.
144+
///
145+
/// 3. [`ExportedRoomKey`] is very similar to `ForwardedRoomKeyContent`. The
146+
/// only difference is that the original sender's Ed25519 key is embedded in
147+
/// a `sender_claimed_keys` map rather than a top-level
148+
/// `sender_claimed_ed25519_key` field.
149+
///
150+
/// 4. [`BackedUpRoomKey`] is essentially the same as `ExportedRoomKey`, but
151+
/// lacks explicit `room_id` and `session_id` (since those are implied by
152+
/// other parts of the key backup structure).
153+
///
154+
/// 5. [`HistoricRoomKey`] is also similar to `ExportedRoomKey`, but omits
155+
/// `forwarding_curve25519_key_chain` (since it has not been useful in
156+
/// practice) and `shared_history` (because any key being shared via that
157+
/// mechanism is inherently suitable for sharing with other users).
158+
///
159+
/// | Type | Self-signed room key | `room_id`, `session_id` | `sender_key` | Sender's Ed25519 key | `forwarding _curve25519 _key _chain` | `shared _history` |
160+
/// |----------|----------------------|-------------------------|--------------|----------------------|------------------------------------|------------------|
161+
/// | [`RoomKeyContent`] | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ |
162+
/// | [`ForwardedRoomKeyContent`] | ❌ | ✅ | ✅ | `sender_claimed_ed25519_key` | ✅ | ✅ |
163+
/// | [`ExportedRoomKey`] | ❌ | ✅ | ✅ | `sender_claimed_keys` | ✅ | ✅ |
164+
/// | [`BackedUpRoomKey`] | ❌ | ❌ | ✅ | `sender_claimed_keys` | ✅ | ✅ |
165+
/// | [`HistoricRoomKey`] | ❌ | ✅ | ✅ | `sender_claimed_keys` | ❌ | ❌ |
110166
#[derive(Clone)]
111167
pub struct InboundGroupSession {
112168
inner: Arc<Mutex<InnerSession>>,

crates/matrix-sdk-crypto/src/olm/group_sessions/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@ pub enum SessionExportError {
6464
MissingEd25519Key,
6565
}
6666

67-
/// An exported version of an `InboundGroupSession`
67+
/// An exported version of an [`InboundGroupSession`].
6868
///
6969
/// This can be used to share the `InboundGroupSession` in an exported file.
70+
///
71+
/// See <https://spec.matrix.org/v1.13/client-server-api/#key-export-format>.
7072
#[derive(Deserialize, Serialize)]
7173
#[allow(missing_debug_implementations)]
7274
pub struct ExportedRoomKey {
@@ -144,7 +146,9 @@ impl ExportedRoomKey {
144146
/// This can be used to back up the [`InboundGroupSession`] to the server using
145147
/// [server-side key backups].
146148
///
147-
/// [server-side key backups]: https://spec.matrix.org/unstable/client-server-api/#server-side-key-backups
149+
/// See <https://spec.matrix.org/v1.13/client-server-api/#definition-backedupsessiondata>.
150+
///
151+
/// [server-side key backups]: https://spec.matrix.org/v1.13/client-server-api/#server-side-key-backups
148152
#[derive(Deserialize, Serialize)]
149153
#[allow(missing_debug_implementations)]
150154
pub struct BackedUpRoomKey {

crates/matrix-sdk-crypto/src/types/events/forwarded_room_key.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ use serde_json::Value;
2222
use vodozemac::{megolm::ExportedSessionKey, Curve25519PublicKey, Ed25519PublicKey};
2323

2424
use super::{EventType, ToDeviceEvent};
25+
#[cfg(doc)]
26+
use crate::olm::InboundGroupSession;
2527
use crate::types::{
2628
deserialize_curve_key, deserialize_curve_key_vec, deserialize_ed25519_key, serialize_curve_key,
2729
serialize_curve_key_vec, serialize_ed25519_key, EventEncryptionAlgorithm, SigningKeys,
@@ -39,11 +41,15 @@ impl ForwardedRoomKeyEvent {
3941

4042
/// The `m.forwarded_room_key` event content.
4143
///
42-
/// This is an enum over the different room key algorithms we support.
44+
/// This is an enum over the different room key algorithms we support. The
45+
/// currently-supported implementations are used to share
46+
/// [`InboundGroupSession`]s.
4347
///
4448
/// This event type is used to forward keys for end-to-end encryption.
45-
/// Typically it is encrypted as an m.room.encrypted event, then sent as a
49+
/// Typically, it is encrypted as an m.room.encrypted event, then sent as a
4650
/// to-device event.
51+
///
52+
/// See <https://spec.matrix.org/v1.13/client-server-api/#mforwarded_room_key>.
4753
#[derive(Debug, Deserialize)]
4854
#[serde(try_from = "RoomKeyHelper")]
4955
pub enum ForwardedRoomKeyContent {

crates/matrix-sdk-crypto/src/types/events/room_key.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ use serde_json::{value::to_raw_value, Value};
2222
use vodozemac::megolm::SessionKey;
2323

2424
use super::{EventType, ToDeviceEvent};
25+
#[cfg(doc)]
26+
use crate::olm::InboundGroupSession;
2527
use crate::types::EventEncryptionAlgorithm;
2628

2729
/// The `m.room_key` to-device event.
@@ -40,11 +42,15 @@ impl EventType for RoomKeyContent {
4042

4143
/// The `m.room_key` event content.
4244
///
43-
/// This is an enum over the different room key algorithms we support.
45+
/// This is an enum over the different room key algorithms we support. The
46+
/// currently-supported implementations are used to share
47+
/// [`InboundGroupSession`]s.
4448
///
4549
/// This event type is used to exchange keys for end-to-end encryption.
46-
/// Typically it is encrypted as an m.room.encrypted event, then sent as a
50+
/// Typically, it is encrypted as an m.room.encrypted event, then sent as a
4751
/// to-device event.
52+
///
53+
/// See <https://spec.matrix.org/v1.13/client-server-api/#mroom_key>.
4854
#[derive(Debug, Deserialize)]
4955
#[serde(try_from = "RoomKeyHelper")]
5056
pub enum RoomKeyContent {

crates/matrix-sdk-crypto/src/types/room_history.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,36 +24,45 @@ use ruma::{DeviceKeyAlgorithm, OwnedRoomId};
2424
use serde::{Deserialize, Serialize};
2525
use vodozemac::{megolm::ExportedSessionKey, Curve25519PublicKey};
2626

27-
#[cfg(doc)]
28-
use crate::olm::InboundGroupSession;
2927
use crate::{
3028
olm::ExportedRoomKey,
3129
types::{
3230
deserialize_curve_key, events::room_key_withheld::RoomKeyWithheldContent,
3331
serialize_curve_key, EventEncryptionAlgorithm, SigningKeys,
3432
},
3533
};
34+
#[cfg(doc)]
35+
use crate::{olm::InboundGroupSession, types::events::room_key::RoomKeyContent};
3636

37-
/// A bundle of room keys, for sharing encrypted room history.
37+
/// A bundle of historic room keys, for sharing encrypted room history, per
38+
/// [MSC4268].
39+
///
40+
/// [MSC4268]: https://github.com/matrix-org/matrix-spec-proposals/pull/4268
3841
#[derive(Deserialize, Serialize, Debug, Default)]
3942
pub struct RoomKeyBundle {
4043
/// Keys that we are sharing with the recipient.
41-
pub room_keys: Vec<SharedRoomKey>,
44+
pub room_keys: Vec<HistoricRoomKey>,
4245

4346
/// Keys that we are *not* sharing with the recipient.
4447
pub withheld: Vec<RoomKeyWithheldContent>,
4548
}
4649

47-
/// An [`InboundGroupSession`] for sharing as part of the key bundle.
50+
/// An [`InboundGroupSession`] for sharing as part of a [`RoomKeyBundle`].
51+
///
52+
/// Note: unlike a room key received via an `m.room_key` message (i.e., a
53+
/// [`RoomKeyContent`]), we have no direct proof that the original sender
54+
/// actually created this session; rather, we have to take the word of
55+
/// whoever sent us this key bundle.
4856
#[derive(Deserialize, Serialize)]
49-
pub struct SharedRoomKey {
57+
pub struct HistoricRoomKey {
5058
/// The encryption algorithm that the session uses.
5159
pub algorithm: EventEncryptionAlgorithm,
5260

5361
/// The room where the session is used.
5462
pub room_id: OwnedRoomId,
5563

56-
/// The Curve25519 key of the device which initiated the session originally.
64+
/// The Curve25519 key of the device which initiated the session originally,
65+
/// according to the device that sent us this key.
5766
#[serde(deserialize_with = "deserialize_curve_key", serialize_with = "serialize_curve_key")]
5867
pub sender_key: Curve25519PublicKey,
5968

@@ -63,12 +72,13 @@ pub struct SharedRoomKey {
6372
/// The key for the session.
6473
pub session_key: ExportedSessionKey,
6574

66-
/// The Ed25519 key of the device which initiated the session originally.
75+
/// The Ed25519 key of the device which initiated the session originally,
76+
/// according to the device that sent us this key.
6777
#[serde(default)]
6878
pub sender_claimed_keys: SigningKeys<DeviceKeyAlgorithm>,
6979
}
7080

71-
impl Debug for SharedRoomKey {
81+
impl Debug for HistoricRoomKey {
7282
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7383
f.debug_struct("SharedRoomKey")
7484
.field("algorithm", &self.algorithm)
@@ -80,7 +90,7 @@ impl Debug for SharedRoomKey {
8090
}
8191
}
8292

83-
impl From<ExportedRoomKey> for SharedRoomKey {
93+
impl From<ExportedRoomKey> for HistoricRoomKey {
8494
fn from(exported_room_key: ExportedRoomKey) -> Self {
8595
let ExportedRoomKey {
8696
algorithm,
@@ -92,7 +102,7 @@ impl From<ExportedRoomKey> for SharedRoomKey {
92102
shared_history: _,
93103
forwarding_curve25519_key_chain: _,
94104
} = exported_room_key;
95-
SharedRoomKey {
105+
HistoricRoomKey {
96106
algorithm,
97107
room_id,
98108
sender_key,

0 commit comments

Comments
 (0)