use std::fmt;
use std::io::{self, Read, Write};
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Error {
Encrypt,
Decrypt,
Algorithm,
Key,
Base64Decode(String),
Read(String),
Write(String),
Platform(String),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Encrypt => write!(f, "Could not encrypt input."),
Self::Decrypt => write!(
f,
"\
Could not decrypt input.
You are likely using the wrong key, or the data is corrupted."
),
Self::Algorithm => write!(f, "Incompatible cipher algorithm."),
Self::Key => write!(f, "The key is not compatible with the algoritm."),
Self::Base64Decode(reason) => write!(f, "Could not decode base64: {reason}"),
Self::Read(reason) => write!(f, "Could not read from input: {reason}"),
Self::Write(reason) => write!(f, "Could not write to output: {reason}"),
Self::Platform(reason) => write!(f, "{reason}"),
}
}
}
impl std::error::Error for Error {}
pub type Result<T> = std::result::Result<T, Error>;
pub enum GeneratedKey {
Symmetric(Vec<u8>),
None,
}
pub trait Cipher {
fn new() -> Self
where
Self: Sized;
#[must_use]
fn generate_key(&self) -> GeneratedKey;
fn encrypt(&self, key: &[u8], plaintext: &[u8]) -> Result<Vec<u8>> {
let mut encrypted = Vec::new();
self.encrypt_stream(key, &mut io::Cursor::new(plaintext), &mut encrypted)?;
Ok(encrypted)
}
fn decrypt(&self, key: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>> {
let mut decrypted = Vec::new();
self.decrypt_stream(key, &mut io::Cursor::new(ciphertext), &mut decrypted)?;
Ok(decrypted)
}
fn encrypt_stream(
&self,
key: &[u8],
reader: &mut dyn Read,
writer: &mut dyn Write,
) -> Result<()>;
fn decrypt_stream(
&self,
key: &[u8],
reader: &mut dyn Read,
writer: &mut dyn Write,
) -> Result<()>;
}
pub trait Base64Encode {
#[must_use]
fn base64_encode(&self) -> String;
}
pub trait Base64Decode {
fn base64_decode(&self) -> Result<Vec<u8>>;
}