use crate::error::*;
pub type EncryptorDecryptor = jwcrypto::EncryptorDecryptor<Error>;
#[handle_error(Error)]
pub fn create_canary(text: &str, key: &str) -> ApiResult<String> {
EncryptorDecryptor::new(key)?.create_canary(text)
}
#[handle_error(Error)]
pub fn check_canary(canary: &str, text: &str, key: &str) -> ApiResult<bool> {
EncryptorDecryptor::new(key)?.check_canary(canary, text)
}
#[handle_error(Error)]
pub fn create_key() -> ApiResult<String> {
EncryptorDecryptor::create_key()
}
#[cfg(test)]
pub mod test_utils {
use super::*;
use serde::{de::DeserializeOwned, Serialize};
lazy_static::lazy_static! {
pub static ref TEST_ENCRYPTION_KEY: String = serde_json::to_string(&jwcrypto::Jwk::new_direct_key(Some("test-key".to_string())).unwrap()).unwrap();
pub static ref TEST_ENCRYPTOR: EncryptorDecryptor = EncryptorDecryptor::new(&TEST_ENCRYPTION_KEY).unwrap();
}
pub fn encrypt(value: &str) -> String {
TEST_ENCRYPTOR.encrypt(value, "test encrypt").unwrap()
}
pub fn decrypt(value: &str) -> String {
TEST_ENCRYPTOR.decrypt(value, "test decrypt").unwrap()
}
pub fn encrypt_struct<T: Serialize>(fields: &T) -> String {
TEST_ENCRYPTOR
.encrypt_struct(fields, "test encrypt struct")
.unwrap()
}
pub fn decrypt_struct<T: DeserializeOwned>(ciphertext: String) -> T {
TEST_ENCRYPTOR
.decrypt_struct(&ciphertext, "test decrypt struct")
.unwrap()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_encrypt() {
let ed = EncryptorDecryptor::new(&create_key().unwrap()).unwrap();
let cleartext = "secret";
let ciphertext = ed.encrypt(cleartext, "test encrypt").unwrap();
assert_eq!(ed.decrypt(&ciphertext, "test decrypt").unwrap(), cleartext);
let ed2 = EncryptorDecryptor::new(&create_key().unwrap()).unwrap();
assert!(matches!(
ed2.decrypt(&ciphertext, "test decrypt").err().unwrap(),
Error::CryptoError(jwcrypto::EncryptorDecryptorError { description, .. })
if description == "test decrypt"
));
}
#[test]
fn test_key_error() {
let storage_err = EncryptorDecryptor::new("bad-key").err().unwrap();
assert!(matches!(
storage_err,
Error::CryptoError(jwcrypto::EncryptorDecryptorError {
from: jwcrypto::JwCryptoError::InvalidKey,
..
})
));
}
#[test]
fn test_canary_functionality() {
const CANARY_TEXT: &str = "Arbitrary sequence of text";
let key = create_key().unwrap();
let canary = create_canary(CANARY_TEXT, &key).unwrap();
assert!(check_canary(&canary, CANARY_TEXT, &key).unwrap());
let different_key = create_key().unwrap();
assert!(matches!(
check_canary(&canary, CANARY_TEXT, &different_key)
.err()
.unwrap(),
LoginsApiError::IncorrectKey
));
}
}