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