Add support for megolm.v2 forwarded keys

This commit is contained in:
Damir Jelić committed 2022-08-29 10:21:04 +02:00
1 parent 3aaf70cb5a
commit 0673ad315f
5 files changed
+37 -7

No files matched your search

@@ -895,9 +895,10 @@ impl GossipMachine {
info: &GossipRequest, info: &GossipRequest,
sender: &UserId, sender: &UserId,
sender_key: Curve25519PublicKey, sender_key: Curve25519PublicKey,
algorithm: EventEncryptionAlgorithm,
content: &ForwardedMegolmV1AesSha2Content, content: &ForwardedMegolmV1AesSha2Content,
) -> Result<Option<InboundGroupSession>, CryptoStoreError> { ) -> Result<Option<InboundGroupSession>, CryptoStoreError> {
match InboundGroupSession::from_forwarded_key(sender_key, content) { match InboundGroupSession::from_forwarded_key(sender_key, &algorithm, content) {
Ok(session) => { Ok(session) => {
let old_session = self let old_session = self
.store .store
@@ -932,6 +933,7 @@ impl GossipMachine {
claimed_sender_key = content.claimed_sender_key.to_base64(), claimed_sender_key = content.claimed_sender_key.to_base64(),
room_id = s.room_id().as_str(), room_id = s.room_id().as_str(),
session_id = session_id.as_str(), session_id = session_id.as_str(),
%algorithm,
"Received a forwarded room key", "Received a forwarded room key",
); );
} else { } else {
@@ -941,6 +943,7 @@ impl GossipMachine {
claimed_sender_key = content.claimed_sender_key.to_base64(), claimed_sender_key = content.claimed_sender_key.to_base64(),
room_id = %content.room_id, room_id = %content.room_id,
session_id = session_id.as_str(), session_id = session_id.as_str(),
%algorithm,
"Received a forwarded room key but we already have a better version of it", "Received a forwarded room key but we already have a better version of it",
); );
} }
@@ -953,6 +956,7 @@ impl GossipMachine {
sender_key = sender_key.to_base64(), sender_key = sender_key.to_base64(),
claimed_sender_key = content.claimed_sender_key.to_base64(), claimed_sender_key = content.claimed_sender_key.to_base64(),
room_id = content.room_id.as_str(), room_id = content.room_id.as_str(),
%algorithm,
"Couldn't create a group session from a received room key" "Couldn't create a group session from a received room key"
); );
Err(e.into()) Err(e.into())
@@ -967,9 +971,17 @@ impl GossipMachine {
event: &DecryptedForwardedRoomKeyEvent, event: &DecryptedForwardedRoomKeyEvent,
) -> Result<Option<InboundGroupSession>, CryptoStoreError> { ) -> Result<Option<InboundGroupSession>, CryptoStoreError> {
match &event.content { match &event.content {
ForwardedRoomKeyContent::MegolmV1AesSha2(content) => { ForwardedRoomKeyContent::MegolmV1AesSha2(content)
| ForwardedRoomKeyContent::MegolmV2AesSha2(content) => {
if let Some(info) = self.get_key_info(content).await? { if let Some(info) = self.get_key_info(content).await? {
self.accept_forwarded_room_key(&info, &event.sender, sender_key, content).await self.accept_forwarded_room_key(
&info,
&event.sender,
sender_key,
event.content.algorithm(),
content,
)
.await
} else { } else {
warn!( warn!(
sender = event.sender.as_str(), sender = event.sender.as_str(),
@@ -171,9 +171,9 @@ impl InboundGroupSession {
/// to create the `InboundGroupSession`. /// to create the `InboundGroupSession`.
pub fn from_forwarded_key( pub fn from_forwarded_key(
sender_key: Curve25519PublicKey, sender_key: Curve25519PublicKey,
algorithm: &EventEncryptionAlgorithm,
content: &ForwardedMegolmV1AesSha2Content, content: &ForwardedMegolmV1AesSha2Content,
) -> Result<Self, SessionCreationError> { ) -> Result<Self, SessionCreationError> {
let algorithm = EventEncryptionAlgorithm::MegolmV1AesSha2;
let config = OutboundGroupSession::session_config(&algorithm)?; let config = OutboundGroupSession::session_config(&algorithm)?;
let session = InnerSession::import(&content.session_key, config); let session = InnerSession::import(&content.session_key, config);
@@ -196,7 +196,7 @@ impl InboundGroupSession {
forwarding_chains: forwarding_chains.into(), forwarding_chains: forwarding_chains.into(),
imported: true, imported: true,
backed_up: AtomicBool::new(false).into(), backed_up: AtomicBool::new(false).into(),
algorithm: algorithm.into(), algorithm: algorithm.to_owned().into(),
}) })
} }
@@ -176,14 +176,17 @@ impl TryFrom<ForwardedRoomKeyContent> for ExportedRoomKey {
/// Convert the content of a forwarded room key into a exported room key. /// Convert the content of a forwarded room key into a exported room key.
fn try_from(forwarded_key: ForwardedRoomKeyContent) -> Result<Self, Self::Error> { fn try_from(forwarded_key: ForwardedRoomKeyContent) -> Result<Self, Self::Error> {
let algorithm = forwarded_key.algorithm();
match forwarded_key { match forwarded_key {
ForwardedRoomKeyContent::MegolmV1AesSha2(content) => { ForwardedRoomKeyContent::MegolmV1AesSha2(content)
| ForwardedRoomKeyContent::MegolmV2AesSha2(content) => {
let mut sender_claimed_keys = SigningKeys::new(); let mut sender_claimed_keys = SigningKeys::new();
sender_claimed_keys sender_claimed_keys
.insert(DeviceKeyAlgorithm::Ed25519, content.claimed_ed25519_key.into()); .insert(DeviceKeyAlgorithm::Ed25519, content.claimed_ed25519_key.into());
Ok(Self { Ok(Self {
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2, algorithm,
room_id: content.room_id, room_id: content.room_id,
session_id: content.session_id, session_id: content.session_id,
forwarding_curve25519_key_chain: content.forwarding_curve25519_key_chain, forwarding_curve25519_key_chain: content.forwarding_curve25519_key_chain,
@@ -50,6 +50,9 @@ pub enum ForwardedRoomKeyContent {
/// The `m.megolm.v1.aes-sha2` variant of the `m.forwarded_room_key` /// The `m.megolm.v1.aes-sha2` variant of the `m.forwarded_room_key`
/// content. /// content.
MegolmV1AesSha2(Box<ForwardedMegolmV1AesSha2Content>), MegolmV1AesSha2(Box<ForwardedMegolmV1AesSha2Content>),
/// The `m.megolm.v2.aes-sha2` variant of the `m.forwarded_room_key`
/// content.
MegolmV2AesSha2(Box<ForwardedMegolmV1AesSha2Content>),
/// An unknown and unsupported variant of the `m.forwarded_room_key` /// An unknown and unsupported variant of the `m.forwarded_room_key`
/// content. /// content.
Unknown(UnknownRoomKeyContent), Unknown(UnknownRoomKeyContent),
@@ -62,6 +65,9 @@ impl ForwardedRoomKeyContent {
ForwardedRoomKeyContent::MegolmV1AesSha2(_) => { ForwardedRoomKeyContent::MegolmV1AesSha2(_) => {
EventEncryptionAlgorithm::MegolmV1AesSha2 EventEncryptionAlgorithm::MegolmV1AesSha2
} }
ForwardedRoomKeyContent::MegolmV2AesSha2(_) => {
EventEncryptionAlgorithm::MegolmV2AesSha2
}
ForwardedRoomKeyContent::Unknown(c) => c.algorithm.to_owned(), ForwardedRoomKeyContent::Unknown(c) => c.algorithm.to_owned(),
} }
} }
@@ -161,6 +167,10 @@ impl TryFrom<RoomKeyHelper> for ForwardedRoomKeyContent {
let content: ForwardedMegolmV1AesSha2Content = serde_json::from_value(value.other)?; let content: ForwardedMegolmV1AesSha2Content = serde_json::from_value(value.other)?;
Self::MegolmV1AesSha2(content.into()) Self::MegolmV1AesSha2(content.into())
} }
EventEncryptionAlgorithm::MegolmV2AesSha2 => {
let content: ForwardedMegolmV1AesSha2Content = serde_json::from_value(value.other)?;
Self::MegolmV2AesSha2(content.into())
}
_ => Self::Unknown(UnknownRoomKeyContent { _ => Self::Unknown(UnknownRoomKeyContent {
algorithm: value.algorithm, algorithm: value.algorithm,
other: serde_json::from_value(value.other)?, other: serde_json::from_value(value.other)?,
@@ -179,6 +189,10 @@ impl Serialize for ForwardedRoomKeyContent {
algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2, algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
other: serde_json::to_value(r).map_err(serde::ser::Error::custom)?, other: serde_json::to_value(r).map_err(serde::ser::Error::custom)?,
}, },
Self::MegolmV2AesSha2(r) => RoomKeyHelper {
algorithm: EventEncryptionAlgorithm::MegolmV2AesSha2,
other: serde_json::to_value(r).map_err(serde::ser::Error::custom)?,
},
Self::Unknown(r) => RoomKeyHelper { Self::Unknown(r) => RoomKeyHelper {
algorithm: r.algorithm.clone(), algorithm: r.algorithm.clone(),
other: serde_json::to_value(r.other.clone()).map_err(serde::ser::Error::custom)?, other: serde_json::to_value(r.other.clone()).map_err(serde::ser::Error::custom)?,
@@ -201,6 +201,7 @@ impl ToDeviceEvents {
ToDeviceEvents::ForwardedRoomKey(mut e) => { ToDeviceEvents::ForwardedRoomKey(mut e) => {
match &mut e.content { match &mut e.content {
ForwardedRoomKeyContent::MegolmV1AesSha2(c) => c.session_key.zeroize(), ForwardedRoomKeyContent::MegolmV1AesSha2(c) => c.session_key.zeroize(),
ForwardedRoomKeyContent::MegolmV2AesSha2(c) => c.session_key.zeroize(),
ForwardedRoomKeyContent::Unknown(_) => (), ForwardedRoomKeyContent::Unknown(_) => (),
} }