aboutsummaryrefslogtreecommitdiffstats
path: root/src/cipherstring.rs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2020-04-18 01:28:48 -0400
committerJesse Luehrs <doy@tozt.net>2020-04-18 01:28:48 -0400
commit777b810db4675305854c373dcd57aedc40061e5d (patch)
treeed35c77e39416073fb5222aebdb5ef484c238dd3 /src/cipherstring.rs
parent3babc8801c0d09b7868be9be7751f7cfdf32c8bb (diff)
downloadrbw-777b810db4675305854c373dcd57aedc40061e5d.tar.gz
rbw-777b810db4675305854c373dcd57aedc40061e5d.zip
add encryption to the agent protocol
Diffstat (limited to 'src/cipherstring.rs')
-rw-r--r--src/cipherstring.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/cipherstring.rs b/src/cipherstring.rs
index 9f2c261..2398b07 100644
--- a/src/cipherstring.rs
+++ b/src/cipherstring.rs
@@ -2,6 +2,7 @@ use crate::prelude::*;
use block_modes::BlockMode as _;
use hmac::Mac as _;
+use rand::RngCore as _;
pub struct CipherString {
ty: u8,
@@ -51,6 +52,34 @@ impl CipherString {
})
}
+ pub fn encrypt(
+ keys: &crate::locked::Keys,
+ plaintext: &[u8],
+ ) -> Result<Self> {
+ let iv = random_iv();
+
+ let cipher = block_modes::Cbc::<
+ aes::Aes256,
+ block_modes::block_padding::Pkcs7,
+ >::new_var(keys.enc_key(), &iv)
+ .context(crate::error::CreateBlockMode)?;
+ let ciphertext = cipher.encrypt_vec(plaintext);
+
+ let mut digest =
+ hmac::Hmac::<sha2::Sha256>::new_varkey(keys.mac_key())
+ .map_err(|_| Error::InvalidMacKey)?;
+ digest.input(&iv);
+ digest.input(&ciphertext);
+ let mac = digest.result().code().to_vec();
+
+ Ok(Self {
+ ty: 2,
+ iv,
+ ciphertext,
+ mac: Some(mac),
+ })
+ }
+
pub fn decrypt(&self, keys: &crate::locked::Keys) -> Result<Vec<u8>> {
let cipher = self.decrypt_common(keys)?;
cipher
@@ -102,6 +131,19 @@ impl CipherString {
}
}
+impl std::fmt::Display for CipherString {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ let iv = base64::encode(&self.iv);
+ let ciphertext = base64::encode(&self.ciphertext);
+ if let Some(mac) = &self.mac {
+ let mac = base64::encode(&mac);
+ write!(f, "{}.{}|{}|{}", self.ty, iv, ciphertext, mac)
+ } else {
+ write!(f, "{}.{}|{}", self.ty, iv, ciphertext)
+ }
+ }
+}
+
fn macs_equal(mac1: &[u8], mac2: &[u8], mac_key: &[u8]) -> Result<bool> {
let mut digest = hmac::Hmac::<sha2::Sha256>::new_varkey(mac_key)
.map_err(|_| Error::InvalidMacKey)?;
@@ -115,3 +157,10 @@ fn macs_equal(mac1: &[u8], mac2: &[u8], mac_key: &[u8]) -> Result<bool> {
Ok(hmac1 == hmac2)
}
+
+fn random_iv() -> Vec<u8> {
+ let mut iv = vec![0_u8; 16];
+ let mut rng = rand::thread_rng();
+ rng.fill_bytes(&mut iv);
+ iv
+}