ruma_signatures/verification.rs
1//! Verification of digital signatures.
2
3use ed25519_dalek::{Verifier as _, VerifyingKey};
4use ruma_common::SigningKeyAlgorithm;
5
6use crate::{Error, ParseError, VerificationError};
7
8/// A digital signature verifier.
9pub(crate) trait Verifier {
10 /// Use a public key to verify a signature against the JSON object that was signed.
11 ///
12 /// # Parameters
13 ///
14 /// * `public_key`: The raw bytes of the public key of the key pair used to sign the message.
15 /// * `signature`: The raw bytes of the signature to verify.
16 /// * `message`: The raw bytes of the message that was signed.
17 ///
18 /// # Errors
19 ///
20 /// Returns an error if verification fails.
21 fn verify_json(&self, public_key: &[u8], signature: &[u8], message: &[u8])
22 -> Result<(), Error>;
23}
24
25/// A verifier for Ed25519 digital signatures.
26#[derive(Debug, Default)]
27pub(crate) struct Ed25519Verifier;
28
29impl Verifier for Ed25519Verifier {
30 fn verify_json(
31 &self,
32 public_key: &[u8],
33 signature: &[u8],
34 message: &[u8],
35 ) -> Result<(), Error> {
36 VerifyingKey::try_from(public_key)
37 .map_err(ParseError::PublicKey)?
38 .verify(message, &signature.try_into().map_err(ParseError::Signature)?)
39 .map_err(VerificationError::Signature)
40 .map_err(Error::from)
41 }
42}
43
44/// A value returned when an event is successfully verified.
45///
46/// Event verification involves verifying both signatures and a content hash. It is possible for
47/// the signatures on an event to be valid, but for the hash to be different than the one
48/// calculated during verification. This is not necessarily an error condition, as it may indicate
49/// that the event has been redacted. In this case, receiving homeservers should store a redacted
50/// version of the event.
51#[derive(Clone, Debug, Hash, PartialEq, Eq)]
52#[allow(clippy::exhaustive_enums)]
53pub enum Verified {
54 /// All signatures are valid and the content hashes match.
55 All,
56
57 /// All signatures are valid but the content hashes don't match.
58 ///
59 /// This may indicate a redacted event.
60 Signatures,
61}
62
63/// Get the verifier for the given algorithm, if it is supported.
64pub(crate) fn verifier_from_algorithm(
65 algorithm: &SigningKeyAlgorithm,
66) -> Option<impl Verifier + use<>> {
67 match algorithm {
68 SigningKeyAlgorithm::Ed25519 => Some(Ed25519Verifier),
69 _ => None,
70 }
71}