use thiserror::Error;
use crate::{Oid, SigningAlg};
pub trait RawSignatureValidator {
fn validate(
&self,
sig: &[u8],
data: &[u8],
public_key: &[u8],
) -> Result<(), RawSignatureValidationError>;
}
pub fn validator_for_signing_alg(alg: SigningAlg) -> Option<Box<dyn RawSignatureValidator>> {
#[cfg(feature = "rust_native_crypto")]
{
crate::rust_native::validators::validator_for_signing_alg(alg)
}
#[cfg(all(feature = "openssl", not(feature = "rust_native_crypto")))]
{
return crate::openssl::validators::validator_for_signing_alg(alg);
}
#[cfg(not(any(feature = "rust_native_crypto", feature = "openssl")))]
{
let _ = alg;
None
}
}
pub fn validator_for_sig_and_hash_algs(
sig_alg: &Oid,
hash_alg: &Oid,
) -> Option<Box<dyn RawSignatureValidator>> {
#[cfg(feature = "rust_native_crypto")]
{
crate::rust_native::validators::validator_for_sig_and_hash_algs(
sig_alg.as_bytes(),
hash_alg.as_bytes(),
)
}
#[cfg(all(feature = "openssl", not(feature = "rust_native_crypto")))]
{
return crate::openssl::validators::validator_for_sig_and_hash_algs(
sig_alg.as_bytes(),
hash_alg.as_bytes(),
);
}
#[cfg(not(any(feature = "rust_native_crypto", feature = "openssl")))]
{
let _ = (sig_alg, hash_alg);
None
}
}
#[derive(Debug, Eq, Error, PartialEq)]
#[non_exhaustive]
pub enum RawSignatureValidationError {
#[error("the signature does not match the provided data or public key")]
SignatureMismatch,
#[error("an error was reported by the cryptography library: {0}")]
CryptoLibraryError(String),
#[error("invalid public key")]
InvalidPublicKey,
#[error("invalid signature value")]
InvalidSignature,
#[error("signature uses an unsupported algorithm")]
UnsupportedAlgorithm,
#[error("internal error ({0})")]
InternalError(String),
}
#[cfg(feature = "openssl")]
impl From<openssl::error::ErrorStack> for RawSignatureValidationError {
fn from(err: openssl::error::ErrorStack) -> Self {
Self::CryptoLibraryError(err.to_string())
}
}
#[cfg(feature = "openssl")]
impl From<crate::openssl::OpenSslMutexUnavailable> for RawSignatureValidationError {
fn from(err: crate::openssl::OpenSslMutexUnavailable) -> Self {
Self::InternalError(err.to_string())
}
}
#[cfg(test)]
#[cfg(feature = "openssl")]
mod tests {
use super::*;
#[test]
fn mutex_unavailable_maps_to_internal_error() {
let err: RawSignatureValidationError = crate::openssl::OpenSslMutexUnavailable.into();
assert!(matches!(err, RawSignatureValidationError::InternalError(_)));
}
}