From d59a616e2c363507a89c92f34aa67e86ee2cfb49 Mon Sep 17 00:00:00 2001 From: stoically Date: Mon, 8 Jun 2020 15:48:15 +0200 Subject: [PATCH] federation-api: Add query server key discovery endpoints --- ruma-federation-api/src/discovery.rs | 44 +++++++++++++ .../discovery/get_remote_server_keys/mod.rs | 3 + .../discovery/get_remote_server_keys/v2.rs | 38 +++++++++++ .../get_remote_server_keys_batch/mod.rs | 3 + .../get_remote_server_keys_batch/v2.rs | 65 +++++++++++++++++++ .../src/discovery/get_server_keys/v2.rs | 41 ++---------- ruma-identifiers/src/lib.rs | 8 +-- 7 files changed, 162 insertions(+), 40 deletions(-) create mode 100644 ruma-federation-api/src/discovery/get_remote_server_keys/mod.rs create mode 100644 ruma-federation-api/src/discovery/get_remote_server_keys/v2.rs create mode 100644 ruma-federation-api/src/discovery/get_remote_server_keys_batch/mod.rs create mode 100644 ruma-federation-api/src/discovery/get_remote_server_keys_batch/v2.rs diff --git a/ruma-federation-api/src/discovery.rs b/ruma-federation-api/src/discovery.rs index d09f4583..3f10b609 100644 --- a/ruma-federation-api/src/discovery.rs +++ b/ruma-federation-api/src/discovery.rs @@ -1,5 +1,49 @@ //! Server discovery endpoints. +use std::{collections::BTreeMap, time::SystemTime}; + +use ruma_identifiers::ServerKeyId; +use serde::{Deserialize, Serialize}; + pub mod discover_homeserver; +pub mod get_remote_server_keys; +pub mod get_remote_server_keys_batch; pub mod get_server_keys; pub mod get_server_version; + +/// Public key of the homeserver for verifying digital signatures. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct VerifyKey { + /// The Unpadded Base64 encoded key. + pub key: String, +} + +/// A key the server used to use, but stopped using. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct OldVerifyKey { + /// Timestamp when this key expired. + #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] + pub expired_ts: SystemTime, + /// The Unpadded Base64 encoded key. + pub key: String, +} + +// Spec is wrong, all fields are required (see +// https://github.com/matrix-org/matrix-doc/issues/2508) +/// Queried server key, signed by the notary server. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct ServerKey { + /// DNS name of the homeserver. + pub server_name: String, + /// Public keys of the homeserver for verifying digital signatures. + pub verify_keys: BTreeMap, + /// Public keys that the homeserver used to use and when it stopped using them. + pub old_verify_keys: BTreeMap, + /// Digital signatures of this object signed using the verify_keys. Map of + /// server name to keys by key ID + pub signatures: BTreeMap>, + /// Timestamp when the keys should be refreshed. This field MUST be ignored in room + /// versions 1, 2, 3, and 4. + #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] + pub valid_until_ts: SystemTime, +} diff --git a/ruma-federation-api/src/discovery/get_remote_server_keys/mod.rs b/ruma-federation-api/src/discovery/get_remote_server_keys/mod.rs new file mode 100644 index 00000000..83842f4b --- /dev/null +++ b/ruma-federation-api/src/discovery/get_remote_server_keys/mod.rs @@ -0,0 +1,3 @@ +//! Query for another server's keys. The receiving (notary) server must sign the keys returned by the queried server. + +pub mod v2; diff --git a/ruma-federation-api/src/discovery/get_remote_server_keys/v2.rs b/ruma-federation-api/src/discovery/get_remote_server_keys/v2.rs new file mode 100644 index 00000000..3da6f328 --- /dev/null +++ b/ruma-federation-api/src/discovery/get_remote_server_keys/v2.rs @@ -0,0 +1,38 @@ +//! [GET /_matrix/key/v2/query/{serverName}/{keyId}](https://matrix.org/docs/spec/server_server/r0.1.4#get-matrix-key-v2-query-servername-keyid) + +use std::time::SystemTime; + +use crate::discovery::ServerKey; +use ruma_api::ruma_api; + +ruma_api! { + metadata { + description: "Query for another server's keys.", + method: GET, + name: "get_remote_server_keys", + path: "/_matrix/key/v2/query/:server_name", + rate_limited: false, + requires_authentication: false, + } + + request { + /// The server's DNS name to query + #[ruma_api(path)] + pub server_name: String, + + /// A millisecond POSIX timestamp in milliseconds indicating when the + /// returned certificates will need to be valid until to be useful to + /// the requesting server. + /// + /// If not supplied, the current time as determined by the notary server + /// is used. + #[ruma_api(query)] + #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] + pub minimum_valid_until_ts: SystemTime, + } + + response { + /// The queried server's keys, signed by the notary server. + pub server_keys: Vec, + } +} diff --git a/ruma-federation-api/src/discovery/get_remote_server_keys_batch/mod.rs b/ruma-federation-api/src/discovery/get_remote_server_keys_batch/mod.rs new file mode 100644 index 00000000..4bec7de9 --- /dev/null +++ b/ruma-federation-api/src/discovery/get_remote_server_keys_batch/mod.rs @@ -0,0 +1,3 @@ +//! Query for keys from multiple servers in a batch format. The receiving (notary) server must sign the keys returned by the queried servers. + +pub mod v2; diff --git a/ruma-federation-api/src/discovery/get_remote_server_keys_batch/v2.rs b/ruma-federation-api/src/discovery/get_remote_server_keys_batch/v2.rs new file mode 100644 index 00000000..9cbda232 --- /dev/null +++ b/ruma-federation-api/src/discovery/get_remote_server_keys_batch/v2.rs @@ -0,0 +1,65 @@ +//! [GET /_matrix/key/v2/query/{serverName}/{keyId}](https://matrix.org/docs/spec/server_server/r0.1.4#get-matrix-key-v2-query-servername-keyid) + +use std::{collections::BTreeMap, time::SystemTime}; + +use crate::discovery::ServerKey; +use ruma_api::ruma_api; +use ruma_identifiers::ServerKeyId; +use serde::{Deserialize, Serialize}; + +ruma_api! { + metadata { + description: "Query for keys from multiple servers in a batch format.", + method: POST, + name: "get_remote_server_keys_batch", + path: "/_matrix/key/v2/query", + rate_limited: false, + requires_authentication: false, + } + + request { + /// The query criteria. The outer string key on the object is the server + /// name (eg: matrix.org). The inner string key is the Key ID to query + /// for the particular server. If no key IDs are given to be queried, + /// the notary server should query for all keys. If no servers are + /// given, the notary server must return an empty server_keys array in + /// the response. + /// + /// The notary server may return multiple keys regardless of the Key IDs + /// given. + #[ruma_api(body)] + pub server_keys: BTreeMap>, + + /// A millisecond POSIX timestamp in milliseconds indicating when the + /// returned certificates will need to be valid until to be useful to + /// the requesting server. + /// + /// If not supplied, the current time as determined by the notary server + /// is used. + #[ruma_api(query)] + #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] + pub minimum_valid_until_ts: SystemTime, + } + + response { + /// The queried server's keys, signed by the notary server. + pub server_keys: Vec, + } +} + +/// The query criteria. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct QueryCriteria { + /// A millisecond POSIX timestamp in milliseconds indicating when the + /// returned certificates will need to be valid until to be useful to the + /// requesting server. + /// + /// If not supplied, the current time as determined by the notary server is + /// used. + #[serde( + default, + skip_serializing_if = "Option::is_none", + with = "ruma_serde::time::opt_ms_since_unix_epoch" + )] + pub minimum_valid_until_ts: Option, +} diff --git a/ruma-federation-api/src/discovery/get_server_keys/v2.rs b/ruma-federation-api/src/discovery/get_server_keys/v2.rs index 73160322..ca59ec67 100644 --- a/ruma-federation-api/src/discovery/get_server_keys/v2.rs +++ b/ruma-federation-api/src/discovery/get_server_keys/v2.rs @@ -1,9 +1,7 @@ -//! [GET /_matrix/key/v2/server](https://matrix.org/docs/spec/server_server/r0.1.3#get-matrix-key-v2-server-keyid) - -use std::{collections::BTreeMap, time::SystemTime}; +//! [GET /_matrix/key/v2/server](https://matrix.org/docs/spec/server_server/r0.1.4#get-matrix-key-v2-server-keyid) +use crate::discovery::ServerKey; use ruma_api::ruma_api; -use serde::{Deserialize, Serialize}; ruma_api! { metadata { @@ -18,37 +16,8 @@ ruma_api! { request {} response { - // Spec is wrong, all fields are required (see - // https://github.com/matrix-org/matrix-doc/issues/2508) - - /// DNS name of the homeserver. - pub server_name: String, - /// Public keys of the homeserver for verifying digital signatures. - pub verify_keys: BTreeMap, - /// Public keys that the homeserver used to use and when it stopped using them. - pub old_verify_keys: BTreeMap, - /// Digital signatures of this object signed using the verify_keys. - pub signatures: BTreeMap>, - /// Timestamp when the keys should be refreshed. This field MUST be ignored in room - /// versions 1, 2, 3, and 4. - #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] - pub valid_until_ts: SystemTime, + /// Queried server key, signed by the notary server. + #[ruma_api(body)] + pub server_key: ServerKey, } } - -/// Public key of the homeserver for verifying digital signatures. -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct VerifyKey { - /// The Unpadded Base64 encoded key. - pub key: String, -} - -/// A key the server used to use, but stopped using. -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct OldVerifyKey { - /// Timestamp when this key expired. - #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] - pub expired_ts: SystemTime, - /// The Unpadded Base64 encoded key. - pub key: String, -} diff --git a/ruma-identifiers/src/lib.rs b/ruma-identifiers/src/lib.rs index 930b2df4..c7ee58b3 100644 --- a/ruma-identifiers/src/lib.rs +++ b/ruma-identifiers/src/lib.rs @@ -40,13 +40,13 @@ pub mod user_id; pub type DeviceKeyAlgorithm = key_algorithms::DeviceKeyAlgorithm; /// An owned device key identifier containing a key algorithm and device ID. -/// +/// /// Can be created via `TryFrom` and `TryFrom<&str>`; implements `Serialize` /// and `Deserialize` if the `serde` feature is enabled. pub type DeviceKeyId = device_key_id::DeviceKeyId>; /// A reference to a device key identifier containing a key algorithm and device ID. -/// +/// /// Can be created via `TryFrom<&str>`; implements `Serialize` and `Deserialize` /// if the `serde` feature is enabled. pub type DeviceKeyIdRef<'a> = device_key_id::DeviceKeyId<&'a str>; @@ -122,14 +122,14 @@ pub type RoomVersionIdRef<'a> = room_version_id::RoomVersionId<&'a str>; pub type ServerKeyAlgorithm = key_algorithms::ServerKeyAlgorithm; /// An owned homeserver signing key identifier containing a key algorithm and version. -/// +/// /// Can be created via `TryFrom` and `TryFrom<&str>`; implements `Serialize` /// and `Deserialize` if the `serde` feature is enabled. pub type ServerKeyId = server_key_id::ServerKeyId>; /// An reference to a homeserver signing key identifier containing a key /// algorithm and version. -/// +/// /// Can be created via `TryFrom<&str>`; implements `Serialize` /// and `Deserialize` if the `serde` feature is enabled. pub type ServerKeyIdRef<'a> = server_key_id::ServerKeyId<&'a str>;