use super::errors::{NoKeyIdHasherError, PrivateKeyError};
#[derive(Clone, Debug)]
pub enum KeyIdMethod {
Rfc5280Sha1,
Rfc7093Method1Sha256,
Rfc7093Method2Sha384,
Rfc7093Method3Sha512,
Rfc7093Method4 { algorithm_oid: Vec<u32> },
}
impl KeyIdMethod {
pub fn algorithm_oid(&self) -> &[u32] {
match self {
Self::Rfc5280Sha1 => crate::ID_SHA1,
Self::Rfc7093Method1Sha256 => crate::ID_SHA256,
Self::Rfc7093Method2Sha384 => crate::ID_SHA384,
Self::Rfc7093Method3Sha512 => crate::ID_SHA512,
Self::Rfc7093Method4 { algorithm_oid } => algorithm_oid.as_slice(),
}
}
pub fn uses_full_spki_der(&self) -> bool {
matches!(self, Self::Rfc7093Method4 { .. })
}
pub fn apply_output_length(&self, hash: Vec<u8>) -> Vec<u8> {
match self {
Self::Rfc7093Method1Sha256
| Self::Rfc7093Method2Sha384
| Self::Rfc7093Method3Sha512 => hash.into_iter().take(20).collect(),
_ => hash,
}
}
}
pub trait KeyIdHasher {
type Error: std::error::Error + Send + Sync + 'static;
fn hash(&self, algorithm_oid: &[u32], data: &[u8]) -> Result<Vec<u8>, Self::Error>;
}
pub struct NoKeyIdHasher;
impl KeyIdHasher for NoKeyIdHasher {
type Error = NoKeyIdHasherError;
fn hash(&self, _algorithm_oid: &[u32], _data: &[u8]) -> Result<Vec<u8>, NoKeyIdHasherError> {
Err(NoKeyIdHasherError)
}
}
pub trait ErasedKeyIdHasher {
fn hash_erased(&self, algorithm_oid: &[u32], data: &[u8]) -> Result<Vec<u8>, PrivateKeyError>;
}
impl KeyIdHasher for dyn ErasedKeyIdHasher + '_ {
type Error = PrivateKeyError;
fn hash(&self, algorithm_oid: &[u32], data: &[u8]) -> Result<Vec<u8>, PrivateKeyError> {
self.hash_erased(algorithm_oid, data)
}
}
impl KeyIdHasher for Box<dyn ErasedKeyIdHasher> {
type Error = PrivateKeyError;
fn hash(&self, algorithm_oid: &[u32], data: &[u8]) -> Result<Vec<u8>, PrivateKeyError> {
self.as_ref().hash_erased(algorithm_oid, data)
}
}
pub fn default_key_id_hasher() -> Box<dyn ErasedKeyIdHasher> {
#[cfg(all(feature = "nss", not(feature = "openssl")))]
{
crate::nss_backend::nss_key_id_hasher()
}
#[cfg(feature = "openssl")]
{
crate::openssl_backend::openssl_key_id_hasher()
}
#[cfg(not(any(feature = "openssl", feature = "nss")))]
{
Box::new(NoKeyIdHasherErased)
}
}
#[cfg(not(any(feature = "openssl", feature = "nss")))]
struct NoKeyIdHasherErased;
#[cfg(not(any(feature = "openssl", feature = "nss")))]
impl ErasedKeyIdHasher for NoKeyIdHasherErased {
fn hash_erased(
&self,
_algorithm_oid: &[u32],
_data: &[u8],
) -> Result<Vec<u8>, PrivateKeyError> {
Err(PrivateKeyError::new(NoKeyIdHasherError))
}
}