1use coset::iana;
23
24use crate::error::CryptoResult;
25
26pub trait SignatureVerifier: Send + Sync {
31 fn verify(
44 &self,
45 algorithm: iana::Algorithm,
46 key_id: Option<&[u8]>,
47 data: &[u8],
48 signature: &[u8],
49 ) -> CryptoResult<()>;
50}
51
52pub trait Decryptor: Send + Sync {
57 fn decrypt(
70 &self,
71 algorithm: iana::Algorithm,
72 key_id: Option<&[u8]>,
73 nonce: &[u8],
74 aad: &[u8],
75 ciphertext: &[u8],
76 ) -> CryptoResult<Vec<u8>>;
77}
78
79pub trait Signer: Send + Sync {
84 fn sign(
94 &self,
95 algorithm: iana::Algorithm,
96 key_id: Option<&[u8]>,
97 data: &[u8],
98 ) -> CryptoResult<Vec<u8>>;
99
100 fn key_id(&self) -> Option<&[u8]> {
102 None
103 }
104}
105
106pub trait Encryptor: Send + Sync {
111 fn encrypt(
123 &self,
124 algorithm: iana::Algorithm,
125 key_id: Option<&[u8]>,
126 nonce: &[u8],
127 aad: &[u8],
128 plaintext: &[u8],
129 ) -> CryptoResult<Vec<u8>>;
130}
131
132pub trait KeyResolver: Send + Sync {
137 fn resolve_verifier(
139 &self,
140 key_id: Option<&[u8]>,
141 algorithm: iana::Algorithm,
142 ) -> CryptoResult<Box<dyn SignatureVerifier>>;
143
144 fn resolve_decryptor(
146 &self,
147 key_id: Option<&[u8]>,
148 algorithm: iana::Algorithm,
149 ) -> CryptoResult<Box<dyn Decryptor>>;
150}
151
152impl<T: SignatureVerifier + ?Sized> SignatureVerifier for &T {
154 fn verify(
155 &self,
156 algorithm: iana::Algorithm,
157 key_id: Option<&[u8]>,
158 data: &[u8],
159 signature: &[u8],
160 ) -> CryptoResult<()> {
161 (*self).verify(algorithm, key_id, data, signature)
162 }
163}
164
165impl<T: SignatureVerifier + ?Sized> SignatureVerifier for Box<T> {
167 fn verify(
168 &self,
169 algorithm: iana::Algorithm,
170 key_id: Option<&[u8]>,
171 data: &[u8],
172 signature: &[u8],
173 ) -> CryptoResult<()> {
174 self.as_ref().verify(algorithm, key_id, data, signature)
175 }
176}
177
178impl<T: Decryptor + ?Sized> Decryptor for &T {
180 fn decrypt(
181 &self,
182 algorithm: iana::Algorithm,
183 key_id: Option<&[u8]>,
184 nonce: &[u8],
185 aad: &[u8],
186 ciphertext: &[u8],
187 ) -> CryptoResult<Vec<u8>> {
188 (*self).decrypt(algorithm, key_id, nonce, aad, ciphertext)
189 }
190}
191
192impl<T: Decryptor + ?Sized> Decryptor for Box<T> {
194 fn decrypt(
195 &self,
196 algorithm: iana::Algorithm,
197 key_id: Option<&[u8]>,
198 nonce: &[u8],
199 aad: &[u8],
200 ciphertext: &[u8],
201 ) -> CryptoResult<Vec<u8>> {
202 self.as_ref()
203 .decrypt(algorithm, key_id, nonce, aad, ciphertext)
204 }
205}
206
207#[cfg(test)]
208mod tests {
209 use super::*;
210 use crate::error::CryptoError;
211
212 struct MockVerifier {
214 expected_result: bool,
215 }
216
217 impl SignatureVerifier for MockVerifier {
218 fn verify(
219 &self,
220 _algorithm: iana::Algorithm,
221 _key_id: Option<&[u8]>,
222 _data: &[u8],
223 _signature: &[u8],
224 ) -> CryptoResult<()> {
225 if self.expected_result {
226 Ok(())
227 } else {
228 Err(CryptoError::VerificationFailed)
229 }
230 }
231 }
232
233 struct MockDecryptor {
235 plaintext: Vec<u8>,
236 }
237
238 impl Decryptor for MockDecryptor {
239 fn decrypt(
240 &self,
241 _algorithm: iana::Algorithm,
242 _key_id: Option<&[u8]>,
243 _nonce: &[u8],
244 _aad: &[u8],
245 _ciphertext: &[u8],
246 ) -> CryptoResult<Vec<u8>> {
247 Ok(self.plaintext.clone())
248 }
249 }
250
251 struct MockSigner;
253
254 impl Signer for MockSigner {
255 fn sign(
256 &self,
257 _algorithm: iana::Algorithm,
258 _key_id: Option<&[u8]>,
259 _data: &[u8],
260 ) -> CryptoResult<Vec<u8>> {
261 Ok(vec![1, 2, 3, 4])
262 }
263 }
265
266 #[test]
267 fn test_signature_verifier_ref_blanket_impl() {
268 let verifier = MockVerifier {
269 expected_result: true,
270 };
271 let verifier_ref: &dyn SignatureVerifier = &verifier;
272
273 let result = verifier_ref.verify(iana::Algorithm::EdDSA, None, b"data", b"sig");
274 assert!(result.is_ok());
275 }
276
277 #[test]
278 fn test_signature_verifier_box_blanket_impl() {
279 let verifier = MockVerifier {
280 expected_result: true,
281 };
282 let boxed: Box<dyn SignatureVerifier> = Box::new(verifier);
283
284 let result = boxed.verify(iana::Algorithm::EdDSA, None, b"data", b"sig");
285 assert!(result.is_ok());
286 }
287
288 #[test]
289 fn test_signature_verifier_box_failure() {
290 let verifier = MockVerifier {
291 expected_result: false,
292 };
293 let boxed: Box<dyn SignatureVerifier> = Box::new(verifier);
294
295 let result = boxed.verify(iana::Algorithm::EdDSA, None, b"data", b"sig");
296 assert!(result.is_err());
297 assert!(matches!(
298 result.unwrap_err(),
299 CryptoError::VerificationFailed
300 ));
301 }
302
303 #[test]
304 fn test_decryptor_ref_blanket_impl() {
305 let decryptor = MockDecryptor {
306 plaintext: vec![1, 2, 3],
307 };
308 let decryptor_ref: &dyn Decryptor = &decryptor;
309
310 let result = decryptor_ref.decrypt(iana::Algorithm::A256GCM, None, b"nonce", b"aad", b"ct");
311 assert!(result.is_ok());
312 assert_eq!(result.unwrap(), vec![1, 2, 3]);
313 }
314
315 #[test]
316 fn test_decryptor_box_blanket_impl() {
317 let decryptor = MockDecryptor {
318 plaintext: vec![4, 5, 6],
319 };
320 let boxed: Box<dyn Decryptor> = Box::new(decryptor);
321
322 let result = boxed.decrypt(iana::Algorithm::A256GCM, None, b"nonce", b"aad", b"ct");
323 assert!(result.is_ok());
324 assert_eq!(result.unwrap(), vec![4, 5, 6]);
325 }
326
327 #[test]
328 fn test_signer_default_key_id() {
329 let signer = MockSigner;
330 assert!(signer.key_id().is_none());
331 }
332
333 #[test]
334 fn test_signature_verifier_with_key_id() {
335 let verifier = MockVerifier {
336 expected_result: true,
337 };
338 let key_id = b"test-key-id";
339
340 let result = verifier.verify(iana::Algorithm::EdDSA, Some(key_id), b"data", b"sig");
341 assert!(result.is_ok());
342 }
343
344 #[test]
345 fn test_decryptor_with_key_id() {
346 let decryptor = MockDecryptor {
347 plaintext: vec![7, 8, 9],
348 };
349 let key_id = b"decrypt-key-id";
350
351 let result = decryptor.decrypt(
352 iana::Algorithm::A256GCM,
353 Some(key_id),
354 b"nonce",
355 b"aad",
356 b"ciphertext",
357 );
358 assert!(result.is_ok());
359 assert_eq!(result.unwrap(), vec![7, 8, 9]);
360 }
361}