|  | @@ -2,12 +2,30 @@
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  use super::*;
 |  |  use super::*;
 | 
											
												
													
														|  |  use openssl::{
 |  |  use openssl::{
 | 
											
												
													
														|  | -    symm::{Cipher, Crypter, Mode}
 |  | 
 | 
											
												
													
														|  | 
 |  | +    symm::{Cipher, encrypt as openssl_encrypt, decrypt as openssl_decrypt}
 | 
											
												
													
														|  |  };
 |  |  };
 | 
											
												
													
														|  | 
 |  | +use serde_block_tree::{to_vec, from_vec};
 | 
											
												
													
														|  | 
 |  | +use serde::de::{DeserializeOwned};
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +/// Data that may or may not be encrypted.
 | 
											
												
													
														|  | 
 |  | +#[derive(Debug, PartialEq, Serialize, Deserialize)]
 | 
											
												
													
														|  | 
 |  | +pub enum Cryptotext<T: Serialize> {
 | 
											
												
													
														|  | 
 |  | +    /// The inner value of `T` is in plaintext.
 | 
											
												
													
														|  | 
 |  | +    Plain(T),
 | 
											
												
													
														|  | 
 |  | +    /// The inner value of `T` is in ciphertext.
 | 
											
												
													
														|  | 
 |  | +    Cipher(Vec<u8>),
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +pub trait Hydrate<const N: usize> {
 | 
											
												
													
														|  | 
 |  | +    fn hydrate(template: Self, data: [u8; N]) -> Self;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  /// Errors that can occur during cryptographic operations.
 |  |  /// Errors that can occur during cryptographic operations.
 | 
											
												
													
														|  | 
 |  | +#[derive(Debug)]
 | 
											
												
													
														|  |  pub enum Error {
 |  |  pub enum Error {
 | 
											
												
													
														|  | -    NoReadCap
 |  | 
 | 
											
												
													
														|  | 
 |  | +    NoReadCap,
 | 
											
												
													
														|  | 
 |  | +    Encryption(String),
 | 
											
												
													
														|  | 
 |  | +    Decryption(String),
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  pub type Result<T> = std::result::Result<T, Error>;
 |  |  pub type Result<T> = std::result::Result<T, Error>;
 | 
											
										
											
												
													
														|  | @@ -33,20 +51,78 @@ pub enum Signature {
 | 
											
												
													
														|  |  #[allow(dead_code)]
 |  |  #[allow(dead_code)]
 | 
											
												
													
														|  |  #[derive(Debug, PartialEq, Serialize, Deserialize)]
 |  |  #[derive(Debug, PartialEq, Serialize, Deserialize)]
 | 
											
												
													
														|  |  pub enum Key {
 |  |  pub enum Key {
 | 
											
												
													
														|  | -    Xsalsa20Poly1305([u8; 32]),
 |  | 
 | 
											
												
													
														|  | 
 |  | +    // For keys that contain IVs, the key always comes first. The function `key_len` can be used
 | 
											
												
													
														|  | 
 |  | +    // to get the length of the key part of a variant's array.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /// A key for the AES 256 cipher in Cipher Block Chaining mode. Note that this includes the
 | 
											
												
													
														|  | 
 |  | +    /// initialization vector, so that a value of this variant contains all the information needed
 | 
											
												
													
														|  | 
 |  | +    /// to fully initialize a cipher context.
 | 
											
												
													
														|  | 
 |  | +    #[serde(with = "BigArray")]
 | 
											
												
													
														|  | 
 |  | +    Aes256Cbc([u8; 32 + 16]),
 | 
											
												
													
														|  | 
 |  | +    /// A key for the AES 256 cipher in counter mode.
 | 
											
												
													
														|  | 
 |  | +    Aes256Ctr([u8; 32]),
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  impl Key {
 |  |  impl Key {
 | 
											
												
													
														|  | -    /// Returns the data in the key as a slice.
 |  | 
 | 
											
												
													
														|  | -    fn as_slice(&self) -> &[u8] {
 |  | 
 | 
											
												
													
														|  | -        let Key::Xsalsa20Poly1305(array) = self;
 |  | 
 | 
											
												
													
														|  | -        array
 |  | 
 | 
											
												
													
														|  | 
 |  | +    /// Returns the array in this `Key` as a slice.
 | 
											
												
													
														|  | 
 |  | +    pub fn as_slice(&self) -> &[u8] {
 | 
											
												
													
														|  | 
 |  | +        match self {
 | 
											
												
													
														|  | 
 |  | +            Key::Aes256Cbc(array) => array,
 | 
											
												
													
														|  | 
 |  | +            Key::Aes256Ctr(array) => array,
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    /// Returns the data in the key as a mutable slice.
 |  | 
 | 
											
												
													
														|  | -    fn as_mut_slice(&mut self) -> &mut [u8] {
 |  | 
 | 
											
												
													
														|  | -        let Key::Xsalsa20Poly1305(array) = self;
 |  | 
 | 
											
												
													
														|  | -        array
 |  | 
 | 
											
												
													
														|  | 
 |  | +    /// Returns the array in this `Key` as a mutable slice.
 | 
											
												
													
														|  | 
 |  | +    pub fn as_mut_slice(&mut self) -> &mut [u8] {
 | 
											
												
													
														|  | 
 |  | +        match self {
 | 
											
												
													
														|  | 
 |  | +            Key::Aes256Cbc(array) => array,
 | 
											
												
													
														|  | 
 |  | +            Key::Aes256Ctr(array) => array,
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /// Returns the length of the key part of the array in this `Key`. Note that the bytes of the
 | 
											
												
													
														|  | 
 |  | +    /// key come before the bytes of the IV.
 | 
											
												
													
														|  | 
 |  | +    const fn key_len(&self) -> usize {
 | 
											
												
													
														|  | 
 |  | +        let (array_len, key_len) = match self {
 | 
											
												
													
														|  | 
 |  | +            Key::Aes256Cbc(array) => (array.len(), 32),
 | 
											
												
													
														|  | 
 |  | +            Key::Aes256Ctr(array) => (array.len(), 32)
 | 
											
												
													
														|  | 
 |  | +        };
 | 
											
												
													
														|  | 
 |  | +        debug_assert!(key_len <= array_len);
 | 
											
												
													
														|  | 
 |  | +        key_len
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /// Returns the key part of this `Key`.
 | 
											
												
													
														|  | 
 |  | +    pub fn key_slice(&self) -> &[u8] {
 | 
											
												
													
														|  | 
 |  | +        let key_len = self.key_len();
 | 
											
												
													
														|  | 
 |  | +        &self.as_slice()[..key_len]
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /// Returns the IV part of this`Key`.
 | 
											
												
													
														|  | 
 |  | +    pub fn iv_slice(&self) -> Option<&[u8]> {
 | 
											
												
													
														|  | 
 |  | +        let key_len = self.key_len();
 | 
											
												
													
														|  | 
 |  | +        let slice = self.as_slice();
 | 
											
												
													
														|  | 
 |  | +        if key_len == slice.len() {
 | 
											
												
													
														|  | 
 |  | +            None
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        else {
 | 
											
												
													
														|  | 
 |  | +            Some(&slice[key_len..])
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /// Packs the given key and IV into the given output buffer.
 | 
											
												
													
														|  | 
 |  | +    pub fn pack(output: &mut [u8], key: &[u8], iv: &[u8]) {
 | 
											
												
													
														|  | 
 |  | +        debug_assert_eq!(output.len(), key.len() + iv.len());
 | 
											
												
													
														|  | 
 |  | +        let key_len = key.len();
 | 
											
												
													
														|  | 
 |  | +        output[..key_len].copy_from_slice(key);
 | 
											
												
													
														|  | 
 |  | +        output[key_len..].copy_from_slice(iv);
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /// Returns the cipher that this key is for.
 | 
											
												
													
														|  | 
 |  | +    fn cipher(&self) -> Cipher {
 | 
											
												
													
														|  | 
 |  | +        match self {
 | 
											
												
													
														|  | 
 |  | +            Key::Aes256Cbc(_) => Cipher::aes_256_cbc(),
 | 
											
												
													
														|  | 
 |  | +            Key::Aes256Ctr(_) => Cipher::aes_256_ctr(),
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -67,16 +143,16 @@ pub(crate) fn encrypt_block(
 | 
											
												
													
														|  |      versioned_block: VersionedBlock, principal: &Principal, key: &Key
 |  |      versioned_block: VersionedBlock, principal: &Principal, key: &Key
 | 
											
												
													
														|  |  ) -> Result<VersionedBlock> {
 |  |  ) -> Result<VersionedBlock> {
 | 
											
												
													
														|  |      let VersionedBlock::V0(mut block) = versioned_block;
 |  |      let VersionedBlock::V0(mut block) = versioned_block;
 | 
											
												
													
														|  | -    let mut body = match block.body {
 |  | 
 | 
											
												
													
														|  | 
 |  | +    let body = match block.body {
 | 
											
												
													
														|  |          Cryptotext::Cipher(_) => return Ok(VersionedBlock::V0(block)),
 |  |          Cryptotext::Cipher(_) => return Ok(VersionedBlock::V0(block)),
 | 
											
												
													
														|  |          Cryptotext::Plain(body) => body
 |  |          Cryptotext::Plain(body) => body
 | 
											
												
													
														|  |      };
 |  |      };
 | 
											
												
													
														|  |      let (principal_owned, read_cap) = block.read_caps.remove_entry(principal)
 |  |      let (principal_owned, read_cap) = block.read_caps.remove_entry(principal)
 | 
											
												
													
														|  |          .ok_or(Error::NoReadCap)?;
 |  |          .ok_or(Error::NoReadCap)?;
 | 
											
												
													
														|  |      let block_key = decrypt(read_cap, key)?;
 |  |      let block_key = decrypt(read_cap, key)?;
 | 
											
												
													
														|  | -    encrypt_in_place(&mut body, &block_key)?;
 |  | 
 | 
											
												
													
														|  | -    block.body = Cryptotext::Cipher(body);
 |  | 
 | 
											
												
													
														|  | -    block.read_caps.insert(principal_owned, encrypt(block_key, key)?);
 |  | 
 | 
											
												
													
														|  | 
 |  | +    let new_body = encrypt_slice(&body, &block_key)?;
 | 
											
												
													
														|  | 
 |  | +    block.body = Cryptotext::Cipher(new_body);
 | 
											
												
													
														|  | 
 |  | +    block.read_caps.insert(principal_owned, encrypt(&block_key, key)?);
 | 
											
												
													
														|  |      Ok(VersionedBlock::V0(block))
 |  |      Ok(VersionedBlock::V0(block))
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -85,90 +161,98 @@ pub(crate) fn decrypt_block(
 | 
											
												
													
														|  |      versioned_block: VersionedBlock, principal: &Principal, key: &Key
 |  |      versioned_block: VersionedBlock, principal: &Principal, key: &Key
 | 
											
												
													
														|  |  ) -> Result<VersionedBlock> {
 |  |  ) -> Result<VersionedBlock> {
 | 
											
												
													
														|  |      let VersionedBlock::V0(mut block) = versioned_block;
 |  |      let VersionedBlock::V0(mut block) = versioned_block;
 | 
											
												
													
														|  | -    let mut body = match block.body {
 |  | 
 | 
											
												
													
														|  | 
 |  | +    let body = match block.body {
 | 
											
												
													
														|  |          Cryptotext::Plain(_) => return Ok(VersionedBlock::V0(block)),
 |  |          Cryptotext::Plain(_) => return Ok(VersionedBlock::V0(block)),
 | 
											
												
													
														|  |          Cryptotext::Cipher(body) => body
 |  |          Cryptotext::Cipher(body) => body
 | 
											
												
													
														|  |      };
 |  |      };
 | 
											
												
													
														|  |      let (principal_owned, read_cap) = block.read_caps.remove_entry(principal)
 |  |      let (principal_owned, read_cap) = block.read_caps.remove_entry(principal)
 | 
											
												
													
														|  |          .ok_or(Error::NoReadCap)?;
 |  |          .ok_or(Error::NoReadCap)?;
 | 
											
												
													
														|  |      let block_key = decrypt(read_cap, key)?;
 |  |      let block_key = decrypt(read_cap, key)?;
 | 
											
												
													
														|  | -    decrypt_in_place(&mut body, &block_key)?;
 |  | 
 | 
											
												
													
														|  | -    block.body = Cryptotext::Plain(body);
 |  | 
 | 
											
												
													
														|  | 
 |  | +    let new_body = decrypt_slice(&body, &block_key)?;
 | 
											
												
													
														|  | 
 |  | +    block.body = Cryptotext::Plain(new_body);
 | 
											
												
													
														|  |      block.read_caps.insert(principal_owned, Cryptotext::Plain(block_key));
 |  |      block.read_caps.insert(principal_owned, Cryptotext::Plain(block_key));
 | 
											
												
													
														|  |      Ok(VersionedBlock::V0(block))
 |  |      Ok(VersionedBlock::V0(block))
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -fn encrypt<T: AsRef<[u8]> + AsMut<[u8]>>(mut data: T, key: &Key) -> Result<Cryptotext<T>> {
 |  | 
 | 
											
												
													
														|  | -    encrypt_in_place(data.as_mut(), key)?;
 |  | 
 | 
											
												
													
														|  | -    Ok(Cryptotext::Cipher(data))
 |  | 
 | 
											
												
													
														|  | 
 |  | +fn encrypt<T: Serialize>(value: &T, key: &Key) -> Result<Cryptotext<T>> {
 | 
											
												
													
														|  | 
 |  | +    let data = to_vec(value).map_err(|err| Error::Encryption(err.to_string()))?;
 | 
											
												
													
														|  | 
 |  | +    let vec = encrypt_slice(data.as_slice(), key);
 | 
											
												
													
														|  | 
 |  | +    Ok(Cryptotext::Cipher(vec?))
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -fn decrypt<T: AsRef<[u8]> + AsMut<[u8]>>(cryptotext: Cryptotext<T>, key: &Key) -> Result<T> {
 |  | 
 | 
											
												
													
														|  | -    let mut data = match cryptotext {
 |  | 
 | 
											
												
													
														|  | -        Cryptotext::Plain(data) => return Ok(data),
 |  | 
 | 
											
												
													
														|  | 
 |  | +fn decrypt<T: Serialize + DeserializeOwned>(cryptotext: Cryptotext<T>, key: &Key) -> Result<T> {
 | 
											
												
													
														|  | 
 |  | +    let data = match cryptotext {
 | 
											
												
													
														|  | 
 |  | +        Cryptotext::Plain(value) => return Ok(value),
 | 
											
												
													
														|  |          Cryptotext::Cipher(data) => data
 |  |          Cryptotext::Cipher(data) => data
 | 
											
												
													
														|  |      };
 |  |      };
 | 
											
												
													
														|  | -    decrypt_in_place(data.as_mut(), key)?;
 |  | 
 | 
											
												
													
														|  | -    Ok(data)
 |  | 
 | 
											
												
													
														|  | 
 |  | +    let vec = decrypt_slice(data.as_ref(), key);
 | 
											
												
													
														|  | 
 |  | +    let value = from_vec(&vec?).map_err(|err| Error::Decryption(err.to_string()));
 | 
											
												
													
														|  | 
 |  | +    value
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -fn encrypt_in_place(_plaintext: &mut [u8], _key: &Key) -> Result<()> {
 |  | 
 | 
											
												
													
														|  | -    unimplemented!();
 |  | 
 | 
											
												
													
														|  | 
 |  | +fn encrypt_slice(plaintext: &[u8], key: &Key) -> Result<Vec<u8>> {
 | 
											
												
													
														|  | 
 |  | +    let cipher = key.cipher();
 | 
											
												
													
														|  | 
 |  | +    let key_slice = key.key_slice();
 | 
											
												
													
														|  | 
 |  | +    let iv_slice = key.iv_slice();
 | 
											
												
													
														|  | 
 |  | +    openssl_encrypt(cipher, key_slice, iv_slice, plaintext)
 | 
											
												
													
														|  | 
 |  | +        .map_err(|err| Error::Encryption(err.to_string()))
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -fn decrypt_in_place(_ciphertext: &mut [u8], _key: &Key) -> Result<()> {
 |  | 
 | 
											
												
													
														|  | -    unimplemented!();
 |  | 
 | 
											
												
													
														|  | 
 |  | +fn decrypt_slice(ciphertext: &[u8], key: &Key) -> Result<Vec<u8>> {
 | 
											
												
													
														|  | 
 |  | +    let cipher = key.cipher();
 | 
											
												
													
														|  | 
 |  | +    let key_slice = key.key_slice();
 | 
											
												
													
														|  | 
 |  | +    let iv_slice = key.iv_slice();
 | 
											
												
													
														|  | 
 |  | +    openssl_decrypt(cipher, key_slice, iv_slice, ciphertext)
 | 
											
												
													
														|  | 
 |  | +        .map_err(|err| Error::Decryption(err.to_string()))
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -/// Tests that validate the dependencies of this module.
 |  | 
 | 
											
												
													
														|  |  #[cfg(test)]
 |  |  #[cfg(test)]
 | 
											
												
													
														|  | -mod dependency_tests {
 |  | 
 | 
											
												
													
														|  | 
 |  | +mod tests {
 | 
											
												
													
														|  |      use super::*;
 |  |      use super::*;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    static KEY: [u8; 32] = [
 |  | 
 | 
											
												
													
														|  | 
 |  | +    const KEY: [u8; 32] = [
 | 
											
												
													
														|  |          0xB2, 0xB3, 0xDA, 0x5A, 0x1A, 0xF6, 0xB3, 0x78, 0x30, 0xAB, 0x1D, 0x33, 0x33, 0xE7, 0xE3,
 |  |          0xB2, 0xB3, 0xDA, 0x5A, 0x1A, 0xF6, 0xB3, 0x78, 0x30, 0xAB, 0x1D, 0x33, 0x33, 0xE7, 0xE3,
 | 
											
												
													
														|  |          0x5B, 0xBB, 0xF9, 0xFE, 0xD0, 0xC1, 0xF7, 0x90, 0x34, 0x69, 0xB7, 0xE7, 0xC6, 0x1C, 0x46,
 |  |          0x5B, 0xBB, 0xF9, 0xFE, 0xD0, 0xC1, 0xF7, 0x90, 0x34, 0x69, 0xB7, 0xE7, 0xC6, 0x1C, 0x46,
 | 
											
												
													
														|  |          0x85, 0x48,
 |  |          0x85, 0x48,
 | 
											
												
													
														|  |      ];
 |  |      ];
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    static IV: [u8; 16] = [
 |  | 
 | 
											
												
													
														|  | 
 |  | +    const IV: [u8; 16] = [
 | 
											
												
													
														|  |          0x60, 0xE0, 0xBE, 0x45, 0xA9, 0xAB, 0x5D, 0x99, 0x3B, 0x3A, 0x1E, 0x54, 0x18, 0xE0, 0x46,
 |  |          0x60, 0xE0, 0xBE, 0x45, 0xA9, 0xAB, 0x5D, 0x99, 0x3B, 0x3A, 0x1E, 0x54, 0x18, 0xE0, 0x46,
 | 
											
												
													
														|  |          0xDE,
 |  |          0xDE,
 | 
											
												
													
														|  |      ];
 |  |      ];
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    /// This test validates that data decrypted with the `Crypter` API matches data that was
 |  | 
 | 
											
												
													
														|  | -    /// previously encrypted using it.
 |  | 
 | 
											
												
													
														|  |      #[test]
 |  |      #[test]
 | 
											
												
													
														|  | -    fn cryptor() {
 |  | 
 | 
											
												
													
														|  | -        let expected = b"We attack at the crack of noon!";
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -        let cipher = Cipher::aes_256_cbc();
 |  | 
 | 
											
												
													
														|  | -        let mut encrypter = Crypter::new(
 |  | 
 | 
											
												
													
														|  | -            cipher,
 |  | 
 | 
											
												
													
														|  | -            Mode::Encrypt,
 |  | 
 | 
											
												
													
														|  | -            &KEY,
 |  | 
 | 
											
												
													
														|  | -            Some(&IV)).unwrap();
 |  | 
 | 
											
												
													
														|  | -        let mut ciphertext = vec![0; expected.len() + cipher.block_size()];
 |  | 
 | 
											
												
													
														|  | -        let mut written = encrypter.update(expected.as_slice(), &mut ciphertext).unwrap();
 |  | 
 | 
											
												
													
														|  | -        written += encrypter.finalize(&mut ciphertext[written..]).unwrap();
 |  | 
 | 
											
												
													
														|  | -        ciphertext.truncate(written);
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -        let mut actual = vec![0u8; ciphertext.len() + cipher.block_size()];
 |  | 
 | 
											
												
													
														|  | -        let mut decrypter = Crypter::new(
 |  | 
 | 
											
												
													
														|  | -            cipher,
 |  | 
 | 
											
												
													
														|  | -            Mode::Decrypt,
 |  | 
 | 
											
												
													
														|  | -            &KEY,
 |  | 
 | 
											
												
													
														|  | -            Some(&IV)).unwrap();
 |  | 
 | 
											
												
													
														|  | -        let mut written = decrypter.update(&ciphertext, &mut actual).unwrap();
 |  | 
 | 
											
												
													
														|  | -        written += decrypter.finalize(&mut actual[written..]).unwrap();
 |  | 
 | 
											
												
													
														|  | -        actual.truncate(written);
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -        assert_eq!(expected, actual.as_slice());
 |  | 
 | 
											
												
													
														|  | 
 |  | +    fn key_aes256cbc_key_part_is_correct() {
 | 
											
												
													
														|  | 
 |  | +        let mut array = [0u8; KEY.len() + IV.len()];
 | 
											
												
													
														|  | 
 |  | +        Key::pack(&mut array, &KEY, &IV);
 | 
											
												
													
														|  | 
 |  | +        let key = Key::Aes256Cbc(array);
 | 
											
												
													
														|  | 
 |  | +        let key_part = key.key_slice();
 | 
											
												
													
														|  | 
 |  | +        assert_eq!(KEY, key_part);
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  | -}
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -/// Tests for the code that is actually in this module.
 |  | 
 | 
											
												
													
														|  | -#[cfg(test)]
 |  | 
 | 
											
												
													
														|  | -mod tests {
 |  | 
 | 
											
												
													
														|  | 
 |  | +    #[test]
 | 
											
												
													
														|  | 
 |  | +    fn key_aes256cbc_iv_part_is_correct() {
 | 
											
												
													
														|  | 
 |  | +        let mut array = [0u8; KEY.len() + IV.len()];
 | 
											
												
													
														|  | 
 |  | +        Key::pack(&mut array, &KEY, &IV);
 | 
											
												
													
														|  | 
 |  | +        let key = Key::Aes256Cbc(array);
 | 
											
												
													
														|  | 
 |  | +        let iv_part = key.iv_slice().unwrap();
 | 
											
												
													
														|  | 
 |  | +        assert_eq!(IV, iv_part);
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /// Tests that validate the dependencies of this module.
 | 
											
												
													
														|  | 
 |  | +    mod dependency_tests {
 | 
											
												
													
														|  | 
 |  | +        /// This test validates that data decrypted with the `Crypter` API matches data that was
 | 
											
												
													
														|  | 
 |  | +        /// previously encrypted using it.
 | 
											
												
													
														|  | 
 |  | +        #[test]
 | 
											
												
													
														|  | 
 |  | +        fn crypter() {
 | 
											
												
													
														|  | 
 |  | +            use super::*;
 | 
											
												
													
														|  | 
 |  | +            let expected = b"We attack at the crack of noon!";
 | 
											
												
													
														|  | 
 |  | +            let cipher = Cipher::aes_256_cbc();
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -}
 |  | 
 | 
											
												
													
														|  | 
 |  | +            let ciphertext = openssl_encrypt(cipher, &KEY, Some(&IV), expected).unwrap();
 | 
											
												
													
														|  | 
 |  | +            let actual = openssl_decrypt(cipher, &KEY, Some(&IV), ciphertext.as_slice()).unwrap();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            assert_eq!(expected, actual.as_slice());
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +}
 |