diff --git a/crates/ruma-signatures/src/functions.rs b/crates/ruma-signatures/src/functions.rs index f767475b..605cdf74 100644 --- a/crates/ruma-signatures/src/functions.rs +++ b/crates/ruma-signatures/src/functions.rs @@ -10,7 +10,8 @@ use base64::{alphabet, Engine}; use ruma_common::{ canonical_json::{redact, JsonType}, serde::{base64::Standard, Base64}, - CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, OwnedServerName, RoomVersionId, UserId, + CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, OwnedServerName, + OwnedServerSigningKeyId, RoomVersionId, UserId, }; use serde_json::to_string as to_json_string; use sha2::{digest::Digest, Sha256}; @@ -632,6 +633,34 @@ fn canonical_json_with_fields_to_remove( to_json_string(&owned_object).map_err(|e| Error::Json(e.into())) } +/// Extracts the server names and key ids to check signatures for given event. +pub fn required_keys( + object: &CanonicalJsonObject, + version: &RoomVersionId, +) -> Result>, Error> { + use CanonicalJsonValue::Object; + + let mut map = BTreeMap::>::new(); + let Some(Object(signatures)) = object.get("signatures") else { + return Ok(map); + }; + + for server in servers_to_check_signatures(object, version)? { + let Some(Object(set)) = signatures.get(server.as_str()) else { + continue; + }; + + let entry = map.entry(server.clone()).or_default(); + set.into_iter() + .map(|(k, _)| k.clone()) + .map(TryInto::try_into) + .filter_map(Result::ok) + .for_each(|key_id| entry.push(key_id)); + } + + Ok(map) +} + /// Extracts the server names to check signatures for given event. /// /// It will return the sender's server (unless it's a third party invite) and the event id server @@ -639,7 +668,7 @@ fn canonical_json_with_fields_to_remove( /// /// Starting with room version 8, if join_authorised_via_users_server is present, a signature from /// that user is required. -fn servers_to_check_signatures( +pub fn servers_to_check_signatures( object: &CanonicalJsonObject, version: &RoomVersionId, ) -> Result, Error> { diff --git a/crates/ruma-signatures/src/lib.rs b/crates/ruma-signatures/src/lib.rs index b4c06883..20fa372a 100644 --- a/crates/ruma-signatures/src/lib.rs +++ b/crates/ruma-signatures/src/lib.rs @@ -49,8 +49,8 @@ use ruma_common::serde::{AsRefStr, DisplayAsRefStr}; pub use self::{ error::{Error, JsonError, ParseError, VerificationError}, functions::{ - canonical_json, content_hash, hash_and_sign_event, reference_hash, sign_json, verify_event, - verify_json, + canonical_json, content_hash, hash_and_sign_event, reference_hash, required_keys, + servers_to_check_signatures, sign_json, verify_event, verify_json, }, keys::{Ed25519KeyPair, KeyPair, PublicKeyMap, PublicKeySet}, signatures::Signature,