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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! Selective disclosure for JWTs (SD-JWT, RFC 9901) and SD-JWT-based verifiable credentials
//! (SD-JWT VC), with the Token Status List and SD-JWT VC type metadata.
//!
//! - [`SdJwt`] is the data format: an issuer-signed JWT, its [`Disclosure`]s and an optional
//! key binding JWT, parsed from and serialized to the `~`-separated compact form.
//! [`SdJwt::process`] matches the disclosures to the digests (RFC 9901 §7.1) and yields the
//! processed payload; [`SdJwt::disclose`] and [`SdJwt::select`] make a presentation;
//! [`SdJwt::sign_key_binding`] turns it into an SD-JWT+KB.
//! - [`SdJwtBuilder`] issues: it conceals the claims at the given [`ClaimPath`]s, nested ones
//! recursively, adds decoys and signs with any [`Signer`](crate::jose::Signer).
//! - [`SdJwtVc`] is an SD-JWT VC: `typ: dc+sd-jwt`, a `vct`, the registered claims that may
//! not be selectively disclosed kept as such, [`SdJwtVcBuilder`] to issue one and
//! [`SdJwtCredentialValidator`] to validate one, key binding included.
//! - [`SdJwtCredentialV2`] is a VCDM 2.0 credential secured with SD-JWT (VC-JOSE-COSE
//! §3.2.1): `typ: vc+sd-jwt`, the [`CredentialV2`](crate::vc::CredentialV2) itself as the
//! payload, [`SdJwtCredentialV2Builder`] to issue one and
//! [`SdJwtCredentialValidator::validate_v2`] to validate one.
//! - [`TypeMetadata`] implements the SD-JWT VC type metadata with its claim paths, integrity
//! metadata and `extends` processing.
//!
//! The Token Status List referenced from the `status` claim is not specific to SD-JWT and
//! lives in [`status_list`](crate::status_list), which this feature enables. Its types are
//! still reachable here, deprecated, for one release.
//!
//! The SD-JWT layer is implemented here rather than taken from a dependency (ADR 0005).
//!
//! # Two SD-JWT credential types
//!
//! An SD-JWT VC ([`SdJwtVc`]) carries a flat claims set typed by `vct`, with `typ:
//! dc+sd-jwt` (`vc+sd-jwt` in earlier drafts). A VCDM 2.0 credential secured with SD-JWT
//! ([`SdJwtCredentialV2`]) carries the credential's own `@context`, `type`, `issuer` and
//! `credentialSubject`, with `typ: vc+sd-jwt` and media type `application/vc+sd-jwt`. So
//! `vc+sd-jwt` alone does not say which one a token is; the payload does: an SD-JWT VC has
//! `vct`, a VCDM 2.0 credential has `@context` and no `vct`.
//!
//! A verifier that accepts both picks the parser by `typ` first and by the payload second.
//! [`SdJwtVc::from_sd_jwt`] accepts `vc+sd-jwt` only when the payload has `vct`, and reports a
//! `vc+sd-jwt` payload with `@context` and no `vct` as [`SdJwtVcError::VcdmPayload`], so that
//! a caller which tried the SD-JWT VC parser first can fall through:
//!
//! ```
//! use identity_kit::sd_jwt_vc::{SdJwt, SdJwtCredentialV2, SdJwtVc, SdJwtVcError};
//!
//! enum Parsed {
//! SdJwtVc(SdJwtVc),
//! Vcdm(SdJwtCredentialV2),
//! }
//!
//! fn parse(sd_jwt: SdJwt) -> Result<Parsed, Box<dyn std::error::Error>> {
//! match SdJwtVc::from_sd_jwt(sd_jwt.clone()) {
//! Ok(credential) => Ok(Parsed::SdJwtVc(credential)),
//! Err(SdJwtVcError::VcdmPayload | SdJwtVcError::MissingTyp) => {
//! Ok(Parsed::Vcdm(SdJwtCredentialV2::from_sd_jwt(sd_jwt)?))
//! }
//! Err(error) => Err(error.into()),
//! }
//! }
//! # let _ = parse;
//! ```
pub use ;
pub use ;
pub use ;
pub use Disclosure;
pub use SdJwtError;
pub use HashAlgorithm;
pub use ;
pub use crate;
pub use ;
pub use ;
// `#[deprecated]` has no effect on a `pub use` (rust-lang/rust#30827), so the old paths are
// deprecated type aliases. Remove them in the release after the next one.
/// Moved to [`status_list::Status`](crate::status_list::Status).
pub type Status = crateStatus;
/// Moved to [`status_list::StatusList`](crate::status_list::StatusList).
pub type StatusList = crateStatusList;
/// Moved to [`status_list::StatusListError`](crate::status_list::StatusListError).
pub type StatusListError = crateStatusListError;
/// Moved to [`status_list::StatusListRef`](crate::status_list::StatusListRef).
pub type StatusListRef = crateStatusListRef;
/// Moved to [`status_list::StatusListToken`](crate::status_list::StatusListToken).
pub type StatusListToken = crateStatusListToken;
/// Moved to [`status_list::StatusMechanism`](crate::status_list::StatusMechanism).
pub type StatusMechanism<'a> = crateStatusMechanism;
/// Moved to [`status_list::StatusType`](crate::status_list::StatusType).
pub type StatusType = crateStatusType;