#![allow(dead_code)] use libsignal_protocol::{ crypto::{Crypto, Sha256Hmac, Sha512Digest, SignalCipherType}, InternalError, }; use std::{panic::RefUnwindSafe, sync::Mutex}; pub(crate) struct MockCrypto { inner: C, random_func: Option< Box< dyn Fn(&mut [u8]) -> Result<(), InternalError> + RefUnwindSafe + 'static, >, >, } impl MockCrypto { pub fn new(inner: C) -> MockCrypto { MockCrypto { inner, random_func: None, } } pub fn random_func(mut self, func: F) -> Self where F: Fn(&mut [u8]) -> Result<(), InternalError> + RefUnwindSafe + 'static, { self.random_func = Some(Box::new(func)); self } } impl Crypto for MockCrypto { fn fill_random(&self, buffer: &mut [u8]) -> Result<(), InternalError> { if let Some(ref random_func) = self.random_func { random_func(buffer) } else { self.inner.fill_random(buffer) } } fn hmac_sha256( &self, key: &[u8], ) -> Result, InternalError> { self.inner.hmac_sha256(key) } fn sha512_digest(&self) -> Result, InternalError> { self.inner.sha512_digest() } fn encrypt( &self, cipher: SignalCipherType, key: &[u8], iv: &[u8], data: &[u8], ) -> Result, InternalError> { self.inner.encrypt(cipher, key, iv, data) } fn decrypt( &self, cipher: SignalCipherType, key: &[u8], iv: &[u8], data: &[u8], ) -> Result, InternalError> { self.inner.decrypt(cipher, key, iv, data) } } pub fn fake_random_generator() -> impl Fn(&mut [u8]) -> Result<(), InternalError> { let test_next_random = Mutex::new(0); move |data| { let mut test_next_random = test_next_random.lock().unwrap(); for i in 0..data.len() { data[i] = *test_next_random; *test_next_random = test_next_random.wrapping_add(1); } Ok(()) } }