add required_keys util to signatures

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk 2024-10-12 07:38:11 +00:00
parent 90fb81eabe
commit d7baeb7e5c
2 changed files with 33 additions and 4 deletions

View File

@ -10,7 +10,8 @@ use base64::{alphabet, Engine};
use ruma_common::{ use ruma_common::{
canonical_json::{redact, JsonType}, canonical_json::{redact, JsonType},
serde::{base64::Standard, Base64}, 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 serde_json::to_string as to_json_string;
use sha2::{digest::Digest, Sha256}; 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())) 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<BTreeMap<OwnedServerName, Vec<OwnedServerSigningKeyId>>, Error> {
use CanonicalJsonValue::Object;
let mut map = BTreeMap::<OwnedServerName, Vec<OwnedServerSigningKeyId>>::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. /// 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 /// 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 /// Starting with room version 8, if join_authorised_via_users_server is present, a signature from
/// that user is required. /// that user is required.
fn servers_to_check_signatures( pub fn servers_to_check_signatures(
object: &CanonicalJsonObject, object: &CanonicalJsonObject,
version: &RoomVersionId, version: &RoomVersionId,
) -> Result<BTreeSet<OwnedServerName>, Error> { ) -> Result<BTreeSet<OwnedServerName>, Error> {

View File

@ -49,8 +49,8 @@ use ruma_common::serde::{AsRefStr, DisplayAsRefStr};
pub use self::{ pub use self::{
error::{Error, JsonError, ParseError, VerificationError}, error::{Error, JsonError, ParseError, VerificationError},
functions::{ functions::{
canonical_json, content_hash, hash_and_sign_event, reference_hash, sign_json, verify_event, canonical_json, content_hash, hash_and_sign_event, reference_hash, required_keys,
verify_json, servers_to_check_signatures, sign_json, verify_event, verify_json,
}, },
keys::{Ed25519KeyPair, KeyPair, PublicKeyMap, PublicKeySet}, keys::{Ed25519KeyPair, KeyPair, PublicKeyMap, PublicKeySet},
signatures::Signature, signatures::Signature,