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}