use std::{error::Error as StdError, fmt};
use serde::{Deserialize, Serialize};
use crate::jwa;
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
#[non_exhaustive]
pub enum Algorithm {
#[cfg(feature = "hmac")]
#[cfg_attr(docsrs, doc(cfg(feature = "hmac")))]
Hmac(jwa::hmac::SigningAlgorithm),
#[cfg(feature = "rsa")]
#[cfg_attr(docsrs, doc(cfg(feature = "rsa")))]
Rsa(jwa::rsa::SigningAlgorithm),
#[cfg(feature = "ec")]
#[cfg_attr(docsrs, doc(cfg(feature = "ec")))]
EllipticCurve(jwa::ec::SigningAlgorithm),
}
#[cfg(feature = "hmac")]
#[cfg_attr(docsrs, doc(cfg(feature = "hmac")))]
impl Algorithm {
pub const HS256: Algorithm = Self::Hmac(jwa::hmac::SigningAlgorithm::HS256);
pub const HS384: Algorithm = Self::Hmac(jwa::hmac::SigningAlgorithm::HS384);
pub const HS512: Algorithm = Self::Hmac(jwa::hmac::SigningAlgorithm::HS512);
}
#[cfg(feature = "rsa")]
#[cfg_attr(docsrs, doc(cfg(feature = "rsa")))]
impl Algorithm {
pub const RS256: Algorithm = Self::Rsa(jwa::rsa::SigningAlgorithm::RS256);
pub const RS384: Algorithm = Self::Rsa(jwa::rsa::SigningAlgorithm::RS384);
pub const RS512: Algorithm = Self::Rsa(jwa::rsa::SigningAlgorithm::RS512);
pub const PS256: Algorithm = Self::Rsa(jwa::rsa::SigningAlgorithm::PS256);
pub const PS384: Algorithm = Self::Rsa(jwa::rsa::SigningAlgorithm::PS384);
pub const PS512: Algorithm = Self::Rsa(jwa::rsa::SigningAlgorithm::PS512);
}
#[cfg(feature = "ec")]
#[cfg_attr(docsrs, doc(cfg(feature = "ec")))]
impl Algorithm {
pub const ES256: Algorithm = Self::EllipticCurve(jwa::ec::SigningAlgorithm::ES256);
pub const ES384: Algorithm = Self::EllipticCurve(jwa::ec::SigningAlgorithm::ES384);
pub const ES512: Algorithm = Self::EllipticCurve(jwa::ec::SigningAlgorithm::ES512);
}
impl Algorithm {
#[must_use]
pub fn signature_size(self) -> usize {
match self {
#[cfg(feature = "hmac")]
Self::Hmac(alg) => alg.signature_size(),
#[cfg(feature = "rsa")]
Self::Rsa(alg) => alg.signature_size(),
#[cfg(feature = "ec")]
Self::EllipticCurve(alg) => alg.signature_size(),
}
}
}
pub trait Signer {
type Algorithm;
type Error: fmt::Debug + fmt::Display + Sync + Send + 'static;
fn can_sign(&self, alg: Self::Algorithm) -> bool;
fn sign(&self, alg: Self::Algorithm, data: &[u8]) -> Result<Vec<u8>, Self::Error>;
}
pub trait Verifier {
type Algorithm;
type Error: StdError + Send + Sync + 'static;
fn can_verify(&self, alg: Self::Algorithm) -> bool;
fn verify(
&self,
alg: Self::Algorithm,
data: &[u8],
signature: &[u8],
) -> Result<(), Self::Error>;
}
impl fmt::Display for Algorithm {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
#[cfg(feature = "hmac")]
Self::Hmac(a) => fmt::Display::fmt(a, f),
#[cfg(feature = "rsa")]
Self::Rsa(a) => fmt::Display::fmt(a, f),
#[cfg(feature = "ec")]
Self::EllipticCurve(a) => fmt::Display::fmt(a, f),
#[cfg(not(any(feature = "hmac", feature = "rsa", feature = "ec")))]
_ => unreachable!(),
}
}
}