ssi_verification_methods_core/
verification.rs

1use std::{
2    fmt,
3    ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign},
4};
5
6use iref::{Iri, IriBuf};
7use ssi_claims_core::{ProofValidationError, ProofValidity};
8use ssi_jwk::JWK;
9use static_iref::iri;
10
11macro_rules! proof_purposes {
12    ($($(#[$doc:meta])* $id:ident: $variant:ident = $iri:literal),*) => {
13        /// Proof purposes.
14        #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, linked_data::Serialize, linked_data::Deserialize)]
15        #[derive(serde::Serialize, serde::Deserialize)]
16        pub enum ProofPurpose {
17            $(
18                $(#[$doc])*
19                #[ld($iri)]
20                $variant
21            ),*
22        }
23
24        impl ProofPurpose {
25            pub fn from_iri(iri: &Iri) -> Option<Self> {
26                $(
27                    if iri == iri!($iri) {
28                        return Some(Self::$variant)
29                    }
30                )*
31
32                None
33            }
34
35            pub fn iri(&self) -> &Iri {
36                match self {
37                    $(
38                        Self::$variant => iri!($iri)
39                    ),*
40                }
41            }
42        }
43
44        impl BitOr<ProofPurpose> for ProofPurpose {
45            type Output = ProofPurposes;
46
47            fn bitor(self, other: Self) -> ProofPurposes {
48                let result: ProofPurposes = self.into();
49                result | other
50            }
51        }
52
53        /// Set of proof purposes.
54        #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
55        pub struct ProofPurposes {
56            $(
57                pub $id: bool
58            ),*
59        }
60
61        impl ProofPurposes {
62            pub fn none() -> Self {
63                Self::default()
64            }
65
66            pub fn all() -> Self {
67                Self {
68                    $(
69                        $id: true
70                    ),*
71                }
72            }
73
74            pub fn contains(&self, p: ProofPurpose) -> bool {
75                match p {
76                    $(
77                        ProofPurpose::$variant => {
78                            self.$id
79                        }
80                    )*
81                }
82            }
83
84            pub fn contains_all(&self, p: Self) -> bool {
85                *self & p == p
86            }
87
88            pub fn insert(&mut self, p: ProofPurpose) {
89                match p {
90                    $(
91                        ProofPurpose::$variant => {
92                            self.$id = true
93                        }
94                    )*
95                }
96            }
97
98            pub fn remove(&mut self, p: ProofPurpose) {
99                match p {
100                    $(
101                        ProofPurpose::$variant => {
102                            self.$id = false
103                        }
104                    )*
105                }
106            }
107
108            pub fn iter(&self) -> ProofPurposesIter {
109                ProofPurposesIter {
110                    $(
111                        $id: self.$id
112                    ),*
113                }
114            }
115        }
116
117        impl From<ProofPurpose> for ProofPurposes {
118            fn from(p: ProofPurpose) -> Self {
119                match p {
120                    $(
121                        ProofPurpose::$variant => {
122                            Self {
123                                $id: true,
124                                ..Self::default()
125                            }
126                        }
127                    )*
128                }
129            }
130        }
131
132        impl BitOr for ProofPurposes {
133            type Output = Self;
134
135            fn bitor(self, other: Self) -> Self {
136                Self {
137                    $(
138                        $id: self.$id | other.$id
139                    ),*
140                }
141            }
142        }
143
144        impl BitOrAssign for ProofPurposes {
145            fn bitor_assign(&mut self, other: Self) {
146                $(
147                    self.$id |= other.$id;
148                )*
149            }
150        }
151
152        impl BitOr<ProofPurpose> for ProofPurposes {
153            type Output = Self;
154
155            fn bitor(self, other: ProofPurpose) -> Self {
156                match other {
157                    $(
158                        ProofPurpose::$variant => {
159                            Self {
160                                $id: true,
161                                ..self
162                            }
163                        }
164                    )*
165                }
166            }
167        }
168
169        impl BitOrAssign<ProofPurpose> for ProofPurposes {
170            fn bitor_assign(&mut self, other: ProofPurpose) {
171                match other {
172                    $(
173                        ProofPurpose::$variant => {
174                            self.$id = true;
175                        }
176                    )*
177                }
178            }
179        }
180
181        impl BitAnd for ProofPurposes {
182            type Output = Self;
183
184            fn bitand(self, other: Self) -> Self {
185                Self {
186                    $(
187                        $id: self.$id & other.$id
188                    ),*
189                }
190            }
191        }
192
193        impl BitAndAssign for ProofPurposes {
194            fn bitand_assign(&mut self, other: Self) {
195                $(
196                    self.$id &= other.$id;
197                )*
198            }
199        }
200
201        impl BitAnd<ProofPurpose> for ProofPurposes {
202            type Output = Self;
203
204            fn bitand(self, other: ProofPurpose) -> Self {
205                match other {
206                    $(
207                        ProofPurpose::$variant => {
208                            Self {
209                                $id: true,
210                                ..Self::default()
211                            }
212                        }
213                    )*
214                }
215            }
216        }
217
218        impl BitAndAssign<ProofPurpose> for ProofPurposes {
219            fn bitand_assign(&mut self, other: ProofPurpose) {
220                match other {
221                    $(
222                        ProofPurpose::$variant => {
223                            *self = Self {
224                                $id: true,
225                                ..Self::default()
226                            };
227                        }
228                    )*
229                }
230            }
231        }
232
233        impl IntoIterator for ProofPurposes {
234            type Item = ProofPurpose;
235            type IntoIter = ProofPurposesIter;
236
237            fn into_iter(self) -> Self::IntoIter {
238                self.iter()
239            }
240        }
241
242        #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
243        pub struct ProofPurposesIter {
244            $(
245                pub $id: bool
246            ),*
247        }
248
249        impl Iterator for ProofPurposesIter {
250            type Item = ProofPurpose;
251
252            fn next(&mut self) -> Option<ProofPurpose> {
253                $(
254                    if self.$id {
255                        self.$id = false;
256                        return Some(ProofPurpose::$variant)
257                    }
258                )*
259
260                None
261            }
262        }
263    };
264}
265
266proof_purposes! {
267    /// <https://w3id.org/security#assertionMethod>
268    #[serde(rename = "assertionMethod")]
269    #[default]
270    assertion_method: Assertion = "https://w3id.org/security#assertionMethod",
271
272    /// <https://w3id.org/security#authentication>
273    #[serde(rename = "authentication")]
274    authentication: Authentication = "https://w3id.org/security#authentication",
275
276    /// <https://w3id.org/security#capabilityInvocation>
277    #[serde(rename = "capabilityInvocation")]
278    capability_invocation: CapabilityInvocation = "https://w3id.org/security#capabilityInvocation",
279
280    /// <https://w3id.org/security#capabilityDelegation>
281    #[serde(rename = "capabilityDelegation")]
282    capability_delegation: CapabilityDelegation = "https://w3id.org/security#capabilityDelegation",
283
284    /// <https://w3id.org/security#keyAgreement>
285    #[serde(rename = "keyAgreement")]
286    key_agreement: KeyAgreement = "https://w3id.org/security#keyAgreement"
287}
288
289impl fmt::Display for ProofPurpose {
290    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
291        self.iri().fmt(f)
292    }
293}
294
295pub struct UnknownProofPurpose(pub IriBuf);
296
297impl TryFrom<IriBuf> for ProofPurpose {
298    type Error = UnknownProofPurpose;
299
300    fn try_from(value: IriBuf) -> Result<Self, Self::Error> {
301        match Self::from_iri(value.as_iri()) {
302            Some(p) => Ok(p),
303            None => Err(UnknownProofPurpose(value)),
304        }
305    }
306}
307
308pub trait VerifyBytes<A> {
309    fn verify_bytes(
310        &self,
311        algorithm: A,
312        signing_bytes: &[u8],
313        signature: &[u8],
314    ) -> Result<ProofValidity, ProofValidationError>;
315}
316
317pub trait VerifyBytesWithRecoveryJwk<A> {
318    fn verify_bytes_with_public_jwk(
319        &self,
320        public_jwk: &JWK,
321        algorithm: A,
322        signing_bytes: &[u8],
323        signature: &[u8],
324    ) -> Result<ProofValidity, ProofValidationError>;
325}