identity_credential/sd_jwt_vc/presentation.rs
1// Copyright 2020-2024 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use super::Error;
5use super::Result;
6use super::SdJwtVc;
7use super::SdJwtVcClaims;
8
9use sd_jwt::Disclosure;
10use sd_jwt::Hasher;
11use sd_jwt::SdJwtPresentationBuilder;
12
13/// Builder structure to create an SD-JWT VC presentation.
14/// It allows users to conceal claims and attach a key binding JWT.
15#[derive(Debug, Clone)]
16pub struct SdJwtVcPresentationBuilder {
17 vc_claims: SdJwtVcClaims,
18 builder: SdJwtPresentationBuilder,
19}
20
21impl SdJwtVcPresentationBuilder {
22 /// Prepare a presentation for a given [`SdJwtVc`].
23 pub fn new(token: SdJwtVc, hasher: &dyn Hasher) -> Result<Self> {
24 let SdJwtVc {
25 mut sd_jwt,
26 parsed_claims: mut vc_claims,
27 } = token;
28 // Make sure to set the parsed claims back into the SD-JWT Token.
29 // The reason we do this is to make sure that the underlying SdJwtPresetationBuilder
30 // that operates on the wrapped SdJwt token can handle the claims.
31 std::mem::swap(sd_jwt.claims_mut(), &mut vc_claims.sd_jwt_claims);
32 let builder = sd_jwt.into_presentation(hasher).map_err(Error::SdJwt)?;
33
34 Ok(Self { vc_claims, builder })
35 }
36 /// Removes the disclosure for the property at `path`, conceiling it.
37 ///
38 /// ## Notes
39 /// - When concealing a claim more than one disclosure may be removed: the disclosure for the claim itself and the
40 /// disclosures for any concealable sub-claim.
41 pub fn conceal(mut self, path: &str) -> Result<Self> {
42 self.builder = self.builder.conceal(path).map_err(Error::SdJwt)?;
43 Ok(self)
44 }
45
46 /// Removes all disclosures from this SD-JWT, resulting in a token that,
47 /// when presented, will have *all* selectively-disclosable properties
48 /// omitted.
49 pub fn conceal_all(mut self) -> Self {
50 self.builder = self.builder.conceal_all();
51 self
52 }
53
54 /// Discloses a value that was previously concealed.
55 /// # Notes
56 /// - This method may disclose multiple values, if the given path references a disclosable value stored within another
57 /// disclosable value. That is, [disclose](Self::disclose) will unconceal the selectively disclosable value at
58 /// `path` together with *all* its parents that are disclosable values themselves.
59 /// - By default *all* disclosable claims are disclosed, therefore this method can only be used to *undo* any
60 /// concealment operations previously performed by either [Self::conceal] or [Self::conceal_all].
61 pub fn disclose(mut self, path: &str) -> Result<Self> {
62 self.builder = self.builder.disclose(path).map_err(Error::SdJwt)?;
63 Ok(self)
64 }
65
66 /// Returns the resulting [`SdJwtVc`] together with all removed disclosures.
67 pub fn finish(mut self) -> (SdJwtVc, Vec<Disclosure>) {
68 let (mut sd_jwt, disclosures) = self.builder.finish();
69 // Move the token's claim back into parsed VC claims.
70 std::mem::swap(sd_jwt.claims_mut(), &mut self.vc_claims.sd_jwt_claims);
71
72 (SdJwtVc::new(sd_jwt, self.vc_claims), disclosures)
73 }
74}