From 227db80b9d40526387f1e4a64f90464618fb885b Mon Sep 17 00:00:00 2001 From: Azul Date: Wed, 9 Dec 2020 20:26:52 +0100 Subject: buffered-reader: Require Cookies to be Send and Sync. - This way the entire `BufferedReader` will be `Send` and `Sync`. - Modify all other crates accordingly. - See #615. --- autocrypt/src/lib.rs | 2 +- buffered-reader/src/adapter.rs | 12 ++++---- buffered-reader/src/decompress_bzip2.rs | 10 +++--- buffered-reader/src/decompress_deflate.rs | 22 +++++++------- buffered-reader/src/dup.rs | 10 +++--- buffered-reader/src/eof.rs | 2 +- buffered-reader/src/file_generic.rs | 12 ++++---- buffered-reader/src/file_unix.rs | 20 ++++++------ buffered-reader/src/generic.rs | 14 ++++----- buffered-reader/src/lib.rs | 12 ++++---- buffered-reader/src/limitor.rs | 10 +++--- buffered-reader/src/memory.rs | 10 +++--- buffered-reader/src/reserve.rs | 12 ++++---- ipc/src/sexp/parse/mod.rs | 2 +- openpgp-ffi/include/sequoia/io.h | 8 ++++- openpgp-ffi/include/sequoia/openpgp.h | 18 +++++++++++ openpgp-ffi/src/io.rs | 25 +++++++++++---- openpgp-ffi/src/parse/stream.rs | 49 +++++++++++++++++++++++------- openpgp/src/armor.rs | 5 +-- openpgp/src/cert.rs | 4 +-- openpgp/src/cert/parser/mod.rs | 4 +-- openpgp/src/crypto/aead.rs | 2 +- openpgp/src/crypto/symmetric.rs | 12 ++++---- openpgp/src/message/mod.rs | 4 +-- openpgp/src/packet_pile.rs | 2 +- openpgp/src/parse.rs | 34 ++++++++++----------- openpgp/src/parse/mpis.rs | 10 +++--- openpgp/src/parse/packet_parser_builder.rs | 2 +- openpgp/src/parse/packet_pile_parser.rs | 4 +-- openpgp/src/parse/stream.rs | 8 ++--- sq/src/commands/decrypt.rs | 6 ++-- sq/src/commands/dump.rs | 3 +- sq/src/commands/mod.rs | 6 ++-- sq/src/commands/sign.rs | 8 +++-- sq/src/sq.rs | 4 +-- 35 files changed, 219 insertions(+), 149 deletions(-) diff --git a/autocrypt/src/lib.rs b/autocrypt/src/lib.rs index 3b52cb69..7a51b5f3 100644 --- a/autocrypt/src/lib.rs +++ b/autocrypt/src/lib.rs @@ -538,7 +538,7 @@ impl AutocryptSetupMessage { /// Parses the autocrypt setup message in `r`. /// /// `passcode` is the passcode used to protect the message. - pub fn from_reader<'a, R: io::Read + 'a>(r: R) + pub fn from_reader<'a, R: io::Read + Send + Sync + 'a>(r: R) -> Result> { // The outer message uses ASCII-armor. It includes a password // hint. Hence, we need to parse it aggressively. diff --git a/buffered-reader/src/adapter.rs b/buffered-reader/src/adapter.rs index 65c7a8aa..3734d9bc 100644 --- a/buffered-reader/src/adapter.rs +++ b/buffered-reader/src/adapter.rs @@ -10,7 +10,7 @@ use super::*; /// `Adapter` also changes cookie types, but does no buffering of its /// own. #[derive(Debug)] -pub struct Adapter, B: fmt::Debug, C: fmt::Debug> { +pub struct Adapter, B: fmt::Debug + Send + Sync, C: fmt::Debug + Sync + Send> { reader: T, _ghostly_cookie: std::marker::PhantomData, cookie: C, @@ -21,13 +21,13 @@ assert_send_and_sync!(Adapter B: fmt::Debug, C: fmt::Debug); -impl, B: fmt::Debug, C: fmt::Debug> fmt::Display for Adapter { +impl, B: fmt::Debug + Send + Sync, C: fmt::Debug + Sync + Send> fmt::Display for Adapter { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Adapter").finish() } } -impl, B: fmt::Debug> Adapter { +impl, B: fmt::Debug + Sync + Send> Adapter { /// Instantiates a new adapter. /// /// `reader` is the source to wrap. @@ -36,7 +36,7 @@ impl, B: fmt::Debug> Adapter { } } -impl, B: fmt::Debug, C: fmt::Debug> Adapter { +impl, B: fmt::Debug + Send + Sync, C: fmt::Debug + Sync + Send> Adapter { /// Like `new()`, but sets a cookie. /// /// The cookie can be retrieved using the `cookie_ref` and @@ -51,13 +51,13 @@ impl, B: fmt::Debug, C: fmt::Debug> Adapter { } } -impl, B: fmt::Debug, C: fmt::Debug> io::Read for Adapter { +impl, B: fmt::Debug + Send + Sync, C: fmt::Debug + Sync + Send> io::Read for Adapter { fn read(&mut self, buf: &mut [u8]) -> Result { self.reader.read(buf) } } -impl, B: fmt::Debug, C: fmt::Debug> BufferedReader for Adapter { +impl, B: fmt::Debug + Send + Sync, C: fmt::Debug + Sync + Send> BufferedReader for Adapter { fn buffer(&self) -> &[u8] { self.reader.buffer() } diff --git a/buffered-reader/src/decompress_bzip2.rs b/buffered-reader/src/decompress_bzip2.rs index 8902c2af..febe37fc 100644 --- a/buffered-reader/src/decompress_bzip2.rs +++ b/buffered-reader/src/decompress_bzip2.rs @@ -9,7 +9,7 @@ use super::*; /// Decompresses the underlying `BufferedReader` using the bzip2 /// algorithm. #[derive(Debug)] -pub struct Bzip, C: fmt::Debug> { +pub struct Bzip, C: fmt::Debug + Sync + Send> { reader: Generic, C>, } @@ -26,7 +26,7 @@ impl > Bzip { } } -impl , C: fmt::Debug> Bzip { +impl , C: fmt::Debug + Sync + Send> Bzip { /// Like `new()`, but uses a cookie. /// /// The cookie can be retrieved using the `cookie_ref` and @@ -39,19 +39,19 @@ impl , C: fmt::Debug> Bzip { } } -impl, C: fmt::Debug> io::Read for Bzip { +impl, C: fmt::Debug + Sync + Send> io::Read for Bzip { fn read(&mut self, buf: &mut [u8]) -> Result { self.reader.read(buf) } } -impl, C: fmt::Debug> fmt::Display for Bzip { +impl, C: fmt::Debug + Sync + Send> fmt::Display for Bzip { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Bzip").finish() } } -impl, C: fmt::Debug> BufferedReader for Bzip { +impl, C: fmt::Debug + Send + Sync> BufferedReader for Bzip { fn buffer(&self) -> &[u8] { return self.reader.buffer(); } diff --git a/buffered-reader/src/decompress_deflate.rs b/buffered-reader/src/decompress_deflate.rs index 43084a5f..d1d1a16b 100644 --- a/buffered-reader/src/decompress_deflate.rs +++ b/buffered-reader/src/decompress_deflate.rs @@ -9,7 +9,7 @@ use super::*; /// Decompresses the underlying `BufferedReader` using the deflate /// algorithm. #[derive(Debug)] -pub struct Deflate, C: fmt::Debug> { +pub struct Deflate, C: fmt::Debug + Sync + Send> { reader: Generic, C>, } @@ -26,7 +26,7 @@ impl > Deflate { } } -impl , C: fmt::Debug> Deflate { +impl , C: fmt::Debug + Sync + Send> Deflate { /// Like `new()`, but uses a cookie. /// /// The cookie can be retrieved using the `cookie_ref` and @@ -39,19 +39,19 @@ impl , C: fmt::Debug> Deflate { } } -impl, C: fmt::Debug> io::Read for Deflate { +impl, C: fmt::Debug + Sync + Send> io::Read for Deflate { fn read(&mut self, buf: &mut [u8]) -> Result { self.reader.read(buf) } } -impl, C: fmt::Debug> fmt::Display for Deflate { +impl, C: fmt::Debug + Sync + Send> fmt::Display for Deflate { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Deflate").finish() } } -impl, C: fmt::Debug> BufferedReader +impl, C: fmt::Debug + Send + Sync> BufferedReader for Deflate { fn buffer(&self) -> &[u8] { return self.reader.buffer(); @@ -127,7 +127,7 @@ impl, C: fmt::Debug> BufferedReader /// Decompresses the underlying `BufferedReader` using the zlib /// algorithm. -pub struct Zlib, C: fmt::Debug> { +pub struct Zlib, C: fmt::Debug + Sync + Send> { reader: Generic, C>, } @@ -144,7 +144,7 @@ impl > Zlib { } } -impl , C: fmt::Debug> Zlib { +impl , C: fmt::Debug + Sync + Send> Zlib { /// Like `new()`, but uses a cookie. /// /// The cookie can be retrieved using the `cookie_ref` and @@ -157,19 +157,19 @@ impl , C: fmt::Debug> Zlib { } } -impl, C: fmt::Debug> io::Read for Zlib { +impl, C: fmt::Debug + Sync + Send> io::Read for Zlib { fn read(&mut self, buf: &mut [u8]) -> Result { self.reader.read(buf) } } -impl, C: fmt::Debug> fmt::Display for Zlib { +impl, C: fmt::Debug + Sync + Send> fmt::Display for Zlib { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Zlib") } } -impl, C: fmt::Debug> fmt::Debug for Zlib { +impl, C: fmt::Debug + Sync + Send> fmt::Debug for Zlib { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Zlib") .field("reader", &self.get_ref().unwrap()) @@ -177,7 +177,7 @@ impl, C: fmt::Debug> fmt::Debug for Zlib { } } -impl, C: fmt::Debug> BufferedReader +impl, C: fmt::Debug + Send + Sync> BufferedReader for Zlib { fn buffer(&self) -> &[u8] { return self.reader.buffer(); diff --git a/buffered-reader/src/dup.rs b/buffered-reader/src/dup.rs index 50a9aa26..d7d3f7e5 100644 --- a/buffered-reader/src/dup.rs +++ b/buffered-reader/src/dup.rs @@ -11,7 +11,7 @@ use super::*; /// much data as you read. Thus, it should only be used for peeking /// at the underlying `BufferedReader`. #[derive(Debug)] -pub struct Dup, C: fmt::Debug> { +pub struct Dup, C: fmt::Debug + Sync + Send> { reader: T, // The number of bytes that have been consumed. @@ -25,7 +25,7 @@ assert_send_and_sync!(Dup where T: BufferedReader, C: fmt::Debug); -impl, C: fmt::Debug> fmt::Display for Dup { +impl, C: fmt::Debug + Sync + Send> fmt::Display for Dup { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Dup") .field("cursor", &self.cursor) @@ -42,7 +42,7 @@ impl> Dup { } } -impl, C: fmt::Debug> Dup { +impl, C: fmt::Debug + Sync + Send> Dup { /// Like `new()`, but uses a cookie. /// /// The cookie can be retrieved using the `cookie_ref` and @@ -66,7 +66,7 @@ impl, C: fmt::Debug> Dup { } } -impl, C: fmt::Debug> io::Read for Dup { +impl, C: fmt::Debug + Sync + Send> io::Read for Dup { fn read(&mut self, buf: &mut [u8]) -> Result { let data = self.reader.data(self.cursor + buf.len())?; assert!(data.len() >= self.cursor); @@ -81,7 +81,7 @@ impl, C: fmt::Debug> io::Read for Dup { } } -impl, C: fmt::Debug> BufferedReader for Dup { +impl, C: fmt::Debug + Send + Sync> BufferedReader for Dup { fn buffer(&self) -> &[u8] { let data = self.reader.buffer(); assert!(data.len() >= self.cursor); diff --git a/buffered-reader/src/eof.rs b/buffered-reader/src/eof.rs index c21ecde9..b0312630 100644 --- a/buffered-reader/src/eof.rs +++ b/buffered-reader/src/eof.rs @@ -44,7 +44,7 @@ impl Read for EOF { } } -impl BufferedReader for EOF { +impl BufferedReader for EOF { fn buffer(&self) -> &[u8] { return &b""[..]; } diff --git a/buffered-reader/src/file_generic.rs b/buffered-reader/src/file_generic.rs index cc9f1367..2c61e571 100644 --- a/buffered-reader/src/file_generic.rs +++ b/buffered-reader/src/file_generic.rs @@ -10,18 +10,18 @@ use crate::file_error::FileError; /// /// This is a generic implementation that may be replaced by /// platform-specific versions. -pub struct File(Generic, PathBuf); +pub struct File(Generic, PathBuf); assert_send_and_sync!(File where C: fmt::Debug); -impl fmt::Display for File { +impl fmt::Display for File { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "File {:?}", self.1.display()) } } -impl fmt::Debug for File { +impl fmt::Debug for File { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("File") .field(&self.0) @@ -37,7 +37,7 @@ impl File<()> { } } -impl File { +impl File { /// Like `open()`, but sets a cookie. pub fn with_cookie>(path: P, cookie: C) -> io::Result { let path = path.as_ref(); @@ -46,14 +46,14 @@ impl File { } } -impl io::Read for File { +impl io::Read for File { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.0.read(buf) .map_err(|e| FileError::new(&self.1, e)) } } -impl BufferedReader for File { +impl BufferedReader for File { fn buffer(&self) -> &[u8] { self.0.buffer() } diff --git a/buffered-reader/src/file_unix.rs b/buffered-reader/src/file_unix.rs index 9502021f..a1298737 100644 --- a/buffered-reader/src/file_unix.rs +++ b/buffered-reader/src/file_unix.rs @@ -25,18 +25,18 @@ const MMAP_THRESHOLD: u64 = 16 * 4096; /// /// This implementation tries to mmap the file, falling back to /// just using a generic reader. -pub struct File<'a, C: fmt::Debug>(Imp<'a, C>, PathBuf); +pub struct File<'a, C: fmt::Debug + Sync + Send>(Imp<'a, C>, PathBuf); assert_send_and_sync!(File<'_, C> where C: fmt::Debug); -impl<'a, C: fmt::Debug> fmt::Display for File<'a, C> { +impl<'a, C: fmt::Debug + Sync + Send> fmt::Display for File<'a, C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{} {:?}", self.0, self.1.display()) } } -impl<'a, C: fmt::Debug> fmt::Debug for File<'a, C> { +impl<'a, C: fmt::Debug + Sync + Send> fmt::Debug for File<'a, C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("File") .field(&self.0) @@ -46,14 +46,14 @@ impl<'a, C: fmt::Debug> fmt::Debug for File<'a, C> { } /// The implementation. -enum Imp<'a, C: fmt::Debug> { +enum Imp<'a, C: fmt::Debug + Sync + Send> { Generic(Generic), MMAP { reader: Memory<'a, C>, } } -impl<'a, C: fmt::Debug> Drop for Imp<'a, C> { +impl<'a, C: fmt::Debug + Sync + Send> Drop for Imp<'a, C> { fn drop(&mut self) { match self { Imp::Generic(_) => (), @@ -67,7 +67,7 @@ impl<'a, C: fmt::Debug> Drop for Imp<'a, C> { } } -impl<'a, C: fmt::Debug> fmt::Display for Imp<'a, C> { +impl<'a, C: fmt::Debug + Sync + Send> fmt::Display for Imp<'a, C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "File(")?; match self { @@ -78,7 +78,7 @@ impl<'a, C: fmt::Debug> fmt::Display for Imp<'a, C> { } } -impl<'a, C: fmt::Debug> fmt::Debug for Imp<'a, C> { +impl<'a, C: fmt::Debug + Sync + Send> fmt::Debug for Imp<'a, C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Imp::Generic(ref g) => @@ -102,7 +102,7 @@ impl<'a> File<'a, ()> { } } -impl<'a, C: fmt::Debug> File<'a, C> { +impl<'a, C: fmt::Debug + Sync + Send> File<'a, C> { /// Like `open()`, but sets a cookie. pub fn with_cookie>(path: P, cookie: C) -> io::Result { let path = path.as_ref(); @@ -160,7 +160,7 @@ impl<'a, C: fmt::Debug> File<'a, C> { } } -impl<'a, C: fmt::Debug> io::Read for File<'a, C> { +impl<'a, C: fmt::Debug + Sync + Send> io::Read for File<'a, C> { fn read(&mut self, buf: &mut [u8]) -> io::Result { match self.0 { Imp::Generic(ref mut reader) => reader.read(buf), @@ -169,7 +169,7 @@ impl<'a, C: fmt::Debug> io::Read for File<'a, C> { } } -impl<'a, C: fmt::Debug> BufferedReader for File<'a, C> { +impl<'a, C: fmt::Debug + Sync + Send> BufferedReader for File<'a, C> { fn buffer(&self) -> &[u8] { match self.0 { Imp::Generic(ref reader) => reader.buffer(), diff --git a/buffered-reader/src/generic.rs b/buffered-reader/src/generic.rs index 25c56272..d2e9acfa 100644 --- a/buffered-reader/src/generic.rs +++ b/buffered-reader/src/generic.rs @@ -13,7 +13,7 @@ use super::*; /// /// [`File`]: struct.File.html /// [`Memory`]: struct.Memory.html -pub struct Generic { +pub struct Generic { buffer: Option>, // The next byte to read in the buffer. cursor: usize, @@ -32,13 +32,13 @@ assert_send_and_sync!(Generic where T: io::Read, C: fmt::Debug); -impl fmt::Display for Generic { +impl fmt::Display for Generic { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Generic") } } -impl fmt::Debug for Generic { +impl fmt::Debug for Generic { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let buffered_data = if let Some(ref buffer) = self.buffer { buffer.len() - self.cursor @@ -53,7 +53,7 @@ impl fmt::Debug for Generic { } } -impl Generic { +impl Generic { /// Instantiate a new generic reader. `reader` is the source to /// wrap. `preferred_chuck_size` is the preferred chuck size. If /// None, then the default will be used, which is usually what you @@ -63,7 +63,7 @@ impl Generic { } } -impl Generic { +impl Generic { /// Like `new()`, but sets a cookie, which can be retrieved using /// the `cookie_ref` and `cookie_mut` methods, and set using /// the `cookie_set` method. @@ -206,13 +206,13 @@ impl Generic { } } -impl io::Read for Generic { +impl io::Read for Generic { fn read(&mut self, buf: &mut [u8]) -> Result { return buffered_reader_generic_read_impl(self, buf); } } -impl BufferedReader for Generic { +impl BufferedReader for Generic { fn buffer(&self) -> &[u8] { if let Some(ref buffer) = self.buffer { &buffer[self.cursor..] diff --git a/buffered-reader/src/lib.rs b/buffered-reader/src/lib.rs index 45c12726..f146741d 100644 --- a/buffered-reader/src/lib.rs +++ b/buffered-reader/src/lib.rs @@ -300,8 +300,8 @@ fn vec_truncate(v: &mut Vec, len: usize) { } /// The generic `BufferReader` interface. -pub trait BufferedReader : io::Read + fmt::Debug + fmt::Display - where C: fmt::Debug +pub trait BufferedReader : io::Read + fmt::Debug + fmt::Display + Send + Sync + where C: fmt::Debug + Send + Sync { /// Returns a reference to the internal buffer. /// @@ -907,7 +907,7 @@ pub trait BufferedReader : io::Read + fmt::Debug + fmt::Display /// /// but, alas, Rust doesn't like that ("error\[E0119\]: conflicting /// implementations of trait `std::io::Read` for type `&mut _`"). -pub fn buffered_reader_generic_read_impl, C: fmt::Debug> +pub fn buffered_reader_generic_read_impl, C: fmt::Debug + Sync + Send> (bio: &mut T, buf: &mut [u8]) -> Result { match bio.data_consume(buf.len()) { Ok(inner) => { @@ -920,7 +920,7 @@ pub fn buffered_reader_generic_read_impl, C: fmt::Debug> } /// Make a `Box` look like a BufferedReader. -impl <'a, C: fmt::Debug> BufferedReader for Box + 'a> { +impl <'a, C: fmt::Debug + Sync + Send> BufferedReader for Box + 'a> { fn buffer(&self) -> &[u8] { return self.as_ref().buffer(); } @@ -1018,7 +1018,7 @@ impl <'a, C: fmt::Debug> BufferedReader for Box + 'a> { // // for i in $(seq 0 9999); do printf "%04d\n" $i; done > buffered-reader-test.txt #[cfg(test)] -fn buffered_reader_test_data_check<'a, T: BufferedReader + 'a, C: fmt::Debug>(bio: &mut T) { +fn buffered_reader_test_data_check<'a, T: BufferedReader + 'a, C: fmt::Debug + Sync + Send>(bio: &mut T) { use std::str; for i in 0 .. 10000 { @@ -1072,7 +1072,7 @@ mod test { } #[cfg(test)] - fn buffered_reader_read_test_aux<'a, T: BufferedReader + 'a, C: fmt::Debug> + fn buffered_reader_read_test_aux<'a, T: BufferedReader + 'a, C: fmt::Debug + Sync + Send> (mut bio: T, data: &[u8]) { let mut buffer = [0; 99]; diff --git a/buffered-reader/src/limitor.rs b/buffered-reader/src/limitor.rs index de75ee5e..16f3897e 100644 --- a/buffered-reader/src/limitor.rs +++ b/buffered-reader/src/limitor.rs @@ -6,7 +6,7 @@ use super::*; /// Limits the amount of data that can be read from a /// `BufferedReader`. #[derive(Debug)] -pub struct Limitor, C: fmt::Debug> { +pub struct Limitor, C: fmt::Debug + Sync + Send> { reader: T, limit: u64, @@ -17,7 +17,7 @@ assert_send_and_sync!(Limitor where T: BufferedReader, C: fmt::Debug); -impl, C: fmt::Debug> fmt::Display for Limitor { +impl, C: fmt::Debug + Sync + Send> fmt::Display for Limitor { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Limitor") .field("limit", &self.limit) @@ -35,7 +35,7 @@ impl> Limitor { } } -impl, C: fmt::Debug> Limitor { +impl, C: fmt::Debug + Sync + Send> Limitor { /// Like `new()`, but sets a cookie. /// /// The cookie can be retrieved using the `cookie_ref` and @@ -50,7 +50,7 @@ impl, C: fmt::Debug> Limitor { } } -impl, C: fmt::Debug> io::Read for Limitor { +impl, C: fmt::Debug + Sync + Send> io::Read for Limitor { fn read(&mut self, buf: &mut [u8]) -> Result { let len = cmp::min(self.limit, buf.len() as u64) as usize; let result = self.reader.read(&mut buf[0..len]); @@ -61,7 +61,7 @@ impl, C: fmt::Debug> io::Read for Limitor { } } -impl, C: fmt::Debug> BufferedReader for Limitor { +impl, C: fmt::Debug + Sync + Send> BufferedReader for Limitor { fn buffer(&self) -> &[u8] { let buf = self.reader.buffer(); &buf[..cmp::min(buf.len(), diff --git a/buffered-reader/src/memory.rs b/buffered-reader/src/memory.rs index d13dd018..b469a652 100644 --- a/buffered-reader/src/memory.rs +++ b/buffered-reader/src/memory.rs @@ -12,7 +12,7 @@ use super::*; /// buffer, this implementation is optimized for a memory buffer, and /// avoids double buffering. #[derive(Debug)] -pub struct Memory<'a, C: fmt::Debug> { +pub struct Memory<'a, C: fmt::Debug + Sync + Send> { buffer: &'a [u8], // The next byte to read in the buffer. cursor: usize, @@ -24,7 +24,7 @@ pub struct Memory<'a, C: fmt::Debug> { assert_send_and_sync!(Memory<'_, C> where C: fmt::Debug); -impl<'a, C: fmt::Debug> fmt::Display for Memory<'a, C> { +impl<'a, C: fmt::Debug + Sync + Send> fmt::Display for Memory<'a, C> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Memory ({} of {} bytes read)", self.cursor, self.buffer.len()) @@ -40,7 +40,7 @@ impl<'a> Memory<'a, ()> { } } -impl<'a, C: fmt::Debug> Memory<'a, C> { +impl<'a, C: fmt::Debug + Sync + Send> Memory<'a, C> { /// Like `new()`, but sets a cookie. /// /// The cookie can be retrieved using the `cookie_ref` and @@ -65,7 +65,7 @@ impl<'a, C: fmt::Debug> Memory<'a, C> { } } -impl<'a, C: fmt::Debug> io::Read for Memory<'a, C> { +impl<'a, C: fmt::Debug + Sync + Send> io::Read for Memory<'a, C> { fn read(&mut self, buf: &mut [u8]) -> Result { let amount = cmp::min(buf.len(), self.buffer.len() - self.cursor); buf[0..amount].copy_from_slice( @@ -75,7 +75,7 @@ impl<'a, C: fmt::Debug> io::Read for Memory<'a, C> { } } -impl<'a, C: fmt::Debug> BufferedReader for Memory<'a, C> { +impl<'a, C: fmt::Debug + Sync + Send> BufferedReader for Memory<'a, C> { fn buffer(&self) -> &[u8] { &self.buffer[self.cursor..] } diff --git a/buffered-reader/src/reserve.rs b/buffered-reader/src/reserve.rs index b9c59b69..76d82124 100644 --- a/buffered-reader/src/reserve.rs +++ b/buffered-reader/src/reserve.rs @@ -10,7 +10,7 @@ use super::*; /// how much data can be read from the underlying `BufferedReader`, /// it causes at least N bytes to by buffered. #[derive(Debug)] -pub struct Reserve, C: fmt::Debug> { +pub struct Reserve, C: fmt::Debug + Sync + Send> { reader: T, reserve: usize, @@ -21,7 +21,7 @@ assert_send_and_sync!(Reserve where T: BufferedReader, C: fmt::Debug); -impl, C: fmt::Debug> fmt::Display for Reserve { +impl, C: fmt::Debug + Sync + Send> fmt::Display for Reserve { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Reserve") .field("reserve", &self.reserve) @@ -39,7 +39,7 @@ impl> Reserve { } } -impl, C: fmt::Debug> Reserve { +impl, C: fmt::Debug + Sync + Send> Reserve { /// Like `new()`, but sets a cookie. /// /// The cookie can be retrieved using the `cookie_ref` and @@ -54,7 +54,7 @@ impl, C: fmt::Debug> Reserve { } } -impl, C: fmt::Debug> io::Read for Reserve { +impl, C: fmt::Debug + Sync + Send> io::Read for Reserve { fn read(&mut self, buf: &mut [u8]) -> Result { let to_read = { let data = self.reader.data(buf.len() + self.reserve)?; @@ -71,7 +71,7 @@ impl, C: fmt::Debug> io::Read for Reserve { } } -impl, C: fmt::Debug> BufferedReader for Reserve { +impl, C: fmt::Debug + Send + Sync> BufferedReader for Reserve { fn buffer(&self) -> &[u8] { let buf = self.reader.buffer(); if buf.len() > self.reserve { @@ -171,7 +171,7 @@ mod test { // orig: [ | to_read | | ] // \ total / // - fn read_chunk<'a, R: BufferedReader, C: fmt::Debug>( + fn read_chunk<'a, R: BufferedReader, C: fmt::Debug + Sync + Send>( orig: &[u8], r: &mut R, to_read: usize, cursor: usize, total: usize, mode: usize) { diff --git a/ipc/src/sexp/parse/mod.rs b/ipc/src/sexp/parse/mod.rs index 84a6e2e3..46905fc3 100644 --- a/ipc/src/sexp/parse/mod.rs +++ b/ipc/src/sexp/parse/mod.rs @@ -30,7 +30,7 @@ lalrpop_mod!( ); impl<'a> Parse<'a, Sexp> for Sexp { - fn from_reader(reader: R) -> Result { + fn from_reader(reader: R) -> Result { Self::from_bytes( buffered_reader::Generic::new(reader, None).data_eof()?) } diff --git a/openpgp-ffi/include/sequoia/io.h b/openpgp-ffi/include/sequoia/io.h index e574aefb..35c397dc 100644 --- a/openpgp-ffi/include/sequoia/io.h +++ b/openpgp-ffi/include/sequoia/io.h @@ -36,7 +36,13 @@ typedef ssize_t (*pgp_reader_cb_t) (void *cookie, const void *buf, size_t len); /*/ /// Creates an reader from a callback and cookie. /// -/// This reader calls the given callback to write data. +/// This reader calls the given callback to read data. +/// +/// # Sending objects across thread boundaries +/// +/// If you send a Sequoia object (like a pgp_verifier_t) that reads +/// from an callback across thread boundaries, you must make sure that +/// the callback and cookie support that as well. /*/ pgp_reader_t pgp_reader_from_callback (pgp_reader_cb_t, void *); diff --git a/openpgp-ffi/include/sequoia/openpgp.h b/openpgp-ffi/include/sequoia/openpgp.h index cb6bc31d..82506efd 100644 --- a/openpgp-ffi/include/sequoia/openpgp.h +++ b/openpgp-ffi/include/sequoia/openpgp.h @@ -1999,6 +1999,12 @@ bool pgp_verification_result_bad_signature (pgp_verification_result_t, /// first parameter to each of them. /// /// Note: all of the parameters are required; none may be NULL. +/// +/// # Sending objects across thread boundaries +/// +/// If you send a Sequoia object (like a pgp_verifier_t) that reads +/// from an callback across thread boundaries, you must make sure that +/// the callbacks and cookie support that as well. /*/ pgp_reader_t pgp_decryptor_new (pgp_error_t *errp, pgp_policy_t policy, @@ -2014,6 +2020,12 @@ pgp_reader_t pgp_decryptor_new (pgp_error_t *errp, /// /// No attempt is made to decrypt any encryption packets. These are /// treated as opaque containers. +/// +/// # Sending objects across thread boundaries +/// +/// If you send a Sequoia object (like a pgp_verifier_t) that reads +/// from an callback across thread boundaries, you must make sure that +/// the callbacks and cookie support that as well. /*/ pgp_reader_t pgp_verifier_new (pgp_error_t *errp, pgp_policy_t policy, @@ -2025,6 +2037,12 @@ pgp_reader_t pgp_verifier_new (pgp_error_t *errp, /*/ /// Verifies a detached OpenPGP signature. +/// +/// # Sending objects across thread boundaries +/// +/// If you send a Sequoia object (like a pgp_verifier_t) that reads +/// from an callback across thread boundaries, you must make sure that +/// the callbacks and cookie support that as well. /*/ pgp_detached_verifier_t pgp_detached_verifier_new (pgp_error_t *errp, pgp_policy_t policy, diff --git a/openpgp-ffi/src/io.rs b/openpgp-ffi/src/io.rs index 484615cf..3c5668d6 100644 --- a/openpgp-ffi/src/io.rs +++ b/openpgp-ffi/src/io.rs @@ -26,7 +26,7 @@ pub struct Reader(ReaderKind); /// In some cases, we want to call functions on concrete types. To /// avoid nasty hacks, we have specialized variants for that. pub(crate) enum ReaderKind { - Generic(Box), + Generic(Box), Armored(openpgp::armor::Reader<'static>), } @@ -80,26 +80,39 @@ type ReaderCallbackFn = extern fn(*mut c_void, *const c_void, size_t) -> ssize_t /// Creates an reader from a callback and cookie. /// /// This reader calls the given callback to write data. +/// +/// # Sending objects across thread boundaries +/// +/// If you send a Sequoia object (like a pgp_verifier_t) that reads +/// from an callback across thread boundaries, you must make sure that +/// the callback and cookie support that as well. #[::sequoia_ffi_macros::extern_fn] #[no_mangle] pub extern "C" fn pgp_reader_from_callback(cb: ReaderCallbackFn, cookie: *mut c_void) -> *mut Reader { - let r: Box = Box::new(ReaderCallback { - cb, cookie, - }); + let r: Box = + Box::new(ReaderCallback(Mutex::new(ReaderClosure { + cb, cookie, + }))); ReaderKind::Generic(r).move_into_raw() } /// A generic callback-based reader implementation. -struct ReaderCallback { +struct ReaderCallback(Mutex); + +struct ReaderClosure { cb: ReaderCallbackFn, cookie: *mut c_void, } +unsafe impl Send for ReaderClosure {} + impl Read for ReaderCallback { fn read(&mut self, buf: &mut [u8]) -> io::Result { + let closure = self.0.get_mut().expect("Mutex not to be poisoned"); let r = - (self.cb)(self.cookie, buf.as_mut_ptr() as *mut c_void, buf.len()); + (closure.cb)(closure.cookie, + buf.as_mut_ptr() as *mut c_void, buf.len()); if r < 0 { use std::io as stdio; Err(stdio::Error::new(stdio::ErrorKind::Other, diff --git a/openpgp-ffi/src/parse/stream.rs b/openpgp-ffi/src/parse/stream.rs index 747452a0..16fb1829 100644 --- a/openpgp-ffi/src/parse/stream.rs +++ b/openpgp-ffi/src/parse/stream.rs @@ -11,6 +11,7 @@ //! [`sequoia-openpgp::parse::stream`]: ../../../../sequoia_openpgp/parse/stream/index.html use std::ptr; +use std::sync::Mutex; use libc::{c_int, c_void, time_t}; use sequoia_openpgp as openpgp; @@ -430,13 +431,16 @@ type CheckCallback = extern fn(*mut HelperCookie, -> Status; // This fetches keys and computes the validity of the verification. -struct VHelper { +struct VHelper(Mutex); +struct VHelperClosure { inspect_cb: Option, get_certs_cb: GetPublicKeysCallback, check_signatures_cb: CheckCallback, cookie: *mut HelperCookie, } +unsafe impl Send for VHelperClosure {} + impl VHelper { fn new(inspect_cb: Option, get_certs: GetPublicKeysCallback, @@ -444,19 +448,20 @@ impl VHelper { cookie: *mut HelperCookie) -> Self { - VHelper { + VHelper(Mutex::new(VHelperClosure { inspect_cb, get_certs_cb: get_certs, check_signatures_cb: check_signatures, - cookie, - } + cookie: cookie, + })) } } impl VerificationHelper for VHelper { fn inspect(&mut self, pp: &PacketParser) -> openpgp::Result<()> { - if let Some(cb) = self.inspect_cb { - match cb(self.cookie, pp) { + let closure = self.0.get_mut().expect("Mutex not to be poisoned"); + if let Some(cb) = closure.inspect_cb { + match cb(closure.cookie, pp) { Status::Success => Ok(()), // XXX: Convert the status to an error better. status => Err(anyhow::anyhow!( @@ -481,8 +486,9 @@ impl VerificationHelper for VHelper { let mut free : FreeCallback = |_| {}; - let result = (self.get_certs_cb)( - self.cookie, + let closure = self.0.get_mut().expect("Mutex not to be poisoned"); + let result = (closure.get_certs_cb)( + closure.cookie, ids.as_ptr(), ids.len(), &mut cert_refs_raw, &mut cert_refs_raw_len as *mut usize, &mut free); @@ -515,8 +521,9 @@ impl VerificationHelper for VHelper { fn check(&mut self, structure: stream::MessageStructure) -> Result<(), anyhow::Error> { - let result = (self.check_signatures_cb)(self.cookie, - structure.move_into_raw()); + let closure = self.0.get_mut().expect("Mutex not to be poisoned"); + let result = (closure.check_signatures_cb)(closure.cookie, + structure.move_into_raw()); if result != Status::Success { // XXX: We need to convert the status to an error. A // status contains less information, but we should do the @@ -535,6 +542,12 @@ impl VerificationHelper for VHelper { /// No attempt is made to decrypt any encryption packets. These are /// treated as opaque containers. /// +/// # Sending objects across thread boundaries +/// +/// If you send a Sequoia object (like a pgp_verifier_t) that reads +/// from an callback across thread boundaries, you must make sure that +/// the callbacks and cookie support that as well. +/// /// # Examples /// /// ```c @@ -663,6 +676,12 @@ pub struct DetachedVerifier(openpgp::parse::stream::DetachedVerifier<'static, VH /// Verifies a detached OpenPGP signature. /// +/// # Sending objects across thread boundaries +/// +/// If you send a Sequoia object (like a pgp_verifier_t) that reads +/// from an callback across thread boundaries, you must make sure that +/// the callbacks and cookie support that as well. +/// /// # Examples /// /// ```c @@ -871,8 +890,10 @@ impl DecryptionHelper for DHelper { (*closure)(algo.into(), sk.ref_raw()) } + let closure = + self.vhelper.0.get_mut().expect("Mutex not to be poisoned"); let result = (self.decrypt_cb)( - self.vhelper.cookie, + closure.cookie, pkesks.as_ptr(), pkesks.len(), skesks.as_ptr(), skesks.len(), sym_algo.map(|s| u8::from(s)).unwrap_or(0), trampoline::, @@ -904,6 +925,12 @@ impl DecryptionHelper for DHelper { /// /// Note: all of the parameters are required; none may be NULL. /// +/// # Sending objects across thread boundaries +/// +/// If you send a Sequoia object (like a pgp_verifier_t) that reads +/// from an callback across thread boundaries, you must make sure that +/// the callbacks and cookie support that as well. +/// /// # Examples /// /// ```c diff --git a/openpgp/src/armor.rs b/openpgp/src/armor.rs index 686ea939..88b31a6c 100644 --- a/openpgp/src/armor.rs +++ b/openpgp/src/armor.rs @@ -486,6 +486,7 @@ struct IoReader<'a> { prefix_len: usize, prefix_remaining: usize, } +assert_send_and_sync!(IoReader<'_>); impl Default for ReaderMode { fn default() -> Self { @@ -563,7 +564,7 @@ impl<'a> Reader<'a> { /// # } /// ``` pub fn new(inner: R, mode: M) -> Self - where R: 'a + Read, + where R: 'a + Read + Send + Sync, M: Into> { Self::from_buffered_reader( @@ -574,7 +575,7 @@ impl<'a> Reader<'a> { /// Creates a `Reader` from an `io::Read`er. pub fn from_reader(reader: R, mode: M) -> Self - where R: 'a + Read, + where R: 'a + Read + Send + Sync, M: Into> { Self::from_buffered_reader( diff --git a/openpgp/src/cert.rs b/openpgp/src/cert.rs index 7acf8e4e..bb2970fc 100644 --- a/openpgp/src/cert.rs +++ b/openpgp/src/cert.rs @@ -740,7 +740,7 @@ impl std::str::FromStr for Cert { impl<'a> Parse<'a, Cert> for Cert { /// Returns the first Cert encountered in the reader. - fn from_reader(reader: R) -> Result { + fn from_reader(reader: R) -> Result { Cert::try_from(PacketParser::from_reader(reader)?) } @@ -752,7 +752,7 @@ impl<'a> Parse<'a, Cert> for Cert { /// Returns the first Cert found in `buf`. /// /// `buf` must be an OpenPGP-encoded message. - fn from_bytes + ?Sized>(data: &'a D) -> Result { + fn from_bytes + ?Sized + Send + Sync>(data: &'a D) -> Result { Cert::try_from(PacketParser::from_bytes(data)?) } } diff --git a/openpgp/src/cert/parser/mod.rs b/openpgp/src/cert/parser/mod.rs index 5538bbf1..48b340c9 100644 --- a/openpgp/src/cert/parser/mod.rs +++ b/openpgp/src/cert/parser/mod.rs @@ -610,7 +610,7 @@ impl<'a> From> for CertParser<'a> { impl<'a> Parse<'a, CertParser<'a>> for CertParser<'a> { /// Initializes a `CertParser` from a `Read`er. - fn from_reader(reader: R) -> Result { + fn from_reader(reader: R) -> Result { Ok(Self::from(PacketParser::from_reader(reader)?)) } @@ -620,7 +620,7 @@ impl<'a> Parse<'a, CertParser<'a>> for CertParser<'a> } /// Initializes a `CertParser` from a byte string. - fn from_bytes + ?Sized>(data: &'a D) -> Result { + fn from_bytes + ?Sized + Send + Sync>(data: &'a D) -> Result { Ok(Self::from(PacketParser::from_bytes(data)?)) } } diff --git a/openpgp/src/crypto/aead.rs b/openpgp/src/crypto/aead.rs index fb95b087..5e9b5eeb 100644 --- a/openpgp/src/crypto/aead.rs +++ b/openpgp/src/crypto/aead.rs @@ -121,7 +121,7 @@ impl<'a> Decryptor<'a> { /// Instantiate a new AEAD decryptor. /// /// `source` is the source to wrap. - pub fn new(version: u8, sym_algo: SymmetricAlgorithm, + pub fn new(version: u8, sym_algo: SymmetricAlgorithm, aead: AEADAlgorithm, chunk_size: usize, iv: &[u8], key: &SessionKey, source: R) -> Result diff --git a/openpgp/src/crypto/symmetric.rs b/openpgp/src/crypto/symmetric.rs index 0a022cc3..381cbe95 100644 --- a/openpgp/src/crypto/symmetric.rs +++ b/openpgp/src/crypto/symmetric.rs @@ -194,11 +194,11 @@ impl io::Read for Decryptor { /// A `BufferedReader` that decrypts symmetrically-encrypted data as /// it is read. -pub(crate) struct BufferedReaderDecryptor, C: fmt::Debug> { +pub(crate) struct BufferedReaderDecryptor, C: fmt::Debug + Send + Sync> { reader: buffered_reader::Generic, C>, } -impl , C: fmt::Debug> BufferedReaderDecryptor { +impl , C: fmt::Debug + Send + Sync> BufferedReaderDecryptor { /// Like `new()`, but sets a cookie, which can be retrieved using /// the `cookie_ref` and `cookie_mut` methods, and set using /// the `cookie_set` method. @@ -213,19 +213,19 @@ impl , C: fmt::Debug> BufferedReaderDecryptor { } } -impl, C: fmt::Debug> io::Read for BufferedReaderDecryptor { +impl, C: fmt::Debug + Send + Sync> io::Read for BufferedReaderDecryptor { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.reader.read(buf) } } -impl, C: fmt::Debug> fmt::Display for BufferedReaderDecryptor { +impl, C: fmt::Debug + Send + Sync> fmt::Display for BufferedReaderDecryptor { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "BufferedReaderDecryptor") } } -impl, C: fmt::Debug> fmt::Debug for BufferedReaderDecryptor { +impl, C: fmt::Debug + Send + Sync> fmt::Debug for BufferedReaderDecryptor { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("BufferedReaderDecryptor") .field("reader", &self.get_ref().unwrap()) @@ -233,7 +233,7 @@ impl, C: fmt::Debug> fmt::Debug for BufferedReaderDecryptor } } -impl, C: fmt::Debug> BufferedReader +impl, C: fmt::Debug + Send + Sync> BufferedReader for BufferedReaderDecryptor { fn buffer(&self) -> &[u8] { return self.reader.buffer(); diff --git a/openpgp/src/message/mod.rs b/openpgp/src/message/mod.rs index e92581a5..2fb0daa3 100644 --- a/openpgp/src/message/mod.rs +++ b/openpgp/src/message/mod.rs @@ -363,7 +363,7 @@ impl<'a> Parse<'a, Message> for Message { /// See [`Message::try_from`] for more details. /// /// [`Message::try_from`]: #method.try_from - fn from_reader(reader: R) -> Result { + fn from_reader(reader: R) -> Result { Self::try_from(PacketPile::from_reader(reader)?) } @@ -381,7 +381,7 @@ impl<'a> Parse<'a, Message> for Message { /// See [`Message::try_from`] for more details. /// /// [`Message::try_from`]: #method.try_from - fn from_bytes + ?Sized>(data: &'a D) -> Result { + fn from_bytes + ?Sized + Send + Sync>(data: &'a D) -> Result { Self::try_from(PacketPile::from_bytes(data)?) } } diff --git a/openpgp/src/packet_pile.rs b/openpgp/src/packet_pile.rs index 09a432b2..330d02cf 100644 --- a/openpgp/src/packet_pile.rs +++ b/openpgp/src/packet_pile.rs @@ -137,7 +137,7 @@ impl<'a> Parse<'a, PacketPile> for PacketPile { /// /// [`PacketParser`]: parse/struct.PacketParser.html /// [`PacketPileParser`]: parse/struct.PacketPileParser.html - fn from_reader(reader: R) -> Result { + fn from_reader(reader: R) -> Result { let bio = buffered_reader::Generic::with_cookie( reader, None, Cookie::default()); PacketPile::from_buffered_reader(Box::new(bio)) diff --git a/openpgp/src/parse.rs b/openpgp/src/parse.rs index 5840436c..e557850e 100644 --- a/openpgp/src/parse.rs +++ b/openpgp/src/parse.rs @@ -270,7 +270,7 @@ const TRACE : bool = false; /// related data structures. pub trait Parse<'a, T> { /// Reads from the given reader. - fn from_reader(reader: R) -> Result; + fn from_reader(reader: R) -> Result; /// Reads from the given file. /// @@ -289,7 +289,7 @@ pub trait Parse<'a, T> { /// implementations can provide their own specialized version. /// /// [`from_reader(..)`]: #tymethod.from_reader - fn from_bytes + ?Sized>(data: &'a D) -> Result { + fn from_bytes + ?Sized + Send + Sync>(data: &'a D) -> Result { Self::from_reader(io::Cursor::new(data)) } } @@ -297,7 +297,7 @@ pub trait Parse<'a, T> { macro_rules! impl_parse_generic_packet { ($typ: ident) => { impl<'a> Parse<'a, $typ> for $typ { - fn from_reader(reader: R) -> Result { + fn from_reader(reader: R) -> Result { let bio = buffered_reader::Generic::with_cookie( reader, None, Cookie::default()); let parser = PacketHeaderParser::new_naked(bio); @@ -1082,7 +1082,7 @@ impl S2K { impl<'a> Parse<'a, S2K> for S2K { /// Reads an S2K from `reader`. - fn from_reader(reader: R) -> Result { + fn from_reader(reader: R) -> Result { let bio = buffered_reader::Generic::with_cookie( reader, None, Cookie::default()); let mut parser = PacketHeaderParser::new_naked(bio); @@ -1091,7 +1091,7 @@ impl<'a> Parse<'a, S2K> for S2K { } impl Header { - pub(crate) fn parse, C: fmt::Debug> (bio: &mut R) + pub(crate) fn parse, C: fmt::Debug + Send + Sync> (bio: &mut R) -> Result
{ let ctb = CTB::try_from(bio.data_consume_hard(1)?[0])?; @@ -1109,7 +1109,7 @@ impl<'a> Parse<'a, Header> for Header { /// of RFC 4880]. /// /// [Section 4.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-4.2 - fn from_reader(reader: R) -> Result + fn from_reader(reader: R) -> Result { let mut reader = buffered_reader::Generic::with_cookie( reader, None, Cookie::default()); @@ -1122,7 +1122,7 @@ impl BodyLength { /// 4.2.2 of RFC 4880]. /// /// [Section 4.2.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-4.2.2 - pub(crate) fn parse_new_format, C: fmt::Debug> (bio: &mut T) + pub(crate) fn parse_new_format, C: fmt::Debug + Send + Sync> (bio: &mut T) -> io::Result { let octet1 : u8 = bio.data_consume_hard(1)?[0]; @@ -1145,7 +1145,7 @@ impl BodyLength { /// 4.2.1 of RFC 4880]. /// /// [Section 4.2.1 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-4.2.1 - pub(crate) fn parse_old_format, C: fmt::Debug> + pub(crate) fn parse_old_format, C: fmt::Debug + Send + Sync> (bio: &mut T, length_type: PacketLengthType) -> Result { @@ -1230,7 +1230,7 @@ impl Unknown { // Note: we only need this function for testing purposes in a // different module. #[cfg(test)] -pub(crate) fn to_unknown_packet(reader: R) -> Result +pub(crate) fn to_unknown_packet(reader: R) -> Result { let mut reader = buffered_reader::Generic::with_cookie( reader, None, Cookie::default()); @@ -1732,7 +1732,7 @@ impl Subpacket { impl SubpacketLength { /// Parses a subpacket length. - fn parse, C: fmt::Debug>(bio: &mut R) -> Result { + fn parse, C: fmt::Debug + Send + Sync>(bio: &mut R) -> Result { let octet1 = bio.data_consume_hard(1)?[0]; if octet1 < 192 { // One octet. @@ -1964,7 +1964,7 @@ fn one_pass_sig_parser_test () { } impl<'a> Parse<'a, OnePassSig3> for OnePassSig3 { - fn from_reader(reader: R) -> Result { + fn from_reader(reader: R) -> Result { OnePassSig::from_reader(reader).and_then(|p| match p { OnePassSig::V3(p) => Ok(p), // XXX: Once we have a second variant. @@ -2238,7 +2238,7 @@ impl Key4 } impl<'a> Parse<'a, key::UnspecifiedKey> for key::UnspecifiedKey { - fn from_reader(reader: R) -> Result { + fn from_reader(reader: R) -> Result { let bio = buffered_reader::Generic::with_cookie( reader, None, Cookie::default()); let parser = PacketHeaderParser::new_naked(bio); @@ -2863,7 +2863,7 @@ impl MPI { impl<'a> Parse<'a, MPI> for MPI { // Reads an MPI from `reader`. - fn from_reader(reader: R) -> Result { + fn from_reader(reader: R) -> Result { let bio = buffered_reader::Generic::with_cookie( reader, None, Cookie::default()); let mut parser = PacketHeaderParser::new_naked(bio); @@ -2904,7 +2904,7 @@ impl PKESK3 { } impl<'a> Parse<'a, PKESK3> for PKESK3 { - fn from_reader(reader: R) -> Result { + fn from_reader(reader: R) -> Result { PKESK::from_reader(reader).and_then(|p| match p { PKESK::V3(p) => Ok(p), // XXX: Once we have a second variant. @@ -2916,7 +2916,7 @@ impl<'a> Parse<'a, PKESK3> for PKESK3 { } impl<'a> Parse<'a, Packet> for Packet { - fn from_reader(reader: R) -> Result { + fn from_reader(reader: R) -> Result { let ppr = PacketParserBuilder::from_reader(reader) ?.buffer_unread_content().build()?; @@ -3676,7 +3676,7 @@ impl<'a> Parse<'a, PacketParserResult<'a>> for PacketParser<'a> { /// /// This function returns a `PacketParser` for the first packet in /// the stream. - fn from_reader(reader: R) + fn from_reader(reader: R) -> Result> { PacketParserBuilder::from_reader(reader)?.build() } @@ -3694,7 +3694,7 @@ impl<'a> Parse<'a, PacketParserResult<'a>> for PacketParser<'a> { /// /// This function returns a `PacketParser` for the first packet in /// the stream. - fn from_bytes + ?Sized>(data: &'a D) + fn from_bytes + ?Sized + Send + Sync>(data: &'a D) -> Result> { PacketParserBuilder::from_bytes(data)?.build() } diff --git a/openpgp/src/parse/mpis.rs b/openpgp/src/parse/mpis.rs index b7ca51da..35537c0f 100644 --- a/openpgp/src/parse/mpis.rs +++ b/openpgp/src/parse/mpis.rs @@ -22,7 +22,7 @@ impl mpi::PublicKey { /// See [Section 3.2 of RFC 4880] for details. /// /// [Section 3.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-3.2 - pub fn parse(algo: PublicKeyAlgorithm, reader: R) -> Result + pub fn parse(algo: PublicKeyAlgorithm, reader: R) -> Result { let bio = buffered_reader::Generic::with_cookie( reader, None, Cookie::default()); @@ -151,7 +151,7 @@ impl mpi::SecretKeyMaterial { /// Parses secret key MPIs for `algo` plus their SHA1 checksum. /// /// Fails if the checksum is wrong. - pub fn parse_with_checksum(algo: PublicKeyAlgorithm, + pub fn parse_with_checksum(algo: PublicKeyAlgorithm, reader: R, checksum: mpi::SecretKeyChecksum) -> Result { @@ -166,7 +166,7 @@ impl mpi::SecretKeyMaterial { /// See [Section 3.2 of RFC 4880] for details. /// /// [Section 3.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-3.2 - pub fn parse(algo: PublicKeyAlgorithm, reader: R) -> Result + pub fn parse(algo: PublicKeyAlgorithm, reader: R) -> Result { let bio = buffered_reader::Generic::with_cookie( reader, None, Cookie::default()); @@ -305,7 +305,7 @@ impl mpi::Ciphertext { /// See [Section 3.2 of RFC 4880] for details. /// /// [Section 3.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-3.2 - pub fn parse(algo: PublicKeyAlgorithm, reader: R) -> Result + pub fn parse(algo: PublicKeyAlgorithm, reader: R) -> Result { let bio = buffered_reader::Generic::with_cookie( reader, None, Cookie::default()); @@ -384,7 +384,7 @@ impl mpi::Signature { /// See [Section 3.2 of RFC 4880] for details. /// /// [Section 3.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-3.2 - pub fn parse(algo: PublicKeyAlgorithm, reader: R) -> Result + pub fn parse(algo: PublicKeyAlgorithm, reader: R) -> Result { let bio = buffered_reader::Generic::with_cookie( reader, None, Cookie::default()); diff --git a/openpgp/src/parse/packet_parser_builder.rs b/openpgp/src/parse/packet_parser_builder.rs index a5617a04..56ea6067 100644 --- a/openpgp/src/parse/packet_parser_builder.rs +++ b/openpgp/src/parse/packet_parser_builder.rs @@ -100,7 +100,7 @@ pub struct PacketParserBuilder<'a> { impl<'a> Parse<'a, PacketParserBuilder<'a>> for PacketParserBuilder<'a> { /// Creates a `PacketParserBuilder` for an OpenPGP message stored /// in a `std::io::Read` object. - fn from_reader(reader: R) -> Result { + fn from_reader(reader: R) -> Result { PacketParserBuilder::from_buffered_reader( Box::new(buffered_reader::Generic::with_cookie( reader, None, Cookie::default()))) diff --git a/openpgp/src/parse/packet_pile_parser.rs b/openpgp/src/parse/packet_pile_parser.rs index fe1e989c..4b04fab9 100644 --- a/openpgp/src/parse/packet_pile_parser.rs +++ b/openpgp/src/parse/packet_pile_parser.rs @@ -220,7 +220,7 @@ impl<'a> TryFrom> for PacketPileParser<'a> { impl<'a> Parse<'a, PacketPileParser<'a>> for PacketPileParser<'a> { /// Creates a `PacketPileParser` to parse the OpenPGP message stored /// in the `io::Read` object. - fn from_reader(reader: R) + fn from_reader(reader: R) -> Result> { let bio = Box::new(buffered_reader::Generic::with_cookie( reader, None, Cookie::default())); @@ -237,7 +237,7 @@ impl<'a> Parse<'a, PacketPileParser<'a>> for PacketPileParser<'a> { /// Creates a `PacketPileParser` to parse the OpenPGP message stored /// in the provided buffer. - fn from_bytes + ?Sized>(data: &'a D) + fn from_bytes + ?Sized + Send + Sync>(data: &'a D) -> Result> { let bio = Box::new(buffered_reader::Memory::with_cookie( data.as_ref(), Cookie::default())); diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs index a55f263f..7fc2eafb 100644 --- a/openpgp/src/parse/stream.rs +++ b/openpgp/src/parse/stream.rs @@ -1004,7 +1004,7 @@ impl<'a> Parse<'a, VerifierBuilder<'a>> for VerifierBuilder<'a> { fn from_reader(reader: R) -> Result> - where R: io::Read + 'a, + where R: io::Read + 'a + Send + Sync, { VerifierBuilder::new(buffered_reader::Generic::with_cookie( reader, None, Default::default())) @@ -1412,7 +1412,7 @@ impl<'a> Parse<'a, DetachedVerifierBuilder<'a>> for DetachedVerifierBuilder<'a> { fn from_reader(reader: R) -> Result> - where R: io::Read + 'a, + where R: io::Read + 'a + Send + Sync, { DetachedVerifierBuilder::new(buffered_reader::Generic::with_cookie( reader, None, Default::default())) @@ -1575,7 +1575,7 @@ impl<'a> DetachedVerifierBuilder<'a> { impl<'a, H: VerificationHelper> DetachedVerifier<'a, H> { /// Verifies the given data. - pub fn verify_reader(&mut self, reader: R) -> Result<()> { + pub fn verify_reader(&mut self, reader: R) -> Result<()> { self.verify(buffered_reader::Generic::with_cookie( reader, None, Default::default()).as_boxed()) } @@ -1767,7 +1767,7 @@ impl<'a> Parse<'a, DecryptorBuilder<'a>> for DecryptorBuilder<'a> { fn from_reader(reader: R) -> Result> - where R: io::Read + 'a, + where R: io::Read + 'a + Send + Sync, { DecryptorBuilder::new(buffered_reader::Generic::with_cookie( reader, None, Default::default())) diff --git a/sq/src/commands/decrypt.rs b/sq/src/commands/decrypt.rs index 07adabe6..a2d24514 100644 --- a/sq/src/commands/decrypt.rs +++ b/sq/src/commands/decrypt.rs @@ -275,7 +275,8 @@ impl<'a> DecryptionHelper for Helper<'a> { } pub fn decrypt(ctx: &Context, policy: &dyn Policy, mapping: &mut store::Mapping, - input: &mut dyn io::Read, output: &mut dyn io::Write, + input: &mut (dyn io::Read + Sync + Send), + output: &mut dyn io::Write, signatures: usize, certs: Vec, secrets: Vec, dump_session_key: bool, dump: bool, hex: bool) @@ -299,7 +300,8 @@ pub fn decrypt(ctx: &Context, policy: &dyn Policy, mapping: &mut store::Mapping, pub fn decrypt_unwrap(ctx: &Context, policy: &dyn Policy, mapping: &mut store::Mapping, - input: &mut dyn io::Read, output: &mut dyn io::Write, + input: &mut (dyn io::Read + Sync + Send), + output: &mut dyn io::Write, secrets: Vec, dump_session_key: bool) -> Result<()> { diff --git a/sq/src/commands/dump.rs b/sq/src/commands/dump.rs index eddce8c8..4334feb7 100644 --- a/sq/src/commands/dump.rs +++ b/sq/src/commands/dump.rs @@ -52,7 +52,8 @@ impl Convert> for Timestamp { } } -pub fn dump(input: &mut dyn io::Read, output: &mut dyn io::Write, +pub fn dump(input: &mut (dyn io::Read + Sync + Send), + output: &mut dyn io::Write, mpis: bool, hex: bool, sk: Option<&SessionKey>, width: W) -> Result diff --git a/sq/src/commands/mod.rs b/sq/src/commands/mod.rs index f7f47787..83a02237 100644 --- a/sq/src/commands/mod.rs +++ b/sq/src/commands/mod.rs @@ -374,8 +374,8 @@ impl<'a> VerificationHelper for VHelper<'a> { pub fn verify(ctx: &Context, policy: &dyn Policy, mapping: &mut store::Mapping, - input: &mut dyn io::Read, - detached: Option<&mut dyn io::Read>, + input: &mut (dyn io::Read + Sync + Send), + detached: Option<&mut (dyn io::Read + Sync + Send)>, output: &mut dyn io::Write, signatures: usize, certs: Vec) -> Result<()> { @@ -396,7 +396,7 @@ pub fn verify(ctx: &Context, policy: &dyn Policy, Ok(()) } -pub fn split(input: &mut dyn io::Read, prefix: &str) +pub fn split(input: &mut (dyn io::Read + Sync + Send), prefix: &str) -> Result<()> { // We (ab)use the mapping feature to create byte-accurate dumps of // nested packets. diff --git a/sq/src/commands/sign.rs b/sq/src/commands/sign.rs index f8906ac3..5c72d15a 100644 --- a/sq/src/commands/sign.rs +++ b/sq/src/commands/sign.rs @@ -24,7 +24,8 @@ use crate::{ }; pub fn sign(policy: &dyn Policy, - input: &mut dyn io::Read, output_path: Option<&str>, + input: &mut (dyn io::Read + Sync + Send), + output_path: Option<&str>, secrets: Vec, detached: bool, binary: bool, append: bool, notarize: bool, time: Option, force: bool) @@ -140,7 +141,8 @@ fn sign_data(policy: &dyn Policy, } fn sign_message(policy: &dyn Policy, - input: &mut dyn io::Read, output_path: Option<&str>, + input: &mut (dyn io::Read + Sync + Send), + output_path: Option<&str>, secrets: Vec, binary: bool, notarize: bool, time: Option, force: bool) -> Result<()> { @@ -154,7 +156,7 @@ fn sign_message(policy: &dyn Policy, } fn sign_message_(policy: &dyn Policy, - input: &mut dyn io::Read, + input: &mut (dyn io::Read + Sync + Send), output: &mut (dyn io::Write + Sync + Send), secrets: Vec, notarize: bool, time: Option) diff --git a/sq/src/sq.rs b/sq/src/sq.rs index d75c2cae..00477329 100644 --- a/sq/src/sq.rs +++ b/sq/src/sq.rs @@ -40,7 +40,7 @@ mod sq_cli; mod commands; use commands::dump::Convert; -fn open_or_stdin(f: Option<&str>) -> Result> { +fn open_or_stdin(f: Option<&str>) -> Result> { match f { Some(f) => Ok(Box::new(File::open(f) .context("Failed to open input file")?)), @@ -294,7 +294,7 @@ fn main() -> Result<()> { let mut mapping = Mapping::open(&ctx, realm_name, mapping_name) .context("Failed to ope