From 3c9450490cbc1c4e965b6fd3d710f1701e0ccb75 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 20 Dec 2024 18:19:04 +0100 Subject: [PATCH] fix(crypto): Serialize sender data msk in base64 instead of numbers --- .../src/olm/group_sessions/sender_data.rs | 74 ++++++++++++++++++- ...r_data__tests__snapshot_sender_data-4.snap | 35 +-------- ...r_data__tests__snapshot_sender_data-5.snap | 35 +-------- ...r_data__tests__snapshot_sender_data-6.snap | 35 +-------- 4 files changed, 74 insertions(+), 105 deletions(-) diff --git a/crates/matrix-sdk-crypto/src/olm/group_sessions/sender_data.rs b/crates/matrix-sdk-crypto/src/olm/group_sessions/sender_data.rs index d10758546d..fa79b6b6ab 100644 --- a/crates/matrix-sdk-crypto/src/olm/group_sessions/sender_data.rs +++ b/crates/matrix-sdk-crypto/src/olm/group_sessions/sender_data.rs @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::cmp::Ordering; +use std::{cmp::Ordering, fmt}; use ruma::{DeviceId, OwnedDeviceId, OwnedUserId, UserId}; -use serde::{Deserialize, Serialize}; +use serde::{de, de::Visitor, Deserialize, Deserializer, Serialize}; use vodozemac::Ed25519PublicKey; -use crate::types::DeviceKeys; +use crate::types::{serialize_ed25519_key, DeviceKeys}; /// Information about the sender of a megolm session where we know the /// cross-signing identity of the sender. @@ -33,9 +33,55 @@ pub struct KnownSenderData { pub device_id: Option, /// The cross-signing key of the user who established this session. + #[serde( + serialize_with = "serialize_ed25519_key", + deserialize_with = "deserialize_sender_msk_base64_or_array" + )] pub master_key: Box, } +/// In an initial version the master key was serialized as an array of number, +/// it is now exported in base64. This code adds backward compatibility. +pub(crate) fn deserialize_sender_msk_base64_or_array<'de, D>( + de: D, +) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + struct KeyVisitor; + + impl<'de> Visitor<'de> for KeyVisitor { + type Value = Box; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(formatter, "a base64 string or an array of 32 bytes") + } + + fn visit_str(self, v: &str) -> Result + where + E: de::Error, + { + let decoded = Ed25519PublicKey::from_base64(v) + .map_err(|_| de::Error::custom("Base64 decoding error"))?; + Ok(Box::new(decoded)) + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: de::SeqAccess<'de>, + { + let mut buf = [0u8; 32]; + for (i, item) in buf.iter_mut().enumerate() { + *item = seq.next_element()?.ok_or_else(|| de::Error::invalid_length(i, &self))?; + } + let key = Ed25519PublicKey::from_slice(&buf).map_err(|e| de::Error::custom(&e))?; + Ok(Box::new(key)) + } + } + + de.deserialize_any(KeyVisitor) +} + /// Information on the device and user that sent the megolm session data to us /// /// Sessions start off in `UnknownDevice` state, and progress into `DeviceInfo` @@ -287,6 +333,7 @@ mod tests { use ruma::{ device_id, owned_device_id, owned_user_id, user_id, DeviceKeyAlgorithm, DeviceKeyId, }; + use serde_json::json; use vodozemac::{Curve25519PublicKey, Ed25519PublicKey}; use super::SenderData; @@ -530,4 +577,25 @@ mod tests { master_key: Box::new(Ed25519PublicKey::from_slice(&[1u8; 32]).unwrap()), })); } + + #[test] + fn test_sender_known_data_migration() { + let old_format = json!( + { + "SenderVerified": { + "user_id": "@foo:bar.baz", + "device_id": null, + "master_key": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + } + }); + + let migrated: SenderData = serde_json::from_value(old_format).unwrap(); + + assert_let!(SenderData::SenderVerified(KnownSenderData { master_key, .. }) = migrated); + + assert_eq!( + master_key.to_base64(), + Ed25519PublicKey::from_slice(&[0u8; 32]).unwrap().to_base64() + ); + } } diff --git a/crates/matrix-sdk-crypto/src/olm/group_sessions/snapshots/matrix_sdk_crypto__olm__group_sessions__sender_data__tests__snapshot_sender_data-4.snap b/crates/matrix-sdk-crypto/src/olm/group_sessions/snapshots/matrix_sdk_crypto__olm__group_sessions__sender_data__tests__snapshot_sender_data-4.snap index da1c8e4c40..d1fb11f190 100644 --- a/crates/matrix-sdk-crypto/src/olm/group_sessions/snapshots/matrix_sdk_crypto__olm__group_sessions__sender_data__tests__snapshot_sender_data-4.snap +++ b/crates/matrix-sdk-crypto/src/olm/group_sessions/snapshots/matrix_sdk_crypto__olm__group_sessions__sender_data__tests__snapshot_sender_data-4.snap @@ -6,39 +6,6 @@ expression: "SenderData::VerificationViolation(KnownSenderData\n{\n user_id: "VerificationViolation": { "user_id": "@foo:bar.baz", "device_id": "DEV", - "master_key": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ] + "master_key": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" } } diff --git a/crates/matrix-sdk-crypto/src/olm/group_sessions/snapshots/matrix_sdk_crypto__olm__group_sessions__sender_data__tests__snapshot_sender_data-5.snap b/crates/matrix-sdk-crypto/src/olm/group_sessions/snapshots/matrix_sdk_crypto__olm__group_sessions__sender_data__tests__snapshot_sender_data-5.snap index 36f6beb3dc..2a737872f7 100644 --- a/crates/matrix-sdk-crypto/src/olm/group_sessions/snapshots/matrix_sdk_crypto__olm__group_sessions__sender_data__tests__snapshot_sender_data-5.snap +++ b/crates/matrix-sdk-crypto/src/olm/group_sessions/snapshots/matrix_sdk_crypto__olm__group_sessions__sender_data__tests__snapshot_sender_data-5.snap @@ -6,39 +6,6 @@ expression: "SenderData::SenderUnverified(KnownSenderData\n{\n user_id: owned "SenderUnverified": { "user_id": "@foo:bar.baz", "device_id": null, - "master_key": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ] + "master_key": "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE" } } diff --git a/crates/matrix-sdk-crypto/src/olm/group_sessions/snapshots/matrix_sdk_crypto__olm__group_sessions__sender_data__tests__snapshot_sender_data-6.snap b/crates/matrix-sdk-crypto/src/olm/group_sessions/snapshots/matrix_sdk_crypto__olm__group_sessions__sender_data__tests__snapshot_sender_data-6.snap index 62e7b8e7ce..b2d09e4f34 100644 --- a/crates/matrix-sdk-crypto/src/olm/group_sessions/snapshots/matrix_sdk_crypto__olm__group_sessions__sender_data__tests__snapshot_sender_data-6.snap +++ b/crates/matrix-sdk-crypto/src/olm/group_sessions/snapshots/matrix_sdk_crypto__olm__group_sessions__sender_data__tests__snapshot_sender_data-6.snap @@ -6,39 +6,6 @@ expression: "SenderData::SenderVerified(KnownSenderData\n{\n user_id: owned_u "SenderVerified": { "user_id": "@foo:bar.baz", "device_id": null, - "master_key": [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ] + "master_key": "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE" } }