#![allow(missing_copy_implementations)]
use std::error::Error as StdError;
use thiserror::Error;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Error)]
#[error("key incompatible with algorithm '{alg}'")]
pub struct IncompatibleAlgorithm {
alg: crate::jwa::Algorithm,
}
#[inline]
pub(crate) fn incompatible_algorithm(
alg: impl Into<crate::jwa::Algorithm>,
) -> IncompatibleAlgorithm {
IncompatibleAlgorithm { alg: alg.into() }
}
#[derive(Debug, Error)]
#[error("'{alg}' does not match supported algorithms")]
pub struct UnknownAlgorithm {
alg: String,
}
#[inline]
pub(crate) fn unknown_algorithm(alg: String) -> UnknownAlgorithm {
UnknownAlgorithm { alg }
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Error)]
#[error("JWK cannot be used in this way")]
pub struct JwkUsageMismatch {
_p: (),
}
pub(crate) const fn jwk_usage_mismatch() -> JwkUsageMismatch {
JwkUsageMismatch { _p: () }
}
#[derive(Clone, Copy, Debug, Error)]
#[error("malformed JWT")]
pub struct MalformedJwt {
_p: (),
}
pub(crate) fn malformed_jwt() -> MalformedJwt {
MalformedJwt { _p: () }
}
#[derive(Debug, Error)]
#[error("malformed JWT header")]
pub struct MalformedJwtHeader {
#[from]
source: Box<dyn StdError + Send + Sync + 'static>,
}
pub(crate) fn malformed_jwt_header(
source: impl Into<Box<dyn StdError + Send + Sync + 'static>>,
) -> MalformedJwtHeader {
MalformedJwtHeader {
source: source.into(),
}
}
#[derive(Debug, Error)]
#[error("malformed JWT payload")]
pub struct MalformedJwtPayload {
#[from]
source: Box<dyn StdError + Send + Sync + 'static>,
}
pub(crate) fn malformed_jwt_payload(
source: impl Into<Box<dyn StdError + Send + Sync + 'static>>,
) -> MalformedJwtPayload {
MalformedJwtPayload {
source: source.into(),
}
}
#[derive(Debug, Error)]
#[error("malformed JWT signature")]
pub struct MalformedJwtSignature {
#[from]
source: Box<dyn StdError + Send + Sync + 'static>,
}
pub(crate) fn malformed_jwt_signature(
source: impl Into<Box<dyn StdError + Send + Sync + 'static>>,
) -> MalformedJwtSignature {
MalformedJwtSignature {
source: source.into(),
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Error)]
#[error("signature mismatch")]
pub struct SignatureMismatch {
_p: (),
}
pub(crate) const fn signature_mismatch() -> SignatureMismatch {
SignatureMismatch { _p: () }
}
#[derive(Debug, Error)]
#[error("key rejected")]
pub struct KeyRejected {
#[from]
source: Box<dyn StdError + Send + Sync + 'static>,
}
pub(crate) fn key_rejected(
source: impl Into<Box<dyn StdError + Send + Sync + 'static>>,
) -> KeyRejected {
KeyRejected {
source: source.into(),
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Error)]
#[error("cannot sign without a private key")]
pub struct MissingPrivateKey {
_p: (),
}
pub(crate) const fn missing_private_key() -> MissingPrivateKey {
MissingPrivateKey { _p: () }
}
#[derive(Debug, Error)]
#[error("unexpected error")]
pub struct Unexpected {
#[from]
source: Box<dyn StdError + Send + Sync + 'static>,
}
#[allow(dead_code)]
pub(crate) fn unexpected(
source: impl Into<Box<dyn StdError + Send + Sync + 'static>>,
) -> Unexpected {
Unexpected {
source: source.into(),
}
}
#[derive(Debug, Error)]
pub enum SigningError {
#[error(transparent)]
MissingPrivateKey(#[from] MissingPrivateKey),
#[error(transparent)]
JwkUsageMismatch(#[from] JwkUsageMismatch),
#[error(transparent)]
IncompatibleAlgorithm(#[from] IncompatibleAlgorithm),
#[error(transparent)]
Unexpected(#[from] Unexpected),
}
impl From<std::convert::Infallible> for SigningError {
fn from(_: std::convert::Infallible) -> Self {
unreachable!("infallible result")
}
}
#[derive(Debug, Error)]
pub enum JwkVerifyError {
#[error(transparent)]
IncompatibleAlgorithm(#[from] IncompatibleAlgorithm),
#[error(transparent)]
JwkUsageMismatch(#[from] JwkUsageMismatch),
#[error(transparent)]
SignatureMismatch(#[from] SignatureMismatch),
#[error(transparent)]
Unexpected(#[from] Unexpected),
}
impl JwkVerifyError {
#[must_use]
pub fn is_incompatible_alg(&self) -> bool {
matches!(self, Self::IncompatibleAlgorithm(_))
}
#[must_use]
pub fn is_usage_mismatch(&self) -> bool {
matches!(self, Self::JwkUsageMismatch(_))
}
#[must_use]
pub fn is_signature_mismatch(&self) -> bool {
matches!(self, Self::SignatureMismatch(_))
}
}
#[derive(Debug, Error)]
pub enum JwtVerifyError {
#[error("token rejected by JWK")]
JwkVerifyError(#[from] JwkVerifyError),
#[error(transparent)]
MalformedToken(#[from] MalformedJwt),
#[error(transparent)]
MalformedTokenHeader(#[from] MalformedJwtHeader),
#[error(transparent)]
MalformedTokenPayload(#[from] MalformedJwtPayload),
#[error(transparent)]
MalformedTokenSignature(#[from] MalformedJwtSignature),
#[error("token rejected by claims validator")]
ClaimsRejected(#[from] ClaimsRejected),
#[error(transparent)]
Unexpected(#[from] Unexpected),
}
#[derive(Debug, Error)]
pub enum JwtSigningError {
#[error(transparent)]
SigningError(#[from] SigningError),
#[error(transparent)]
MalformedJwtHeader(#[from] MalformedJwtHeader),
#[error(transparent)]
MalformedJwtPayload(#[from] MalformedJwtPayload),
#[error(transparent)]
Unexpected(#[from] Unexpected),
}
#[derive(Debug, Error)]
pub enum ClaimsRejected {
#[error("invalid algorithm")]
InvalidAlgorithm,
#[error("invalid audience")]
InvalidAudience,
#[error("invalid issuer")]
InvalidIssuer,
#[error("invalid subject")]
InvalidSubject,
#[error("token expired")]
TokenExpired,
#[error("token not yet valid")]
TokenNotYetValid,
#[error("required {_0} claim missing")]
MissingRequiredClaim(&'static str),
#[error(transparent)]
Custom(Box<dyn StdError + Send + Sync>),
}