#[cfg(feature = "alloc")]
use alloc::string::String;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use core::fmt;
use core::ops::ControlFlow;
use pki_types::UnixTime;
#[cfg(feature = "alloc")]
use pki_types::{AlgorithmIdentifier, ServerName};
use crate::verify_cert::RequiredEkuNotFoundContext;
#[derive(Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum Error {
BadDer,
BadDerTime,
CaUsedAsEndEntity,
CertExpired {
time: UnixTime,
not_after: UnixTime,
},
CertNotValidForName(InvalidNameContext),
CertNotValidYet {
time: UnixTime,
not_before: UnixTime,
},
CertRevoked,
CrlExpired {
time: UnixTime,
next_update: UnixTime,
},
EmptyEkuExtension,
EndEntityUsedAsCa,
ExtensionValueInvalid,
InvalidCertValidity,
InvalidCrlNumber,
InvalidNetworkMaskConstraint,
InvalidSerialNumber,
InvalidCrlSignatureForPublicKey,
InvalidSignatureForPublicKey,
IssuerNotCrlSigner,
MalformedDnsIdentifier,
MalformedExtensions,
MalformedNameConstraint,
MaximumNameConstraintComparisonsExceeded,
MaximumPathBuildCallsExceeded,
MaximumPathDepthExceeded,
MaximumSignatureChecksExceeded,
NameConstraintViolation,
PathLenConstraintViolated,
#[deprecated(since = "0.103.2", note = "use RequiredEkuNotFoundContext instead")]
RequiredEkuNotFound,
RequiredEkuNotFoundContext(RequiredEkuNotFoundContext),
SignatureAlgorithmMismatch,
TrailingData(DerTypeId),
UnknownIssuer,
UnknownRevocationStatus,
UnsupportedCertVersion,
UnsupportedCriticalExtension,
UnsupportedCrlIssuingDistributionPoint,
UnsupportedCrlVersion,
UnsupportedDeltaCrl,
UnsupportedIndirectCrl,
UnsupportedNameType,
UnsupportedRevocationReason,
UnsupportedRevocationReasonsPartitioning,
#[deprecated(
since = "0.103.4",
note = "use UnsupportedCrlSignatureAlgorithmContext instead"
)]
UnsupportedCrlSignatureAlgorithm,
UnsupportedCrlSignatureAlgorithmContext(UnsupportedSignatureAlgorithmContext),
#[deprecated(
since = "0.103.4",
note = "use UnsupportedSignatureAlgorithmContext instead"
)]
UnsupportedSignatureAlgorithm,
UnsupportedSignatureAlgorithmContext(UnsupportedSignatureAlgorithmContext),
#[deprecated(
since = "0.103.4",
note = "use UnsupportedCrlSignatureAlgorithmForPublicKeyContext instead"
)]
UnsupportedCrlSignatureAlgorithmForPublicKey,
UnsupportedCrlSignatureAlgorithmForPublicKeyContext(
UnsupportedSignatureAlgorithmForPublicKeyContext,
),
#[deprecated(
since = "0.103.4",
note = "use UnsupportedSignatureAlgorithmForPublicKeyContext instead"
)]
UnsupportedSignatureAlgorithmForPublicKey,
UnsupportedSignatureAlgorithmForPublicKeyContext(
UnsupportedSignatureAlgorithmForPublicKeyContext,
),
}
impl Error {
pub(crate) fn most_specific(self, new: Self) -> Self {
if self.rank() >= new.rank() { self } else { new }
}
#[allow(clippy::as_conversions)] pub(crate) fn rank(&self) -> u32 {
match &self {
Self::CertNotValidYet { .. } | Self::CertExpired { .. } => 290,
Self::CertNotValidForName(_) => 280,
Self::CertRevoked | Self::UnknownRevocationStatus | Self::CrlExpired { .. } => 270,
Self::InvalidCrlSignatureForPublicKey | Self::InvalidSignatureForPublicKey => 260,
Self::SignatureAlgorithmMismatch => 250,
Self::EmptyEkuExtension => 245,
#[allow(deprecated)]
Self::RequiredEkuNotFound | Self::RequiredEkuNotFoundContext(_) => 240,
Self::NameConstraintViolation => 230,
Self::PathLenConstraintViolated => 220,
Self::CaUsedAsEndEntity | Self::EndEntityUsedAsCa => 210,
Self::IssuerNotCrlSigner => 200,
Self::InvalidCertValidity => 190,
Self::InvalidNetworkMaskConstraint => 180,
Self::InvalidSerialNumber => 170,
Self::InvalidCrlNumber => 160,
#[allow(deprecated)]
Self::UnsupportedCrlSignatureAlgorithmForPublicKey
| Self::UnsupportedCrlSignatureAlgorithmForPublicKeyContext(_)
| Self::UnsupportedSignatureAlgorithmForPublicKey
| Self::UnsupportedSignatureAlgorithmForPublicKeyContext(_) => 150,
#[allow(deprecated)]
Self::UnsupportedCrlSignatureAlgorithm
| Self::UnsupportedCrlSignatureAlgorithmContext(_)
| Self::UnsupportedSignatureAlgorithm
| Self::UnsupportedSignatureAlgorithmContext(_) => 140,
Self::UnsupportedCriticalExtension => 130,
Self::UnsupportedCertVersion => 130,
Self::UnsupportedCrlVersion => 120,
Self::UnsupportedDeltaCrl => 110,
Self::UnsupportedIndirectCrl => 100,
Self::UnsupportedNameType => 95,
Self::UnsupportedRevocationReason => 90,
Self::UnsupportedRevocationReasonsPartitioning => 80,
Self::UnsupportedCrlIssuingDistributionPoint => 70,
Self::MaximumPathDepthExceeded => 61,
Self::MalformedDnsIdentifier => 60,
Self::MalformedNameConstraint => 50,
Self::MalformedExtensions | Self::TrailingData(_) => 40,
Self::ExtensionValueInvalid => 30,
Self::BadDerTime => 20,
Self::BadDer => 10,
Self::MaximumSignatureChecksExceeded => 0,
Self::MaximumPathBuildCallsExceeded => 0,
Self::MaximumNameConstraintComparisonsExceeded => 0,
Self::UnknownIssuer => 0,
}
}
#[inline]
pub(crate) fn is_fatal(&self) -> bool {
matches!(
self,
Self::MaximumSignatureChecksExceeded
| Self::MaximumPathBuildCallsExceeded
| Self::MaximumNameConstraintComparisonsExceeded
)
}
}
impl From<Error> for ControlFlow<Error, Error> {
fn from(value: Error) -> Self {
match value {
err if err.is_fatal() => Self::Break(err),
err => Self::Continue(err),
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{self:?}")
}
}
#[cfg(feature = "std")]
impl ::std::error::Error for Error {}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct InvalidNameContext {
#[cfg(feature = "alloc")]
pub expected: ServerName<'static>,
#[cfg(feature = "alloc")]
pub presented: Vec<String>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UnsupportedSignatureAlgorithmForPublicKeyContext {
#[cfg(feature = "alloc")]
pub signature_algorithm_id: Vec<u8>,
#[cfg(feature = "alloc")]
pub public_key_algorithm_id: Vec<u8>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UnsupportedSignatureAlgorithmContext {
#[cfg(feature = "alloc")]
pub signature_algorithm_id: Vec<u8>,
#[cfg(feature = "alloc")]
pub supported_algorithms: Vec<AlgorithmIdentifier>,
}
#[allow(missing_docs)]
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum DerTypeId {
BitString,
Bool,
Certificate,
CertificateExtensions,
CertificateTbsCertificate,
CertRevocationList,
CertRevocationListExtension,
CrlDistributionPoint,
CommonNameInner,
CommonNameOuter,
DistributionPointName,
Extension,
GeneralName,
RevocationReason,
Signature,
SignatureAlgorithm,
SignedData,
SubjectPublicKeyInfo,
Time,
TrustAnchorV1,
TrustAnchorV1TbsCertificate,
U8,
RevokedCertificate,
RevokedCertificateExtension,
RevokedCertEntry,
IssuingDistributionPoint,
}