libvctrl_handler 5.0.0

Fundamental contracts for building a version control system – no implementations, only traits and types
Documentation
//! Verification trait.
//!
//! # Architecture
//! This module defines the abstract contract for verifying cryptographic signatures.
//! It is the counterpart to the [`Signer`](crate::traits::core::signer::Signer) module.
//! By abstracting verification into a trait, the crate allows the core engine to
//! authenticate commits and tags without being coupled to a specific cryptographic
//! backend (e.g., GPG, SSH, or X.509).
//!
//! # Design Rationale: Stateless Verification
//! Unlike signing, which may require stateful operations (e.g., consuming nonces or
//! locking hardware tokens), signature verification is a pure, stateless mathematical
//! operation. It only requires the public key, the raw data, and the signature.
//! Therefore, the `verify` method takes `&self` instead of `&mut self`. This allows
//! multiple threads to concurrently verify different commits in a revision graph
//! without any synchronization overhead.

use crate::errors::VctrlError;

/// Trait for verifying signatures.
///
/// # Why this exists
/// Provides a unified interface for authenticating data. In Git, verifying signed
/// commits and tags ensures that the authorship is genuine and the data has not been
/// tampered with. This trait allows the engine to delegate the complex cryptography
/// to a dedicated backend, ensuring that the core logic remains agnostic of the
/// underlying Public Key Infrastructure (PKI).
///
/// # How it works
/// The implementor receives a `key_id` (to locate the correct public key), the raw
/// `data` that was signed, and the `signature` bytes. The backend applies the
/// verification algorithm (e.g., RSA-SHA256, Ed25519) to confirm that the signature
/// was indeed generated by the owner of the private key corresponding to the public key.
///
/// # Design Rationale: `Result<bool, VctrlError>`
/// The return type distinguishes between a cryptographic failure and a system failure:
/// - `Ok(true)`: The signature is mathematically valid.
/// - `Ok(false)`: The signature is mathematically invalid (tampered data or wrong key).
/// - `Err(VctrlError)`: A system error occurred (e.g., public key not found, I/O error
///   reading the keyring, or unsupported algorithm).
/// This prevents confusing an invalid signature with a system-level fault, allowing
/// callers to handle security violations explicitly.
///
/// # Examples
///
/// Implementing the trait for a mock verifier:
///
/// ```
/// # use libvctrl_handler::traits::core::verifier::Verifier;
/// # use libvctrl_handler::VctrlError;
/// #
/// struct MockVerifier;
///
/// impl Verifier for MockVerifier {
///     fn verify(&self, key_id: &str, data: &[u8], signature: &[u8]) -> Result<bool, VctrlError> {
///         // A real implementation would use a public key here.
///         if key_id != "trusted_key" {
///             return Ok(false); // Unknown key implies invalid signature
///         }
///         Ok(data == signature) // Simplified mock verification
///     }
/// }
///
/// let verifier = MockVerifier;
/// let data = b"commit data";
/// let sig = b"commit data";
///
/// assert!(verifier.verify("trusted_key", data, sig)?);
/// assert!(!verifier.verify("untrusted_key", data, sig)?);
/// # Ok::<(), VctrlError>(())
/// ```
pub trait Verifier: Send + Sync {
    /// Verifies data against a signature using the specified key ID.
    ///
    /// # How it works
    /// Resolves the `key_id` to a public key within the backend's keyring. It then
    /// applies the verification algorithm to the `data` and `signature` slices.
    /// The operation is purely computational and does not mutate the verifier's state.
    ///
    /// # Errors
    ///
    /// Returns [`VctrlError`] if:
    /// - The `key_id` cannot be found in the keyring.
    /// - The underlying cryptographic library encounters an error.
    /// - An I/O error occurs while accessing the keyring.
    ///
    /// Note: An invalid signature returns `Ok(false)`, not `Err`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use libvctrl_handler::traits::core::verifier::Verifier;
    /// # use libvctrl_handler::VctrlError;
    /// # struct MockVerifier;
    /// # impl Verifier for MockVerifier {
    /// #     fn verify(&self, key_id: &str, data: &[u8], signature: &[u8]) -> Result<bool, VctrlError> {
    /// #         Ok(key_id == "trusted" && data == signature)
    /// #     }
    /// # }
    /// let verifier = MockVerifier;
    /// let is_valid = verifier.verify("trusted", b"data", b"data")?;
    /// assert!(is_valid);
    /// # Ok::<(), VctrlError>(())
    /// ```
    fn verify(&self, key_id: &str, data: &[u8], signature: &[u8]) -> Result<bool, VctrlError>;
}