mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-18 21:52:30 -04:00
Merge pull request #4450 from matrix-org/valere/serialize_known_sender_data_b64
fix(crypto): Serialize sender data msk in base64 instead of numbers
This commit is contained in:
@@ -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<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`
|
||||
@@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user