ssi_data_integrity_core/
lib.rs

1//! Verifiable Credential Data Integrity 1.0 core implementation.
2//!
3//! See: <https://www.w3.org/TR/vc-data-integrity/>
4use std::ops::{Deref, DerefMut};
5
6pub mod canonicalization;
7mod de;
8mod decode;
9mod document;
10pub mod hashing;
11mod options;
12mod proof;
13pub mod signing;
14pub mod suite;
15
16pub use decode::*;
17use educe::Educe;
18pub use options::ProofOptions;
19pub use proof::value_or_array;
20pub use proof::*;
21use serde::Serialize;
22use ssi_claims_core::{
23    ProofValidationError, ValidateClaims, ValidateProof, VerifiableClaims, Verification,
24};
25pub use suite::{
26    CloneCryptographicSuite, CryptographicSuite, DebugCryptographicSuite,
27    DeserializeCryptographicSuite, SerializeCryptographicSuite, StandardCryptographicSuite,
28};
29use suite::{CryptographicSuiteSelect, SelectionError};
30
31pub use document::*;
32#[doc(hidden)]
33pub use ssi_rdf;
34
35/// Data-Integrity-secured document.
36#[derive(Educe, Serialize)]
37#[serde(bound(serialize = "T: Serialize, S: SerializeCryptographicSuite"))]
38#[educe(Debug(bound("T: std::fmt::Debug, S: DebugCryptographicSuite")))]
39#[educe(Clone(bound("T: Clone, S: CloneCryptographicSuite")))]
40pub struct DataIntegrity<T, S: CryptographicSuite> {
41    #[serde(flatten)]
42    pub claims: T,
43
44    #[serde(rename = "proof", skip_serializing_if = "Proofs::is_empty")]
45    pub proofs: Proofs<S>,
46}
47
48impl<T, S: CryptographicSuite> DataIntegrity<T, S> {
49    /// Create new Data-Integrity-secured claims by providing the proofs.
50    pub fn new(claims: T, proofs: Proofs<S>) -> Self {
51        Self { claims, proofs }
52    }
53
54    /// Verify the claims and proofs.
55    ///
56    /// The `params` argument provides all the verification parameters required
57    /// to validate the claims and proof.
58    ///
59    /// # What verification parameters should I use?
60    ///
61    /// It really depends on the claims type `T` and cryptosuite type `S`,
62    /// but the `ssi::claims::VerificationParameters` type is a good starting
63    /// point that should work most of the time.
64    ///
65    /// # Passing the parameters by reference
66    ///
67    /// If the validation traits are implemented for `P`, they will be
68    /// implemented for `&P` as well. This means the parameters can be passed
69    /// by move *or* by reference.
70    pub async fn verify<P>(&self, params: P) -> Result<Verification, ProofValidationError>
71    where
72        T: ValidateClaims<P, Proofs<S>>,
73        Proofs<S>: ValidateProof<P, T>,
74    {
75        VerifiableClaims::verify(self, params).await
76    }
77
78    /// Select a subset of claims to disclose.
79    ///
80    /// The `params` argument is similar to the verification parameters of the
81    /// `verify` function. It must provides resources necessary to the selection
82    /// of claims. This depends on the cryptosuite type `S`, but probably
83    /// includes a verification method resolver.
84    /// Using `ssi::claims::VerificationParameters` will work in most cases.
85    pub async fn select<P>(
86        &self,
87        params: P,
88        options: S::SelectionOptions,
89    ) -> Result<DataIntegrity<ssi_json_ld::syntax::Object, S>, SelectionError>
90    where
91        S: CryptographicSuiteSelect<T, P>,
92    {
93        match self.proofs.split_first() {
94            Some((proof, [])) => {
95                proof
96                    .suite()
97                    .select(&self.claims, proof.borrowed(), params, options)
98                    .await
99            }
100            Some(_) => Err(SelectionError::AmbiguousProof),
101            None => Err(SelectionError::MissingProof),
102        }
103    }
104
105    pub fn map<U>(self, f: impl FnOnce(T) -> U) -> DataIntegrity<U, S> {
106        DataIntegrity {
107            claims: f(self.claims),
108            proofs: self.proofs,
109        }
110    }
111}
112
113impl<T, S: CryptographicSuite> Deref for DataIntegrity<T, S> {
114    type Target = T;
115
116    fn deref(&self) -> &Self::Target {
117        &self.claims
118    }
119}
120
121impl<T, S: CryptographicSuite> DerefMut for DataIntegrity<T, S> {
122    fn deref_mut(&mut self) -> &mut Self::Target {
123        &mut self.claims
124    }
125}
126
127impl<T, S: CryptographicSuite> VerifiableClaims for DataIntegrity<T, S> {
128    type Claims = T;
129    type Proof = Proofs<S>;
130
131    fn claims(&self) -> &Self::Claims {
132        &self.claims
133    }
134
135    fn proof(&self) -> &Self::Proof {
136        &self.proofs
137    }
138}