pub struct SdJwt { /* private fields */ }sd-jwt only.Expand description
An SD-JWT: an issuer-signed JWT, its disclosures and, in an SD-JWT+KB, a key binding JWT,
as the compact serialization <JWT>~<Disclosure 1>~…~<Disclosure N>~[<KB-JWT>].
Parsing checks the structure only. SdJwt::process matches the disclosures to the
digests and yields the processed payload; the signature is the validator’s business
(SdJwtCredentialValidator for an SD-JWT VC).
§Examples
The presentation of RFC 9901 §5.2, processed.
use identity_kit::sd_jwt_vc::SdJwt;
use serde_json::json;
let presentation = "eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImV4YW1wbGUrc2Qtand0In0.eyJfc2QiOiBbIkNyUWU3UzVr\
cUJBSHQtbk1ZWGdjNmJkdDJTSDVhVFkxc1VfTS1QZ2tqUEkiLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVa\
dTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFV\
QTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAi\
WFFfM2tQS3QxWHlYN0tBTmtxVlI2eVoyVmE1TnJQSXZQWWJ5TXZSS0JNTSIsICJYekZyendzY002R242\
Q0pEYzZ2Vks4QmtNbmZHOHZPU0tmcFBJWmRBZmRFIiwgImdiT3NJNEVkcTJ4Mkt3LXc1d1BFemFrb2I5\
aFYxY1JEMEFUTjNvUUw5Sk0iLCAianN1OXlWdWx3UVFsaEZsTV8zSmx6TWFTRnpnbGhRRzBEcGZheVF3\
TFVLNCJdLCAiaXNzIjogImh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwgImlhdCI6IDE2ODMwMDAw\
MDAsICJleHAiOiAxODgzMDAwMDAwLCAic3ViIjogInVzZXJfNDIiLCAibmF0aW9uYWxpdGllcyI6IFt7\
Ii4uLiI6ICJwRm5kamtaX1ZDem15VGE2VWpsWm8zZGgta284YUlLUWM5RGxHemhhVllvIn0sIHsiLi4u\
IjogIjdDZjZKa1B1ZHJ5M2xjYndIZ2VaOGtoQXYxVTFPU2xlclAwVmtCSnJXWjAifV0sICJfc2RfYWxn\
IjogInNoYS0yNTYiLCAiY25mIjogeyJqd2siOiB7Imt0eSI6ICJFQyIsICJjcnYiOiAiUC0yNTYiLCAi\
eCI6ICJUQ0FFUjE5WnZ1M09IRjRqNFc0dmZTVm9ISVAxSUxpbERsczd2Q2VHZW1jIiwgInkiOiAiWnhq\
aVdXYlpNUUdIVldLVlE0aGJTSWlyc1ZmdWVjQ0U2dDRqVDlGMkhaUSJ9fX0.xJUoRLl1sVRxz57ralck\
9kBWbzbq0soK6dQ5liBXuge3IY8vVYq2xi1tywYwvlRTtPIM2A-XDzyta-SaJLhexQ~WyJlbHVWNU9nM\
2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyJBSngtMDk1VlBycFR0TjRRTU9x\
Uk9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5\
IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyIyR0xD\
NDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~WyJsa2x4RjVqTVlsR1RQVW9\
2TU5JdkNBIiwgIlVTIl0~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6IC\
IxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUub3JnIiwgImlhdCI6ID\
E3NDg1MzY4NjUsICJzZF9oYXNoIjogImZNVjA1dnVNQVJzM3VHMERnMEJZZF83bVFSOUVHQmtSb2YwY1\
RaeXVxWEUifQ.76YniH11s4EDLnqNXKzYtIU1yXEBNzY8wfTd1QkpKzcJ0JY_KXbURL8qQBJA7xpZiA8\
vXYrlpPpd4yfHJTfhQA";
let sd_jwt: SdJwt = presentation.parse()?;
assert_eq!(sd_jwt.disclosures().len(), 4);
assert!(sd_jwt.key_binding_jwt().is_some());
let processed = sd_jwt.process()?;
assert_eq!(processed.payload["given_name"], "John");
assert_eq!(processed.payload["nationalities"], json!(["US"]));
assert!(!processed.payload.contains_key("email"));Implementations§
Source§impl SdJwt
impl SdJwt
Sourcepub fn new(jwt: Jwt, disclosures: Vec<Disclosure>) -> Self
pub fn new(jwt: Jwt, disclosures: Vec<Disclosure>) -> Self
An SD-JWT of jwt and disclosures, without key binding.
Sourcepub fn parse(s: &str) -> Result<Self, SdJwtError>
pub fn parse(s: &str) -> Result<Self, SdJwtError>
Parses the compact serialization.
§Errors
SdJwtError::Format without a ~ or with an empty disclosure, SdJwtError::Jws
when the JWT or the key binding JWT does not decode,
SdJwtError::InvalidDisclosure and SdJwtError::DuplicateDisclosure.
Sourcepub fn disclosures(&self) -> &[Disclosure]
pub fn disclosures(&self) -> &[Disclosure]
The disclosures, in order.
Sourcepub fn key_binding_jwt(&self) -> Option<&Jwt>
pub fn key_binding_jwt(&self) -> Option<&Jwt>
The key binding JWT, when this is an SD-JWT+KB.
Sourcepub fn with_key_binding(self, key_binding: Jwt) -> Self
pub fn with_key_binding(self, key_binding: Jwt) -> Self
This SD-JWT with key_binding as its key binding JWT.
Sourcepub fn without_key_binding(self) -> Self
pub fn without_key_binding(self) -> Self
This SD-JWT without its key binding JWT.
Sourcepub fn payload(&self) -> Result<Map<String, Value>, SdJwtError>
pub fn payload(&self) -> Result<Map<String, Value>, SdJwtError>
The issuer-signed JWT payload as issued: digests in place, nothing disclosed, nothing verified.
§Errors
SdJwtError::Payload when the payload is not a JSON object.
Sourcepub fn hash_algorithm(&self) -> Result<HashAlgorithm, SdJwtError>
pub fn hash_algorithm(&self) -> Result<HashAlgorithm, SdJwtError>
The hash algorithm, from _sd_alg; SHA-256 when absent.
§Errors
SdJwtError::Payload when _sd_alg is not a string,
SdJwtError::UnsupportedHashAlgorithm when it names an algorithm this crate does not
implement.
Sourcepub fn to_string_without_key_binding(&self) -> String
pub fn to_string_without_key_binding(&self) -> String
The compact serialization without the key binding JWT: the input of sd_hash.
Sourcepub fn sd_hash(&self, alg: HashAlgorithm) -> String
pub fn sd_hash(&self, alg: HashAlgorithm) -> String
The sd_hash a key binding JWT over this SD-JWT carries (RFC 9901 §4.3.1): the digest
under alg of the serialization without the key binding JWT.
Sourcepub fn process(&self) -> Result<Processed, SdJwtError>
pub fn process(&self) -> Result<Processed, SdJwtError>
Processes the disclosures into the payload (RFC 9901 §7.1, steps 3 to 5): every disclosure must match a digest, no digest may appear twice, no disclosure may name a reserved or existing claim.
The claims may nest at most SdJwtBuilder::MAX_DEPTH containers deep, counting the
payload and those a disclosure’s value adds alike, so a chain of disclosures, each
referencing the next, cannot nest them without bound. Whatever the builder issues stays
within the limit.
§Errors
SdJwtError::Payload, SdJwtError::UnsupportedHashAlgorithm,
SdJwtError::DuplicateDigest, SdJwtError::UnusedDisclosure,
SdJwtError::WrongDisclosureKind, SdJwtError::ReservedClaimName,
SdJwtError::DuplicateClaim or SdJwtError::TooDeep.
Sourcepub fn select(
&self,
keep: impl FnMut(&Disclosure) -> bool,
) -> Result<Self, SdJwtError>
pub fn select( &self, keep: impl FnMut(&Disclosure) -> bool, ) -> Result<Self, SdJwtError>
This SD-JWT with only the disclosures keep selects and no key binding JWT, for
presentation (RFC 9901 §7.2). A kept disclosure nested in another needs that one kept
too.
§Errors
As process, plus SdJwtError::MissingParentDisclosure.
Sourcepub fn disclose<'a>(
&self,
paths: impl IntoIterator<Item = &'a ClaimPath>,
) -> Result<Self, SdJwtError>
pub fn disclose<'a>( &self, paths: impl IntoIterator<Item = &'a ClaimPath>, ) -> Result<Self, SdJwtError>
This SD-JWT with only the disclosures at paths and beneath them, plus the disclosures
they are nested in, and no key binding JWT. A path may use null for every element.
§Errors
As process, plus SdJwtError::NoSuchClaim for a path selecting
no disclosure.
Sourcepub async fn sign_key_binding(
self,
binding: &KeyBinding,
signer: &dyn Signer,
) -> Result<Self, SdJwtError>
pub async fn sign_key_binding( self, binding: &KeyBinding, signer: &dyn Signer, ) -> Result<Self, SdJwtError>
This SD-JWT as an SD-JWT+KB: binding signed by the holder with signer over the
sd_hash of this SD-JWT (RFC 9901 §4.3), replacing any key binding JWT present.
§Errors
As hash_algorithm, or SdJwtError::Jws when signing
fails.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for SdJwt
impl<'de> Deserialize<'de> for SdJwt
Source§fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
impl Eq for SdJwt
impl StructuralPartialEq for SdJwt
Auto Trait Implementations§
impl Freeze for SdJwt
impl RefUnwindSafe for SdJwt
impl Send for SdJwt
impl Sync for SdJwt
impl Unpin for SdJwt
impl UnsafeUnpin for SdJwt
impl UnwindSafe for SdJwt
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.