|
@@ -239,6 +239,12 @@ pub(crate) enum SymKey {
|
|
|
},
|
|
|
}
|
|
|
|
|
|
+struct SymParams<'a> {
|
|
|
+ cipher: Cipher,
|
|
|
+ key: &'a [u8],
|
|
|
+ iv: Option<&'a [u8]>,
|
|
|
+}
|
|
|
+
|
|
|
/// Returns an array of the given length filled with cryptographically random data.
|
|
|
fn rand_array<const LEN: usize>() -> Result<[u8; LEN]> {
|
|
|
let mut array = [0; LEN];
|
|
@@ -257,6 +263,14 @@ impl SymKey {
|
|
|
},
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ fn params<'a>(&'a self) -> SymParams<'a> {
|
|
|
+ let (cipher, key, iv) = match self {
|
|
|
+ SymKey::Aes256Cbc { key, iv } => (Cipher::aes_256_cbc(), key, Some(iv.as_slice())),
|
|
|
+ SymKey::Aes256Ctr { key, iv } => (Cipher::aes_256_ctr(), key, Some(iv.as_slice())),
|
|
|
+ };
|
|
|
+ SymParams { cipher, key, iv }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
|
@@ -337,125 +351,59 @@ impl Owned for KeyPair {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-enum EncryptionAlgo<'a> {
|
|
|
- Symmetric {
|
|
|
- cipher: Cipher,
|
|
|
- key: &'a [u8],
|
|
|
- iv: Option<&'a [u8]>
|
|
|
- },
|
|
|
- Asymmetric {
|
|
|
- key: PKey<OsslPublic>,
|
|
|
- rsa_padding: Option<OpensslPadding>,
|
|
|
- }
|
|
|
+trait Encryptor {
|
|
|
+ fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>>;
|
|
|
}
|
|
|
|
|
|
-impl<'a> EncryptionAlgo<'a> {
|
|
|
+impl Encryptor for SymKey {
|
|
|
fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
- match self {
|
|
|
- EncryptionAlgo::Symmetric { cipher, key, iv } => {
|
|
|
- openssl_encrypt(*cipher, key, *iv, slice).map_err(Error::from)
|
|
|
- },
|
|
|
- EncryptionAlgo::Asymmetric { key, rsa_padding } => {
|
|
|
- let mut encrypter = Encrypter::new(key).map_err(Error::from)?;
|
|
|
- if let Some(padding) = rsa_padding {
|
|
|
- encrypter.set_rsa_padding(*padding).map_err(Error::from)?;
|
|
|
- }
|
|
|
- let buffer_len = encrypter.encrypt_len(slice).map_err(Error::from)?;
|
|
|
- let mut ciphertext = vec![0; buffer_len];
|
|
|
- let ciphertext_len = encrypter.encrypt(slice, &mut ciphertext)
|
|
|
- .map_err(Error::from)?;
|
|
|
- ciphertext.truncate(ciphertext_len);
|
|
|
- Ok(ciphertext)
|
|
|
- }
|
|
|
- }
|
|
|
+ let SymParams { cipher, key, iv } = self.params();
|
|
|
+ openssl_encrypt(cipher, key, iv, slice).map_err(Error::from)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<'a> TryFrom<&'a SymKey> for EncryptionAlgo<'a> {
|
|
|
- type Error = Error;
|
|
|
- fn try_from(key: &'a SymKey) -> Result<EncryptionAlgo<'a>> {
|
|
|
- match key {
|
|
|
- SymKey::Aes256Cbc { key: key_slice, iv } => Ok(EncryptionAlgo::Symmetric {
|
|
|
- cipher: Cipher::aes_256_cbc(),
|
|
|
- key: key_slice,
|
|
|
- iv: Some(iv),
|
|
|
- }),
|
|
|
- SymKey::Aes256Ctr { key: key_slice, iv } => Ok(EncryptionAlgo::Symmetric {
|
|
|
- cipher: Cipher::aes_256_ctr(),
|
|
|
- key: key_slice,
|
|
|
- iv: Some(iv),
|
|
|
- }),
|
|
|
+impl Encryptor for AsymKey<Public> {
|
|
|
+ fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
+ let (pkey, rsa_padding) = match self {
|
|
|
+ AsymKey::Rsa { der, padding, .. }
|
|
|
+ => (PKey::public_key_from_der(der.as_slice()).map_err(Error::from)?, Some(padding)),
|
|
|
+ };
|
|
|
+ let mut encrypter = Encrypter::new(&pkey).map_err(Error::from)?;
|
|
|
+ if let Some(padding) = rsa_padding {
|
|
|
+ encrypter.set_rsa_padding((*padding).into()).map_err(Error::from)?;
|
|
|
}
|
|
|
+ let buffer_len = encrypter.encrypt_len(slice).map_err(Error::from)?;
|
|
|
+ let mut ciphertext = vec![0; buffer_len];
|
|
|
+ let ciphertext_len = encrypter.encrypt(slice, &mut ciphertext)
|
|
|
+ .map_err(Error::from)?;
|
|
|
+ ciphertext.truncate(ciphertext_len);
|
|
|
+ Ok(ciphertext)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<'a> TryFrom<&'a AsymKey<Public>> for EncryptionAlgo<'a> {
|
|
|
- type Error = Error;
|
|
|
- fn try_from(key: &'a AsymKey<Public>) -> Result<EncryptionAlgo<'a>> {
|
|
|
- match key {
|
|
|
- AsymKey::Rsa { der, padding, .. } => {
|
|
|
- let key = PKey::public_key_from_der(der.as_slice()).map_err(Error::from)?;
|
|
|
- Ok(EncryptionAlgo::Asymmetric { key, rsa_padding: Some((*padding).into()) })
|
|
|
- },
|
|
|
- }
|
|
|
- }
|
|
|
+trait Decryptor {
|
|
|
+ fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>>;
|
|
|
}
|
|
|
|
|
|
-enum DecryptionAlgo<'a> {
|
|
|
- Symmetric {
|
|
|
- cipher: Cipher,
|
|
|
- key: &'a [u8],
|
|
|
- iv: Option<&'a [u8]>
|
|
|
- },
|
|
|
- Asymmetric(PKey<OsslPrivate>),
|
|
|
-}
|
|
|
-
|
|
|
-impl<'a> DecryptionAlgo<'a> {
|
|
|
+impl Decryptor for SymKey {
|
|
|
fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
- match self {
|
|
|
- DecryptionAlgo::Symmetric { cipher, key, iv } => {
|
|
|
- openssl_decrypt(*cipher, key, *iv, slice).map_err(Error::from)
|
|
|
- },
|
|
|
- DecryptionAlgo::Asymmetric(pkey) => {
|
|
|
- let decrypter = Decrypter::new(pkey).map_err(Error::from)?;
|
|
|
- let buffer_len = decrypter.decrypt_len(slice).map_err(Error::from)?;
|
|
|
- let mut plaintext = vec![0; buffer_len];
|
|
|
- let plaintext_len = decrypter.decrypt(slice, &mut plaintext)
|
|
|
- .map_err(Error::from)?;
|
|
|
- plaintext.truncate(plaintext_len);
|
|
|
- Ok(plaintext)
|
|
|
- },
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<'a> TryFrom<&'a SymKey> for DecryptionAlgo<'a> {
|
|
|
- type Error = Error;
|
|
|
- fn try_from(key: &'a SymKey) -> Result<DecryptionAlgo<'a>> {
|
|
|
- match key {
|
|
|
- SymKey::Aes256Cbc { key: key_slice, iv } => Ok(DecryptionAlgo::Symmetric {
|
|
|
- cipher: Cipher::aes_256_cbc(),
|
|
|
- key: key_slice,
|
|
|
- iv: Some(iv),
|
|
|
- }),
|
|
|
- SymKey::Aes256Ctr { key: key_slice, iv } => Ok(DecryptionAlgo::Symmetric {
|
|
|
- cipher: Cipher::aes_256_ctr(),
|
|
|
- key: key_slice,
|
|
|
- iv: Some(iv),
|
|
|
- }),
|
|
|
- }
|
|
|
+ let SymParams { cipher, key, iv } = self.params();
|
|
|
+ openssl_decrypt(cipher, key, iv, slice).map_err(Error::from)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<'a> TryFrom<&'a AsymKey<Private>> for DecryptionAlgo<'a> {
|
|
|
- type Error = Error;
|
|
|
- fn try_from(key: &'a AsymKey<Private>) -> Result<DecryptionAlgo<'a>> {
|
|
|
- match key {
|
|
|
- AsymKey::Rsa { der, .. } => {
|
|
|
- let pkey = PKey::private_key_from_der(der.as_slice()).map_err(Error::from);
|
|
|
- Ok(DecryptionAlgo::Asymmetric(pkey?))
|
|
|
- }
|
|
|
- }
|
|
|
+impl Decryptor for AsymKey<Private> {
|
|
|
+ fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
|
|
|
+ let pkey = match self {
|
|
|
+ AsymKey::Rsa { der, .. }
|
|
|
+ => PKey::private_key_from_der(der.as_slice()).map_err(Error::from)?
|
|
|
+ };
|
|
|
+ let decrypter = Decrypter::new(&pkey).map_err(Error::from)?;
|
|
|
+ let buffer_len = decrypter.decrypt_len(slice).map_err(Error::from)?;
|
|
|
+ let mut plaintext = vec![0; buffer_len];
|
|
|
+ let plaintext_len = decrypter.decrypt(slice, &mut plaintext).map_err(Error::from)?;
|
|
|
+ plaintext.truncate(plaintext_len);
|
|
|
+ Ok(plaintext)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -535,7 +483,7 @@ pub(crate) fn encrypt_block(
|
|
|
let (principal_owned, read_cap) = block.readcaps.remove_entry(principal)
|
|
|
.ok_or(Error::NoReadCap)?;
|
|
|
let block_key = decrypt(read_cap, &key.private)?;
|
|
|
- let new_body = encrypt_slice(&body, &block_key)?;
|
|
|
+ let new_body = block_key.encrypt(&body)?;
|
|
|
block.body = Cryptotext::Cipher(new_body);
|
|
|
block.readcaps.insert(principal_owned, encrypt(&block_key, &key.public)?);
|
|
|
Ok(block)
|
|
@@ -551,45 +499,29 @@ pub(crate) fn decrypt_block(
|
|
|
let (principal_owned, read_cap) = block.readcaps.remove_entry(principal)
|
|
|
.ok_or(Error::NoReadCap)?;
|
|
|
let block_key = decrypt(read_cap, key)?;
|
|
|
- let new_body = decrypt_slice(&body, &block_key)?;
|
|
|
+ let new_body = block_key.decrypt(&body)?;
|
|
|
block.body = Cryptotext::Plain(new_body);
|
|
|
block.readcaps.insert(principal_owned, Cryptotext::Plain(block_key));
|
|
|
Ok(block)
|
|
|
}
|
|
|
|
|
|
-fn encrypt<'a, T: Serialize, K: TryInto<EncryptionAlgo<'a>, Error = Error>>(
|
|
|
- value: &T, key: K
|
|
|
-) -> Result<Cryptotext<T>> {
|
|
|
+fn encrypt<'a, T: Serialize, K: Encryptor>(value: &T, key: &K) -> Result<Cryptotext<T>> {
|
|
|
let data = to_vec(value).map_err(Error::from)?;
|
|
|
- let vec = encrypt_slice(&data, key);
|
|
|
+ let vec = key.encrypt(&data);
|
|
|
Ok(Cryptotext::Cipher(vec?))
|
|
|
}
|
|
|
|
|
|
-fn decrypt<'a, T: Serialize + DeserializeOwned, K: TryInto<DecryptionAlgo<'a>, Error = Error>>(
|
|
|
- cryptotext: Cryptotext<T>, key: K
|
|
|
+fn decrypt<'a, T: Serialize + DeserializeOwned, K: Decryptor>(
|
|
|
+ cryptotext: Cryptotext<T>, key: &K
|
|
|
) -> Result<T> {
|
|
|
let data = match cryptotext {
|
|
|
Cryptotext::Plain(value) => return Ok(value),
|
|
|
Cryptotext::Cipher(data) => data
|
|
|
};
|
|
|
- let vec = decrypt_slice(&data, key);
|
|
|
+ let vec = key.decrypt(&data);
|
|
|
from_vec(&vec?).map_err(Error::from)
|
|
|
}
|
|
|
|
|
|
-fn encrypt_slice<'a, K: TryInto<EncryptionAlgo<'a>, Error = Error>>(
|
|
|
- plaintext: &[u8], key: K
|
|
|
-) -> Result<Vec<u8>> {
|
|
|
- let algo: EncryptionAlgo<'a> = key.try_into()?;
|
|
|
- algo.encrypt(plaintext)
|
|
|
-}
|
|
|
-
|
|
|
-fn decrypt_slice<'a, K: TryInto<DecryptionAlgo<'a>, Error = Error>>(
|
|
|
- ciphertext: &[u8], key: K
|
|
|
-) -> Result<Vec<u8>> {
|
|
|
- let algo: DecryptionAlgo<'a> = key.try_into()?;
|
|
|
- algo.decrypt(ciphertext)
|
|
|
-}
|
|
|
-
|
|
|
#[derive(Serialize)]
|
|
|
struct SigHeader<'a> {
|
|
|
path: &'a Path,
|