summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openpgp/NEWS2
-rw-r--r--openpgp/src/armor.rs9
-rw-r--r--openpgp/src/cert.rs17
-rw-r--r--openpgp/src/cert/parser/mod.rs10
-rw-r--r--openpgp/src/cert/raw.rs23
-rw-r--r--openpgp/src/message/mod.rs16
-rw-r--r--openpgp/src/packet_pile.rs11
-rw-r--r--openpgp/src/parse.rs46
-rw-r--r--openpgp/src/parse/packet_parser_builder.rs11
-rw-r--r--openpgp/src/parse/packet_pile_parser.rs7
-rw-r--r--openpgp/src/parse/stream.rs21
11 files changed, 158 insertions, 15 deletions
diff --git a/openpgp/NEWS b/openpgp/NEWS
index f694f869..1aac12d3 100644
--- a/openpgp/NEWS
+++ b/openpgp/NEWS
@@ -12,6 +12,8 @@
- KeyAmalgamation::active_certifications_by_key
- UserIDAmalgamation::valid_third_party_revocations_by_key
- KeyAmalgamation::valid_third_party_revocations_by_key
+ - Parse::from_buffered_reader
+ - armor::Reader::from_buffered_reader
* Changes in 1.17.0
** Notable fixes
- Sequoia now ignores some formatting errors when reading secret
diff --git a/openpgp/src/armor.rs b/openpgp/src/armor.rs
index 97e82d1e..992977b7 100644
--- a/openpgp/src/armor.rs
+++ b/openpgp/src/armor.rs
@@ -627,6 +627,15 @@ impl<'a> Reader<'a> {
mode, Default::default())
}
+ /// Constructs a new `Reader` from the given `BufferedReader`.
+ pub fn from_buffered_reader<R, M>(reader: R, mode: M) -> Result<Self>
+ where
+ R: BufferedReader<Cookie> + 'a,
+ M: Into<Option<ReaderMode>>,
+ {
+ Ok(Self::from_cookie_reader(reader.into_boxed(), mode, Default::default()))
+ }
+
/// Constructs a new `Reader` from the given `io::Read`er.
///
/// [ASCII Armor], designed to protect OpenPGP data in transit,
diff --git a/openpgp/src/cert.rs b/openpgp/src/cert.rs
index 9c8a1869..81a05c5d 100644
--- a/openpgp/src/cert.rs
+++ b/openpgp/src/cert.rs
@@ -141,6 +141,8 @@ use std::fmt;
use std::ops::{Deref, DerefMut};
use std::time;
+use buffered_reader::BufferedReader;
+
use crate::{
crypto::{
Signer,
@@ -165,7 +167,7 @@ use crate::{
KeyHandle,
policy::Policy,
};
-use crate::parse::{Parse, PacketParserResult, PacketParser};
+use crate::parse::{Cookie, Parse, PacketParserResult, PacketParser};
use crate::types::{
AEADAlgorithm,
CompressionAlgorithm,
@@ -775,6 +777,19 @@ impl<'a> Parse<'a, Cert> for Cert {
///
/// If `reader` contains multiple certificates, this returns an
/// error. Use [`CertParser`] if you want to parse a keyring.
+ fn from_buffered_reader<R>(reader: R) -> Result<Cert>
+ where
+ R: BufferedReader<Cookie> + 'a,
+ {
+ Cert::try_from(PacketParser::from_buffered_reader(reader)?)
+ }
+
+ /// Parses and returns a certificate.
+ ///
+ /// The reader must return an OpenPGP-encoded certificate.
+ ///
+ /// If `reader` contains multiple certificates, this returns an
+ /// error. Use [`CertParser`] if you want to parse a keyring.
fn from_reader<R: io::Read + Send + Sync>(reader: R) -> Result<Self> {
Cert::try_from(PacketParser::from_reader(reader)?)
}
diff --git a/openpgp/src/cert/parser/mod.rs b/openpgp/src/cert/parser/mod.rs
index 147f32de..e8963d94 100644
--- a/openpgp/src/cert/parser/mod.rs
+++ b/openpgp/src/cert/parser/mod.rs
@@ -3,6 +3,7 @@ use std::mem;
use std::vec;
use std::path::Path;
+use buffered_reader::BufferedReader;
use lalrpop_util::ParseError;
use crate::{
@@ -11,6 +12,7 @@ use crate::{
packet::Tag,
Packet,
parse::{
+ Cookie,
Parse,
PacketParserResult,
PacketParser
@@ -594,6 +596,14 @@ impl<'a> From<Vec<Packet>> for CertParser<'a> {
impl<'a> Parse<'a, CertParser<'a>> for CertParser<'a>
{
+ /// Initializes a `CertParser` from a `BufferedReader`.
+ fn from_buffered_reader<R>(reader: R) -> Result<CertParser<'a>>
+ where
+ R: BufferedReader<Cookie> + 'a,
+ {
+ Ok(Self::from(PacketParser::from_buffered_reader(reader)?))
+ }
+
/// Initializes a `CertParser` from a `Read`er.
fn from_reader<R: 'a + io::Read + Send + Sync>(reader: R) -> Result<Self> {
Ok(Self::from(PacketParser::from_reader(reader)?))
diff --git a/openpgp/src/cert/raw.rs b/openpgp/src/cert/raw.rs
index e9610818..bd981c24 100644
--- a/openpgp/src/cert/raw.rs
+++ b/openpgp/src/cert/raw.rs
@@ -459,8 +459,11 @@ impl<'a> Parse<'a, RawCert<'a>> for RawCert<'a> {
/// Returns the first RawCert encountered in the reader.
///
/// Returns an error if there are multiple certificates.
- fn from_reader<R: 'a + Read + Send + Sync>(reader: R) -> Result<Self> {
- let mut parser = RawCertParser::from_reader(reader)?;
+ fn from_buffered_reader<R>(reader: R) -> Result<RawCert<'a>>
+ where
+ R: BufferedReader<Cookie> + 'a
+ {
+ let mut parser = RawCertParser::from_buffered_reader(reader)?;
if let Some(cert_result) = parser.next() {
if parser.next().is_some() {
Err(Error::MalformedCert(
@@ -473,6 +476,14 @@ impl<'a> Parse<'a, RawCert<'a>> for RawCert<'a> {
Err(Error::MalformedCert("No data".into()).into())
}
}
+
+ /// Returns the first RawCert encountered in the reader.
+ ///
+ /// Returns an error if there are multiple certificates.
+ fn from_reader<R: 'a + Read + Send + Sync>(reader: R) -> Result<Self> {
+ let br = Generic::with_cookie(reader, None, Cookie::default());
+ Self::from_buffered_reader(br)
+ }
}
impl<'a> crate::seal::Sealed for RawCert<'a> {}
@@ -655,6 +666,14 @@ impl<'a> RawCertParser<'a> {
impl<'a> Parse<'a, RawCertParser<'a>> for RawCertParser<'a>
{
+ /// Initializes a `RawCertParser` from a `BufferedReader`.
+ fn from_buffered_reader<R>(reader: R) -> Result<RawCertParser<'a>>
+ where
+ R: BufferedReader<Cookie> + 'a
+ {
+ RawCertParser::new(reader)
+ }
+
/// Initializes a `RawCertParser` from a `Read`er.
fn from_reader<R: 'a + Read + Send + Sync>(reader: R) -> Result<Self> {
RawCertParser::new(Generic::with_cookie(reader, None, Default::default()))
diff --git a/openpgp/src/message/mod.rs b/openpgp/src/message/mod.rs
index 5a9d3b1f..d6da5a8f 100644
--- a/openpgp/src/message/mod.rs
+++ b/openpgp/src/message/mod.rs
@@ -29,13 +29,15 @@ use std::fmt;
use std::io;
use std::path::Path;
+use buffered_reader::BufferedReader;
+
use crate::Result;
use crate::Error;
use crate::Packet;
use crate::PacketPile;
use crate::packet::Literal;
use crate::packet::Tag;
-use crate::parse::Parse;
+use crate::parse::{Cookie, Parse};
mod lexer;
lalrpop_util::lalrpop_mod!(#[allow(clippy::all, deprecated)] grammar, "/message/grammar.rs");
@@ -348,6 +350,18 @@ impl<'a> Parse<'a, Message> for Message {
/// See [`Message::try_from`] for more details.
///
/// [`Message::try_from`]: Message::try_from()
+ fn from_buffered_reader<R>(reader: R) -> Result<Message>
+ where
+ R: BufferedReader<Cookie> + 'a,
+ {
+ Self::try_from(PacketPile::from_buffered_reader(reader)?)
+ }
+
+ /// Reads a `Message` from the specified reader.
+ ///
+ /// See [`Message::try_from`] for more details.
+ ///
+ /// [`Message::try_from`]: Message::try_from()
fn from_reader<R: 'a + io::Read + Send + Sync>(reader: R) -> Result<Self> {
Self::try_from(PacketPile::from_reader(reader)?)
}
diff --git a/openpgp/src/packet_pile.rs b/openpgp/src/packet_pile.rs
index f62eb6f6..1678c523 100644
--- a/openpgp/src/packet_pile.rs
+++ b/openpgp/src/packet_pile.rs
@@ -120,6 +120,17 @@ impl fmt::Debug for PacketPile {
}
impl<'a> Parse<'a, PacketPile> for PacketPile {
+ /// Deserializes the OpenPGP message stored in the file named by
+ /// `path`.
+ ///
+ /// See `from_reader` for more details and caveats.
+ fn from_buffered_reader<R>(reader: R) -> Result<PacketPile>
+ where
+ R: BufferedReader<Cookie> + 'a,
+ {
+ PacketPile::from_cookie_reader(reader.into_boxed())
+ }
+
/// Deserializes the OpenPGP message stored in a `std::io::Read`
/// object.
///
diff --git a/openpgp/src/parse.rs b/openpgp/src/parse.rs
index 1b2333a0..b731b74e 100644
--- a/openpgp/src/parse.rs
+++ b/openpgp/src/parse.rs
@@ -281,6 +281,20 @@ pub(crate) const RECOVERY_THRESHOLD: usize = 32 * 1024;
/// This is a uniform interface to parse packets, messages, keys, and
/// related data structures.
pub trait Parse<'a, T> {
+ /// Reads from the given buffered reader.
+ fn from_buffered_reader<R>(reader: R) -> Result<T>
+ where
+ R: BufferedReader<Cookie> + 'a,
+ {
+ // XXXv2: Make this function the mandatory one instead of
+ // Parse::from_reader.
+
+ // Currently, we express the default implementation over
+ // Self::from_reader, which is no worse than using from_reader
+ // directly.
+ Self::from_reader(reader)
+ }
+
/// Reads from the given reader.
fn from_reader<R: 'a + Read + Send + Sync>(reader: R) -> Result<T>;
@@ -338,15 +352,14 @@ macro_rules! impl_parse_with_buffered_reader {
// from_buffered_reader should be a closure that takes a
// BufferedReader and returns a Result<Self>.
($typ: ident, $from_buffered_reader: expr) => {
- impl $typ {
- fn from_buffered_reader<'a, B>(br: B) -> Result<Self>
- where B: 'a + BufferedReader<Cookie>,
+ impl<'a> Parse<'a, $typ> for $typ {
+ fn from_buffered_reader<R>(reader: R) -> Result<Self>
+ where
+ R: BufferedReader<Cookie> + 'a,
{
- Ok($from_buffered_reader(br.into_boxed())?)
+ Ok($from_buffered_reader(reader.into_boxed())?)
}
- }
- impl<'a> Parse<'a, $typ> for $typ {
fn from_reader<R: 'a + Read + Send + Sync>(reader: R) -> Result<Self> {
let br = buffered_reader::Generic::with_cookie(
reader, None, Cookie::default());
@@ -3222,10 +3235,11 @@ impl_parse_with_buffered_reader!(
})
});
-impl<'a> Parse<'a, Packet> for Packet {
- fn from_reader<R: 'a + Read + Send + Sync>(reader: R) -> Result<Self> {
+impl_parse_with_buffered_reader!(
+ Packet,
+ |br| -> Result<Self> {
let ppr =
- PacketParserBuilder::from_reader(reader)
+ PacketParserBuilder::from_buffered_reader(br)
?.buffer_unread_content().build()?;
let (p, ppr) = match ppr {
@@ -3244,8 +3258,7 @@ impl<'a> Parse<'a, Packet> for Packet {
Err(Error::InvalidOperation(
"Excess data after packet".into()).into()),
}
- }
-}
+ });
// State that lives for the life of the packet parser, not the life of
// an individual packet.
@@ -3968,6 +3981,17 @@ impl<'a> PacketParserResult<'a> {
}
impl<'a> Parse<'a, PacketParserResult<'a>> for PacketParser<'a> {
+ /// Starts parsing an OpenPGP object stored in a `BufferedReader` object.
+ ///
+ /// This function returns a `PacketParser` for the first packet in
+ /// the stream.
+ fn from_buffered_reader<R>(reader: R) -> Result<PacketParserResult<'a>>
+ where
+ R: BufferedReader<Cookie> + 'a,
+ {
+ PacketParserBuilder::from_buffered_reader(reader)?.build()
+ }
+
/// Starts parsing an OpenPGP message stored in a `std::io::Read` object.
///
/// This function returns a `PacketParser` for the first packet in
diff --git a/openpgp/src/parse/packet_parser_builder.rs b/openpgp/src/parse/packet_parser_builder.rs
index 02a83ad3..2b52efd5 100644
--- a/openpgp/src/parse/packet_parser_builder.rs
+++ b/openpgp/src/parse/packet_parser_builder.rs
@@ -99,6 +99,17 @@ pub struct PacketParserBuilder<'a> {
assert_send_and_sync!(PacketParserBuilder<'_>);
impl<'a> Parse<'a, PacketParserBuilder<'a>> for PacketParserBuilder<'a> {
+ /// Starts parsing an OpenPGP object stored in a `BufferedReader` object.
+ ///
+ /// This function returns a `PacketParser` for the first packet in
+ /// the stream.
+ fn from_buffered_reader<R>(reader: R) -> Result<PacketParserBuilder<'a>>
+ where
+ R: BufferedReader<Cookie> + 'a,
+ {
+ PacketParserBuilder::from_cookie_reader(reader.into_boxed())
+ }
+
/// Creates a `PacketParserBuilder` for an OpenPGP message stored
/// in a `std::io::Read` object.
fn from_reader<R: io::Read + 'a + Send + Sync>(reader: R) -> Result<Self> {
diff --git a/openpgp/src/parse/packet_pile_parser.rs b/openpgp/src/parse/packet_pile_parser.rs
index ea65912e..b06cf6d8 100644
--- a/openpgp/src/parse/packet_pile_parser.rs
+++ b/openpgp/src/parse/packet_pile_parser.rs
@@ -218,6 +218,13 @@ impl<'a> TryFrom<PacketParserBuilder<'a>> for PacketPileParser<'a> {
}
impl<'a> Parse<'a, PacketPileParser<'a>> for PacketPileParser<'a> {
+ fn from_buffered_reader<R>(reader: R) -> Result<PacketPileParser<'a>>
+ where
+ R: BufferedReader<Cookie> + 'a
+ {
+ PacketPileParser::from_cookie_reader(reader.into_boxed())
+ }
+
/// Creates a `PacketPileParser` to parse the OpenPGP message stored
/// in the `io::Read` object.
fn from_reader<R: io::Read + 'a + Send + Sync>(reader: R)
diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs
index 288df6ac..63d42507 100644
--- a/openpgp/src/parse/stream.rs
+++ b/openpgp/src/parse/stream.rs
@@ -1059,6 +1059,13 @@ assert_send_and_sync!(VerifierBuilder<'_>);
impl<'a> Parse<'a, VerifierBuilder<'a>>
for VerifierBuilder<'a>
{
+ fn from_buffered_reader<R>(reader: R) -> Result<VerifierBuilder<'a>>
+ where
+ R: BufferedReader<Cookie> + 'a,
+ {
+ VerifierBuilder::new(reader)
+ }
+
fn from_reader<R>(reader: R) -> Result<VerifierBuilder<'a>>
where R: io::Read + 'a + Send + Sync,
{
@@ -1460,6 +1467,13 @@ assert_send_and_sync!(DetachedVerifierBuilder<'_>);
impl<'a> Parse<'a, DetachedVerifierBuilder<'a>>
for DetachedVerifierBuilder<'a>
{
+ fn from_buffered_reader<R>(reader: R) -> Result<DetachedVerifierBuilder<'a>>
+ where
+ R: BufferedReader<Cookie> + 'a,
+ {
+ DetachedVerifierBuilder::new(reader)
+ }
+
fn from_reader<R>(reader: R) -> Result<DetachedVerifierBuilder<'a>>
where R: io::Read + 'a + Send + Sync,
{
@@ -1817,6 +1831,13 @@ assert_send_and_sync!(DecryptorBuilder<'_>);
impl<'a> Parse<'a, DecryptorBuilder<'a>>
for DecryptorBuilder<'a>
{
+ fn from_buffered_reader<R>(reader: R) -> Result<DecryptorBuilder<'a>>
+ where
+ R: BufferedReader<Cookie> + 'a,
+ {
+ DecryptorBuilder::new(reader)
+ }
+
fn from_reader<R>(reader: R) -> Result<DecryptorBuilder<'a>>
where R: io::Read + 'a + Send + Sync,
{