summaryrefslogtreecommitdiffstats
path: root/openpgp
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-04-03 13:38:05 +0200
committerJustus Winter <justus@sequoia-pgp.org>2020-04-03 13:59:25 +0200
commit6b4207285b182ca1a94f55608455646c1e36b859 (patch)
tree857f15b265b03d86c1836df8fa5066d687f10e7e /openpgp
parent3537bf41630139cb4cd44a8b13a21e7cce27211e (diff)
openpgp: Unify Message and writer::Stack, hide writers.
- Previously, Message::new returned a writer::Stack, and Message was just an empty struct. Unify the types. This makes sense, because if you have a message, and encrypt it, you get a message. - Make the writer module private. This is an implementation detail.
Diffstat (limited to 'openpgp')
-rw-r--r--openpgp/src/serialize/stream.rs74
-rw-r--r--openpgp/src/serialize/stream/padding.rs13
-rw-r--r--openpgp/src/serialize/stream/partial_body.rs15
-rw-r--r--openpgp/src/serialize/stream/writer/mod.rs51
-rw-r--r--openpgp/src/serialize/stream/writer/writer_bzip2.rs6
-rw-r--r--openpgp/src/serialize/stream/writer/writer_deflate.rs10
6 files changed, 85 insertions, 84 deletions
diff --git a/openpgp/src/serialize/stream.rs b/openpgp/src/serialize/stream.rs
index 2316ec43..04d610ff 100644
--- a/openpgp/src/serialize/stream.rs
+++ b/openpgp/src/serialize/stream.rs
@@ -43,7 +43,7 @@ use crate::types::{
SymmetricAlgorithm,
};
-pub mod writer;
+pub(crate) mod writer;
#[cfg(feature = "compression-deflate")]
pub mod padding;
mod partial_body;
@@ -83,17 +83,31 @@ impl Default for Cookie {
/// Streams an OpenPGP message.
///
/// Wraps a `std::io::Write`r for use with the streaming subsystem.
-pub struct Message {
-}
+#[derive(Debug)]
+pub struct Message<'a, C>(writer::BoxStack<'a, C>);
-impl Message {
+impl<'a> Message<'a, Cookie> {
/// Streams an OpenPGP message.
- pub fn new<'a, W: 'a + io::Write>(w: W) -> writer::Stack<'a, Cookie> {
+ pub fn new<W: 'a + io::Write>(w: W) -> Message<'a, Cookie> {
writer::Generic::new(w, Cookie::new(0))
}
+
+ /// Finalizes this writer, returning the underlying writer.
+ pub fn finalize_one(self) -> Result<Option<Message<'a, Cookie>>> {
+ Ok(self.0.into_inner()?.map(|bs| Self::from(bs)))
+ }
+
+ /// Finalizes all writers, tearing down the whole stack.
+ pub fn finalize(self) -> Result<()> {
+ let mut stack = self;
+ while let Some(s) = stack.finalize_one()? {
+ stack = s;
+ }
+ Ok(())
+ }
}
-impl<'a> From<&'a mut dyn io::Write> for writer::Stack<'a, Cookie> {
+impl<'a> From<&'a mut dyn io::Write> for Message<'a, Cookie> {
fn from(w: &'a mut dyn io::Write) -> Self {
writer::Generic::new(w, Cookie::new(0))
}
@@ -133,11 +147,11 @@ pub struct ArbitraryWriter<'a> {
impl<'a> ArbitraryWriter<'a> {
/// Creates a new writer with the given tag.
- pub fn new(mut inner: writer::Stack<'a, Cookie>, tag: Tag)
- -> Result<writer::Stack<'a, Cookie>> {
+ pub fn new(mut inner: Message<'a, Cookie>, tag: Tag)
+ -> Result<Message<'a, Cookie>> {
let level = inner.as_ref().cookie_ref().level + 1;
CTB::new(tag).serialize(&mut inner)?;
- Ok(writer::Stack::from(Box::new(ArbitraryWriter {
+ Ok(Message::from(Box::new(ArbitraryWriter {
inner: PartialBodyFilter::new(inner, Cookie::new(level)).into()
})))
}
@@ -281,7 +295,7 @@ impl<'a> Signer<'a> {
/// # Ok(())
/// # }
/// ```
- pub fn new<S>(inner: writer::Stack<'a, Cookie>, signer: S) -> Self
+ pub fn new<S>(inner: Message<'a, Cookie>, signer: S) -> Self
where S: crypto::Signer + 'a
{
let inner = writer::BoxStack::from(inner);
@@ -406,7 +420,7 @@ impl<'a> Signer<'a> {
}
/// Finalizes the signer, returning the writer stack.
- pub fn build(mut self) -> Result<writer::Stack<'a, Cookie>>
+ pub fn build(mut self) -> Result<Message<'a, Cookie>>
{
assert!(self.signers.len() > 0, "The constructor adds a signer.");
assert!(self.inner.is_some(), "The constructor adds an inner writer.");
@@ -426,7 +440,7 @@ impl<'a> Signer<'a> {
}
}
- Ok(writer::Stack::from(Box::new(self)))
+ Ok(Message::from(Box::new(self)))
}
fn emit_signatures(&mut self) -> Result<()> {
@@ -583,7 +597,7 @@ pub struct LiteralWriter<'a> {
impl<'a> LiteralWriter<'a> {
/// Creates a new literal writer.
- pub fn new(inner: writer::Stack<'a, Cookie>) -> Self {
+ pub fn new(inner: Message<'a, Cookie>) -> Self {
LiteralWriter {
template: Literal::new(DataFormat::default()),
inner: writer::BoxStack::from(inner),
@@ -620,7 +634,7 @@ impl<'a> LiteralWriter<'a> {
/// be authenticated by signatures (but will be authenticated by a
/// SEIP/MDC container), and are therefore unreliable and should
/// not be trusted.
- pub fn build(mut self) -> Result<writer::Stack<'a, Cookie>> {
+ pub fn build(mut self) -> Result<Message<'a, Cookie>> {
let level = self.inner.cookie_ref().level + 1;
// For historical reasons, signatures over literal data
@@ -651,13 +665,13 @@ impl<'a> LiteralWriter<'a> {
// Neither is any framing added by the PartialBodyFilter.
self.inner
- = PartialBodyFilter::new(writer::Stack::from(self.inner),
+ = PartialBodyFilter::new(Message::from(self.inner),
Cookie::new(level)).into();
// Nor the headers.
self.template.serialize_headers(&mut self.inner, false)?;
- Ok(writer::Stack::from(Box::new(self)))
+ Ok(Message::from(Box::new(self)))
}
}
@@ -770,7 +784,7 @@ impl<'a> Compressor<'a> {
///
/// Passing `None` to `compression_level` selects the default
/// compression level.
- pub fn new(inner: writer::Stack<'a, Cookie>) -> Self {
+ pub fn new(inner: Message<'a, Cookie>) -> Self {
Self {
algo: Default::default(),
level: Default::default(),
@@ -791,13 +805,13 @@ impl<'a> Compressor<'a> {
}
/// Finalizes the compressor, returning the writer stack.
- pub fn build(mut self) -> Result<writer::Stack<'a, Cookie>> {
+ pub fn build(mut self) -> Result<Message<'a, Cookie>> {
let level = self.inner.cookie_ref().level + 1;
// Packet header.
CTB::new(Tag::CompressedData).serialize(&mut self.inner)?;
- let inner: writer::Stack<'a, Cookie>
- = PartialBodyFilter::new(writer::Stack::from(self.inner),
+ let inner: Message<'a, Cookie>
+ = PartialBodyFilter::new(Message::from(self.inner),
Cookie::new(level));
Self::new_naked(inner, self.algo, self.level, level)
@@ -806,17 +820,17 @@ impl<'a> Compressor<'a> {
/// Creates a new compressor using the given algorithm.
pub(crate) // For CompressedData::serialize.
- fn new_naked(mut inner: writer::Stack<'a, Cookie>,
+ fn new_naked(mut inner: Message<'a, Cookie>,
algo: CompressionAlgorithm,
compression_level: writer::CompressionLevel,
level: usize)
- -> Result<writer::Stack<'a, Cookie>>
+ -> Result<Message<'a, Cookie>>
{
// Compressed data header.
inner.as_mut().write_u8(algo.into())?;
// Create an appropriate filter.
- let inner: writer::Stack<'a, Cookie> = match algo {
+ let inner: Message<'a, Cookie> = match algo {
CompressionAlgorithm::Uncompressed => {
// Avoid warning about unused value if compiled
// without any compression support.
@@ -836,7 +850,7 @@ impl<'a> Compressor<'a> {
return Err(Error::UnsupportedCompressionAlgorithm(a).into()),
};
- Ok(writer::Stack::from(Box::new(Self {
+ Ok(Message::from(Box::new(Self {
algo,
level: compression_level,
inner: inner.into(),
@@ -1027,7 +1041,7 @@ impl<'a> Encryptor<'a> {
/// # Ok(())
/// # }
/// ```
- pub fn for_recipient(inner: writer::Stack<'a, Cookie>,
+ pub fn for_recipient(inner: Message<'a, Cookie>,
recipient: Recipient<'a>) -> Self {
Self {
inner: Some(inner.into()),
@@ -1076,7 +1090,7 @@ impl<'a> Encryptor<'a> {
/// # Ok(())
/// # }
/// ```
- pub fn with_password(inner: writer::Stack<'a, Cookie>,
+ pub fn with_password(inner: Message<'a, Cookie>,
password: Password) -> Self {
Self {
inner: Some(inner.into()),
@@ -1121,7 +1135,7 @@ impl<'a> Encryptor<'a> {
const AEAD_CHUNK_SIZE : usize = 4096;
/// Finalizes the encryptor, returning the writer stack.
- pub fn build(mut self) -> Result<writer::Stack<'a, Cookie>> {
+ pub fn build(mut self) -> Result<Message<'a, Cookie>> {
assert!(self.recipients.len() + self.passwords.len() > 0,
"The constructors add at least one recipient or password");
@@ -1175,7 +1189,7 @@ impl<'a> Encryptor<'a> {
if let Some(aead) = aead {
// Write the AED packet.
CTB::new(Tag::AED).serialize(&mut inner)?;
- let mut inner = PartialBodyFilter::new(writer::Stack::from(inner),
+ let mut inner = PartialBodyFilter::new(Message::from(inner),
Cookie::new(level));
let aed = AED1::new(self.sym_algo, aead.algo, aead.chunk_size, aead.nonce)?;
aed.serialize_headers(&mut inner)?;
@@ -1192,7 +1206,7 @@ impl<'a> Encryptor<'a> {
} else {
// Write the SEIP packet.
CTB::new(Tag::SEIP).serialize(&mut inner)?;
- let mut inner = PartialBodyFilter::new(writer::Stack::from(inner),
+ let mut inner = PartialBodyFilter::new(Message::from(inner),
Cookie::new(level));
inner.write_all(&[1])?; // Version.
@@ -1214,7 +1228,7 @@ impl<'a> Encryptor<'a> {
self.write_all(&iv)?;
self.write_all(&iv[iv.len() - 2..])?;
- Ok(writer::Stack::from(Box::new(self)))
+ Ok(Message::from(Box::new(self)))
}
}
diff --git a/openpgp/src/serialize/stream/padding.rs b/openpgp/src/serialize/stream/padding.rs
index db190253..3b08aa50 100644
--- a/openpgp/src/serialize/stream/padding.rs
+++ b/openpgp/src/serialize/stream/padding.rs
@@ -51,6 +51,7 @@ use crate::serialize::{
stream::{
writer,
Cookie,
+ Message,
PartialBodyFilter,
},
};
@@ -132,26 +133,26 @@ pub struct Padder<'a, P: Fn(u64) -> u64 + 'a> {
impl<'a, P: Fn(u64) -> u64 + 'a> Padder<'a, P> {
/// Creates a new padder with the given policy.
- pub fn new(inner: writer::Stack<'a, Cookie>, p: P)
- -> Result<writer::Stack<'a, Cookie>> {
+ pub fn new(inner: Message<'a, Cookie>, p: P)
+ -> Result<Message<'a, Cookie>> {
let mut inner = writer::BoxStack::from(inner);
let level = inner.cookie_ref().level + 1;
// Packet header.
CTB::new(Tag::CompressedData).serialize(&mut inner)?;
- let mut inner: writer::Stack<'a, Cookie>
- = PartialBodyFilter::new(writer::Stack::from(inner),
+ let mut inner: Message<'a, Cookie>
+ = PartialBodyFilter::new(Message::from(inner),
Cookie::new(level));
// Compressed data header.
inner.as_mut().write_u8(CompressionAlgorithm::Zip.into())?;
// Create an appropriate filter.
- let inner: writer::Stack<'a, Cookie> =
+ let inner: Message<'a, Cookie> =
writer::ZIP::new(inner, Cookie::new(level),
writer::CompressionLevel::none());
- Ok(writer::Stack::from(Box::new(Self {
+ Ok(Message::from(Box::new(Self {
inner: inner.into(),
policy: p,
})))
diff --git a/openpgp/src/serialize/stream/partial_body.rs b/openpgp/src/serialize/stream/partial_body.rs
index e5aef8ca..24e0ea52 100644
--- a/openpgp/src/serialize/stream/partial_body.rs
+++ b/openpgp/src/serialize/stream/partial_body.rs
@@ -10,7 +10,10 @@ use crate::Result;
use crate::packet::header::BodyLength;
use crate::serialize::{
log2,
- stream::writer,
+ stream::{
+ writer,
+ Message,
+ },
write_byte,
Marshal,
};
@@ -48,8 +51,8 @@ const PARTIAL_BODY_FILTER_BUFFER_THRESHOLD : usize = 4 * 1024 * 1024;
impl<'a, C: 'a> PartialBodyFilter<'a, C> {
/// Returns a new partial body encoder.
- pub fn new(inner: writer::Stack<'a, C>, cookie: C)
- -> writer::Stack<'a, C> {
+ pub fn new(inner: Message<'a, C>, cookie: C)
+ -> Message<'a, C> {
Self::with_limits(inner, cookie,
PARTIAL_BODY_FILTER_BUFFER_THRESHOLD,
PARTIAL_BODY_FILTER_MAX_CHUNK_SIZE)
@@ -57,10 +60,10 @@ impl<'a, C: 'a> PartialBodyFilter<'a, C> {
}
/// Returns a new partial body encoder with the given limits.
- pub fn with_limits(inner: writer::Stack<'a, C>, cookie: C,
+ pub fn with_limits(inner: Message<'a, C>, cookie: C,
buffer_threshold: usize,
max_chunk_size: usize)
- -> Result<writer::Stack<'a, C>> {
+ -> Result<Message<'a, C>> {
if buffer_threshold.count_ones() != 1 {
return Err(Error::InvalidArgument(
"buffer_threshold is not a power of two".into()).into());
@@ -76,7 +79,7 @@ impl<'a, C: 'a> PartialBodyFilter<'a, C> {
"max_chunk_size exceeds limit".into()).into());
}
- Ok(writer::Stack::from(Box::new(PartialBodyFilter {
+ Ok(Message::from(Box::new(PartialBodyFilter {
inner: Some(inner.into()),
cookie,
buffer: Vec::with_capacity(buffer_threshold),
diff --git a/openpgp/src/serialize/stream/writer/mod.rs b/openpgp/src/serialize/stream/writer/mod.rs
index 2141ca98..1006f0f5 100644
--- a/openpgp/src/serialize/stream/writer/mod.rs
+++ b/openpgp/src/serialize/stream/writer/mod.rs
@@ -23,14 +23,11 @@ use crate::{
Result,
crypto::SessionKey,
};
+use super::Message;
-/// A stack of writers.
-#[derive(Debug)]
-pub struct Stack<'a, C>(BoxStack<'a, C>);
-
-impl<'a, C> Stack<'a, C> {
+impl<'a, C> Message<'a, C> {
pub(crate) fn from(bs: BoxStack<'a, C>) -> Self {
- Stack(bs)
+ Message(bs)
}
pub(crate) fn as_ref(&self) -> &BoxStack<'a, C> {
@@ -40,23 +37,9 @@ impl<'a, C> Stack<'a, C> {
pub(crate) fn as_mut(&mut self) -> &mut BoxStack<'a, C> {
&mut self.0
}
-
- /// Finalizes this writer, returning the underlying writer.
- pub fn finalize_one(self) -> Result<Option<Stack<'a, C>>> {
- Ok(self.0.into_inner()?.map(|bs| Self::from(bs)))
- }
-
- /// Finalizes all writers, tearing down the whole stack.
- pub fn finalize(self) -> Result<()> {
- let mut stack = self;
- while let Some(s) = stack.finalize_one()? {
- stack = s;
- }
- Ok(())
- }
}
-impl<'a, C> io::Write for Stack<'a, C> {
+impl<'a, C> io::Write for Message<'a, C> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
}
@@ -66,8 +49,8 @@ impl<'a, C> io::Write for Stack<'a, C> {
}
}
-impl<'a, C> From<Stack<'a, C>> for BoxStack<'a, C> {
- fn from(s: Stack<'a, C>) -> Self {
+impl<'a, C> From<Message<'a, C>> for BoxStack<'a, C> {
+ fn from(s: Message<'a, C>) -> Self {
s.0
}
}
@@ -214,9 +197,9 @@ pub struct Identity<'a, C> {
impl<'a, C: 'a> Identity<'a, C> {
/// Makes an identity writer.
- pub fn new(inner: Stack<'a, C>, cookie: C)
- -> Stack<'a, C> {
- Stack::from(Box::new(Self{inner: Some(inner.into()), cookie }))
+ pub fn new(inner: Message<'a, C>, cookie: C)
+ -> Message<'a, C> {
+ Message::from(Box::new(Self{inner: Some(inner.into()), cookie }))
}
}
@@ -294,8 +277,8 @@ pub struct Generic<W: io::Write, C> {
impl<'a, W: 'a + io::Write, C: 'a> Generic<W, C> {
/// Wraps an `io::Write`r.
- pub fn new(inner: W, cookie: C) -> Stack<'a, C> {
- Stack::from(Box::new(Self::new_unboxed(inner.into(), cookie)))
+ pub fn new(inner: W, cookie: C) -> Message<'a, C> {
+ Message::from(Box::new(Self::new_unboxed(inner.into(), cookie)))
}
fn new_unboxed(inner: W, cookie: C) -> Self {
@@ -378,11 +361,11 @@ pub struct Encryptor<'a, C: 'a> {
impl<'a, C: 'a> Encryptor<'a, C> {
/// Makes an encrypting writer.
- pub fn new(inner: Stack<'a, C>, cookie: C, algo: SymmetricAlgorithm,
+ pub fn new(inner: Message<'a, C>, cookie: C, algo: SymmetricAlgorithm,
key: &[u8])
- -> Result<Stack<'a, C>>
+ -> Result<Message<'a, C>>
{
- Ok(Stack::from(Box::new(Encryptor {
+ Ok(Message::from(Box::new(Encryptor {
inner: Generic::new_unboxed(
symmetric::Encryptor::new(algo, key, inner.into())?,
cookie),
@@ -449,12 +432,12 @@ pub struct AEADEncryptor<'a, C: 'a> {
impl<'a, C: 'a> AEADEncryptor<'a, C> {
/// Makes an encrypting writer.
- pub fn new(inner: Stack<'a, C>, cookie: C,
+ pub fn new(inner: Message<'a, C>, cookie: C,
cipher: SymmetricAlgorithm, aead: AEADAlgorithm,
chunk_size: usize, iv: &[u8], key: &SessionKey)
- -> Result<Stack<'a, C>>
+ -> Result<Message<'a, C>>
{
- Ok(Stack::from(Box::new(AEADEncryptor {
+ Ok(Message::from(Box::new(AEADEncryptor {
inner: Generic::new_unboxed(
aead::Encryptor::new(1, cipher, aead, chunk_size, iv, key,
inner.into())?,
diff --git a/openpgp/src/serialize/stream/writer/writer_bzip2.rs b/openpgp/src/serialize/stream/writer/writer_bzip2.rs
index 62affd0c..1f5b6cdf 100644
--- a/openpgp/src/serialize/stream/writer/writer_bzip2.rs
+++ b/openpgp/src/serialize/stream/writer/writer_bzip2.rs
@@ -3,7 +3,7 @@ use std::fmt;
use std::io;
use crate::Result;
-use super::{Generic, Stack, BoxStack, Stackable, CompressionLevel};
+use super::{Generic, Message, BoxStack, Stackable, CompressionLevel};
/// BZing writer.
pub struct BZ<'a, C: 'a> {
@@ -12,10 +12,10 @@ pub struct BZ<'a, C: 'a> {
impl<'a, C: 'a> BZ<'a, C> {
/// Makes a BZ compressing writer.
- pub fn new<L>(inner: Stack<'a, C>, cookie: C, level: L) -> Stack<'a, C>
+ pub fn new<L>(inner: Message<'a, C>, cookie: C, level: L) -> Message<'a, C>
where L: Into<Option<CompressionLevel>>
{
- Stack::from(Box::new(BZ {
+ Message::from(Box::new(BZ {
inner: Generic::new_unboxed(
BzEncoder::new(inner.into(),
level.into().unwrap_or_default().into()),
diff --git a/openpgp/src/serialize/stream/writer/writer_deflate.rs b/openpgp/src/serialize/stream/writer/writer_deflate.rs
index 387b3f2c..b2cdd74f 100644
--- a/openpgp/src/serialize/stream/writer/writer_deflate.rs
+++ b/openpgp/src/serialize/stream/writer/writer_deflate.rs
@@ -3,7 +3,7 @@ use std::fmt;
use std::io;
use crate::Result;
-use super::{Generic, Stack, BoxStack, Stackable, CompressionLevel};
+use super::{Generic, Message, BoxStack, Stackable, CompressionLevel};
/// ZIPing writer.
pub struct ZIP<'a, C: 'a> {
@@ -12,10 +12,10 @@ pub struct ZIP<'a, C: 'a> {
impl<'a, C: 'a> ZIP<'a, C> {
/// Makes a ZIP compressing writer.
- pub fn new<L>(inner: Stack<'a, C>, cookie: C, level: L) -> Stack<'a, C>
+ pub fn new<L>(inner: Message<'a, C>, cookie: C, level: L) -> Message<'a, C>
where L: Into<Option<CompressionLevel>>
{
- Stack::from(Box::new(ZIP {
+ Message::from(Box::new(ZIP {
inner: Generic::new_unboxed(
DeflateEncoder::new(inner.into(),
level.into().unwrap_or_default().into()),
@@ -80,10 +80,10 @@ pub struct ZLIB<'a, C: 'a> {
impl<'a, C: 'a> ZLIB<'a, C> {
/// Makes a ZLIB compressing writer.
- pub fn new<L>(inner: Stack<'a, C>, cookie: C, level: L) -> Stack<'a, C>
+ pub fn new<L>(inner: Message<'a, C>, cookie: C, level: L) -> Message<'a, C>
where L: Into<Option<CompressionLevel>>
{
- Stack::from(Box::new(ZLIB {
+ Message::from(Box::new(ZLIB {
inner: Generic::new_unboxed(
ZlibEncoder::new(inner.into(),
level.into().unwrap_or_default().into()),