From 1319808028a44dd13e2e04904590eb7f2a3a013f Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 10 Jan 2025 11:07:38 +0100 Subject: [PATCH] fix(crypto): migration failure due to optimized handling of &[u8] --- crates/matrix-sdk-crypto/Cargo.toml | 1 + .../src/olm/group_sessions/sender_data.rs | 49 ++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/crates/matrix-sdk-crypto/Cargo.toml b/crates/matrix-sdk-crypto/Cargo.toml index 551c89a9bac..17c7c1c746b 100644 --- a/crates/matrix-sdk-crypto/Cargo.toml +++ b/crates/matrix-sdk-crypto/Cargo.toml @@ -87,6 +87,7 @@ http = { workspace = true } indoc = "2.0.5" insta = { workspace = true } matrix-sdk-test = { workspace = true } +rmp-serde = { workspace = true } proptest = { workspace = true } similar-asserts = { workspace = true } # required for async_test macro 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 fa79b6b6ab3..97de16342fa 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 @@ -77,6 +77,21 @@ where let key = Ed25519PublicKey::from_slice(&buf).map_err(|e| de::Error::custom(&e))?; Ok(Box::new(key)) } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: de::Error, + { + if v.len() == Ed25519PublicKey::LENGTH { + let mut buf = [0u8; 32]; + buf.copy_from_slice(v); + + let key = Ed25519PublicKey::from_slice(&buf).map_err(|e| de::Error::custom(&e))?; + Ok(Box::new(key)) + } else { + Err(de::Error::invalid_length(v.len(), &self)) + } + } } de.deserialize_any(KeyVisitor) @@ -334,11 +349,11 @@ mod tests { device_id, owned_device_id, owned_user_id, user_id, DeviceKeyAlgorithm, DeviceKeyId, }; use serde_json::json; - use vodozemac::{Curve25519PublicKey, Ed25519PublicKey}; + use vodozemac::{base64_decode, Curve25519PublicKey, Ed25519PublicKey}; use super::SenderData; use crate::{ - olm::KnownSenderData, + olm::{KnownSenderData, PickledInboundGroupSession}, types::{DeviceKey, DeviceKeys, EventEncryptionAlgorithm, Signatures}, }; @@ -598,4 +613,34 @@ mod tests { Ed25519PublicKey::from_slice(&[0u8; 32]).unwrap().to_base64() ); } + + #[test] + fn test_sender_known_data_migration_with_efficient_bytes_array() { + // This is an serialized PickledInboundGroupSession as rmp_serde will generate. + // This export use efficient storage for &[u8]. + // This an export when the `KnownSenderData` master_key was exported as an array + // instead of a base64 encoded string + let serialized_b64 = concat!( + "iaZwaWNrbGWEr2luaXRpYWxfcmF0Y2hldIKlaW5uZXLcAIABYMzfSnBRzMlPKF1uKjYbzLtkzNJ4RcylzN0HzP9D", + "zON1Tm05zO7M2MzFQsy9Acz9zPnMqDvM4syQzNrMzxF5KzbM4sy9zPUbBWfM7m4/zJzM18zDzMESKgfMkE7MyszI", + "HszqWjYyQURbzKTMkx7M58zANsy+AGPM2A8tbcyFYczge8ykzMFdbVxJMMyAzN8azJEXGsy8zPJazMMaP8ziDszm", + "WwfM+My2ajLMr8y+eczTRm9TFadjb3VudGVyAKtzaWduaW5nX2tlecQgefpCr6Duu7QUWzKIeMOFmxv/NjfcsYwZ", + "z8IN2ZOhdaS0c2lnbmluZ19rZXlfdmVyaWZpZWTDpmNvbmZpZ4GndmVyc2lvbqJWMapzZW5kZXJfa2V52StoMkIy", + "SDg2ajFpYmk2SW13ak9UUkhzbTVMamtyT2kyUGtiSXVUb0w0TWtFq3NpZ25pbmdfa2V5gadlZDI1NTE52StUWHJq", + "NS9UYXpia3Yram1CZDl4UlB4NWNVaFFzNUNnblc1Q1pNRjgvNjZzq3NlbmRlcl9kYXRhgbBTZW5kZXJVbnZlcmlm", + "aWVkg6d1c2VyX2lks0B2YWxvdTM1Om1hdHJpeC5vcmepZGV2aWNlX2lkqkZJQlNaRlJLUE2qbWFzdGVyX2tlecQg", + "kOp9s4ClyQujYD7rRZA8xgE6kvYlqKSNnMrQNmSrcuGncm9vbV9pZL4hRWt5VEtGdkViYlB6SmxhaUhFOm1hdHJp", + "eC5vcmeoaW1wb3J0ZWTCqWJhY2tlZF91cMKyaGlzdG9yeV92aXNpYmlsaXR5wKlhbGdvcml0aG20bS5tZWdvbG0u", + "djEuYWVzLXNoYTI"); + let input = base64_decode(serialized_b64).unwrap(); + + let sd: PickledInboundGroupSession = rmp_serde::from_slice(&input) + .expect("Should be able to deserialize serialized inbound group session"); + + assert_let!( + SenderData::SenderUnverified(KnownSenderData { master_key, .. }) = sd.sender_data + ); + + assert_eq!(master_key.to_base64(), "kOp9s4ClyQujYD7rRZA8xgE6kvYlqKSNnMrQNmSrcuE"); + } }