identifiers: Differentiate one-time and fallback keys from device keys

Move the `DeviceKeyAlgorithm::SignedCurve25519` into the new
`OneTimeKeyAlgorithm` type.
Add `(Owned)OneTimeKeyId` and `(Owned)OneTimeKeyName` instead of using
`(Owned)DeviceKeyId`.
This commit is contained in:
Kévin Commaille 2024-10-10 10:27:31 +02:00 committed by strawberry
parent 263ddb6545
commit 09ff0b2819
17 changed files with 130 additions and 51 deletions

View File

@ -1,5 +1,11 @@
# [unreleased] # [unreleased]
Breaking changes:
- Use `OwnedOneTimeKeyId` and `OneTimeKeyAlgorithm` instead of
`OwnedDeviceKeyId` and `DeviceKeyAlgorithm` respectively to identify one-time
and fallback keys and their algorithm.
# 0.10.0 # 0.10.0
Breaking changes: Breaking changes:

View File

@ -30,7 +30,7 @@ pub mod v1 {
presence::PresenceState, serde::from_raw_json_value, OwnedEventId, OwnedRoomId, presence::PresenceState, serde::from_raw_json_value, OwnedEventId, OwnedRoomId,
}; };
#[cfg(feature = "unstable-msc3202")] #[cfg(feature = "unstable-msc3202")]
use ruma_common::{DeviceKeyAlgorithm, OwnedDeviceId}; use ruma_common::{OneTimeKeyAlgorithm, OwnedDeviceId};
use ruma_events::AnyTimelineEvent; use ruma_events::AnyTimelineEvent;
#[cfg(feature = "unstable-msc2409")] #[cfg(feature = "unstable-msc2409")]
use ruma_events::{receipt::Receipt, AnyToDeviceEvent}; use ruma_events::{receipt::Receipt, AnyToDeviceEvent};
@ -80,7 +80,7 @@ pub mod v1 {
rename = "org.matrix.msc3202.device_one_time_keys_count" rename = "org.matrix.msc3202.device_one_time_keys_count"
)] )]
pub device_one_time_keys_count: pub device_one_time_keys_count:
BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, BTreeMap<DeviceKeyAlgorithm, UInt>>>, BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, BTreeMap<OneTimeKeyAlgorithm, UInt>>>,
/// A list of key algorithms for which the server has an unused fallback key for the /// A list of key algorithms for which the server has an unused fallback key for the
/// device. /// device.
@ -91,7 +91,7 @@ pub mod v1 {
rename = "org.matrix.msc3202.device_unused_fallback_key_types" rename = "org.matrix.msc3202.device_unused_fallback_key_types"
)] )]
pub device_unused_fallback_key_types: pub device_unused_fallback_key_types:
BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, Vec<DeviceKeyAlgorithm>>>, BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, Vec<OneTimeKeyAlgorithm>>>,
/// A list of EDUs. /// A list of EDUs.
#[cfg(feature = "unstable-msc2409")] #[cfg(feature = "unstable-msc2409")]

View File

@ -16,6 +16,11 @@ Breaking changes:
- Remove `RuleScope`, due to a clarification in the Matrix 1.12 where the `global` - Remove `RuleScope`, due to a clarification in the Matrix 1.12 where the `global`
scope is now hardcoded. scope is now hardcoded.
- The `push` endpoints don't take a scope anymore. - The `push` endpoints don't take a scope anymore.
- Make `Content-Type` and `Content-Disposition` mandatory when creating media
responses, according to MSC2701 / MSC2702 / Matrix 1.12.
- Use `OwnedOneTimeKeyId` and `OneTimeKeyAlgorithm` instead of
`OwnedDeviceKeyId` and `DeviceKeyAlgorithm` respectively to identify one-time
and fallback keys and their algorithm.
Improvements: Improvements:

View File

@ -14,7 +14,7 @@ pub mod unstable {
encryption::{DeviceKeys, OneTimeKey}, encryption::{DeviceKeys, OneTimeKey},
metadata, metadata,
serde::Raw, serde::Raw,
OwnedDeviceId, OwnedDeviceKeyId, OwnedDeviceId, OwnedOneTimeKeyId,
}; };
use crate::dehydrated_device::DehydratedDeviceData; use crate::dehydrated_device::DehydratedDeviceData;
@ -46,11 +46,11 @@ pub mod unstable {
/// One-time public keys for "pre-key" messages. /// One-time public keys for "pre-key" messages.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")] #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub one_time_keys: BTreeMap<OwnedDeviceKeyId, Raw<OneTimeKey>>, pub one_time_keys: BTreeMap<OwnedOneTimeKeyId, Raw<OneTimeKey>>,
/// Fallback public keys for "pre-key" messages. /// Fallback public keys for "pre-key" messages.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")] #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub fallback_keys: BTreeMap<OwnedDeviceKeyId, Raw<OneTimeKey>>, pub fallback_keys: BTreeMap<OwnedOneTimeKeyId, Raw<OneTimeKey>>,
} }
/// Response type for the `upload_keys` endpoint. /// Response type for the `upload_keys` endpoint.

View File

@ -9,7 +9,7 @@ use ruma_common::{
encryption::OneTimeKey, encryption::OneTimeKey,
metadata, metadata,
serde::Raw, serde::Raw,
DeviceKeyAlgorithm, OwnedDeviceId, OwnedDeviceKeyId, OwnedUserId, OneTimeKeyAlgorithm, OwnedDeviceId, OwnedOneTimeKeyId, OwnedUserId,
}; };
use serde_json::Value as JsonValue; use serde_json::Value as JsonValue;
@ -36,7 +36,7 @@ pub struct Request {
pub timeout: Option<Duration>, pub timeout: Option<Duration>,
/// The keys to be claimed. /// The keys to be claimed.
pub one_time_keys: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, DeviceKeyAlgorithm>>, pub one_time_keys: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, OneTimeKeyAlgorithm>>,
} }
/// Response type for the `claim_keys` endpoint. /// Response type for the `claim_keys` endpoint.
@ -55,7 +55,7 @@ pub struct Response {
impl Request { impl Request {
/// Creates a new `Request` with the given key claims and the recommended 10 second timeout. /// Creates a new `Request` with the given key claims and the recommended 10 second timeout.
pub fn new( pub fn new(
one_time_keys: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, DeviceKeyAlgorithm>>, one_time_keys: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, OneTimeKeyAlgorithm>>,
) -> Self { ) -> Self {
Self { timeout: Some(Duration::from_secs(10)), one_time_keys } Self { timeout: Some(Duration::from_secs(10)), one_time_keys }
} }
@ -69,4 +69,4 @@ impl Response {
} }
/// The one-time keys for a given device. /// The one-time keys for a given device.
pub type OneTimeKeys = BTreeMap<OwnedDeviceId, BTreeMap<OwnedDeviceKeyId, Raw<OneTimeKey>>>; pub type OneTimeKeys = BTreeMap<OwnedDeviceId, BTreeMap<OwnedOneTimeKeyId, Raw<OneTimeKey>>>;

View File

@ -9,7 +9,7 @@ use ruma_common::{
encryption::OneTimeKey, encryption::OneTimeKey,
metadata, metadata,
serde::Raw, serde::Raw,
DeviceKeyAlgorithm, OwnedDeviceId, OwnedDeviceKeyId, OwnedUserId, OneTimeKeyAlgorithm, OwnedDeviceId, OwnedOneTimeKeyId, OwnedUserId,
}; };
use serde_json::Value as JsonValue; use serde_json::Value as JsonValue;
@ -35,7 +35,7 @@ pub struct Request {
pub timeout: Option<Duration>, pub timeout: Option<Duration>,
/// The keys to be claimed. /// The keys to be claimed.
pub one_time_keys: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, Vec<DeviceKeyAlgorithm>>>, pub one_time_keys: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, Vec<OneTimeKeyAlgorithm>>>,
} }
/// Response type for the `claim_keys` endpoint. /// Response type for the `claim_keys` endpoint.
@ -54,7 +54,7 @@ pub struct Response {
impl Request { impl Request {
/// Creates a new `Request` with the given key claims and the recommended 10 second timeout. /// Creates a new `Request` with the given key claims and the recommended 10 second timeout.
pub fn new( pub fn new(
one_time_keys: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, Vec<DeviceKeyAlgorithm>>>, one_time_keys: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, Vec<OneTimeKeyAlgorithm>>>,
) -> Self { ) -> Self {
Self { timeout: Some(Duration::from_secs(10)), one_time_keys } Self { timeout: Some(Duration::from_secs(10)), one_time_keys }
} }
@ -68,4 +68,4 @@ impl Response {
} }
/// The one-time keys for a given device. /// The one-time keys for a given device.
pub type OneTimeKeys = BTreeMap<OwnedDeviceId, BTreeMap<OwnedDeviceKeyId, Raw<OneTimeKey>>>; pub type OneTimeKeys = BTreeMap<OwnedDeviceId, BTreeMap<OwnedOneTimeKeyId, Raw<OneTimeKey>>>;

View File

@ -15,7 +15,7 @@ pub mod v3 {
encryption::{DeviceKeys, OneTimeKey}, encryption::{DeviceKeys, OneTimeKey},
metadata, metadata,
serde::Raw, serde::Raw,
DeviceKeyAlgorithm, OwnedDeviceKeyId, OneTimeKeyAlgorithm, OwnedOneTimeKeyId,
}; };
const METADATA: Metadata = metadata! { const METADATA: Metadata = metadata! {
@ -40,11 +40,11 @@ pub mod v3 {
/// One-time public keys for "pre-key" messages. /// One-time public keys for "pre-key" messages.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")] #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub one_time_keys: BTreeMap<OwnedDeviceKeyId, Raw<OneTimeKey>>, pub one_time_keys: BTreeMap<OwnedOneTimeKeyId, Raw<OneTimeKey>>,
/// Fallback public keys for "pre-key" messages. /// Fallback public keys for "pre-key" messages.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")] #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub fallback_keys: BTreeMap<OwnedDeviceKeyId, Raw<OneTimeKey>>, pub fallback_keys: BTreeMap<OwnedOneTimeKeyId, Raw<OneTimeKey>>,
} }
/// Response type for the `upload_keys` endpoint. /// Response type for the `upload_keys` endpoint.
@ -52,7 +52,7 @@ pub mod v3 {
pub struct Response { pub struct Response {
/// For each key algorithm, the number of unclaimed one-time keys of that /// For each key algorithm, the number of unclaimed one-time keys of that
/// type currently held on the server for this device. /// type currently held on the server for this device.
pub one_time_key_counts: BTreeMap<DeviceKeyAlgorithm, UInt>, pub one_time_key_counts: BTreeMap<OneTimeKeyAlgorithm, UInt>,
} }
impl Request { impl Request {
@ -64,7 +64,7 @@ pub mod v3 {
impl Response { impl Response {
/// Creates a new `Response` with the given one time key counts. /// Creates a new `Response` with the given one time key counts.
pub fn new(one_time_key_counts: BTreeMap<DeviceKeyAlgorithm, UInt>) -> Self { pub fn new(one_time_key_counts: BTreeMap<OneTimeKeyAlgorithm, UInt>) -> Self {
Self { one_time_key_counts } Self { one_time_key_counts }
} }
} }

View File

@ -10,7 +10,7 @@ use ruma_common::{
metadata, metadata,
presence::PresenceState, presence::PresenceState,
serde::Raw, serde::Raw,
DeviceKeyAlgorithm, OwnedEventId, OwnedRoomId, OwnedUserId, OneTimeKeyAlgorithm, OwnedEventId, OwnedRoomId, OwnedUserId,
}; };
use ruma_events::{ use ruma_events::{
presence::PresenceEvent, AnyGlobalAccountDataEvent, AnyRoomAccountDataEvent, presence::PresenceEvent, AnyGlobalAccountDataEvent, AnyRoomAccountDataEvent,
@ -102,14 +102,13 @@ pub struct Response {
/// For each key algorithm, the number of unclaimed one-time keys /// For each key algorithm, the number of unclaimed one-time keys
/// currently held on the server for a device. /// currently held on the server for a device.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")] #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub device_one_time_keys_count: BTreeMap<DeviceKeyAlgorithm, UInt>, pub device_one_time_keys_count: BTreeMap<OneTimeKeyAlgorithm, UInt>,
/// For each key algorithm, the number of unclaimed one-time keys /// The unused fallback key algorithms.
/// currently held on the server for a device.
/// ///
/// The presence of this field indicates that the server supports /// The presence of this field indicates that the server supports
/// fallback keys. /// fallback keys.
pub device_unused_fallback_key_types: Option<Vec<DeviceKeyAlgorithm>>, pub device_unused_fallback_key_types: Option<Vec<OneTimeKeyAlgorithm>>,
} }
impl Request { impl Request {

View File

@ -14,7 +14,7 @@ use ruma_common::{
metadata, metadata,
room::RoomType, room::RoomType,
serde::{deserialize_cow_str, duration::opt_ms, Raw}, serde::{deserialize_cow_str, duration::opt_ms, Raw},
DeviceKeyAlgorithm, MilliSecondsSinceUnixEpoch, OwnedMxcUri, OwnedRoomId, OwnedUserId, RoomId, MilliSecondsSinceUnixEpoch, OneTimeKeyAlgorithm, OwnedMxcUri, OwnedRoomId, OwnedUserId, RoomId,
}; };
use ruma_events::{ use ruma_events::{
receipt::SyncReceiptEvent, typing::SyncTypingEvent, AnyGlobalAccountDataEvent, receipt::SyncReceiptEvent, typing::SyncTypingEvent, AnyGlobalAccountDataEvent,
@ -700,15 +700,14 @@ pub struct E2EE {
/// For each key algorithm, the number of unclaimed one-time keys /// For each key algorithm, the number of unclaimed one-time keys
/// currently held on the server for a device. /// currently held on the server for a device.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")] #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub device_one_time_keys_count: BTreeMap<DeviceKeyAlgorithm, UInt>, pub device_one_time_keys_count: BTreeMap<OneTimeKeyAlgorithm, UInt>,
/// For each key algorithm, the number of unclaimed one-time keys /// The unused fallback key algorithms.
/// currently held on the server for a device.
/// ///
/// The presence of this field indicates that the server supports /// The presence of this field indicates that the server supports
/// fallback keys. /// fallback keys.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub device_unused_fallback_key_types: Option<Vec<DeviceKeyAlgorithm>>, pub device_unused_fallback_key_types: Option<Vec<OneTimeKeyAlgorithm>>,
} }
impl E2EE { impl E2EE {

View File

@ -454,7 +454,7 @@ impl Response {
/// HTTP types related to a [`Response`]. /// HTTP types related to a [`Response`].
pub mod response { pub mod response {
use ruma_common::DeviceKeyAlgorithm; use ruma_common::OneTimeKeyAlgorithm;
use ruma_events::{ use ruma_events::{
receipt::SyncReceiptEvent, typing::SyncTypingEvent, AnyGlobalAccountDataEvent, receipt::SyncReceiptEvent, typing::SyncTypingEvent, AnyGlobalAccountDataEvent,
AnyRoomAccountDataEvent, AnyToDeviceEvent, AnyRoomAccountDataEvent, AnyToDeviceEvent,
@ -645,15 +645,14 @@ pub mod response {
/// For each key algorithm, the number of unclaimed one-time keys /// For each key algorithm, the number of unclaimed one-time keys
/// currently held on the server for a device. /// currently held on the server for a device.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")] #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub device_one_time_keys_count: BTreeMap<DeviceKeyAlgorithm, UInt>, pub device_one_time_keys_count: BTreeMap<OneTimeKeyAlgorithm, UInt>,
/// For each key algorithm, the number of unclaimed one-time keys /// The unused fallback key algorithms.
/// currently held on the server for a device.
/// ///
/// The presence of this field indicates that the server supports /// The presence of this field indicates that the server supports
/// fallback keys. /// fallback keys.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub device_unused_fallback_key_types: Option<Vec<DeviceKeyAlgorithm>>, pub device_unused_fallback_key_types: Option<Vec<OneTimeKeyAlgorithm>>,
} }
impl E2EE { impl E2EE {

View File

@ -27,6 +27,8 @@ Breaking changes:
`SigningKeyAlgorithm` and the `server_signing_key_version` macro. `SigningKeyAlgorithm` and the `server_signing_key_version` macro.
- Rename `Signatures::insert` to `Signatures::insert_signature`. - Rename `Signatures::insert` to `Signatures::insert_signature`.
`Signatures::insert` is now dereferenced to `BTreeMap::insert`. `Signatures::insert` is now dereferenced to `BTreeMap::insert`.
- Move the `DeviceKeyAlgorithm::SignedCurve25519` into the new
`OneTimeKeyAlgorithm` type.
Improvements: Improvements:
@ -45,6 +47,8 @@ Improvements:
- Improve the API of `Signatures`, by implementing `Deref` and `DerefMut`, as - Improve the API of `Signatures`, by implementing `Deref` and `DerefMut`, as
well as `From`, `Extend` and `FromIterator` from a list of well as `From`, `Extend` and `FromIterator` from a list of
`(entity, key_identifier, value)` tuples. `(entity, key_identifier, value)` tuples.
- Add `(Owned)OneTimeKeyId` and `(Owned)OneTimeKeyName` to identify one-time and
fallback keys instead of using `(Owned)DeviceKeyId`.
# 0.13.0 # 0.13.0

View File

@ -18,17 +18,20 @@ use serde::de::{self, Deserializer, Unexpected};
pub use self::{ pub use self::{
client_secret::{ClientSecret, OwnedClientSecret}, client_secret::{ClientSecret, OwnedClientSecret},
crypto_algorithms::{ crypto_algorithms::{
DeviceKeyAlgorithm, EventEncryptionAlgorithm, KeyDerivationAlgorithm, SigningKeyAlgorithm, DeviceKeyAlgorithm, EventEncryptionAlgorithm, KeyDerivationAlgorithm, OneTimeKeyAlgorithm,
SigningKeyAlgorithm,
}, },
device_id::{DeviceId, OwnedDeviceId}, device_id::{DeviceId, OwnedDeviceId},
device_key_id::{DeviceKeyId, OwnedDeviceKeyId}, device_key_id::{DeviceKeyId, OwnedDeviceKeyId},
event_id::{EventId, OwnedEventId}, event_id::{EventId, OwnedEventId},
key_id::{ key_id::{
DeviceSigningKeyId, KeyAlgorithm, KeyId, OwnedDeviceSigningKeyId, OwnedKeyId, DeviceSigningKeyId, KeyAlgorithm, KeyId, OneTimeKeyId, OwnedDeviceSigningKeyId, OwnedKeyId,
OwnedServerSigningKeyId, OwnedSigningKeyId, ServerSigningKeyId, SigningKeyId, OwnedOneTimeKeyId, OwnedServerSigningKeyId, OwnedSigningKeyId, ServerSigningKeyId,
SigningKeyId,
}, },
matrix_uri::{MatrixToUri, MatrixUri}, matrix_uri::{MatrixToUri, MatrixUri},
mxc_uri::{Mxc, MxcUri, OwnedMxcUri}, mxc_uri::{Mxc, MxcUri, OwnedMxcUri},
one_time_key_name::{OneTimeKeyName, OwnedOneTimeKeyName},
room_alias_id::{OwnedRoomAliasId, RoomAliasId}, room_alias_id::{OwnedRoomAliasId, RoomAliasId},
room_id::{OwnedRoomId, RoomId}, room_id::{OwnedRoomId, RoomId},
room_or_alias_id::{OwnedRoomOrAliasId, RoomOrAliasId}, room_or_alias_id::{OwnedRoomOrAliasId, RoomOrAliasId},
@ -53,6 +56,7 @@ mod device_key_id;
mod event_id; mod event_id;
mod key_id; mod key_id;
mod mxc_uri; mod mxc_uri;
mod one_time_key_name;
mod room_alias_id; mod room_alias_id;
mod room_id; mod room_id;
mod room_or_alias_id; mod room_or_alias_id;

View File

@ -4,7 +4,9 @@ use ruma_macros::StringEnum;
use crate::PrivOwnedStr; use crate::PrivOwnedStr;
/// The basic key algorithms in the specification. /// The algorithms for the [device keys] defined in the Matrix spec.
///
/// [device keys]: https://spec.matrix.org/latest/client-server-api/#device-keys
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))] #[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, StringEnum)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, StringEnum)]
#[non_exhaustive] #[non_exhaustive]
@ -16,9 +18,6 @@ pub enum DeviceKeyAlgorithm {
/// The Curve25519 ECDH algorithm. /// The Curve25519 ECDH algorithm.
Curve25519, Curve25519,
/// The Curve25519 ECDH algorithm, but the key also contains signatures
SignedCurve25519,
#[doc(hidden)] #[doc(hidden)]
_Custom(PrivOwnedStr), _Custom(PrivOwnedStr),
} }
@ -66,18 +65,29 @@ pub enum KeyDerivationAlgorithm {
_Custom(PrivOwnedStr), _Custom(PrivOwnedStr),
} }
/// The algorithms for [one-time and fallback keys] defined in the Matrix spec.
///
/// [one-time and fallback keys]: https://spec.matrix.org/latest/client-server-api/#one-time-and-fallback-keys
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, StringEnum)]
#[non_exhaustive]
#[ruma_enum(rename_all = "snake_case")]
pub enum OneTimeKeyAlgorithm {
/// The Curve25519 ECDH algorithm, but the key also contains signatures.
SignedCurve25519,
#[doc(hidden)]
_Custom(PrivOwnedStr),
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{DeviceKeyAlgorithm, SigningKeyAlgorithm}; use super::{DeviceKeyAlgorithm, OneTimeKeyAlgorithm, SigningKeyAlgorithm};
#[test] #[test]
fn parse_device_key_algorithm() { fn parse_device_key_algorithm() {
assert_eq!(DeviceKeyAlgorithm::from("ed25519"), DeviceKeyAlgorithm::Ed25519); assert_eq!(DeviceKeyAlgorithm::from("ed25519"), DeviceKeyAlgorithm::Ed25519);
assert_eq!(DeviceKeyAlgorithm::from("curve25519"), DeviceKeyAlgorithm::Curve25519); assert_eq!(DeviceKeyAlgorithm::from("curve25519"), DeviceKeyAlgorithm::Curve25519);
assert_eq!(
DeviceKeyAlgorithm::from("signed_curve25519"),
DeviceKeyAlgorithm::SignedCurve25519
);
} }
#[test] #[test]
@ -109,4 +119,12 @@ mod tests {
serde_json_eq(KeyDerivationAlgorithm::Pbkfd2, json!("m.pbkdf2")); serde_json_eq(KeyDerivationAlgorithm::Pbkfd2, json!("m.pbkdf2"));
} }
#[test]
fn parse_one_time_key_algorithm() {
assert_eq!(
OneTimeKeyAlgorithm::from("signed_curve25519"),
OneTimeKeyAlgorithm::SignedCurve25519
);
}
} }

View File

@ -6,7 +6,10 @@ use std::{
use ruma_macros::IdZst; use ruma_macros::IdZst;
use super::{crypto_algorithms::SigningKeyAlgorithm, DeviceId, KeyName, ServerSigningKeyVersion}; use super::{
crypto_algorithms::SigningKeyAlgorithm, DeviceId, KeyName, OneTimeKeyAlgorithm, OneTimeKeyName,
ServerSigningKeyVersion,
};
/// A key algorithm and key name delimited by a colon. /// A key algorithm and key name delimited by a colon.
#[repr(transparent)] #[repr(transparent)]
@ -66,6 +69,16 @@ pub type DeviceSigningKeyId = SigningKeyId<DeviceId>;
/// Algorithm + key name for device keys. /// Algorithm + key name for device keys.
pub type OwnedDeviceSigningKeyId = OwnedSigningKeyId<DeviceId>; pub type OwnedDeviceSigningKeyId = OwnedSigningKeyId<DeviceId>;
/// Algorithm + key name for [one-time and fallback keys].
///
/// [one-time and fallback keys]: https://spec.matrix.org/latest/client-server-api/#one-time-and-fallback-keys
pub type OneTimeKeyId = KeyId<OneTimeKeyAlgorithm, OneTimeKeyName>;
/// Algorithm + key name for [one-time and fallback keys].
///
/// [one-time and fallback keys]: https://spec.matrix.org/latest/client-server-api/#one-time-and-fallback-keys
pub type OwnedOneTimeKeyId = OwnedKeyId<OneTimeKeyAlgorithm, OneTimeKeyName>;
// The following impls are usually derived using the std macros. // The following impls are usually derived using the std macros.
// They are implemented manually here to avoid unnecessary bounds. // They are implemented manually here to avoid unnecessary bounds.
impl<A: KeyAlgorithm, K: KeyName + ?Sized> PartialEq for KeyId<A, K> { impl<A: KeyAlgorithm, K: KeyName + ?Sized> PartialEq for KeyId<A, K> {
@ -98,3 +111,5 @@ impl<A: KeyAlgorithm, K: KeyName + ?Sized> Hash for KeyId<A, K> {
pub trait KeyAlgorithm: for<'a> From<&'a str> + AsRef<str> {} pub trait KeyAlgorithm: for<'a> From<&'a str> + AsRef<str> {}
impl KeyAlgorithm for SigningKeyAlgorithm {} impl KeyAlgorithm for SigningKeyAlgorithm {}
impl KeyAlgorithm for OneTimeKeyAlgorithm {}

View File

@ -0,0 +1,25 @@
use ruma_macros::IdZst;
use super::{IdParseError, KeyName};
/// The name of a [one-time or fallback key].
///
/// One-time and fallback key names in Matrix are completely opaque character sequences. This
/// type is provided simply for its semantic value.
///
/// [one-time or fallback key]: https://spec.matrix.org/latest/client-server-api/#one-time-and-fallback-keys
#[repr(transparent)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, IdZst)]
pub struct OneTimeKeyName(str);
impl KeyName for OneTimeKeyName {
fn validate(_s: &str) -> Result<(), IdParseError> {
Ok(())
}
}
impl KeyName for OwnedOneTimeKeyName {
fn validate(_s: &str) -> Result<(), IdParseError> {
Ok(())
}
}

View File

@ -4,6 +4,9 @@ Breaking changes:
- Remove the unused `KeyObject` struct. It is actually supposed to be the same type - Remove the unused `KeyObject` struct. It is actually supposed to be the same type
as `ruma_common::encryption::SignedKey`. as `ruma_common::encryption::SignedKey`.
- Use `OwnedOneTimeKeyId` and `OneTimeKeyAlgorithm` instead of
`OwnedDeviceKeyId` and `DeviceKeyAlgorithm` respectively to identify one-time
and fallback keys and their algorithm.
Bug fixes: Bug fixes:

View File

@ -14,7 +14,7 @@ pub mod v1 {
encryption::OneTimeKey, encryption::OneTimeKey,
metadata, metadata,
serde::Raw, serde::Raw,
DeviceKeyAlgorithm, OwnedDeviceId, OwnedDeviceKeyId, OwnedUserId, OneTimeKeyAlgorithm, OwnedDeviceId, OwnedOneTimeKeyId, OwnedUserId,
}; };
const METADATA: Metadata = metadata! { const METADATA: Metadata = metadata! {
@ -55,9 +55,11 @@ pub mod v1 {
} }
/// A claim for one time keys /// A claim for one time keys
pub type OneTimeKeyClaims = BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, DeviceKeyAlgorithm>>; pub type OneTimeKeyClaims = BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, OneTimeKeyAlgorithm>>;
/// One time keys for use in pre-key messages /// One time keys for use in pre-key messages
pub type OneTimeKeys = pub type OneTimeKeys = BTreeMap<
BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceId, BTreeMap<OwnedDeviceKeyId, Raw<OneTimeKey>>>>; OwnedUserId,
BTreeMap<OwnedDeviceId, BTreeMap<OwnedOneTimeKeyId, Raw<OneTimeKey>>>,
>;
} }