ssi_verification_methods_core/
verification.rs1use 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 #[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 #[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 #[serde(rename = "assertionMethod")]
269 #[default]
270 assertion_method: Assertion = "https://w3id.org/security#assertionMethod",
271
272 #[serde(rename = "authentication")]
274 authentication: Authentication = "https://w3id.org/security#authentication",
275
276 #[serde(rename = "capabilityInvocation")]
278 capability_invocation: CapabilityInvocation = "https://w3id.org/security#capabilityInvocation",
279
280 #[serde(rename = "capabilityDelegation")]
282 capability_delegation: CapabilityDelegation = "https://w3id.org/security#capabilityDelegation",
283
284 #[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}