summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-04-09 13:08:20 +0200
committerJustus Winter <justus@sequoia-pgp.org>2019-04-09 13:08:20 +0200
commit7c92d7381408b375d158dd3aedfa61d340ed3750 (patch)
tree1fe1a0ff202930700e9817ebb1d67b281217ece1
parentb372fdb81fbff4bfca997b4d271aedc6026c158c (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.md8
-rw-r--r--guide/src/chapter_02.md8
-rw-r--r--openpgp-ffi/examples/decrypt-with.c2
-rw-r--r--openpgp-ffi/include/sequoia/openpgp.h6
-rw-r--r--openpgp-ffi/src/parse/stream.rs31
-rw-r--r--openpgp/examples/decrypt-with.rs2
-rw-r--r--openpgp/examples/generate-encrypt-decrypt.rs2
-rw-r--r--openpgp/examples/generate-sign-verify.rs2
-rw-r--r--openpgp/src/lib.rs10
-rw-r--r--openpgp/src/parse/stream.rs176
-rw-r--r--openpgp/src/serialize/stream.rs4
-rw-r--r--tool/src/commands/decrypt.rs2
-rw-r--r--tool/src/commands/mod.rs5
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>>
{
tracer!(TRACE, "Decryptor::from_buffered_reader", 0);
@@ -954,6 +1019,7 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
identity: None,
sigs: Vec::new(),
reserve: None,
+ time: t,
};
let mut issuers = Vec::new();
@@ -1001,8 +1067,8 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> {
if let Some(sig) = sig {
sig.key_f