#![deny(missing_docs)]
#![deny(rustdoc::broken_intra_doc_links)]
pub mod asymmetric;
pub mod cipher;
pub mod encrypter;
pub mod key;
pub mod signer;
pub use asymmetric::{
BoxKeyPair, BoxPublicKey, Ed25519Signer, SealedBox, SigningKeyPair, VerifyingPublicKey,
};
pub use cipher::Cipher;
pub use encrypter::{AeadEncrypter, Encrypter, EncrypterExt};
pub use key::{Key, KeyRing, KEY_LEN};
pub use signer::{HmacSigner, Signer, SignerExt};
use std::sync::Arc;
use rainier_support::Result;
use serde::de::DeserializeOwned;
use serde::Serialize;
#[derive(Clone)]
pub struct Encryption {
encrypter: Arc<dyn Encrypter>,
signer: Arc<dyn Signer>,
}
impl Encryption {
pub fn new(encrypter: Arc<dyn Encrypter>, signer: Arc<dyn Signer>) -> Self {
Self { encrypter, signer }
}
pub fn from_keys(keys: KeyRing) -> Self {
Self::from_keys_with(keys, Cipher::default())
}
pub fn from_keys_with(keys: KeyRing, cipher: Cipher) -> Self {
Self::new(
Arc::new(AeadEncrypter::new(keys.clone()).with_cipher(cipher)),
Arc::new(HmacSigner::new(keys)),
)
}
pub fn encrypter(&self) -> &Arc<dyn Encrypter> {
&self.encrypter
}
pub fn signer(&self) -> &Arc<dyn Signer> {
&self.signer
}
pub fn encrypt(&self, plain: &str) -> Result<String> {
self.encrypter.encrypt(plain)
}
pub fn decrypt(&self, payload: &str) -> Result<String> {
self.encrypter.decrypt(payload)
}
pub fn encrypt_bytes(&self, plain: &[u8]) -> Result<String> {
self.encrypter.encrypt_bytes(plain)
}
pub fn decrypt_bytes(&self, payload: &str) -> Result<Vec<u8>> {
self.encrypter.decrypt_bytes(payload)
}
pub fn encrypt_json<T: Serialize>(&self, value: &T) -> Result<String> {
self.encrypter.encrypt_json(value)
}
pub fn decrypt_json<T: DeserializeOwned>(&self, payload: &str) -> Result<T> {
self.encrypter.decrypt_json(payload)
}
pub fn sign(&self, value: &str) -> Result<String> {
self.signer.sign(value)
}
pub fn verify(&self, signed: &str) -> Result<String> {
self.signer.verify(signed)
}
pub fn is_valid(&self, signed: &str) -> bool {
self.signer.is_valid(signed)
}
}
impl std::fmt::Debug for Encryption {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("Encryption(..)")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_facade_value_does_both_halves() {
let crypt = Encryption::from_keys(KeyRing::new(Key::generate()));
assert_eq!(crypt.decrypt(&crypt.encrypt("sealed").unwrap()).unwrap(), "sealed");
assert_eq!(crypt.verify(&crypt.sign("signed").unwrap()).unwrap(), "signed");
}
#[test]
fn json_round_trips_through_the_facade_value() {
let crypt = Encryption::from_keys(KeyRing::new(Key::generate()));
let payload = crypt.encrypt_json(&vec![1u8, 2, 3]).unwrap();
assert_eq!(crypt.decrypt_json::<Vec<u8>>(&payload).unwrap(), vec![1, 2, 3]);
}
#[test]
fn debug_does_not_disclose_anything() {
let crypt = Encryption::from_keys(KeyRing::new(Key::from_bytes([3u8; KEY_LEN])));
assert_eq!(format!("{crypt:?}"), "Encryption(..)");
}
}