#[non_exhaustive]pub enum TrustError {
Show 21 variants
CertificateGeneration {
reason: String,
},
CertificateParsing {
reason: String,
},
CertificateVerification {
reason: String,
},
CertificateRevocation {
reason: String,
},
MerkleTree {
reason: String,
},
Seal {
reason: String,
},
UnsealFailed,
AttestationFailed,
KeyManagement {
reason: String,
},
Signing {
reason: String,
},
InvalidSignature,
CheckpointEncoding {
reason: String,
},
CheckpointParsing {
reason: String,
},
VerifierKey {
reason: String,
},
NoteVerification,
LogArtifactEncoding {
reason: String,
},
LogArtifactVerification,
ReceiptVerification,
DelegationVerification,
DelegationEncoding {
reason: String,
},
BundleVerification,
}Expand description
Errors returned from the trust primitives.
Variants are grouped by operation: certificate lifecycle (generation, parsing, verification, revocation), the Merkle transparency log, sealed payload transport (seal/unseal), key management, signing, and the dedicated signature-verification failure.
§Why this is #[non_exhaustive]
Downstream matches must carry a wildcard arm, which makes every future
variant an additive change instead of a breaking one. That matters more
here than in a typical library: this crate gains a verification surface with
each new artifact class, and each one wants its own non-oracle failure value
(see Self::ReceiptVerification and Self::BundleVerification). Without
this attribute, giving a new artifact class an honest error would mean a
semver break, and the cheap way out — reusing another class’s variant —
makes errors mean less over time.
§Non-oracle variants carry no cause, deliberately
The verification failures are deliberately causeless. A caller learns that an artifact failed, never which check failed, because these types are reachable from network-exposed surfaces where a distinguishable error is a parsing oracle. Callers diagnosing their own artifacts verify the embedded pieces individually, where the errors are specific and actionable.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
CertificateGeneration
Generating a certificate failed.
CertificateParsing
Parsing a certificate or extracting one of its fields failed.
CertificateVerification
Verifying a certificate chain failed.
CertificateRevocation
A certificate revocation operation failed.
Reserved for consumer-side operations: revocation tracking is
explicitly a consumer concern (a design non-goal for this crate), so
this crate never constructs the variant itself. It exists so
consumers implementing revocation stores can surface failures through
the shared TrustError type.
MerkleTree
A Merkle transparency-log operation failed.
Seal
Sealing a payload for a recipient failed.
UnsealFailed
Unsealing failed — deliberately omits the cause so callers cannot distinguish wrong-key from tampered-ciphertext (non-oracle).
AttestationFailed
Attestation verification failed — the sender’s public key did not match, or the signature over the sealed payload was invalid.
KeyManagement
A key-management operation failed: file I/O, environment loading, base64 decoding, or key-material length validation.
Signing
Producing a signature failed.
Reserved for consumer-side signing pipelines. This crate’s own Ed25519 signing is infallible (dalek 2 deterministic signing), so the crate never constructs the variant itself; consumers whose signing paths can fail (HSMs, remote signers, key lookups) surface those failures through it.
InvalidSignature
A signature failed verification, or the supplied signature or public key bytes were structurally invalid.
This is also the attestation artifact class’s single non-oracle failure: a malformed or non-canonical COSE attestation artifact, a payload-hash mismatch, and an invalid signature all collapse to this one value, so callers cannot distinguish which check rejected the artifact.
CheckpointEncoding
Building or encoding a checkpoint or signed note failed (invalid origin or key name, malformed body).
CheckpointParsing
Parsing a checkpoint body failed. Used on already-verified body text and operator-supplied text; artifact verification collapses it (non-oracle).
VerifierKey
A note verifier key string was malformed or internally inconsistent. Trusted operator input — carries an actionable reason.
NoteVerification
A signed note failed verification — deliberately omits the cause so callers cannot distinguish malformed envelope, unknown key, or bad signature (non-oracle).
LogArtifactEncoding
Building a log proof artifact failed (tree too large for JSON-safe integers, size/index invariant violations at build time).
LogArtifactVerification
A log proof artifact failed verification — deliberately omits the cause (non-oracle): bad checkpoint signature, size mismatch, root mismatch, malformed hashes, and kind confusion are indistinguishable.
ReceiptVerification
An anchor receipt failed verification — deliberately omits the cause (non-oracle): a bad signature, the wrong anchor key, a tampered inclusion path, a malformed or non-canonical artifact, and a leaf the receipt does not prove are all indistinguishable.
Distinct from Self::InvalidSignature, which it previously reused: a
receipt failure is not necessarily a signature failure, and saying so
misdescribed every other way one can fail. The class of artifact is
already known to the caller from the function they called, so naming it
leaks nothing a caller did not supply.
DelegationVerification
An anchor delegation failed verification — deliberately omits the cause
(non-oracle): a malformed or non-canonical artifact, the wrong content
type, a kid that is not the root key the caller named, an origin the
caller did not ask for, an unknown role, an unusable delegated key, an
empty origin, a non-empty unprotected header and a bad signature all
return this one value.
The collapse matters more here than for most artifact classes. A delegation is the statement “this key speaks for that origin”, so a verifier that reported which check fired would let a prober separate “your signature is wrong” from “you named the wrong root key” from “you named the wrong origin” — that is, it would answer questions about the verifier’s own configuration to anyone who can hand it bytes.
§A collapsed error type is not a non-oracle on its own
This variant makes the failures indistinguishable in the return
value, which is one channel. It is not by itself a claim that they are
indistinguishable, and an earlier version of this doc said they were.
An adversarial review measured a 32.8× timing separation between a
kid/origin mismatch and a bad signature, because the first two returned
before the Ed25519 verification ran and that verification dominates
everything preceding it. The error values were identical throughout.
The general rule, which this crate had stated only about error values:
a collapsed error type is not a non-oracle if the amount of work done
differs per cause. An error enum is observable in one channel; a
function is observable in several — wall time, allocation, cache
behaviour. delegation::verify_delegation therefore runs its signature
verification unconditionally and combines all three results at the end.
Any future verifier reaching for this variant inherits that obligation
along with it. (Named without an intra-doc link: it lives behind
unstable-anchor, and a link from ungated docs to a gated item resolves
under --all-features and breaks in the default doc build.)
DelegationEncoding
Building a delegation artifact failed: the claim cannot be encoded into a delegation this crate would itself accept.
§⚠️ Operator-facing only — never return this from a path a stranger can reach
This variant may carry a cause, and that is exactly why its blast radius has to be stated rather than left to judgement. It is for the issuing side: the caller supplied every input, holds the signing key, and already knows everything the reason could tell them, so a descriptive message costs nothing and saves an operator staring at “delegation verification failed” because their origin was 3885 bytes.
Reusing it anywhere reachable by an untrusted party — in
delegation::verify_delegation, or in any future
parse-then-act helper — reintroduces the parsing oracle that
Self::DelegationVerification exists to close. The two variants are
not interchangeable and the compiler cannot tell them apart; only this
sentence can. It follows the same split the crate already makes for
Self::CheckpointEncoding/Self::NoteVerification and
Self::LogArtifactEncoding/Self::LogArtifactVerification.
It exists because encode and decode were allowed to disagree once. The artifact size cap was enforced on the decode side only, so an origin of 3884 bytes signed and verified while 3885 signed successfully and then failed every verification afterwards — precisely the “fails at some later, less debuggable moment” outcome that assembling-with-verification exists to prevent. Every constraint the decoder enforces is now refused at encode too, and this variant is how that refusal is reported.
BundleVerification
A verification bundle failed verification — deliberately omits the cause (non-oracle): a malformed container, a broken inclusion proof, a receipt from the wrong anchor, and a chain whose links do not join are all indistinguishable.
Distinct from Self::LogArtifactVerification, which it previously
reused, for the same reason: a bundle is a different artifact class with
a different set of ways to be wrong.
Trait Implementations§
Source§impl Debug for TrustError
impl Debug for TrustError
Source§impl Display for TrustError
impl Display for TrustError
Source§impl Error for TrustError
impl Error for TrustError
1.30.0 · Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()