mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-11-13 12:16:54 +00:00
fix: SEC8
Reviewed-By: Ginger <ginger@gingershaped.computer> Reviewed-By: Jade <jade@ellis.link> Reviewed-By: Jacob Taylor <jacob@explodie.org>
This commit is contained in:
33 files changed
+1420
-848
No files matched your search
@@ -324,7 +324,7 @@ async fn validate_invite_state(
|
||||
|
||||
services
|
||||
.server_keys
|
||||
.verify_event(&state_event_json, room_version_rules)
|
||||
.verify_event_json(&state_event_json, room_version_rules)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
err!(Request(InvalidParam("Signature verification failed on invite event: {e}")))
|
||||
|
||||
+48
-38
@@ -1,10 +1,8 @@
|
||||
use std::{
|
||||
mem::take,
|
||||
time::{Duration, SystemTime},
|
||||
};
|
||||
use std::{collections::BTreeMap, mem::take, time::Duration};
|
||||
|
||||
use axum::{Json, extract::State, response::IntoResponse};
|
||||
use conduwuit::{Result, utils::timepoint_from_now};
|
||||
use futures::StreamExt;
|
||||
use ruma::{
|
||||
MilliSecondsSinceUnixEpoch,
|
||||
api::{
|
||||
@@ -14,33 +12,62 @@ use ruma::{
|
||||
assign,
|
||||
serde::Raw,
|
||||
};
|
||||
use service::{server_keys, server_keys::in_one_week};
|
||||
|
||||
/// # `GET /_matrix/key/v2/server`
|
||||
///
|
||||
/// Gets the public signing keys of this server.
|
||||
///
|
||||
/// - Matrix does not support invalidating public keys, so the key returned by
|
||||
/// this will be valid forever.
|
||||
// Response type for this endpoint is Json because we need to calculate a
|
||||
// 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 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 = BTreeMap::from([services.server_keys.active_verify_key()]);
|
||||
|
||||
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 old_verify_keys = if let Some(k) = &services.config.old_verify_keys {
|
||||
k.to_owned()
|
||||
} else {
|
||||
// We need to figure out any old signing keys we've acquired from
|
||||
// notaries.
|
||||
let mut keys = services.server_keys.signing_keys_for(server_name);
|
||||
let mut old_keys = BTreeMap::new();
|
||||
while let Some(resp) = keys.next().await {
|
||||
// We need to verify that this response is still trusted based on
|
||||
// the current configuration. It's possible we got this response
|
||||
// from a notary who we no longer trust.
|
||||
if resp.valid_until_ts > in_one_week() {
|
||||
continue;
|
||||
}
|
||||
let trusted = services.config.trusted_servers.iter().any(|notary| {
|
||||
server_keys::Service::verify_server_keys_response(
|
||||
&resp,
|
||||
Some((notary.server_name(), notary.verify_keys())),
|
||||
)
|
||||
.is_ok()
|
||||
});
|
||||
if !trusted {
|
||||
continue;
|
||||
}
|
||||
for (old_key_id, old_key) in resp.old_verify_keys {
|
||||
if old_key.expired_ts > resp.valid_until_ts {
|
||||
// This key expired in the future which is probably illegal
|
||||
continue;
|
||||
}
|
||||
old_keys
|
||||
.entry(old_key_id)
|
||||
.and_modify(|current_old_key: &mut OldVerifyKey| {
|
||||
// Use the lowest expiry timestamp
|
||||
if current_old_key.expired_ts > old_key.expired_ts {
|
||||
*current_old_key = old_key.clone();
|
||||
}
|
||||
})
|
||||
.or_insert(old_key);
|
||||
}
|
||||
}
|
||||
old_keys
|
||||
};
|
||||
|
||||
let server_key = assign!(ServerSigningKeys::new(server_name.to_owned(), valid_until_ts()), {
|
||||
verify_keys: [verify_keys].into(),
|
||||
verify_keys,
|
||||
old_verify_keys,
|
||||
});
|
||||
|
||||
@@ -56,24 +83,7 @@ pub(crate) async fn get_server_keys_route(
|
||||
}
|
||||
|
||||
fn valid_until_ts() -> MilliSecondsSinceUnixEpoch {
|
||||
let dur = Duration::from_hours(168);
|
||||
let dur = Duration::from_hours(12);
|
||||
let timepoint = timepoint_from_now(dur).expect("SystemTime should not overflow");
|
||||
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.
|
||||
///
|
||||
/// - Matrix does not support invalidating public keys, so the key returned by
|
||||
/// this will be valid forever.
|
||||
pub(crate) async fn get_server_keys_deprecated_route(
|
||||
State(services): State<crate::State>,
|
||||
) -> impl IntoResponse {
|
||||
get_server_keys_route(State(services)).await
|
||||
}
|
||||
@@ -142,7 +142,7 @@ pub(crate) async fn validate_any_membership_event(
|
||||
|
||||
services
|
||||
.server_keys
|
||||
.verify_event(&pdu, room_version_rules)
|
||||
.verify_event_json(&pdu, room_version_rules)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
err!(Request(InvalidParam("Signature verification failed on membership event: {e}")))
|
||||
|
||||
Reference in new issue
Block a user