Skip to content

Commit

Permalink
fix(crypto): Serialize sender data msk in base64 instead of numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
BillCarsonFr committed Jan 8, 2025
1 parent d649606 commit 5ff556f
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 105 deletions.
74 changes: 71 additions & 3 deletions crates/matrix-sdk-crypto/src/olm/group_sessions/sender_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -33,9 +33,55 @@ pub struct KnownSenderData {
pub device_id: Option<OwnedDeviceId>,

/// 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<Ed25519PublicKey>,
}

/// 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<Box<Ed25519PublicKey>, D::Error>
where
D: Deserializer<'de>,
{
struct KeyVisitor;

impl<'de> Visitor<'de> for KeyVisitor {
type Value = Box<Ed25519PublicKey>;

fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "a base64 string or an array of 32 bytes")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
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<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
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`
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}

0 comments on commit 5ff556f

Please sign in to comment.