signatures: Comply with the specified signature checking algorithm.

Based on research https://github.com/ruma/ruma/pull/1491#issuecomment-1445042510 by @zecakeh
This commit is contained in:
Jason Volk 2023-02-25 23:03:03 -08:00 committed by Jonas Platte
parent 920a412da1
commit 87237bf100

View File

@ -578,38 +578,27 @@ pub fn verify_event(
None => return Err(VerificationError::signature_not_found(entity_id)), None => return Err(VerificationError::signature_not_found(entity_id)),
}; };
let mut maybe_signature_and_public_key = None;
let public_keys = public_key_map let public_keys = public_key_map
.get(entity_id.as_str()) .get(entity_id.as_str())
.ok_or_else(|| VerificationError::public_key_not_found(entity_id))?; .ok_or_else(|| VerificationError::public_key_not_found(entity_id))?;
for (key_id, public_key) in public_keys { for (key_id, signature) in signature_set {
// Since only ed25519 is supported right now, we don't actually need to check what the // Since only ed25519 is supported right now, we don't actually need to check what the
// algorithm is. If it split successfully, it's ed25519. // algorithm is. If it split successfully, it's ed25519.
if split_id(key_id).is_err() { if split_id(key_id).is_err() {
continue; continue;
} }
if let Some(signature) = signature_set.get(key_id) { let public_key = match public_keys.get(key_id) {
maybe_signature_and_public_key = Some(SignatureAndPubkey { signature, public_key }); Some(public_key) => public_key,
break;
}
}
let signature_and_pubkey = match maybe_signature_and_public_key {
Some(value) => value,
None => return Err(VerificationError::UnknownPublicKeysForSignature.into()), None => return Err(VerificationError::UnknownPublicKeysForSignature.into()),
}; };
let signature = match signature_and_pubkey.signature { let signature = match signature {
CanonicalJsonValue::String(signature) => signature, CanonicalJsonValue::String(signature) => signature,
_ => return Err(JsonError::not_of_type("signature", JsonType::String)), _ => return Err(JsonError::not_of_type("signature", JsonType::String)),
}; };
let public_key = signature_and_pubkey.public_key;
let signature = Base64::<Standard>::parse(signature) let signature = Base64::<Standard>::parse(signature)
.map_err(|e| ParseError::base64("signature", signature, e))?; .map_err(|e| ParseError::base64("signature", signature, e))?;
@ -620,6 +609,7 @@ pub fn verify_event(
&canonical_json, &canonical_json,
)?; )?;
} }
}
let calculated_hash = content_hash(object)?; let calculated_hash = content_hash(object)?;
@ -632,11 +622,6 @@ pub fn verify_event(
Ok(Verified::Signatures) Ok(Verified::Signatures)
} }
struct SignatureAndPubkey<'a> {
signature: &'a CanonicalJsonValue,
public_key: &'a Base64,
}
/// Internal implementation detail of the canonical JSON algorithm. /// Internal implementation detail of the canonical JSON algorithm.
/// ///
/// Allows customization of the fields that will be removed before serializing. /// Allows customization of the fields that will be removed before serializing.