1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//! Errors of SD-JWT parsing, processing and building.
use super::ClaimPath;
use crate::jose::JwsError;
/// Why an SD-JWT could not be parsed, processed, selected from or built.
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum SdJwtError {
/// The issuer-signed JWT or the key binding JWT is not a compact JWS this crate decodes.
#[error("invalid JWS: {0}")]
Jws(#[from] JwsError),
/// The compact serialization is malformed: no `~`, an empty disclosure.
#[error("invalid SD-JWT: {0}")]
Format(String),
/// A disclosure is not base64url of a JSON array of the right shape.
#[error("invalid disclosure {disclosure:?}: {reason}")]
InvalidDisclosure {
/// The encoded disclosure.
disclosure: String,
/// What is wrong with it.
reason: String,
},
/// The same disclosure is given twice.
#[error("disclosure {0:?} is given twice")]
DuplicateDisclosure(String),
/// The issuer-signed JWT payload is not a JSON object, or `_sd`, `...` or `_sd_alg` is
/// malformed.
#[error("invalid SD-JWT payload: {0}")]
Payload(String),
/// The `_sd_alg` names a hash algorithm this crate does not implement.
#[error("unsupported hash algorithm {0:?}")]
UnsupportedHashAlgorithm(String),
/// A digest appears more than once in the payload, directly or through disclosures.
#[error("digest {0:?} appears more than once")]
DuplicateDigest(String),
/// A disclosure matches no digest in the payload or in another disclosure.
#[error("disclosure {0:?} is referenced by no digest")]
UnusedDisclosure(String),
/// A disclosure of the wrong kind matches a digest: an array element disclosure in `_sd`,
/// or an object property disclosure in an array.
#[error("disclosure {disclosure:?} is not {expected}")]
WrongDisclosureKind {
/// The encoded disclosure.
disclosure: String,
/// `an object property disclosure` or `an array element disclosure`.
expected: &'static str,
},
/// A disclosure names the reserved claim `_sd` or `...`.
#[error("disclosure claim name {0:?} is reserved")]
ReservedClaimName(String),
/// A disclosure names a claim that already exists at the level of its `_sd`.
#[error("claim {name:?} at {path} is both disclosed and present")]
DuplicateClaim {
/// The claim name.
name: String,
/// The object it is duplicated in.
path: ClaimPath,
},
/// A disclosure was selected without the disclosure whose value references it.
#[error("disclosure {disclosure:?} needs the disclosure {parent:?} it is nested in")]
MissingParentDisclosure {
/// The encoded disclosure selected.
disclosure: String,
/// The encoded disclosure it needs.
parent: String,
},
/// A path to conceal or disclose selects no claim.
#[error("no claim at {0}")]
NoSuchClaim(ClaimPath),
/// A claim cannot be made selectively disclosable: it is `_sd` or `...`, or a profile
/// forbids it.
#[error("claim at {path} cannot be selectively disclosable: {reason}")]
NotConcealable {
/// The claim.
path: ClaimPath,
/// Why.
reason: String,
},
/// The claims nest deeper than [`SdJwtBuilder::MAX_DEPTH`](super::SdJwtBuilder::MAX_DEPTH)
/// containers: claims to issue, which no parser of this crate would read back, or claims
/// being processed, through the payload and the disclosures nested in it.
#[error("the claims nest deeper than {max} containers")]
TooDeep {
/// The deepest nesting accepted.
max: usize,
},
/// The key binding JWT is present where an SD-JWT without key binding was expected, or
/// missing.
#[error("{0}")]
KeyBinding(String),
}