diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2019-04-09 13:08:20 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-04-09 13:08:20 +0200 |
commit | 7c92d7381408b375d158dd3aedfa61d340ed3750 (patch) | |
tree | 1fe1a0ff202930700e9817ebb1d67b281217ece1 | |
parent | b372fdb81fbff4bfca997b4d271aedc6026c158c (diff) |
openpgp: Guard signature verifications with a time.
- In the streaming verifier and decryptor, check that
signatures (and binding signatures) are valid at the given time.
- Fixes #247.
-rw-r--r-- | guide/src/chapter_01.md | 8 | ||||
-rw-r--r-- | guide/src/chapter_02.md | 8 | ||||
-rw-r--r-- | openpgp-ffi/examples/decrypt-with.c | 2 | ||||
-rw-r--r-- | openpgp-ffi/include/sequoia/openpgp.h | 6 | ||||
-rw-r--r-- | openpgp-ffi/src/parse/stream.rs | 31 | ||||
-rw-r--r-- | openpgp/examples/decrypt-with.rs | 2 | ||||
-rw-r--r-- | openpgp/examples/generate-encrypt-decrypt.rs | 2 | ||||
-rw-r--r-- | openpgp/examples/generate-sign-verify.rs | 2 | ||||
-rw-r--r-- | openpgp/src/lib.rs | 10 | ||||
-rw-r--r-- | openpgp/src/parse/stream.rs | 176 | ||||
-rw-r--r-- | openpgp/src/serialize/stream.rs | 4 | ||||
-rw-r--r-- | tool/src/commands/decrypt.rs | 2 | ||||
-rw-r--r-- | tool/src/commands/mod.rs | 5 |
13 files changed, 173 insertions, 85 deletions
diff --git a/guide/src/chapter_01.md b/guide/src/chapter_01.md index 580a27d6..ab89c229 100644 --- a/guide/src/chapter_01.md +++ b/guide/src/chapter_01.md @@ -82,7 +82,7 @@ fn main() { # }; # # // Now, create a verifier with a helper using the given TPKs. -# let mut verifier = Verifier::from_bytes(signed_message, helper)?; +# let mut verifier = Verifier::from_bytes(signed_message, helper, None)?; # # // Verify the data. # io::copy(&mut verifier, sink)?; @@ -212,7 +212,7 @@ fn generate() -> openpgp::Result<openpgp::TPK> { # }; # # // Now, create a verifier with a helper using the given TPKs. -# let mut verifier = Verifier::from_bytes(signed_message, helper)?; +# let mut verifier = Verifier::from_bytes(signed_message, helper, None)?; # # // Verify the data. # io::copy(&mut verifier, sink)?; @@ -342,7 +342,7 @@ fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::TPK) # }; # # // Now, create a verifier with a helper using the given TPKs. -# let mut verifier = Verifier::from_bytes(signed_message, helper)?; +# let mut verifier = Verifier::from_bytes(signed_message, helper, None)?; # # // Verify the data. # io::copy(&mut verifier, sink)?; @@ -483,7 +483,7 @@ fn verify(sink: &mut Write, signed_message: &[u8], sender: &openpgp::TPK) }; // Now, create a verifier with a helper using the given TPKs. - let mut verifier = Verifier::from_bytes(signed_message, helper)?; + let mut verifier = Verifier::from_bytes(signed_message, helper, None)?; // Verify the data. io::copy(&mut verifier, sink)?; diff --git a/guide/src/chapter_02.md b/guide/src/chapter_02.md index 2a23b65b..60f1a9b2 100644 --- a/guide/src/chapter_02.md +++ b/guide/src/chapter_02.md @@ -83,7 +83,7 @@ fn main() { # }; # # // Now, create a decryptor with a helper using the given TPKs. -# let mut decryptor = Decryptor::from_bytes(ciphertext, helper)?; +# let mut decryptor = Decryptor::from_bytes(ciphertext, helper, None)?; # # // Decrypt the data. # io::copy(&mut decryptor, sink)?; @@ -217,7 +217,7 @@ fn generate() -> openpgp::Result<openpgp::TPK> { # }; # # // Now, create a decryptor with a helper using the given TPKs. -# let mut decryptor = Decryptor::from_bytes(ciphertext, helper)?; +# let mut decryptor = Decryptor::from_bytes(ciphertext, helper, None)?; # # // Decrypt the data. # io::copy(&mut decryptor, sink)?; @@ -351,7 +351,7 @@ fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::TPK) # }; # # // Now, create a decryptor with a helper using the given TPKs. -# let mut decryptor = Decryptor::from_bytes(ciphertext, helper)?; +# let mut decryptor = Decryptor::from_bytes(ciphertext, helper, None)?; # # // Decrypt the data. # io::copy(&mut decryptor, sink)?; @@ -499,7 +499,7 @@ fn decrypt(sink: &mut Write, ciphertext: &[u8], recipient: &openpgp::TPK) }; // Now, create a decryptor with a helper using the given TPKs. - let mut decryptor = Decryptor::from_bytes(ciphertext, helper)?; + let mut decryptor = Decryptor::from_bytes(ciphertext, helper, None)?; // Decrypt the data. io::copy(&mut decryptor, sink)?; diff --git a/openpgp-ffi/examples/decrypt-with.c b/openpgp-ffi/examples/decrypt-with.c index d68e0902..969b7e28 100644 --- a/openpgp-ffi/examples/decrypt-with.c +++ b/openpgp-ffi/examples/decrypt-with.c @@ -128,7 +128,7 @@ main (int argc, char **argv) }; plaintext = pgp_decryptor_new (&err, source, get_public_keys_cb, decrypt_cb, - check_signatures_cb, &cookie); + check_signatures_cb, &cookie, 0); if (! plaintext) error (1, 0, "pgp_decryptor_new: %s", pgp_error_to_string (err)); diff --git a/openpgp-ffi/include/sequoia/openpgp.h b/openpgp-ffi/include/sequoia/openpgp.h index 73bcc7a6..aa7e117c 100644 --- a/openpgp-ffi/include/sequoia/openpgp.h +++ b/openpgp-ffi/include/sequoia/openpgp.h @@ -1436,7 +1436,7 @@ pgp_reader_t pgp_decryptor_new (pgp_error_t *errp, pgp_reader_t input, pgp_decryptor_get_public_keys_cb_t get_public_keys, pgp_decryptor_decrypt_cb_t decrypt, pgp_decryptor_check_signatures_cb_t check_signatures, - void *cookie); + void *cookie, time_t time); /*/ /// Verifies an OpenPGP message. @@ -1447,7 +1447,7 @@ pgp_reader_t pgp_decryptor_new (pgp_error_t *errp, pgp_reader_t input, pgp_reader_t pgp_verifier_new (pgp_error_t *errp, pgp_reader_t input, pgp_decryptor_get_public_keys_cb_t get_public_keys, pgp_decryptor_check_signatures_cb_t check_signatures, - void *cookie); + void *cookie, time_t time); /*/ /// Verifies a detached OpenPGP signature. @@ -1456,6 +1456,6 @@ pgp_reader_t pgp_detached_verifier_new (pgp_error_t *errp, pgp_reader_t signature_input, pgp_reader_t input, pgp_decryptor_get_public_keys_cb_t get_public_keys, pgp_decryptor_check_signatures_cb_t check_signatures, - void *cookie); + void *cookie, time_t time); #endif diff --git a/openpgp-ffi/src/parse/stream.rs b/openpgp-ffi/src/parse/stream.rs index 420ed5fd..c237866c 100644 --- a/openpgp-ffi/src/parse/stream.rs +++ b/openpgp-ffi/src/parse/stream.rs @@ -11,7 +11,7 @@ //! [`sequoia-openpgp::parse::stream`]: ../../../sequoia_openpgp/parse/stream/index.html use std::ptr; -use libc::{c_int, size_t, c_void, uint8_t}; +use libc::{c_int, size_t, c_void, uint8_t, time_t}; extern crate sequoia_openpgp as openpgp; extern crate time; @@ -374,7 +374,7 @@ impl VerificationHelper for VHelper { /// }; /// plaintext = pgp_verifier_new (NULL, source, /// get_public_keys_cb, check_signatures_cb, -/// &cookie); +/// &cookie, 1554542219); /// assert (source); /// /// nread = pgp_reader_read (NULL, plaintext, buf, sizeof buf); @@ -392,16 +392,25 @@ fn pgp_verifier_new<'a>(errp: Option<&mut *mut ::error::Error>, input: *mut io::Reader, get_public_keys: GetPublicKeysCallback, check_signatures: CheckSignaturesCallback, - cookie: *mut HelperCookie) + cookie: *mut HelperCookie, + time: time_t) -> Maybe<io::Reader> { let helper = VHelper::new(get_public_keys, check_signatures, cookie); - Verifier::from_reader(input.ref_mut_raw(), helper) + Verifier::from_reader(input.ref_mut_raw(), helper, maybe_time(time)) .map(|r| io::ReaderKind::Generic(Box::new(r))) .move_into_raw(errp) } +fn maybe_time(t: time_t) -> Option<time::Tm> { + if t == 0 { + None + } else { + Some(time::at(time::Timespec::new(t as i64, 0))) + } +} + /// Verifies a detached OpenPGP signature. /// /// # Example @@ -480,7 +489,7 @@ fn pgp_verifier_new<'a>(errp: Option<&mut *mut ::error::Error>, /// }; /// plaintext = pgp_detached_verifier_new (NULL, signature, source, /// get_public_keys_cb, check_signatures_cb, -/// &cookie); +/// &cookie, 1554542219); /// assert (source); /// /// nread = pgp_reader_read (NULL, plaintext, buf, sizeof buf); @@ -500,13 +509,14 @@ fn pgp_detached_verifier_new<'a>(errp: Option<&mut *mut ::error::Error>, input: *mut io::Reader, get_public_keys: GetPublicKeysCallback, check_signatures: CheckSignaturesCallback, - cookie: *mut HelperCookie) + cookie: *mut HelperCookie, + time: time_t) -> Maybe<io::Reader> { let helper = VHelper::new(get_public_keys, check_signatures, cookie); DetachedVerifier::from_reader(signature_input.ref_mut_raw(), - input.ref_mut_raw(), helper) + input.ref_mut_raw(), helper, maybe_time(time)) .map(|r| io::ReaderKind::Generic(Box::new(r))) .move_into_raw(errp) } @@ -730,7 +740,7 @@ impl DecryptionHelper for DHelper { /// }; /// plaintext = pgp_decryptor_new (NULL, source, /// get_public_keys_cb, decrypt_cb, -/// check_signatures_cb, &cookie); +/// check_signatures_cb, &cookie, 1554542219); /// assert (plaintext); /// /// nread = pgp_reader_read (NULL, plaintext, buf, sizeof buf); @@ -750,13 +760,14 @@ fn pgp_decryptor_new<'a>(errp: Option<&mut *mut ::error::Error>, get_public_keys: GetPublicKeysCallback, decrypt: DecryptCallback, check_signatures: CheckSignaturesCallback, - cookie: *mut HelperCookie) + cookie: *mut HelperCookie, + time: time_t) -> Maybe<io::Reader> { let helper = DHelper::new( get_public_keys, decrypt, check_signatures, cookie); - Decryptor::from_reader(input.ref_mut_raw(), helper) + Decryptor::from_reader(input.ref_mut_raw(), helper, maybe_time(time)) .map(|r| io::ReaderKind::Generic(Box::new(r))) .move_into_raw(errp) } diff --git a/openpgp/examples/decrypt-with.rs b/openpgp/examples/decrypt-with.rs index 3828e47f..908b8650 100644 --- a/openpgp/examples/decrypt-with.rs +++ b/openpgp/examples/decrypt-with.rs @@ -36,7 +36,7 @@ pub fn main() { // Now, create a decryptor with a helper using the given TPKs. let mut decryptor = - Decryptor::from_reader(io::stdin(), Helper::new(tpks)).unwrap(); + Decryptor::from_reader(io::stdin(), Helper::new(tpks), None).unwrap(); // Finally, stream the decrypted data to stdout. io::copy(&mut decryptor, &mut io::stdout()) diff --git a/openpgp/examples/generate-encrypt-decrypt.rs b/openpgp/examples/generate-encrypt-decrypt.rs index 88f245fb..c19f9eb2 100644 --- a/openpgp/examples/generate-encrypt-decrypt.rs +++ b/openpgp/examples/generate-encrypt-decrypt.rs @@ -74,7 +74,7 @@ fn decrypt(sink: &mut Write, ciphertext: &[u8], recipient: &openpgp::TPK) }; // Now, create a decryptor with a helper using the given TPKs. - let mut decryptor = Decryptor::from_bytes(ciphertext, helper)?; + let mut decryptor = Decryptor::from_bytes(ciphertext, helper, None)?; // Decrypt the data. io::copy(&mut decryptor, sink)?; diff --git a/openpgp/examples/generate-sign-verify.rs b/openpgp/examples/generate-sign-verify.rs index 31138b4e..86d49c60 100644 --- a/openpgp/examples/generate-sign-verify.rs +++ b/openpgp/examples/generate-sign-verify.rs @@ -73,7 +73,7 @@ fn verify(sink: &mut Write, signed_message: &[u8], sender: &openpgp::TPK) }; // Now, create a verifier with a helper using the given TPKs. - let mut verifier = Verifier::from_bytes(signed_message, helper)?; + let mut verifier = Verifier::from_bytes(signed_message, helper, None)?; // Verify the data. io::copy(&mut verifier, sink)?; diff --git a/openpgp/src/lib.rs b/openpgp/src/lib.rs index 08515303..7f1e4b9b 100644 --- a/openpgp/src/lib.rs +++ b/openpgp/src/lib.rs @@ -136,6 +136,16 @@ fn path_to(artifact: &str) -> PathBuf { [env!("CARGO_MANIFEST_DIR"), "tests", "data", "messages", artifact] .iter().collect() } + +/// Returns a timestamp for the tests. +/// +/// The time is chosen to that the subkeys in +/// openpgp/tests/data/keys/neal.pgp are not expired. +#[cfg(test)] +fn frozen_time() -> time::Tm { + use conversions::Time; + time::Tm::from_pgp(1554542220 - 1) +} /// Crate result specialization. pub type Result<T> = ::std::result::Result<T, failure::Error>; diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs index 2c84be25..66fa0f81 100644 --- a/openpgp/src/parse/stream.rs +++ b/openpgp/src/parse/stream.rs @@ -99,7 +99,7 @@ const BUFFER_SIZE: usize = 25 * 1024 * 1024; /// -----END PGP MESSAGE-----"; /// /// let h = Helper {}; -/// let mut v = Verifier::from_bytes(message, h)?; +/// let mut v = Verifier::from_bytes(message, h, None)?; /// /// let mut content = Vec::new(); /// v.read_to_end(&mut content) @@ -124,6 +124,9 @@ pub struct Verifier<'a, H: VerificationHelper> { // The reserve data. reserve: Option<Vec<u8>>, + + /// Signature verification relative to this time. + time: time::Tm, } /// Contains the result of a signature verification. @@ -186,31 +189,48 @@ pub trait VerificationHelper { impl<'a, H: VerificationHelper> Verifier<'a, H> { /// Creates a `Verifier` from the given reader. - pub fn from_reader<R>(reader: R, helper: H) -> Result<Verifier<'a, H>> - where R: io::Read + 'a + /// + /// Signature verifications are done relative to time `t`, or the + /// current time, if `t` is `None`. + pub fn from_reader<R, T>(reader: R, helper: H, t: T) + -> Result<Verifier<'a, H>> + where R: io::Read + 'a, T: Into<Option<time::Tm>> { + let t = t.into().unwrap_or_else(time::now_utc); Verifier::from_buffered_reader( Box::new(buffered_reader::Generic::with_cookie(reader, None, Default::default())), - helper) + helper, t) } /// Creates a `Verifier` from the given file. - pub fn from_file<P>(path: P, helper: H) -> Result<Verifier<'a, H>> - where P: AsRef<Path> + /// + /// Signature verifications are done relative to time `t`, or the + /// current time, if `t` is `None`. + pub fn from_file<P, T>(path: P, helper: H, t: T) -> Result<Verifier<'a, H>> + where P: AsRef<Path>, + T: Into<Option<time::Tm>> { + let t = t.into().unwrap_or_else(time::now_utc); Verifier::from_buffered_reader( Box::new(buffered_reader::File::with_cookie(path, Default::default())?), - helper) + helper, t) } /// Creates a `Verifier` from the given buffer. - pub fn from_bytes(bytes: &'a [u8], helper: H) -> Result<Verifier<'a, H>> { + /// + /// Signature verifications are done relative to time `t`, or the + /// current time, if `t` is `None`. + pub fn from_bytes<T>(bytes: &'a [u8], helper: H, t: T) + -> Result<Verifier<'a, H>> + where T: Into<Option<time::Tm>> + { + let t = t.into().unwrap_or_else(time::now_utc); Verifier::from_buffered_reader( Box::new(buffered_reader::Memory::with_cookie(bytes, Default::default())), - helper) + helper, t) } /// Returns a reference to the helper. @@ -237,8 +257,12 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { } /// Creates the `Verifier`, and buffers the data up to `BUFFER_SIZE`. + /// + /// Signature verifications are done relative to time `t`, or the + /// current time, if `t` is `None`. pub(crate) fn from_buffered_reader(bio: Box<BufferedReader<Cookie> + 'a>, - helper: H) -> Result<Verifier<'a, H>> + helper: H, t: time::Tm) + -> Result<Verifier<'a, H>> { let mut ppr = PacketParser::from_buffered_reader(bio)?; @@ -249,6 +273,7 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { oppr: None, sigs: Vec::new(), reserve: None, + time: t, }; let mut issuers = Vec::new(); @@ -277,8 +302,8 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { if let Some(sig) = sig { sig.key_flags().can_sign() // Check expiry. - && sig.signature_alive() - && sig.key_alive(key) + && sig.signature_alive_at(t) + && sig.key_alive_at(key, t) } else { false } @@ -395,7 +420,9 @@ impl<'a, H: VerificationHelper> Verifier<'a, H> { let tpk = &self.tpks[*i]; let (binding, revocation, key) = tpk.keys_all().nth(*j).unwrap(); - if sig.verify(key).unwrap_or(false) { + if sig.verify(key).unwrap_or(false) && + sig.signature_alive_at(self.time) + { VerificationResult::GoodChecksum (sig, tpk, key, binding, revocation) } else { @@ -695,7 +722,7 @@ impl<'a> io::Read for Transformer<'a> { /// /// let data = b"Hello World!"; /// let h = Helper {}; -/// let mut v = DetachedVerifier::from_bytes(signature, data, h)?; +/// let mut v = DetachedVerifier::from_bytes(signature, data, h, None)?; /// /// let mut content = Vec::new(); /// v.read_to_end(&mut content) @@ -715,49 +742,66 @@ pub struct DetachedVerifier { impl DetachedVerifier { /// Creates a `Verifier` from the given readers. - pub fn from_reader<'a, 's, H, R, S>(signature_reader: S, reader: R, - helper: H) - -> Result<Verifier<'a, H>> - where R: io::Read + 'a, S: io::Read + 's, H: VerificationHelper + /// + /// Signature verifications are done relative to time `t`, or the + /// current time, if `t` is `None`. + pub fn from_reader<'a, 's, H, R, S, T>(signature_reader: S, reader: R, + helper: H, t: T) + -> Result<Verifier<'a, H>> + where R: io::Read + 'a, S: io::Read + 's, H: VerificationHelper, + T: Into<Option<time::Tm>> { + let t = t.into().unwrap_or_else(time::now_utc); Self::from_buffered_reader( Box::new(buffered_reader::Generic::with_cookie(signature_reader, None, Default::default())), Box::new(buffered_reader::Generic::new(reader, None)), - helper) + helper, t) } /// Creates a `Verifier` from the given files. - pub fn from_file<'a, H, P, S>(signature_path: S, path: P, - helper: H) - -> Result<Verifier<'a, H>> - where P: AsRef<Path>, S: AsRef<Path>, H: VerificationHelper + /// + /// Signature verifications are done relative to time `t`, or the + /// current time, if `t` is `None`. + pub fn from_file<'a, H, P, S, T>(signature_path: S, path: P, + helper: H, t: T) + -> Result<Verifier<'a, H>> + where P: AsRef<Path>, S: AsRef<Path>, H: VerificationHelper, + T: Into<Option<time::Tm>> { + let t = t.into().unwrap_or_else(time::now_utc); Self::from_buffered_reader( Box::new(buffered_reader::File::with_cookie(signature_path, Default::default())?), Box::new(buffered_reader::File::open(path)?), - helper) + helper, t) } /// Creates a `Verifier` from the given buffers. - pub fn from_bytes<'a, 's, H>(signature_bytes: &'s [u8], bytes: &'a [u8], - helper: H) - -> Result<Verifier<'a, H>> - where H: VerificationHelper + /// + /// Signature verifications are done relative to time `t`, or the + /// current time, if `t` is `None`. + pub fn from_bytes<'a, 's, H, T>(signature_bytes: &'s [u8], bytes: &'a [u8], + helper: H, t: T) + -> Result<Verifier<'a, H>> + where H: VerificationHelper, T: Into<Option<time::Tm>> { + let t = t.into().unwrap_or_else(time::now_utc); Self::from_buffered_reader( Box::new(buffered_reader::Memory::with_cookie(signature_bytes, Default::default())), Box::new(buffered_reader::Memory::new(bytes)), - helper) + helper, t) } /// Creates the `Verifier`, and buffers the data up to `BUFFER_SIZE`. + /// + /// Signature verifications are done relative to time `t`, or the + /// current time, if `t` is `None`. pub(crate) fn from_buffered_reader<'a, 's, H> (signature_bio: Box<BufferedReader<Cookie> + 's>, reader: Box<'a + BufferedReader<()>>, - helper: H) + helper: H, t: time::Tm) -> Result<Verifier<'a, H>> where H: VerificationHelper { @@ -765,7 +809,7 @@ impl DetachedVerifier { Box::new(buffered_reader::Generic::with_cookie( Transformer::new(signature_bio, reader)?, None, Default::default())), - helper) + helper, t) } } @@ -825,7 +869,7 @@ impl DetachedVerifier { /// -----END PGP MESSAGE-----"; /// /// let h = Helper {}; -/// let mut v = Decryptor::from_bytes(message, h)?; +/// let mut v = Decryptor::from_bytes(message, h, None)?; /// /// let mut content = Vec::new(); /// v.read_to_end(&mut content) @@ -849,6 +893,9 @@ pub struct Decryptor<'a, H: VerificationHelper + DecryptionHelper> { identity: Option<Fingerprint>, sigs: Vec<Vec<Signature>>, reserve: Option<Vec<u8>>, + + /// Signature verification relative to this time. + time: time::Tm, } /// Helper for decrypting messages. @@ -887,31 +934,48 @@ pub trait DecryptionHelper { impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { /// Creates a `Decryptor` from the given reader. - pub fn from_reader<R>(reader: R, helper: H) -> Result<Decryptor<'a, H>> - where R: io::Read + 'a + /// + /// Signature verifications are done relative to time `t`, or the + /// current time, if `t` is `None`. + pub fn from_reader<R, T>(reader: R, helper: H, t: T) + -> Result<Decryptor<'a, H>> + where R: io::Read + 'a, T: Into<Option<time::Tm>> { + let t = t.into().unwrap_or_else(time::now_utc); Decryptor::from_buffered_reader( Box::new(buffered_reader::Generic::with_cookie(reader, None, Default::default())), - helper) + helper, t) } /// Creates a `Decryptor` from the given file. - pub fn from_file<P>(path: P, helper: H) -> Result<Decryptor<'a, H>> - where P: AsRef<Path> + /// + /// Signature verifications are done relative to time `t`, or the + /// current time, if `t` is `None`. + pub fn from_file<P, T>(path: P, helper: H, t: T) -> Result<Decryptor<'a, H>> + where P: AsRef<Path>, + T: Into<Option<time::Tm>> { + let t = t.into().unwrap_or_else(time::now_utc); Decryptor::from_buffered_reader( Box::new(buffered_reader::File::with_cookie(path, Default::default())?), - helper) + helper, t) } /// Creates a `Decryptor` from the given buffer. - pub fn from_bytes(bytes: &'a [u8], helper: H) -> Result<Decryptor<'a, H>> { + /// + /// Signature verifications are done relative to time `t`, or the + /// current time, if `t` is `None`. + pub fn from_bytes<T>(bytes: &'a [u8], helper: H, t: T) + -> Result<Decryptor<'a, H>> + where T: Into<Option<time::Tm>> + { + let t = t.into().unwrap_or_else(time::now_utc); Decryptor::from_buffered_reader( Box::new(buffered_reader::Memory::with_cookie(bytes, Default::default())), - helper) + helper, t) } /// Returns a reference to the helper. @@ -939,7 +1003,8 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { /// Creates the `Decryptor`, and buffers the data up to `BUFFER_SIZE`. pub(crate) fn from_buffered_reader(bio: Box<BufferedReader<Cookie> + 'a>, - helper: H) -> Result<Decryptor<'a, H>> + helper: H, t: time::Tm) + -> Result<Decryptor<'a, H>> |