identifiers: Differentiate signing keys from device keys
Use OwnedCrossSigningKeyId, OwnedDeviceSigningKeyId and OwnedCrossSigningOrDeviceSigningKeyId instead of OwnedDeviceKeyId to identify signing keys.
This commit is contained in:
parent
09ff0b2819
commit
7f8f89eff7
@ -21,6 +21,9 @@ Breaking changes:
|
|||||||
- Use `OwnedOneTimeKeyId` and `OneTimeKeyAlgorithm` instead of
|
- Use `OwnedOneTimeKeyId` and `OneTimeKeyAlgorithm` instead of
|
||||||
`OwnedDeviceKeyId` and `DeviceKeyAlgorithm` respectively to identify one-time
|
`OwnedDeviceKeyId` and `DeviceKeyAlgorithm` respectively to identify one-time
|
||||||
and fallback keys and their algorithm.
|
and fallback keys and their algorithm.
|
||||||
|
- Use `OwnedCrossSigningOrDeviceSigningKeyId` instead of `OwnedDeviceKeyId` to
|
||||||
|
identify signing keys in `BackupAlgorithm::MegolmBackupV1Curve25519AesSha2`'s
|
||||||
|
`signatures`.
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ use std::collections::BTreeMap;
|
|||||||
use js_int::UInt;
|
use js_int::UInt;
|
||||||
use ruma_common::{
|
use ruma_common::{
|
||||||
serde::{Base64, Raw},
|
serde::{Base64, Raw},
|
||||||
OwnedDeviceKeyId, OwnedUserId,
|
OwnedCrossSigningOrDeviceSigningKeyId, OwnedUserId,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ pub enum BackupAlgorithm {
|
|||||||
public_key: Base64,
|
public_key: Base64,
|
||||||
|
|
||||||
/// Signatures of the auth_data as Signed JSON.
|
/// Signatures of the auth_data as Signed JSON.
|
||||||
signatures: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceKeyId, String>>,
|
signatures: BTreeMap<OwnedUserId, BTreeMap<OwnedCrossSigningOrDeviceSigningKeyId, String>>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,13 @@ Breaking changes:
|
|||||||
`Signatures::insert` is now dereferenced to `BTreeMap::insert`.
|
`Signatures::insert` is now dereferenced to `BTreeMap::insert`.
|
||||||
- Move the `DeviceKeyAlgorithm::SignedCurve25519` into the new
|
- Move the `DeviceKeyAlgorithm::SignedCurve25519` into the new
|
||||||
`OneTimeKeyAlgorithm` type.
|
`OneTimeKeyAlgorithm` type.
|
||||||
|
- Add `(Owned)CrossSigningKeyId` and use it instead of `OwnedDeviceKeyId` to
|
||||||
|
identify `CrossSigningKey`'s `keys`.
|
||||||
|
- Add `(Owned)CrossSigningOrDeviceSigningKeyId` and use it instead of
|
||||||
|
`OwnedDeviceKeyId` to identify signing keys in `DeviceKeys`'s and
|
||||||
|
`CrossSigningKey`'s `signatures`.
|
||||||
|
- Use `OwnedDeviceSigningKeyId` instead of `OwnedDeviceKeyId` to identify
|
||||||
|
signing keys in `SignedKey`'s `signatures`.
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
|
|
||||||
@ -49,6 +56,10 @@ Improvements:
|
|||||||
`(entity, key_identifier, value)` tuples.
|
`(entity, key_identifier, value)` tuples.
|
||||||
- Add `(Owned)OneTimeKeyId` and `(Owned)OneTimeKeyName` to identify one-time and
|
- Add `(Owned)OneTimeKeyId` and `(Owned)OneTimeKeyName` to identify one-time and
|
||||||
fallback keys instead of using `(Owned)DeviceKeyId`.
|
fallback keys instead of using `(Owned)DeviceKeyId`.
|
||||||
|
- Add `(Owned)Base64PublicKey` and `(Owned)Base64PublicKeyOrDeviceId` to
|
||||||
|
identify cross-signing keys.
|
||||||
|
- Add `(owned_)base_64_public_key` to construct a compile-time validated
|
||||||
|
`(Owned)Base64PublicKey`.
|
||||||
|
|
||||||
# 0.13.0
|
# 0.13.0
|
||||||
|
|
||||||
|
@ -8,7 +8,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
serde::{Base64, StringEnum},
|
serde::{Base64, StringEnum},
|
||||||
EventEncryptionAlgorithm, OwnedDeviceId, OwnedDeviceKeyId, OwnedUserId, PrivOwnedStr,
|
EventEncryptionAlgorithm, OwnedCrossSigningKeyId, OwnedCrossSigningOrDeviceSigningKeyId,
|
||||||
|
OwnedDeviceId, OwnedDeviceKeyId, OwnedDeviceSigningKeyId, OwnedUserId, PrivOwnedStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Identity keys for a device.
|
/// Identity keys for a device.
|
||||||
@ -32,7 +33,7 @@ pub struct DeviceKeys {
|
|||||||
pub keys: BTreeMap<OwnedDeviceKeyId, String>,
|
pub keys: BTreeMap<OwnedDeviceKeyId, String>,
|
||||||
|
|
||||||
/// Signatures for the device key object.
|
/// Signatures for the device key object.
|
||||||
pub signatures: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceKeyId, String>>,
|
pub signatures: BTreeMap<OwnedUserId, BTreeMap<OwnedCrossSigningOrDeviceSigningKeyId, String>>,
|
||||||
|
|
||||||
/// Additional data added to the device key information by intermediate servers, and
|
/// Additional data added to the device key information by intermediate servers, and
|
||||||
/// not covered by the signatures.
|
/// not covered by the signatures.
|
||||||
@ -48,7 +49,7 @@ impl DeviceKeys {
|
|||||||
device_id: OwnedDeviceId,
|
device_id: OwnedDeviceId,
|
||||||
algorithms: Vec<EventEncryptionAlgorithm>,
|
algorithms: Vec<EventEncryptionAlgorithm>,
|
||||||
keys: BTreeMap<OwnedDeviceKeyId, String>,
|
keys: BTreeMap<OwnedDeviceKeyId, String>,
|
||||||
signatures: BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceKeyId, String>>,
|
signatures: BTreeMap<OwnedUserId, BTreeMap<OwnedCrossSigningOrDeviceSigningKeyId, String>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { user_id, device_id, algorithms, keys, signatures, unsigned: Default::default() }
|
Self { user_id, device_id, algorithms, keys, signatures, unsigned: Default::default() }
|
||||||
}
|
}
|
||||||
@ -76,7 +77,7 @@ impl UnsignedDeviceInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Signatures for a `SignedKey` object.
|
/// Signatures for a `SignedKey` object.
|
||||||
pub type SignedKeySignatures = BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceKeyId, String>>;
|
pub type SignedKeySignatures = BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceSigningKeyId, String>>;
|
||||||
|
|
||||||
/// A key for the SignedCurve25519 algorithm
|
/// A key for the SignedCurve25519 algorithm
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
@ -118,9 +119,12 @@ pub enum OneTimeKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Signatures for a `CrossSigningKey` object.
|
/// Signatures for a `CrossSigningKey` object.
|
||||||
pub type CrossSigningKeySignatures = BTreeMap<OwnedUserId, BTreeMap<OwnedDeviceKeyId, String>>;
|
pub type CrossSigningKeySignatures =
|
||||||
|
BTreeMap<OwnedUserId, BTreeMap<OwnedCrossSigningOrDeviceSigningKeyId, String>>;
|
||||||
|
|
||||||
/// A cross signing key.
|
/// A [cross-signing] key.
|
||||||
|
///
|
||||||
|
/// [cross-signing]: https://spec.matrix.org/latest/client-server-api/#cross-signing
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||||
pub struct CrossSigningKey {
|
pub struct CrossSigningKey {
|
||||||
@ -133,11 +137,15 @@ pub struct CrossSigningKey {
|
|||||||
/// The public key.
|
/// The public key.
|
||||||
///
|
///
|
||||||
/// The object must have exactly one property.
|
/// The object must have exactly one property.
|
||||||
pub keys: BTreeMap<OwnedDeviceKeyId, String>,
|
pub keys: BTreeMap<OwnedCrossSigningKeyId, String>,
|
||||||
|
|
||||||
/// Signatures of the key.
|
/// Signatures of the key.
|
||||||
///
|
///
|
||||||
/// Only optional for master key.
|
/// The master key should be signed by the device key and can be signed by other users'
|
||||||
|
/// user-signing key. The user-signing and self-signing keys must be signed by the master
|
||||||
|
/// key.
|
||||||
|
///
|
||||||
|
/// Only optional for the master key.
|
||||||
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
|
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
|
||||||
pub signatures: CrossSigningKeySignatures,
|
pub signatures: CrossSigningKeySignatures,
|
||||||
}
|
}
|
||||||
@ -147,7 +155,7 @@ impl CrossSigningKey {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
user_id: OwnedUserId,
|
user_id: OwnedUserId,
|
||||||
usage: Vec<KeyUsage>,
|
usage: Vec<KeyUsage>,
|
||||||
keys: BTreeMap<OwnedDeviceKeyId, String>,
|
keys: BTreeMap<OwnedCrossSigningKeyId, String>,
|
||||||
signatures: CrossSigningKeySignatures,
|
signatures: CrossSigningKeySignatures,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { user_id, usage, keys, signatures }
|
Self { user_id, usage, keys, signatures }
|
||||||
|
@ -16,6 +16,8 @@ use serde::de::{self, Deserializer, Unexpected};
|
|||||||
|
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use self::{
|
pub use self::{
|
||||||
|
base64_public_key::{Base64PublicKey, OwnedBase64PublicKey},
|
||||||
|
base64_public_key_or_device_id::{Base64PublicKeyOrDeviceId, OwnedBase64PublicKeyOrDeviceId},
|
||||||
client_secret::{ClientSecret, OwnedClientSecret},
|
client_secret::{ClientSecret, OwnedClientSecret},
|
||||||
crypto_algorithms::{
|
crypto_algorithms::{
|
||||||
DeviceKeyAlgorithm, EventEncryptionAlgorithm, KeyDerivationAlgorithm, OneTimeKeyAlgorithm,
|
DeviceKeyAlgorithm, EventEncryptionAlgorithm, KeyDerivationAlgorithm, OneTimeKeyAlgorithm,
|
||||||
@ -25,9 +27,10 @@ pub use self::{
|
|||||||
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, OneTimeKeyId, OwnedDeviceSigningKeyId, OwnedKeyId,
|
CrossSigningKeyId, CrossSigningOrDeviceSigningKeyId, DeviceSigningKeyId, KeyAlgorithm,
|
||||||
OwnedOneTimeKeyId, OwnedServerSigningKeyId, OwnedSigningKeyId, ServerSigningKeyId,
|
KeyId, OneTimeKeyId, OwnedCrossSigningKeyId, OwnedCrossSigningOrDeviceSigningKeyId,
|
||||||
SigningKeyId,
|
OwnedDeviceSigningKeyId, OwnedKeyId, OwnedOneTimeKeyId, OwnedServerSigningKeyId,
|
||||||
|
OwnedSigningKeyId, ServerSigningKeyId, SigningKeyId,
|
||||||
},
|
},
|
||||||
matrix_uri::{MatrixToUri, MatrixUri},
|
matrix_uri::{MatrixToUri, MatrixUri},
|
||||||
mxc_uri::{Mxc, MxcUri, OwnedMxcUri},
|
mxc_uri::{Mxc, MxcUri, OwnedMxcUri},
|
||||||
@ -49,6 +52,8 @@ pub use self::{
|
|||||||
pub mod matrix_uri;
|
pub mod matrix_uri;
|
||||||
pub mod user_id;
|
pub mod user_id;
|
||||||
|
|
||||||
|
mod base64_public_key;
|
||||||
|
mod base64_public_key_or_device_id;
|
||||||
mod client_secret;
|
mod client_secret;
|
||||||
mod crypto_algorithms;
|
mod crypto_algorithms;
|
||||||
mod device_id;
|
mod device_id;
|
||||||
@ -113,8 +118,8 @@ macro_rules! owned_device_id {
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod __private_macros {
|
pub mod __private_macros {
|
||||||
pub use ruma_macros::{
|
pub use ruma_macros::{
|
||||||
device_key_id, event_id, mxc_uri, room_alias_id, room_id, room_version_id, server_name,
|
base64_public_key, device_key_id, event_id, mxc_uri, room_alias_id, room_id,
|
||||||
server_signing_key_version, user_id,
|
room_version_id, server_name, server_signing_key_version, user_id,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,3 +279,19 @@ macro_rules! owned_user_id {
|
|||||||
$crate::user_id!($s).to_owned()
|
$crate::user_id!($s).to_owned()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compile-time checked [`Base64PublicKey`] construction.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! base64_public_key {
|
||||||
|
($s:literal) => {
|
||||||
|
$crate::__private_macros::base64_public_key!($crate, $s)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compile-time checked [`OwnedBase64PublicKey`] construction.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! owned_base64_public_key {
|
||||||
|
($s:literal) => {
|
||||||
|
$crate::base64_public_key!($s).to_owned()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
84
crates/ruma-common/src/identifiers/base64_public_key.rs
Normal file
84
crates/ruma-common/src/identifiers/base64_public_key.rs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
use ruma_macros::IdZst;
|
||||||
|
|
||||||
|
use super::{IdParseError, KeyName};
|
||||||
|
use crate::serde::{base64::Standard, Base64, Base64DecodeError};
|
||||||
|
|
||||||
|
/// A public key encoded using unpadded base64, used as an identifier for [cross-signing] keys.
|
||||||
|
///
|
||||||
|
/// This string is validated using the set `[a-zA-Z0-9+/=]`, but it is not validated to be decodable
|
||||||
|
/// as base64. This type is provided simply for its semantic value.
|
||||||
|
///
|
||||||
|
/// [cross-signing]: https://spec.matrix.org/latest/client-server-api/#cross-signing
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, IdZst)]
|
||||||
|
#[ruma_id(validate = ruma_identifiers_validation::base64_public_key::validate)]
|
||||||
|
pub struct Base64PublicKey(str);
|
||||||
|
|
||||||
|
impl OwnedBase64PublicKey {
|
||||||
|
/// Construct a new `OwnedBase64PublicKey` by encoding the given bytes using unpadded base64.
|
||||||
|
pub fn with_bytes<B: AsRef<[u8]>>(bytes: B) -> OwnedBase64PublicKey {
|
||||||
|
Base64::<Standard, B>::new(bytes).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyName for Base64PublicKey {
|
||||||
|
fn validate(s: &str) -> Result<(), IdParseError> {
|
||||||
|
ruma_identifiers_validation::base64_public_key::validate(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyName for OwnedBase64PublicKey {
|
||||||
|
fn validate(s: &str) -> Result<(), IdParseError> {
|
||||||
|
ruma_identifiers_validation::base64_public_key::validate(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: AsRef<[u8]>> From<Base64<Standard, B>> for OwnedBase64PublicKey {
|
||||||
|
fn from(value: Base64<Standard, B>) -> Self {
|
||||||
|
value.to_string().try_into().unwrap_or_else(|_| unreachable!())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&Base64PublicKey> for Base64<Standard, Vec<u8>> {
|
||||||
|
type Error = Base64DecodeError;
|
||||||
|
|
||||||
|
fn try_from(value: &Base64PublicKey) -> Result<Self, Self::Error> {
|
||||||
|
Base64::parse(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&OwnedBase64PublicKey> for Base64<Standard, Vec<u8>> {
|
||||||
|
type Error = Base64DecodeError;
|
||||||
|
|
||||||
|
fn try_from(value: &OwnedBase64PublicKey) -> Result<Self, Self::Error> {
|
||||||
|
Base64::parse(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<OwnedBase64PublicKey> for Base64<Standard, Vec<u8>> {
|
||||||
|
type Error = Base64DecodeError;
|
||||||
|
|
||||||
|
fn try_from(value: OwnedBase64PublicKey) -> Result<Self, Self::Error> {
|
||||||
|
Base64::parse(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::{Base64PublicKey, OwnedBase64PublicKey};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn valid_string() {
|
||||||
|
<&Base64PublicKey>::try_from("base64+master+public+key").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn invalid_string() {
|
||||||
|
<&Base64PublicKey>::try_from("not@base@64").unwrap_err();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn constructor() {
|
||||||
|
_ = OwnedBase64PublicKey::with_bytes(b"self-signing master public key");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
use ruma_macros::IdZst;
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
Base64PublicKey, DeviceId, IdParseError, KeyName, OwnedBase64PublicKey, OwnedDeviceId,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A Matrix ID that can be either a [`DeviceId`] or a [`Base64PublicKey`].
|
||||||
|
///
|
||||||
|
/// Device identifiers in Matrix are completely opaque character sequences and cross-signing keys
|
||||||
|
/// are identified by their base64-encoded public key. This type is provided simply for its semantic
|
||||||
|
/// value.
|
||||||
|
///
|
||||||
|
/// It is not recommended to construct this type directly, it should instead be converted from a
|
||||||
|
/// [`DeviceId`] or a [`Base64PublicKey`].
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use ruma_common::{Base64PublicKeyOrDeviceId, OwnedBase64PublicKeyOrDeviceId};
|
||||||
|
///
|
||||||
|
/// let ref_id: &Base64PublicKeyOrDeviceId = "abcdefghi".into();
|
||||||
|
/// assert_eq!(ref_id.as_str(), "abcdefghi");
|
||||||
|
///
|
||||||
|
/// let owned_id: OwnedBase64PublicKeyOrDeviceId = "ijklmnop".into();
|
||||||
|
/// assert_eq!(owned_id.as_str(), "ijklmnop");
|
||||||
|
/// ```
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, IdZst)]
|
||||||
|
pub struct Base64PublicKeyOrDeviceId(str);
|
||||||
|
|
||||||
|
impl KeyName for Base64PublicKeyOrDeviceId {
|
||||||
|
fn validate(_s: &str) -> Result<(), IdParseError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyName for OwnedBase64PublicKeyOrDeviceId {
|
||||||
|
fn validate(_s: &str) -> Result<(), IdParseError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a DeviceId> for &'a Base64PublicKeyOrDeviceId {
|
||||||
|
fn from(value: &'a DeviceId) -> Self {
|
||||||
|
Self::from(value.as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<OwnedDeviceId> for OwnedBase64PublicKeyOrDeviceId {
|
||||||
|
fn from(value: OwnedDeviceId) -> Self {
|
||||||
|
Self::from(value.as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a Base64PublicKey> for &'a Base64PublicKeyOrDeviceId {
|
||||||
|
fn from(value: &'a Base64PublicKey) -> Self {
|
||||||
|
Self::from(value.as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<OwnedBase64PublicKey> for OwnedBase64PublicKeyOrDeviceId {
|
||||||
|
fn from(value: OwnedBase64PublicKey) -> Self {
|
||||||
|
Self::from(value.as_str())
|
||||||
|
}
|
||||||
|
}
|
@ -7,8 +7,8 @@ use std::{
|
|||||||
use ruma_macros::IdZst;
|
use ruma_macros::IdZst;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
crypto_algorithms::SigningKeyAlgorithm, DeviceId, KeyName, OneTimeKeyAlgorithm, OneTimeKeyName,
|
crypto_algorithms::SigningKeyAlgorithm, Base64PublicKey, Base64PublicKeyOrDeviceId, DeviceId,
|
||||||
ServerSigningKeyVersion,
|
KeyName, OneTimeKeyAlgorithm, OneTimeKeyName, ServerSigningKeyVersion,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A key algorithm and key name delimited by a colon.
|
/// A key algorithm and key name delimited by a colon.
|
||||||
@ -63,12 +63,38 @@ pub type ServerSigningKeyId = SigningKeyId<ServerSigningKeyVersion>;
|
|||||||
/// Algorithm + key name for homeserver signing keys.
|
/// Algorithm + key name for homeserver signing keys.
|
||||||
pub type OwnedServerSigningKeyId = OwnedSigningKeyId<ServerSigningKeyVersion>;
|
pub type OwnedServerSigningKeyId = OwnedSigningKeyId<ServerSigningKeyVersion>;
|
||||||
|
|
||||||
/// Algorithm + key name for device keys.
|
/// Algorithm + key name for [device signing keys].
|
||||||
|
///
|
||||||
|
/// [device signing keys]: https://spec.matrix.org/latest/client-server-api/#device-keys
|
||||||
pub type DeviceSigningKeyId = SigningKeyId<DeviceId>;
|
pub type DeviceSigningKeyId = SigningKeyId<DeviceId>;
|
||||||
|
|
||||||
/// Algorithm + key name for device keys.
|
/// Algorithm + key name for [device signing] keys.
|
||||||
|
///
|
||||||
|
/// [device signing keys]: https://spec.matrix.org/latest/client-server-api/#device-keys
|
||||||
pub type OwnedDeviceSigningKeyId = OwnedSigningKeyId<DeviceId>;
|
pub type OwnedDeviceSigningKeyId = OwnedSigningKeyId<DeviceId>;
|
||||||
|
|
||||||
|
/// Algorithm + key name for [cross-signing] keys.
|
||||||
|
///
|
||||||
|
/// [cross-signing]: https://spec.matrix.org/latest/client-server-api/#cross-signing
|
||||||
|
pub type CrossSigningKeyId = SigningKeyId<Base64PublicKey>;
|
||||||
|
|
||||||
|
/// Algorithm + key name for [cross-signing] keys.
|
||||||
|
///
|
||||||
|
/// [cross-signing]: https://spec.matrix.org/latest/client-server-api/#cross-signing
|
||||||
|
pub type OwnedCrossSigningKeyId = OwnedSigningKeyId<Base64PublicKey>;
|
||||||
|
|
||||||
|
/// Algorithm + key name for [cross-signing] or [device signing] keys.
|
||||||
|
///
|
||||||
|
/// [cross-signing]: https://spec.matrix.org/latest/client-server-api/#cross-signing
|
||||||
|
/// [device signing]: https://spec.matrix.org/latest/client-server-api/#device-keys
|
||||||
|
pub type CrossSigningOrDeviceSigningKeyId = SigningKeyId<Base64PublicKeyOrDeviceId>;
|
||||||
|
|
||||||
|
/// Algorithm + key name for [cross-signing] or [device signing] keys.
|
||||||
|
///
|
||||||
|
/// [cross-signing]: https://spec.matrix.org/latest/client-server-api/#cross-signing
|
||||||
|
/// [device signing]: https://spec.matrix.org/latest/client-server-api/#device-keys
|
||||||
|
pub type OwnedCrossSigningOrDeviceSigningKeyId = OwnedSigningKeyId<Base64PublicKeyOrDeviceId>;
|
||||||
|
|
||||||
/// Algorithm + key name for [one-time and fallback keys].
|
/// 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
|
/// [one-time and fallback keys]: https://spec.matrix.org/latest/client-server-api/#one-time-and-fallback-keys
|
||||||
|
@ -11,6 +11,7 @@ Breaking changes:
|
|||||||
Improvements:
|
Improvements:
|
||||||
|
|
||||||
- Add `server_signing_key_version::validate`.
|
- Add `server_signing_key_version::validate`.
|
||||||
|
- Add `base64_public_key::validate`.
|
||||||
|
|
||||||
# 0.9.5
|
# 0.9.5
|
||||||
|
|
||||||
|
10
crates/ruma-identifiers-validation/src/base64_public_key.rs
Normal file
10
crates/ruma-identifiers-validation/src/base64_public_key.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
use crate::Error;
|
||||||
|
|
||||||
|
pub fn validate(s: &str) -> Result<(), Error> {
|
||||||
|
if s.is_empty() {
|
||||||
|
return Err(Error::Empty);
|
||||||
|
} else if !s.chars().all(|c| c.is_alphanumeric() || matches!(c, '+' | '/' | '=')) {
|
||||||
|
return Err(Error::InvalidCharacters);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
#![doc(html_favicon_url = "https://ruma.dev/favicon.ico")]
|
#![doc(html_favicon_url = "https://ruma.dev/favicon.ico")]
|
||||||
#![doc(html_logo_url = "https://ruma.dev/images/logo.png")]
|
#![doc(html_logo_url = "https://ruma.dev/images/logo.png")]
|
||||||
|
|
||||||
|
pub mod base64_public_key;
|
||||||
pub mod client_secret;
|
pub mod client_secret;
|
||||||
pub mod device_key_id;
|
pub mod device_key_id;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
@ -15,8 +15,8 @@ use proc_macro::TokenStream;
|
|||||||
use proc_macro2 as pm2;
|
use proc_macro2 as pm2;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use ruma_identifiers_validation::{
|
use ruma_identifiers_validation::{
|
||||||
device_key_id, event_id, mxc_uri, room_alias_id, room_id, room_version_id, server_name,
|
base64_public_key, device_key_id, event_id, mxc_uri, room_alias_id, room_id, room_version_id,
|
||||||
server_signing_key_version, user_id,
|
server_name, server_signing_key_version, user_id,
|
||||||
};
|
};
|
||||||
use syn::{parse_macro_input, DeriveInput, ItemEnum, ItemStruct};
|
use syn::{parse_macro_input, DeriveInput, ItemEnum, ItemStruct};
|
||||||
|
|
||||||
@ -266,6 +266,19 @@ pub fn user_id(input: TokenStream) -> TokenStream {
|
|||||||
output.into()
|
output.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compile-time checked `Base64PublicKey` construction.
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn base64_public_key(input: TokenStream) -> TokenStream {
|
||||||
|
let IdentifierInput { dollar_crate, id } = parse_macro_input!(input as IdentifierInput);
|
||||||
|
assert!(base64_public_key::validate(&id.value()).is_ok(), "Invalid base64 public key");
|
||||||
|
|
||||||
|
let output = quote! {
|
||||||
|
<&#dollar_crate::DeviceKeyId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
output.into()
|
||||||
|
}
|
||||||
|
|
||||||
/// Derive the `AsRef<str>` trait for an enum.
|
/// Derive the `AsRef<str>` trait for an enum.
|
||||||
#[proc_macro_derive(AsRefStr, attributes(ruma_enum))]
|
#[proc_macro_derive(AsRefStr, attributes(ruma_enum))]
|
||||||
pub fn derive_enum_as_ref_str(input: TokenStream) -> TokenStream {
|
pub fn derive_enum_as_ref_str(input: TokenStream) -> TokenStream {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user