distill active and old keys for federation key/server response

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk 2024-10-24 05:03:31 +00:00 committed by strawberry
parent c769fcc347
commit aa768b5dec
2 changed files with 47 additions and 10 deletions

View file

@ -1,10 +1,14 @@
use std::{collections::BTreeMap, time::Duration};
use std::{
collections::BTreeMap,
mem::take,
time::{Duration, SystemTime},
};
use axum::{extract::State, response::IntoResponse, Json};
use conduit::{utils::timepoint_from_now, Result};
use ruma::{
api::{
federation::discovery::{get_server_keys, ServerSigningKeys},
federation::discovery::{get_server_keys, OldVerifyKey, ServerSigningKeys},
OutgoingResponse,
},
serde::Raw,
@ -21,21 +25,32 @@ use ruma::{
// signature for the response
pub(crate) async fn get_server_keys_route(State(services): State<crate::State>) -> Result<impl IntoResponse> {
let server_name = services.globals.server_name();
let verify_keys = services.server_keys.verify_keys_for(server_name).await;
let active_key_id = services.server_keys.active_key_id();
let mut all_keys = services.server_keys.verify_keys_for(server_name).await;
let verify_keys = all_keys
.remove_entry(active_key_id)
.expect("active verify_key is missing");
let old_verify_keys = all_keys
.into_iter()
.map(|(id, key)| (id, OldVerifyKey::new(expires_ts(), key.key)))
.collect();
let server_key = ServerSigningKeys {
verify_keys,
verify_keys: [verify_keys].into(),
old_verify_keys,
server_name: server_name.to_owned(),
valid_until_ts: valid_until_ts(),
old_verify_keys: BTreeMap::new(),
signatures: BTreeMap::new(),
};
let response = get_server_keys::v2::Response {
server_key: Raw::new(&server_key)?,
}
.try_into_http_response::<Vec<u8>>()?;
let server_key = Raw::new(&server_key)?;
let mut response = get_server_keys::v2::Response::new(server_key)
.try_into_http_response::<Vec<u8>>()
.map(|mut response| take(response.body_mut()))
.and_then(|body| serde_json::from_slice(&body).map_err(Into::into))?;
let mut response = serde_json::from_slice(response.body())?;
services.server_keys.sign_json(&mut response)?;
Ok(Json(response))
@ -47,6 +62,11 @@ fn valid_until_ts() -> MilliSecondsSinceUnixEpoch {
MilliSecondsSinceUnixEpoch::from_system_time(timepoint).expect("UInt should not overflow")
}
fn expires_ts() -> MilliSecondsSinceUnixEpoch {
let timepoint = SystemTime::now();
MilliSecondsSinceUnixEpoch::from_system_time(timepoint).expect("UInt should not overflow")
}
/// # `GET /_matrix/key/v2/server/{keyId}`
///
/// Gets the public signing keys of this server.