diff --git a/ruma-client-api/src/r0/keys.rs b/ruma-client-api/src/r0/keys.rs index 288d2ed9..18047000 100644 --- a/ruma-client-api/src/r0/keys.rs +++ b/ruma-client-api/src/r0/keys.rs @@ -2,8 +2,7 @@ use std::{collections::BTreeMap, fmt::Debug}; -use ruma_events::Algorithm; -use ruma_identifiers::{DeviceId, DeviceKeyId, UserId}; +use ruma_identifiers::{DeviceKeyId, UserId}; use serde::{Deserialize, Serialize}; pub mod claim_keys; @@ -16,37 +15,6 @@ pub mod upload_signatures; #[cfg(feature = "unstable-pre-spec")] pub mod upload_signing_keys; -/// Identity keys for a device. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct DeviceKeys { - /// The ID of the user the device belongs to. Must match the user ID used when logging in. - pub user_id: UserId, - - /// The ID of the device these keys belong to. Must match the device ID used when logging in. - pub device_id: Box, - - /// The encryption algorithms supported by this device. - pub algorithms: Vec, - - /// Public identity keys. - pub keys: BTreeMap, - - /// Signatures for the device key object. - pub signatures: BTreeMap>, - - /// Additional data added to the device key information by intermediate servers, and - /// not covered by the signatures. - #[serde(skip_serializing_if = "Option::is_none")] - pub unsigned: Option, -} - -/// Additional data added to device key information by intermediate servers. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct UnsignedDeviceInfo { - /// The display name which the user set on the device. - pub device_display_name: Option, -} - /// A key for the SignedCurve25519 algorithm #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SignedKey { diff --git a/ruma-client-api/src/r0/keys/get_keys.rs b/ruma-client-api/src/r0/keys/get_keys.rs index c93b69b7..029fe290 100644 --- a/ruma-client-api/src/r0/keys/get_keys.rs +++ b/ruma-client-api/src/r0/keys/get_keys.rs @@ -3,12 +3,12 @@ use std::{collections::BTreeMap, time::Duration}; use ruma_api::ruma_api; +use ruma_common::encryption::DeviceKeys; use ruma_identifiers::{DeviceId, UserId}; use serde_json::Value as JsonValue; #[cfg(feature = "unstable-pre-spec")] use super::CrossSigningKey; -use super::DeviceKeys; ruma_api! { metadata: { diff --git a/ruma-client-api/src/r0/keys/upload_keys.rs b/ruma-client-api/src/r0/keys/upload_keys.rs index 43684808..61457177 100644 --- a/ruma-client-api/src/r0/keys/upload_keys.rs +++ b/ruma-client-api/src/r0/keys/upload_keys.rs @@ -4,9 +4,10 @@ use std::collections::BTreeMap; use js_int::UInt; use ruma_api::ruma_api; +use ruma_common::encryption::DeviceKeys; use ruma_identifiers::{DeviceKeyAlgorithm, DeviceKeyId}; -use super::{DeviceKeys, OneTimeKey}; +use super::OneTimeKey; ruma_api! { metadata: { diff --git a/ruma-common/src/encryption.rs b/ruma-common/src/encryption.rs new file mode 100644 index 00000000..9be2010a --- /dev/null +++ b/ruma-common/src/encryption.rs @@ -0,0 +1,39 @@ +//! Common types for [encryption] related tasks. +//! +//! [encryption](https://matrix.org/docs/spec/client_server/r0.6.1#id62) + +use std::collections::BTreeMap; + +use ruma_identifiers::{DeviceId, DeviceKeyId, EventEncryptionAlgorithm, UserId}; +use serde::{Deserialize, Serialize}; + +/// Identity keys for a device. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct DeviceKeys { + /// The ID of the user the device belongs to. Must match the user ID used when logging in. + pub user_id: UserId, + + /// The ID of the device these keys belong to. Must match the device ID used when logging in. + pub device_id: Box, + + /// The encryption algorithms supported by this device. + pub algorithms: Vec, + + /// Public identity keys. + pub keys: BTreeMap, + + /// Signatures for the device key object. + pub signatures: BTreeMap>, + + /// Additional data added to the device key information by intermediate servers, and + /// not covered by the signatures. + #[serde(skip_serializing_if = "Option::is_none")] + pub unsigned: Option, +} + +/// Additional data added to device key information by intermediate servers. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct UnsignedDeviceInfo { + /// The display name which the user set on the device. + pub device_display_name: Option, +} diff --git a/ruma-common/src/lib.rs b/ruma-common/src/lib.rs index 3f738d0a..a4faa72f 100644 --- a/ruma-common/src/lib.rs +++ b/ruma-common/src/lib.rs @@ -2,6 +2,7 @@ #![warn(missing_docs, missing_debug_implementations)] +pub mod encryption; pub mod presence; pub mod push; mod raw; diff --git a/ruma-events/src/algorithm.rs b/ruma-events/src/algorithm.rs deleted file mode 100644 index 389ee0e0..00000000 --- a/ruma-events/src/algorithm.rs +++ /dev/null @@ -1,64 +0,0 @@ -use std::fmt::{Display, Formatter, Result as FmtResult}; - -use serde::{Deserialize, Serialize}; - -/// An encryption algorithm to be used to encrypt messages sent to a room. -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -#[non_exhaustive] -#[serde(from = "String", into = "String")] -pub enum Algorithm { - /// Olm version 1 using Curve25519, AES-256, and SHA-256. - OlmV1Curve25519AesSha2, - - /// Megolm version 1 using AES-256 and SHA-256. - MegolmV1AesSha2, - - /// Any algorithm that is not part of the specification. - Custom(String), -} - -impl Display for Algorithm { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - let algorithm_str = match *self { - Algorithm::OlmV1Curve25519AesSha2 => "m.olm.v1.curve25519-aes-sha2", - Algorithm::MegolmV1AesSha2 => "m.megolm.v1.aes-sha2", - Algorithm::Custom(ref algorithm) => algorithm, - }; - - write!(f, "{}", algorithm_str) - } -} - -impl From for Algorithm -where - T: Into + AsRef, -{ - fn from(s: T) -> Algorithm { - match s.as_ref() { - "m.olm.v1.curve25519-aes-sha2" => Algorithm::OlmV1Curve25519AesSha2, - "m.megolm.v1.aes-sha2" => Algorithm::MegolmV1AesSha2, - _ => Algorithm::Custom(s.into()), - } - } -} - -impl From for String { - fn from(algorithm: Algorithm) -> String { - algorithm.to_string() - } -} - -#[cfg(test)] -mod tests { - use ruma_serde::test::serde_json_eq; - use serde_json::json; - - use super::Algorithm; - - #[test] - fn serialize_and_deserialize_from_display_form() { - serde_json_eq(Algorithm::MegolmV1AesSha2, json!("m.megolm.v1.aes-sha2")); - serde_json_eq(Algorithm::OlmV1Curve25519AesSha2, json!("m.olm.v1.curve25519-aes-sha2")); - serde_json_eq(Algorithm::Custom("io.ruma.test".into()), json!("io.ruma.test")); - } -} diff --git a/ruma-events/src/forwarded_room_key.rs b/ruma-events/src/forwarded_room_key.rs index c8edd0b8..20aa3cef 100644 --- a/ruma-events/src/forwarded_room_key.rs +++ b/ruma-events/src/forwarded_room_key.rs @@ -1,10 +1,9 @@ //! Types for the *m.forwarded_room_key* event. use ruma_events_macros::BasicEventContent; -use ruma_identifiers::RoomId; +use ruma_identifiers::{EventEncryptionAlgorithm, RoomId}; use serde::{Deserialize, Serialize}; -use super::Algorithm; use crate::BasicEvent; /// This event type is used to forward keys for end-to-end encryption. @@ -17,7 +16,7 @@ pub type ForwardedRoomKeyEvent = BasicEvent; #[ruma_event(type = "m.forwarded_room_key")] pub struct ForwardedRoomKeyEventContent { /// The encryption algorithm the key in this event is to be used with. - pub algorithm: Algorithm, + pub algorithm: EventEncryptionAlgorithm, /// The room where the key is used. pub room_id: RoomId, diff --git a/ruma-events/src/lib.rs b/ruma-events/src/lib.rs index 446b1798..5935b830 100644 --- a/ruma-events/src/lib.rs +++ b/ruma-events/src/lib.rs @@ -121,7 +121,7 @@ use std::fmt::Debug; use js_int::Int; use ruma_common::Raw; -use ruma_identifiers::RoomId; +use ruma_identifiers::{EventEncryptionAlgorithm, RoomId}; use serde::{ de::{self, IgnoredAny}, Deserialize, Serialize, @@ -130,7 +130,6 @@ use serde_json::value::RawValue as RawJsonValue; use self::room::redaction::{RedactionEvent, SyncRedactionEvent}; -mod algorithm; mod enums; mod error; mod event_kinds; @@ -160,7 +159,6 @@ pub mod tag; pub mod typing; pub use self::{ - algorithm::Algorithm, enums::{ AnyBasicEvent, AnyBasicEventContent, AnyEphemeralRoomEvent, AnyEphemeralRoomEventContent, AnyEvent, AnyMessageEvent, AnyMessageEventContent, AnyPossiblyRedactedMessageEvent, diff --git a/ruma-events/src/room/encryption.rs b/ruma-events/src/room/encryption.rs index 2de42ecc..4cba8d6c 100644 --- a/ruma-events/src/room/encryption.rs +++ b/ruma-events/src/room/encryption.rs @@ -4,7 +4,7 @@ use js_int::UInt; use ruma_events_macros::StateEventContent; use serde::{Deserialize, Serialize}; -use crate::{Algorithm, StateEvent}; +use crate::{EventEncryptionAlgorithm, StateEvent}; /// Defines how messages sent in this room should be encrypted. pub type EncryptionEvent = StateEvent; @@ -17,7 +17,7 @@ pub struct EncryptionEventContent { /// The encryption algorithm to be used to encrypt messages sent in this room. /// /// Must be `m.megolm.v1.aes-sha2`. - pub algorithm: Algorithm, + pub algorithm: EventEncryptionAlgorithm, /// How long the session should be used before changing it. /// @@ -34,7 +34,7 @@ pub struct EncryptionEventContent { impl EncryptionEventContent { /// Creates a new `EncryptionEventContent` with the given algorithm. - pub fn new(algorithm: Algorithm) -> Self { + pub fn new(algorithm: EventEncryptionAlgorithm) -> Self { Self { algorithm, rotation_period_ms: None, rotation_period_msgs: None } } } diff --git a/ruma-events/src/room_key.rs b/ruma-events/src/room_key.rs index 786959ec..894b78c5 100644 --- a/ruma-events/src/room_key.rs +++ b/ruma-events/src/room_key.rs @@ -1,10 +1,9 @@ //! Types for the *m.room_key* event. use ruma_events_macros::BasicEventContent; -use ruma_identifiers::RoomId; +use ruma_identifiers::{EventEncryptionAlgorithm, RoomId}; use serde::{Deserialize, Serialize}; -use super::Algorithm; use crate::BasicEvent; /// This event type is used to exchange keys for end-to-end encryption. @@ -19,7 +18,7 @@ pub struct RoomKeyEventContent { /// The encryption algorithm the key in this event is to be used with. /// /// Must be `m.megolm.v1.aes-sha2`. - pub algorithm: Algorithm, + pub algorithm: EventEncryptionAlgorithm, /// The room where the key is used. pub room_id: RoomId, @@ -33,17 +32,17 @@ pub struct RoomKeyEventContent { #[cfg(test)] mod tests { - use ruma_identifiers::room_id; + use ruma_identifiers::{room_id, EventEncryptionAlgorithm}; use serde_json::{json, to_value as to_json_value}; use super::RoomKeyEventContent; - use crate::{Algorithm, BasicEvent}; + use crate::BasicEvent; #[test] fn serialization() { let ev = BasicEvent { content: RoomKeyEventContent { - algorithm: Algorithm::MegolmV1AesSha2, + algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2, room_id: room_id!("!testroomid:example.org"), session_id: "SessId".into(), session_key: "SessKey".into(), diff --git a/ruma-events/src/room_key_request.rs b/ruma-events/src/room_key_request.rs index 1d748ff0..eccafb2c 100644 --- a/ruma-events/src/room_key_request.rs +++ b/ruma-events/src/room_key_request.rs @@ -1,11 +1,10 @@ //! Types for the *m.room_key_request* event. use ruma_events_macros::BasicEventContent; -use ruma_identifiers::{DeviceId, RoomId}; +use ruma_identifiers::{DeviceId, EventEncryptionAlgorithm, RoomId}; use serde::{Deserialize, Serialize}; use strum::{Display, EnumString}; -use super::Algorithm; use crate::BasicEvent; /// This event type is used to request keys for end-to-end encryption. @@ -54,7 +53,7 @@ pub enum Action { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct RequestedKeyInfo { /// The encryption algorithm the requested key in this event is to be used with. - pub algorithm: Algorithm, + pub algorithm: EventEncryptionAlgorithm, /// The room where the key is used. pub room_id: RoomId, diff --git a/ruma-events/tests/to_device.rs b/ruma-events/tests/to_device.rs index 4a3ca6fa..f3df7153 100644 --- a/ruma-events/tests/to_device.rs +++ b/ruma-events/tests/to_device.rs @@ -1,7 +1,5 @@ -use ruma_events::{ - room_key::RoomKeyEventContent, Algorithm, AnyToDeviceEventContent, ToDeviceEvent, -}; -use ruma_identifiers::{room_id, user_id}; +use ruma_events::{room_key::RoomKeyEventContent, AnyToDeviceEventContent, ToDeviceEvent}; +use ruma_identifiers::{room_id, user_id, EventEncryptionAlgorithm}; use serde_json::{json, to_value as to_json_value}; #[test] @@ -9,7 +7,7 @@ fn serialization() { let ev = ToDeviceEvent { sender: user_id!("@example:example.org"), content: AnyToDeviceEventContent::RoomKey(RoomKeyEventContent { - algorithm: Algorithm::MegolmV1AesSha2, + algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2, room_id: room_id!("!testroomid:example.org"), session_id: "SessId".into(), session_key: "SessKey".into(), diff --git a/ruma-identifiers-validation/Cargo.toml b/ruma-identifiers-validation/Cargo.toml index 37cb07fa..3c90880e 100644 --- a/ruma-identifiers-validation/Cargo.toml +++ b/ruma-identifiers-validation/Cargo.toml @@ -16,5 +16,7 @@ edition = "2018" default = ["serde"] [dependencies] +ruma-serde = { version = "0.2.3", path = "../ruma-serde" } serde = { version = "1.0.114", optional = true, features = ["derive"] } +serde_json = "1.0.57" strum = { version = "0.19.2", features = ["derive"] } diff --git a/ruma-identifiers-validation/src/key_algorithms.rs b/ruma-identifiers-validation/src/crypto_algorithms.rs similarity index 50% rename from ruma-identifiers-validation/src/key_algorithms.rs rename to ruma-identifiers-validation/src/crypto_algorithms.rs index 5d4c95d1..00da190c 100644 --- a/ruma-identifiers-validation/src/key_algorithms.rs +++ b/ruma-identifiers-validation/src/crypto_algorithms.rs @@ -1,6 +1,7 @@ //! Key algorithms used in Matrix spec. use std::convert::TryFrom; +use std::fmt::{Display, Formatter, Result as FmtResult}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -65,9 +66,62 @@ impl TryFrom for ServerKeyAlgorithm { } } +/// An encryption algorithm to be used to encrypt messages sent to a room. +#[derive(Clone, Debug, PartialEq)] +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde(from = "String", into = "String") +)] +#[non_exhaustive] +pub enum EventEncryptionAlgorithm { + /// Olm version 1 using Curve25519, AES-256, and SHA-256. + OlmV1Curve25519AesSha2, + + /// Megolm version 1 using AES-256 and SHA-256. + MegolmV1AesSha2, + + /// Any algorithm that is not part of the specification. + Custom(String), +} + +impl Display for EventEncryptionAlgorithm { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + let algorithm_str = match *self { + EventEncryptionAlgorithm::OlmV1Curve25519AesSha2 => "m.olm.v1.curve25519-aes-sha2", + EventEncryptionAlgorithm::MegolmV1AesSha2 => "m.megolm.v1.aes-sha2", + EventEncryptionAlgorithm::Custom(ref algorithm) => algorithm, + }; + + write!(f, "{}", algorithm_str) + } +} + +impl From for EventEncryptionAlgorithm +where + T: Into + AsRef, +{ + fn from(s: T) -> EventEncryptionAlgorithm { + match s.as_ref() { + "m.olm.v1.curve25519-aes-sha2" => EventEncryptionAlgorithm::OlmV1Curve25519AesSha2, + "m.megolm.v1.aes-sha2" => EventEncryptionAlgorithm::MegolmV1AesSha2, + _ => EventEncryptionAlgorithm::Custom(s.into()), + } + } +} + +impl From for String { + fn from(algorithm: EventEncryptionAlgorithm) -> String { + algorithm.to_string() + } +} + #[cfg(test)] mod tests { - use super::{DeviceKeyAlgorithm, ServerKeyAlgorithm}; + use ruma_serde::test::serde_json_eq; + use serde_json::json; + + use super::{DeviceKeyAlgorithm, EventEncryptionAlgorithm, ServerKeyAlgorithm}; #[test] fn parse_device_key_algorithm() { @@ -80,4 +134,17 @@ mod tests { fn parse_server_key_algorithm() { assert_eq!("ed25519".parse(), Ok(ServerKeyAlgorithm::Ed25519)); } + + #[test] + fn event_encryption_algorithm_serde() { + serde_json_eq(EventEncryptionAlgorithm::MegolmV1AesSha2, json!("m.megolm.v1.aes-sha2")); + serde_json_eq( + EventEncryptionAlgorithm::OlmV1Curve25519AesSha2, + json!("m.olm.v1.curve25519-aes-sha2"), + ); + serde_json_eq( + EventEncryptionAlgorithm::Custom("io.ruma.test".into()), + json!("io.ruma.test"), + ); + } } diff --git a/ruma-identifiers-validation/src/device_key_id.rs b/ruma-identifiers-validation/src/device_key_id.rs index 596651c4..a94c733c 100644 --- a/ruma-identifiers-validation/src/device_key_id.rs +++ b/ruma-identifiers-validation/src/device_key_id.rs @@ -1,6 +1,6 @@ use std::{num::NonZeroU8, str::FromStr}; -use crate::{key_algorithms::DeviceKeyAlgorithm, Error}; +use crate::{crypto_algorithms::DeviceKeyAlgorithm, Error}; pub fn validate(s: &str) -> Result { let colon_idx = NonZeroU8::new(s.find(':').ok_or(Error::MissingDeviceKeyDelimiter)? as u8) diff --git a/ruma-identifiers-validation/src/lib.rs b/ruma-identifiers-validation/src/lib.rs index 85785373..48a40a27 100644 --- a/ruma-identifiers-validation/src/lib.rs +++ b/ruma-identifiers-validation/src/lib.rs @@ -1,7 +1,7 @@ +pub mod crypto_algorithms; pub mod device_key_id; pub mod error; pub mod event_id; -pub mod key_algorithms; pub mod room_alias_id; pub mod room_id; pub mod room_id_or_alias_id; diff --git a/ruma-identifiers-validation/src/server_key_id.rs b/ruma-identifiers-validation/src/server_key_id.rs index b3982acd..05a92ff3 100644 --- a/ruma-identifiers-validation/src/server_key_id.rs +++ b/ruma-identifiers-validation/src/server_key_id.rs @@ -1,6 +1,6 @@ use std::{num::NonZeroU8, str::FromStr}; -use crate::{key_algorithms::ServerKeyAlgorithm, Error}; +use crate::{crypto_algorithms::ServerKeyAlgorithm, Error}; pub fn validate(s: &str) -> Result { let colon_idx = NonZeroU8::new(s.find(':').ok_or(Error::MissingServerKeyDelimiter)? as u8) diff --git a/ruma-identifiers/src/device_key_id.rs b/ruma-identifiers/src/device_key_id.rs index c9a81f6c..89f37033 100644 --- a/ruma-identifiers/src/device_key_id.rs +++ b/ruma-identifiers/src/device_key_id.rs @@ -2,7 +2,7 @@ use std::{convert::TryInto, num::NonZeroU8, str::FromStr}; -use ruma_identifiers_validation::{key_algorithms::DeviceKeyAlgorithm, Error}; +use ruma_identifiers_validation::{crypto_algorithms::DeviceKeyAlgorithm, Error}; use crate::DeviceId; @@ -56,7 +56,7 @@ common_impls!(DeviceKeyId, try_from, "Device key ID with algorithm and device ID mod test { use std::convert::TryFrom; - use ruma_identifiers_validation::{key_algorithms::DeviceKeyAlgorithm, Error}; + use ruma_identifiers_validation::{crypto_algorithms::DeviceKeyAlgorithm, Error}; #[cfg(feature = "serde")] use serde_json::{from_value as from_json_value, json, to_value as to_json_value}; diff --git a/ruma-identifiers/src/lib.rs b/ruma-identifiers/src/lib.rs index 5a9d5bb7..09242c78 100644 --- a/ruma-identifiers/src/lib.rs +++ b/ruma-identifiers/src/lib.rs @@ -22,8 +22,8 @@ pub use crate::{ }; #[doc(inline)] pub use ruma_identifiers_validation::{ + crypto_algorithms::{DeviceKeyAlgorithm, EventEncryptionAlgorithm, ServerKeyAlgorithm}, error::Error, - key_algorithms::{DeviceKeyAlgorithm, ServerKeyAlgorithm}, }; #[macro_use] diff --git a/ruma-identifiers/src/server_key_id.rs b/ruma-identifiers/src/server_key_id.rs index 0d4ad725..ce7caf4a 100644 --- a/ruma-identifiers/src/server_key_id.rs +++ b/ruma-identifiers/src/server_key_id.rs @@ -2,7 +2,7 @@ use std::{convert::TryInto, num::NonZeroU8, str::FromStr}; -use ruma_identifiers_validation::{key_algorithms::ServerKeyAlgorithm, Error}; +use ruma_identifiers_validation::{crypto_algorithms::ServerKeyAlgorithm, Error}; /// Key identifiers used for homeserver signing keys. #[derive(Clone, Debug)] @@ -59,7 +59,7 @@ mod tests { use crate::{Error, ServerKeyId}; #[cfg(feature = "serde")] - use ruma_identifiers_validation::key_algorithms::ServerKeyAlgorithm; + use ruma_identifiers_validation::crypto_algorithms::ServerKeyAlgorithm; #[cfg(feature = "serde")] #[test]