use crate::DigestAlgorithm;
pub(crate) mod holder;
pub(crate) use holder::get_crypographer;
#[cfg(feature = "use_openssl")]
mod openssl;
#[cfg(feature = "use_ring")]
mod ring;
#[cfg(not(any(feature = "use_ring", feature = "use_openssl")))]
pub use self::holder::{set_boxed_cryptographer, set_cryptographer};
#[derive(Debug, thiserror::Error)]
pub enum CryptoError {
#[error("Digest algorithm {0:?} is unsupported by this Cryptographer")]
UnsupportedDigest(DigestAlgorithm),
#[error("{0}")]
Other(#[source] anyhow::Error),
}
pub trait Cryptographer: Send + Sync + 'static {
fn rand_bytes(&self, output: &mut [u8]) -> Result<(), CryptoError>;
fn new_key(
&self,
algorithm: DigestAlgorithm,
key: &[u8],
) -> Result<Box<dyn HmacKey>, CryptoError>;
fn new_hasher(&self, algo: DigestAlgorithm) -> Result<Box<dyn Hasher>, CryptoError>;
fn constant_time_compare(&self, a: &[u8], b: &[u8]) -> bool;
}
pub trait HmacKey: Send + Sync + 'static {
fn sign(&self, data: &[u8]) -> Result<Vec<u8>, CryptoError>;
}
pub trait Hasher: Send + Sync + 'static {
fn update(&mut self, data: &[u8]) -> Result<(), CryptoError>;
fn finish(&mut self) -> Result<Vec<u8>, CryptoError>;
}
pub(crate) fn rand_bytes(buffer: &mut [u8]) -> Result<(), CryptoError> {
get_crypographer().rand_bytes(buffer)
}
pub(crate) fn new_key(
algorithm: DigestAlgorithm,
key: &[u8],
) -> Result<Box<dyn HmacKey>, CryptoError> {
get_crypographer().new_key(algorithm, key)
}
pub(crate) fn constant_time_compare(a: &[u8], b: &[u8]) -> bool {
get_crypographer().constant_time_compare(a, b)
}
pub(crate) fn new_hasher(algorithm: DigestAlgorithm) -> Result<Box<dyn Hasher>, CryptoError> {
get_crypographer().new_hasher(algorithm)
}