diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2018-10-12 13:58:34 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2018-10-12 13:58:34 +0200 |
commit | 63334a95320c97171c68a53c8118b70222068061 (patch) | |
tree | ce8f122fcf400b9da89dcd2a872f3c2a438aee38 /openpgp/src/serialize/writer | |
parent | 2d3998eaecd7cacc4102a5c8f737dfa23beb2c95 (diff) |
openpgp: Add an encrypting writer using AEAD.
Diffstat (limited to 'openpgp/src/serialize/writer')
-rw-r--r-- | openpgp/src/serialize/writer/mod.rs | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/openpgp/src/serialize/writer/mod.rs b/openpgp/src/serialize/writer/mod.rs index 6530b4da..02334d59 100644 --- a/openpgp/src/serialize/writer/mod.rs +++ b/openpgp/src/serialize/writer/mod.rs @@ -12,10 +12,15 @@ pub use self::writer_deflate::{ZIP, ZLIB}; use std::fmt; use std::io; +use aead; +use constants::{ + AEADAlgorithm, + SymmetricAlgorithm, +}; use symmetric; use { Result, - SymmetricAlgorithm, + SessionKey, }; /// A stack of writers. @@ -398,6 +403,74 @@ impl<'a, C: 'a> Stackable<'a, C> for Encryptor<'a, C> { } } + +/// AEAD encrypting writer. +pub struct AEADEncryptor<'a, C: 'a> { + inner: Generic<aead::Encryptor<BoxStack<'a, C>>, C>, +} + +impl<'a, C: 'a> AEADEncryptor<'a, C> { + /// Makes an encrypting writer. + pub fn new(inner: Stack<'a, C>, cookie: C, + cipher: SymmetricAlgorithm, aead: AEADAlgorithm, + chunk_size: usize, iv: &[u8], key: &SessionKey) + -> Result<Stack<'a, C>> + { + Ok(Stack::from(Box::new(AEADEncryptor { + inner: Generic::new_unboxed( + aead::Encryptor::new(1, cipher, aead, chunk_size, iv, key, + inner.into())?, + cookie), + }))) + } +} + +impl<'a, C: 'a> fmt::Debug for AEADEncryptor<'a, C> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("writer::AEADEncryptor") + .field("inner", &self.inner) + .finish() + } +} + +impl<'a, C: 'a> io::Write for AEADEncryptor<'a, C> { + fn write(&mut self, bytes: &[u8]) -> io::Result<usize> { + self.inner.write(bytes) + } + + fn flush(&mut self) -> io::Result<()> { + self.inner.flush() + } +} + +impl<'a, C: 'a> Stackable<'a, C> for AEADEncryptor<'a, C> { + fn into_inner(mut self: Box<Self>) -> Result<Option<BoxStack<'a, C>>> { + let inner = self.inner.inner.finish()?; + Ok(Some(inner)) + } + fn pop(&mut self) -> Result<Option<BoxStack<'a, C>>> { + unimplemented!() + } + fn mount(&mut self, _new: BoxStack<'a, C>) { + unimplemented!() + } + fn inner_mut(&mut self) -> Option<&mut Stackable<'a, C>> { + self.inner.inner_mut() + } + fn inner_ref(&self) -> Option<&Stackable<'a, C>> { + self.inner.inner_ref() + } + fn cookie_set(&mut self, cookie: C) -> C { + self.inner.cookie_set(cookie) + } + fn cookie_ref(&self) -> &C { + self.inner.cookie_ref() + } + fn cookie_mut(&mut self) -> &mut C { + self.inner.cookie_mut() + } +} + #[cfg(test)] mod test { use std::io::Write; |