use async_trait::async_trait;
use bcder::Oid;
use thiserror::Error;
use crate::crypto::raw_signature::SigningAlg;
pub trait RawSignatureValidator {
fn validate(
&self,
sig: &[u8],
data: &[u8],
public_key: &[u8],
) -> Result<(), RawSignatureValidationError>;
}
#[async_trait(?Send)]
pub trait AsyncRawSignatureValidator {
async fn validate_async(
&self,
sig: &[u8],
data: &[u8],
public_key: &[u8],
) -> Result<(), RawSignatureValidationError>;
}
pub fn validator_for_signing_alg(alg: SigningAlg) -> Option<Box<dyn RawSignatureValidator>> {
#[cfg(any(feature = "rust_native_crypto", target_arch = "wasm32"))]
{
if let Some(validator) =
crate::crypto::raw_signature::rust_native::validators::validator_for_signing_alg(alg)
{
return Some(validator);
}
}
#[cfg(all(
feature = "openssl",
not(all(feature = "rust_native_crypto", target_arch = "wasm32"))
))]
if let Some(validator) =
crate::crypto::raw_signature::openssl::validators::validator_for_signing_alg(alg)
{
return Some(validator);
}
let _ = alg; None
}
pub(crate) fn validator_for_sig_and_hash_algs<T: AsRef<[u8]>, U: AsRef<[u8]>>(
sig_alg: &Oid<T>,
hash_alg: &Oid<U>,
) -> Option<Box<dyn RawSignatureValidator>> {
#[cfg(any(feature = "rust_native_crypto", target_arch = "wasm32"))]
{
if let Some(validator) =
crate::crypto::raw_signature::rust_native::validators::validator_for_sig_and_hash_algs(
sig_alg, hash_alg,
)
{
return Some(validator);
}
}
#[cfg(all(
feature = "openssl",
not(all(feature = "rust_native_crypto", target_arch = "wasm32"))
))]
if let Some(validator) =
crate::crypto::raw_signature::openssl::validators::validator_for_sig_and_hash_algs(
sig_alg, hash_alg,
)
{
return Some(validator);
}
let _ = sig_alg; let _ = hash_alg;
None
}
#[cfg(target_arch = "wasm32")]
pub fn async_validator_for_signing_alg(
alg: SigningAlg,
) -> Option<Box<dyn AsyncRawSignatureValidator>> {
crate::crypto::raw_signature::rust_native::validators::async_validator_for_signing_alg(alg)
}
#[cfg(target_arch = "wasm32")]
pub(crate) fn async_validator_for_sig_and_hash_algs(
sig_alg: &Oid,
hash_alg: &Oid,
) -> Option<Box<dyn AsyncRawSignatureValidator>> {
crate::crypto::raw_signature::rust_native::validators::async_validator_for_sig_and_hash_algs(
sig_alg, hash_alg,
)
}
#[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(all(
feature = "openssl",
not(all(feature = "rust_native_crypto", target_arch = "wasm32"))
))]
impl From<openssl::error::ErrorStack> for RawSignatureValidationError {
fn from(err: openssl::error::ErrorStack) -> Self {
Self::CryptoLibraryError(err.to_string())
}
}
#[cfg(all(
feature = "openssl",
not(all(feature = "rust_native_crypto", target_arch = "wasm32"))
))]
impl From<crate::crypto::raw_signature::openssl::OpenSslMutexUnavailable>
for RawSignatureValidationError
{
fn from(err: crate::crypto::raw_signature::openssl::OpenSslMutexUnavailable) -> Self {
Self::InternalError(err.to_string())
}
}