use std::error::Error;
use cms::cert::x509::{der, spki::ObjectIdentifier};
use thiserror::Error;
use crate::x509::raw_x509_signature::X509SignatureScheme;
#[cfg(doc)]
use crate::{types::X509Signature, x509::RawX509Signature};
#[derive(Error, Debug)]
pub enum X509SignatureSigningError {
#[error("failed to convert from raw signature: {0}")]
ConversionFailed(#[from] IntoX509SignatureError),
#[error(transparent)]
Custom(Box<dyn Error + Send + Sync>),
}
#[derive(Error, Debug)]
pub enum X509SignatureVerificationError {
#[error("could not parse raw signature: {0}")]
RawSignatureParseError(#[from] RawX509SignatureParseError),
#[error("could not verify the certificate's email or user ID")]
BadUserIdOrEmail,
#[error("missing or invalid first certificate")]
MissingOrInvalidFirstCertificate,
#[error("invalid certificate in chain")]
InvalidCertificateInChain,
#[error("certificate has expired")]
CertificateExpired,
#[error("unable to get default rustls crypto provider")]
MissingCryptoProvider,
#[error("unsupported signature scheme: {0:?}")]
UnsupportedSignatureScheme(X509SignatureScheme),
#[error(transparent)]
Custom(Box<dyn Error + Send + Sync>),
}
#[derive(Error, Debug)]
pub enum IntoX509SignatureError {
#[error("failed to parse certificate chain: {0}")]
CertificateChainParseError(#[source] der::Error),
#[error("empty certificate chain")]
EmptyCertChain,
#[error("failed to parse extensions in leaf certificate: {0}")]
LeafCertificateExtensionParseError(#[source] der::Error),
#[error("failed to parse extensions in last certificate: {0}")]
LastCertificateExtensionParseError(#[source] der::Error),
#[error("no SubjectKeyIdentifier in leaf certificate")]
LeafCertificateMissingSubjectKeyIdentifier,
#[error("no AuthorityKeyIdentifier in last certificate")]
LastCertificateMissingAuthorityKeyIdentifier,
#[error("no KeyIdentifier in AuthorityKeyIdentifier in last certificate")]
LastCertificateMissingKeyIdentifierInAuthorityKeyIdentifier,
}
#[derive(Error, Debug)]
pub enum RawX509SignatureParseError {
#[error("ContentInfo contentType is {}, not ID_SIGNED_DATA ({})", .0.actual, .0.expected)]
UnexpectedContentInfoContentType(OidMismatch),
#[error("EncapsulatedContentInfo eContentType is {}, not ID_DATA ({})", .0.actual, .0.expected)]
UnexpectedEncapsulatedContentInfoContentType(OidMismatch),
#[error("EncapsulatedContentInfo eContent is not NULL")]
EncapsulatedContentNotNull,
#[error("could not parse content of ContentInfo as SignedData")]
ContentInfoParseError(#[source] der::Error),
#[error("no certificate chain in SignedData")]
NoCertificateChainInSignedData,
#[error("empty certificate chain in SignedData")]
EmptyCertificateChainInSignedData,
#[error("non-X.509 certificate in certificate chain")]
NonX509CertificateInCertificateChain,
#[error("failed to parse extensions in leaf certificate: {0}")]
LeafCertificateExtensionParseError(#[source] der::Error),
#[error("no SubjectKeyIdentifier in leaf certificate")]
LeafCertificateMissingSubjectKeyIdentifier,
#[error("SignedData contains certificate revocation lists")]
SignedDataContainsCrls,
#[error("SignerInfos list is empty")]
EmptySignerInfos,
#[error("SignerInfos list contains multiple entries")]
MultipleSignerInfos,
#[error("SignerIdentifier is not a SubjectKeyIdentifier")]
SignerIdentifierNotSubjectKeyIdentifier,
#[error("SignerIdentifier does not match SubjectKeyIdentifier of leaf certificate")]
SignerIdentifierMismatch,
#[error("SignerInfo contains signed attributes")]
SignerInfoContainsSignedAttrs,
#[error("unsupported signature algorithm: {}", .0.actual)]
UnsupportedSignatureAlgorithm(OidMismatch),
#[error("unsupported digest algorithm: {}", .0.actual)]
UnsupportedDigestAlgorithm(OidMismatch),
#[error("digest algorithm parameters are not NULL")]
DigestAlgorithmParametersNotNull,
#[error("SignerInfo.signature_algorithm.parameters not set")]
SignatureAlgorithmParametersNotSet,
#[error("could not parse SignatureAlgorithm.parameters")]
SignatureAlgorithmParametersParseError(#[source] der::Error),
#[error("unsupported SignatureAlgorithm hash algorithm: {}", .0.actual)]
UnsupportedSignatureAlgorithmHash(OidMismatch),
#[error("unsupported SignatureAlgorithm mask generation function: {}", .0.actual)]
UnsupportedSignatureAlgorithmMaskGen(OidMismatch),
#[error("SignatureAlgorithm mask generation function parameters not set")]
SignatureAlgorithmMaskGenParametersNotSet,
#[error(
"unsupported SignatureAlgorithm mask generation function hash algorithm: {}", .0.actual
)]
UnsupportedSignatureAlgorithmMaskGenHash(OidMismatch),
#[error("SignatureAlgorithm salt length is not 64: {0}")]
UnsupportedSignatureAlgorithmSaltLen(u8),
#[error("encoding certificate as PEM failed: {0}")]
CertificatePemEncodingFailed(#[source] der::Error),
}
#[derive(Debug)]
pub struct OidMismatch {
pub actual: ObjectIdentifier,
pub expected: ObjectIdentifier,
}