use crate::crypto::digest::*;
use crate::crypto::key::*;
use crate::crypto::secret::Secret;
use crate::crypto::util::randombytes_into;
use rmp_serde;
fn clone_key(key: &Key) -> Key {
Key::deserialize(key.serialize().unwrap()).unwrap()
}
fn new_password(password: &str) -> Secret {
let bytes = password.as_bytes();
let mut s = Secret::with_len(bytes.len()).unwrap();
unsafe { s.as_mut_slice() }.copy_from_slice(bytes);
s
}
fn random_secret(len: usize) -> Secret {
let mut s = Secret::with_len(len).unwrap();
randombytes_into(unsafe { s.as_mut_slice() });
s
}
#[test]
fn test_nonce_increment() {
crate::init().unwrap();
let nonce = Nonce::new();
let next = Nonce::new();
assert_eq!(nonce, next);
assert_ne!(nonce, next.increment());
}
#[test]
fn test_digest_serde_round_trip() {
crate::init().unwrap();
let key = Key::new_random().unwrap();
let digest = key.get_digest();
let serialized = rmp_serde::to_vec(&digest).unwrap();
let deserialized: Digest = rmp_serde::from_slice(serialized.as_slice()).unwrap();
assert_eq!(digest, deserialized);
}
#[test]
fn test_digest_debug_format() {
crate::init().unwrap();
let key = Key::new_random().unwrap();
let digest = key.get_digest();
let s = format!("{:?}", digest);
assert!(s.starts_with('['), "got {:?}", s);
assert!(s.ends_with(']'), "got {:?}", s);
assert_eq!(63, s.matches(", ").count(), "got {:?}", s);
}
#[test]
fn test_digest_deserialize_wrong_length() {
crate::init().unwrap();
let too_short: Vec<u8> = vec![0u8; 5];
let bytes = rmp_serde::to_vec(&too_short).unwrap();
assert!(rmp_serde::from_slice::<Digest>(&bytes).is_err());
let too_long: Vec<u8> = vec![0u8; 100];
let bytes = rmp_serde::to_vec(&too_long).unwrap();
assert!(rmp_serde::from_slice::<Digest>(&bytes).is_err());
}
#[test]
fn test_password_key_derivation() {
crate::init().unwrap();
let salt = Salt::default();
let _key = Key::new_password(
&new_password("foobar"),
&salt,
OPS_LIMIT_INTERACTIVE,
MEM_LIMIT_INTERACTIVE,
)
.unwrap();
}
#[test]
fn test_basic_key_digest_comparison() {
crate::init().unwrap();
let a = Key::new_random().unwrap();
let b = Key::new_random().unwrap();
let c = clone_key(&a);
assert_eq!(a.get_digest(), c.get_digest());
assert_ne!(a.get_digest(), b.get_digest());
}
#[test]
fn test_encryption_roundtrip() {
crate::init().unwrap();
let key = Key::new_random().unwrap();
let plaintext = random_secret(1024);
let (nonce, ciphertext) = key.encrypt(&plaintext, None).unwrap();
assert_ne!(unsafe { plaintext.as_slice() }, ciphertext.as_slice());
let decrypted = key.decrypt(nonce.as_ref(), ciphertext.as_slice()).unwrap();
assert_eq!(unsafe { plaintext.as_slice() }, unsafe {
decrypted.as_slice()
});
}
fn secret_from_slice(bytes: &[u8]) -> Secret {
let mut s = Secret::with_len(bytes.len()).unwrap();
unsafe { s.as_mut_slice() }.copy_from_slice(bytes);
s
}
#[test]
fn test_key_deserialize_missing_prefix() {
crate::init().unwrap();
let mut bytes = vec![0xffu8; 40];
bytes[0] = 0x00;
assert!(Key::deserialize(secret_from_slice(&bytes)).is_err());
}
#[test]
fn test_key_deserialize_wrong_length() {
crate::init().unwrap();
let mut too_short: Vec<u8> = vec![0x81, 0xa3, 0x4b, 0x65, 0x79, 0x91, 0xc4, 0x20];
too_short.extend_from_slice(&[0u8; 16]);
assert!(Key::deserialize(secret_from_slice(&too_short)).is_err());
let mut too_long: Vec<u8> = vec![0x81, 0xa3, 0x4b, 0x65, 0x79, 0x91, 0xc4, 0x20];
too_long.extend_from_slice(&[0u8; 48]);
assert!(Key::deserialize(secret_from_slice(&too_long)).is_err());
}
#[test]
fn test_key_deserialize_alt_prefix() {
crate::init().unwrap();
let mut bytes: Vec<u8> = vec![0x81, 0x00, 0x91, 0xc4, 0x20];
bytes.extend_from_slice(&[0x42u8; 32]);
let key = Key::deserialize(secret_from_slice(&bytes)).unwrap();
let mut bytes2: Vec<u8> = vec![0x81, 0xa3, 0x4b, 0x65, 0x79, 0x91, 0xc4, 0x20];
bytes2.extend_from_slice(&[0x42u8; 32]);
let key2 = Key::deserialize(secret_from_slice(&bytes2)).unwrap();
assert_eq!(key.get_digest(), key2.get_digest());
}
#[test]
fn test_decrypting_with_wrong_key_fails() {
crate::init().unwrap();
let key = Key::new_random().unwrap();
let plaintext = random_secret(1024);
let (nonce, ciphertext) = key.encrypt(&plaintext, None).unwrap();
assert_ne!(unsafe { plaintext.as_slice() }, ciphertext.as_slice());
let wrong_key = Key::new_random().unwrap();
let decrypted_result = wrong_key.decrypt(nonce.as_ref(), ciphertext.as_slice());
assert!(decrypted_result.is_err());
}
#[test]
fn test_nonce_from_slice_wrong_length() {
crate::init().unwrap();
assert!(Nonce::from_slice(&[0u8; 5]).is_err());
assert!(Nonce::from_slice(&[0u8; 32]).is_err());
assert!(Nonce::from_slice(&[0u8; NONCE_BYTES]).is_ok());
}
#[test]
fn test_decrypt_requires_nonce() {
crate::init().unwrap();
let key = Key::new_random().unwrap();
let plaintext = random_secret(128);
let (_nonce, ciphertext) = key.encrypt(&plaintext, None).unwrap();
assert!(key.decrypt(None, &ciphertext).is_err());
}
#[test]
fn test_decrypt_short_ciphertext() {
crate::init().unwrap();
let key = Key::new_random().unwrap();
let nonce = Nonce::default();
assert!(key.decrypt(Some(&nonce), &[]).is_err());
assert!(key.decrypt(Some(&nonce), &[0u8; TAG_BYTES - 1]).is_err());
}
#[test]
fn test_decrypt_wrong_nonce() {
crate::init().unwrap();
let key = Key::new_random().unwrap();
let plaintext = random_secret(128);
let (nonce, ciphertext) = key.encrypt(&plaintext, None).unwrap();
let wrong_nonce = nonce.unwrap().increment();
assert!(key.decrypt(Some(&wrong_nonce), &ciphertext).is_err());
}