From 777b810db4675305854c373dcd57aedc40061e5d Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sat, 18 Apr 2020 01:28:48 -0400 Subject: add encryption to the agent protocol --- src/cipherstring.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'src/cipherstring.rs') 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 { + 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::::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> { 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 { let mut digest = hmac::Hmac::::new_varkey(mac_key) .map_err(|_| Error::InvalidMacKey)?; @@ -115,3 +157,10 @@ fn macs_equal(mac1: &[u8], mac2: &[u8], mac_key: &[u8]) -> Result { Ok(hmac1 == hmac2) } + +fn random_iv() -> Vec { + let mut iv = vec![0_u8; 16]; + let mut rng = rand::thread_rng(); + rng.fill_bytes(&mut iv); + iv +} -- cgit v1.2.3-54-g00ecf