erc8128/error.rs
1/// Errors produced by ERC-8128 signing and verification.
2#[derive(Debug, thiserror::Error)]
3#[non_exhaustive]
4pub enum Erc8128Error {
5 // -- Signing errors --
6 /// The request URL is not absolute or cannot be parsed.
7 #[error("invalid url: {0}")]
8 InvalidUrl(String),
9
10 /// Sign/verify options are invalid (e.g. `expires <= created`).
11 #[error("invalid options: {0}")]
12 InvalidOptions(String),
13
14 /// A Structured Fields value contains forbidden characters.
15 #[error("invalid header value: {0}")]
16 InvalidHeaderValue(String),
17
18 /// A derived component (`@method`, `@authority`, …) produced non-visible-ASCII.
19 #[error("invalid derived value: {0}")]
20 InvalidDerivedValue(String),
21
22 /// A required field is empty or the overall format is wrong.
23 #[error("invalid format: {0}")]
24 InvalidFormat(String),
25
26 /// `content-digest` handling failed during signing.
27 #[error("digest error: {0}")]
28 DigestError(String),
29
30 /// The signer returned an empty or malformed signature.
31 #[error("signing failed: {0}")]
32 SigningFailed(String),
33
34 // -- Verification errors --
35 /// `Signature-Input` / `Signature` headers are missing.
36 #[error("missing signature headers")]
37 MissingHeaders,
38
39 /// The requested signature label was not found.
40 #[error("label not found")]
41 LabelNotFound,
42
43 /// `Signature-Input` / `Signature` could not be parsed.
44 #[error("bad signature input: {0}")]
45 BadSignatureInput(String),
46
47 /// The `keyid` does not match `erc8128:<chainId>:<address>`.
48 #[error("bad keyid")]
49 BadKeyId,
50
51 /// `created` / `expires` are missing, non-integer, or `expires <= created`.
52 #[error("bad time")]
53 BadTime,
54
55 /// Signature is not yet valid (`now + skew < created`).
56 #[error("not yet valid")]
57 NotYetValid,
58
59 /// Signature has expired (`now - skew > expires`).
60 #[error("expired")]
61 Expired,
62
63 /// `expires - created` exceeds the policy maximum.
64 #[error("validity too long")]
65 ValidityTooLong,
66
67 /// Replayable (nonce-less) signature rejected by policy.
68 #[error("replayable not allowed")]
69 ReplayableNotAllowed,
70
71 /// Replayable signature accepted but no invalidation mechanism is provided.
72 /// Required by ERC-8128 Section 3.2.2 + 5.2.
73 #[error("replayable invalidation required")]
74 ReplayableInvalidationRequired,
75
76 /// Replayable signature rejected: `created` before the per-key `not_before` cutoff.
77 #[error("replayable not before")]
78 ReplayableNotBefore,
79
80 /// Replayable signature explicitly invalidated by policy hook.
81 #[error("replayable invalidated")]
82 ReplayableInvalidated,
83
84 /// Signed components do not satisfy request-bound requirements.
85 #[error("not request bound")]
86 NotRequestBound,
87
88 /// Signed components do not match any class-bound policy.
89 #[error("class bound not allowed")]
90 ClassBoundNotAllowed,
91
92 /// `expires - created` exceeds the nonce retention window.
93 #[error("nonce window too long")]
94 NonceWindowTooLong,
95
96 /// `content-digest` header required by components but missing.
97 #[error("digest required")]
98 DigestRequired,
99
100 /// `content-digest` value does not match the body.
101 #[error("digest mismatch")]
102 DigestMismatch,
103
104 /// Signature bytes could not be decoded (bad base64 or empty).
105 #[error("bad signature bytes")]
106 BadSignatureBytes,
107
108 /// The signature is cryptographically invalid.
109 #[error("bad signature")]
110 BadSignature,
111
112 /// The nonce has already been consumed (replay detected).
113 #[error("replay detected")]
114 Replay,
115
116 /// Algorithm is not allowed by policy.
117 #[error("algorithm not allowed")]
118 AlgNotAllowed,
119
120 /// The cryptographic verification call itself failed (e.g. RPC error).
121 #[error("verification failed: {0}")]
122 VerificationFailed(String),
123}