use thiserror::Error;
#[cfg(feature = "pdf")]
use crate::asset_handlers::pdf_io::PdfError;
use crate::{
asset_handlers::{
bmff_io::BmffError, flac_io::FlacError, gif_io::GifError, jpeg_io::JpegError,
mp3_io::Mp3Error, png_io::PngError, riff_io::RiffError, svg_io::SvgError,
tiff_io::TiffError,
},
crypto::{cose::CoseError, raw_signature::RawSignerError, time_stamp::TimeStampError},
http::HttpResolverError,
};
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum Error {
#[error("claim missing: label = {label}")]
ClaimMissing { label: String },
#[error("Unsupported Assertion version")]
AssertionUnsupportedVersion,
#[error("assertion missing: url = {url}")]
AssertionMissing { url: String },
#[error("unable to encode assertion data")]
AssertionEncoding(String),
#[error(transparent)]
AssertionDecoding(#[from] crate::assertion::AssertionDecodeError),
#[error("assertion could not be redacted")]
AssertionInvalidRedaction,
#[error("could not find the assertion to redact")]
AssertionRedactionNotFound,
#[error("assertion-specific error: {0}")]
AssertionSpecificError(String),
#[error("bad parameter: {0}")]
BadParam(String),
#[error("operation cancelled")]
OperationCancelled,
#[error("required feature missing")]
MissingFeature(String),
#[error("validation rule was violated: {0}")]
ValidationRule(String),
#[error("feature implementation incomplete")]
NotImplemented(String),
#[error("claim could not be converted to CBOR")]
ClaimEncoding,
#[error("claim could not be converted from CBOR")]
ClaimDecoding(String),
#[error("claim already signed, no further changes allowed")]
ClaimAlreadySigned,
#[error("attempt to add new claim without signing last claim")]
ClaimUnsigned,
#[error("missing signature box link")]
ClaimMissingSignatureBox,
#[error("identity required required with copyright assertion")]
ClaimMissingIdentity,
#[error("incompatible claim version")]
ClaimVersion,
#[error("invalid claim content")]
ClaimInvalidContent,
#[error("claim missing hard binding")]
ClaimMissingHardBinding,
#[error("claim contains multiple hard bindings")]
ClaimMultipleHardBinding,
#[error("claim contains self redactions")]
ClaimSelfRedact,
#[error("claim contains disallowed redactions")]
ClaimDisallowedRedaction,
#[error("update manifest is invalid")]
UpdateManifestInvalid,
#[error("more than one manifest store detected")]
TooManyManifestStores,
#[error("assertion limit exceeded: maximum allowed is {max}")]
TooManyAssertions { max: usize },
#[error("manifest is not refernced by any ingredient")]
UnreferencedManifest,
#[error("COSE Sign1 structure can not be parsed: {coset_error}")]
InvalidCoseSignature {
coset_error: coset::CoseError,
},
#[error("COSE signature algorithm is not supported")]
CoseSignatureAlgorithmNotSupported,
#[error("COSE could not find verification key")]
CoseMissingKey,
#[error("could not find signing certificate chain in COSE signature")]
CoseX5ChainMissing,
#[error("COSE error parsing certificate")]
CoseInvalidCert,
#[error("COSE signature invalid")]
CoseSignature,
#[error("COSE verifier failure")]
CoseVerifier,
#[error("COSE certificate has expired")]
CoseCertExpiration,
#[error("COSE certificate has been revoked")]
CoseCertRevoked,
#[error("COSE certificate not trusted")]
CoseCertUntrusted,
#[error("COSE time stamp could not be parsed")]
CoseInvalidTimeStamp,
#[error("COSE time stamp had expired cert")]
CoseTimeStampValidity,
#[error("COSE time stamp does not match data")]
CoseTimeStampMismatch,
#[error("could not generate a trusted time stamp")]
CoseTimeStampGeneration,
#[error("COSE TimeStamp Authority failure")]
CoseTimeStampAuthority,
#[error("COSE Signature too big for JUMBF box")]
CoseSigboxTooSmall,
#[error("COSE Signer does not contain signing certificate")]
CoseNoCerts,
#[error("WASM verifier error")]
WasmVerifier,
#[error("WASM RSA-PSS key import error: {0}")]
WasmRsaKeyImport(String),
#[error("WASM RSA-PSS verification error")]
WasmRsaVerification,
#[error("WASM crypto key error")]
WasmKey,
#[error("WASM not called from window or worker global scope")]
WasmInvalidContext,
#[error("WASM could not load crypto library")]
WasmNoCrypto,
#[error("remote signers are not supported for WASM")]
WasmNoRemoteSigner,
#[error("feature unsupported on Wasm")]
WasmFeatureUnsupported,
#[error("could not create valid JUMBF for claim")]
JumbfCreationError,
#[error("thread receive error")]
ThreadReceiveError,
#[error("no JUMBF data found")]
JumbfNotFound,
#[error("required JUMBF box not found")]
JumbfBoxNotFound,
#[error("could not fetch the remote manifest {0}")]
RemoteManifestFetch(String),
#[error("must fetch remote manifests from url {0}")]
RemoteManifestUrl(String),
#[error("failed to fetch the remote settings")]
FailedToFetchSettings,
#[error("failed to remotely sign data")]
FailedToRemoteSign,
#[error("stopped because of logged error")]
LogStop,
#[error("not found")]
NotFound,
#[error("type is unsupported")]
UnsupportedType,
#[error("thumbnail format {0} is unsupported")]
UnsupportedThumbnailFormat(String),
#[error("`trust.signer_info` is missing from settings")]
MissingSignerSettings,
#[error("`builder.auto_created_action.source_type` must be set if this feature is enabled")]
MissingAutoCreatedActionSourceType,
#[error("embedding error")]
EmbeddingError,
#[error("ingredient file not found")]
IngredientNotFound,
#[error("file not found: {0}")]
FileNotFound(String),
#[error("resource not found: {0}")]
ResourceNotFound(String),
#[error("XMP read error")]
XmpReadError(String),
#[error("XMP write error")]
XmpWriteError(String),
#[error("XMP is not supported")]
XmpNotSupported,
#[error("C2PA provenance not found in XMP")]
ProvenanceMissing,
#[error("hash verification( {0} )")]
HashMismatch(String),
#[error("cyclic ingredient found in path: {claim_label_path:?}")]
CyclicIngredients { claim_label_path: Vec<String> },
#[error("claim verification failure: {0}")]
ClaimVerification(String),
#[error("PDF read error")]
PdfReadError,
#[error(transparent)]
InvalidClaim(#[from] crate::store::InvalidClaimError),
#[error("asset could not be parsed: {0}")]
InvalidAsset(String),
#[error(transparent)]
JumbfParseError(#[from] crate::jumbf::boxes::JumbfParseError),
#[error("The Verifiable Content structure is not valid")]
VerifiableCredentialInvalid,
#[error("could not parse ECDSA signature")]
InvalidEcdsaSignature,
#[error("missing data box")]
MissingDataBox,
#[error("could not generate XML")]
XmlWriteError,
#[error("unknown algorithm")]
UnknownAlgorithm,
#[error("invalid signing key")]
InvalidSigningKey,
#[error(transparent)]
Utf8Error(#[from] std::str::Utf8Error),
#[error(transparent)]
HttpError(#[from] http::Error),
#[error(transparent)]
HttpResolverError(#[from] HttpResolverError),
#[error(transparent)]
TryFromIntError(#[from] std::num::TryFromIntError),
#[error(transparent)]
IoError(#[from] std::io::Error),
#[error(transparent)]
JsonError(#[from] serde_json::Error),
#[error(transparent)]
#[cfg(feature = "add_thumbnails")]
ImageError(#[from] image::ImageError),
#[error(transparent)]
CborError(#[from] c2pa_cbor::Error),
#[error(transparent)]
TomlSerializationError(#[from] toml::ser::Error),
#[error(transparent)]
OtherError(#[from] Box<dyn std::error::Error + Send + Sync + 'static>),
#[error("prerelease content detected")]
PrereleaseError,
#[error("capability is not supported by this version: {0}")]
VersionCompatibility(String),
#[error("insufficient memory space for operation")]
InsufficientMemory,
#[error("parameters out of range")]
OutOfRange,
#[error(transparent)]
TimeStampError(#[from] crate::crypto::time_stamp::TimeStampError),
#[error(transparent)]
RawSignatureValidationError(#[from] crate::crypto::raw_signature::RawSignatureValidationError),
#[error(transparent)]
RawSignerError(#[from] crate::crypto::raw_signature::RawSignerError),
#[error(transparent)]
CertificateProfileError(#[from] crate::crypto::cose::CertificateProfileError),
#[error(transparent)]
CertificateTrustError(#[from] crate::crypto::cose::CertificateTrustError),
#[error(transparent)]
InvalidCertificateError(#[from] crate::crypto::cose::InvalidCertificateError),
#[error("internal error ({0})")]
InternalError(String),
#[error("C2PA Validation Error: {0}")]
C2PAValidation(String),
#[error("error parsing BMFF: {0}")]
BmffError(#[from] BmffError),
#[error("error parsing GIF: {0}")]
GifError(#[from] GifError),
#[error("error parsing JPEG: {0}")]
JpegError(#[from] JpegError),
#[error("error parsing MP3: {0}")]
Mp3Error(#[from] Mp3Error),
#[error("error parsing FLAC: {0}")]
FlacError(#[from] FlacError),
#[cfg(feature = "pdf")]
#[error("error parsing PDF: {0}")]
PdfError(#[from] PdfError),
#[error("error parsing PNG: {0}")]
PngError(#[from] PngError),
#[error("error parsing RIFF: {0}")]
RiffError(#[from] RiffError),
#[error("error parsing SVG: {0}")]
SvgError(#[from] SvgError),
#[error("error parsing TIFF: {0}")]
TiffError(#[from] TiffError),
}
pub type Result<T, E = Error> = std::result::Result<T, E>;
impl From<std::convert::Infallible> for Error {
fn from(never: std::convert::Infallible) -> Self {
match never {}
}
}
impl From<CoseError> for Error {
fn from(err: CoseError) -> Self {
match err {
CoseError::MissingSigningCertificateChain => Self::CoseX5ChainMissing,
CoseError::MultipleSigningCertificateChains => Self::CoseVerifier,
CoseError::NoTimeStampToken => Self::NotFound,
CoseError::UnsupportedSigningAlgorithm => Self::CoseSignatureAlgorithmNotSupported,
CoseError::InvalidEcdsaSignature => Self::InvalidEcdsaSignature,
CoseError::CborParsingError(_) => Self::CoseTimeStampGeneration,
CoseError::CborGenerationError(_) => Self::CoseTimeStampGeneration,
CoseError::TimeStampError(e) => e.into(),
CoseError::CertificateProfileError(e) => e.into(),
CoseError::CertificateTrustError(e) => e.into(),
CoseError::BoxSizeTooSmall => Self::CoseSigboxTooSmall,
CoseError::RawSignerError(e) => e.into(),
CoseError::RawSignatureValidationError(e) => e.into(),
CoseError::InternalError(e) => Self::InternalError(e),
}
}
}
impl From<Error> for CoseError {
fn from(err: Error) -> Self {
match err {
Error::CoseX5ChainMissing => Self::MissingSigningCertificateChain,
Error::CoseVerifier => Self::MultipleSigningCertificateChains,
Error::NotFound => Self::NoTimeStampToken,
Error::CoseSignatureAlgorithmNotSupported => Self::UnsupportedSigningAlgorithm,
Error::InvalidEcdsaSignature => Self::InvalidEcdsaSignature,
Error::CoseTimeStampGeneration => Self::CborGenerationError(err.to_string()),
Error::TimeStampError(e) => Self::TimeStampError(e),
Error::CertificateProfileError(e) => Self::CertificateProfileError(e),
Error::CertificateTrustError(e) => Self::CertificateTrustError(e),
Error::CoseSigboxTooSmall => Self::BoxSizeTooSmall,
Error::RawSignerError(e) => Self::RawSignerError(e),
Error::RawSignatureValidationError(e) => Self::RawSignatureValidationError(e),
_ => Self::InternalError(err.to_string()),
}
}
}
impl From<Error> for RawSignerError {
fn from(err: Error) -> Self {
Self::InternalError(err.to_string())
}
}
impl From<Error> for TimeStampError {
fn from(err: Error) -> Self {
Self::InternalError(err.to_string())
}
}