summaryrefslogtreecommitdiffstats
path: root/tool/src/commands
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2020-01-17 16:01:33 +0100
committerNeal H. Walfield <neal@pep.foundation>2020-01-17 16:17:51 +0100
commit3dc2d24bc3920d0216ff7f19e01e4e073a292a24 (patch)
tree551997319c32bc9c684401a72301dfe41d85bd6c /tool/src/commands
parent7cc22083ffc9874c39c957464bde9662e2fe8317 (diff)
tool: Add an option to specify the signing time.
- Add the option `--time` to the `sign` and `encrypt` subcommands to allow the user to set the signature's creation time. - Use the value of this option to select the signing keys.
Diffstat (limited to 'tool/src/commands')
-rw-r--r--tool/src/commands/mod.rs14
-rw-r--r--tool/src/commands/sign.rs23
2 files changed, 25 insertions, 12 deletions
diff --git a/tool/src/commands/mod.rs b/tool/src/commands/mod.rs
index 1dc7b908..5b640496 100644
--- a/tool/src/commands/mod.rs
+++ b/tool/src/commands/mod.rs
@@ -3,6 +3,7 @@ use std::cmp::Ordering;
use std::collections::{HashMap, HashSet};
use std::fs::File;
use std::io::{self, Write};
+use std::time::SystemTime;
use rpassword;
extern crate sequoia_openpgp as openpgp;
@@ -43,12 +44,12 @@ pub use self::inspect::inspect;
pub mod key;
/// Returns suitable signing keys from a given list of Certs.
-fn get_signing_keys(certs: &[openpgp::Cert])
+fn get_signing_keys(certs: &[openpgp::Cert], timestamp: Option<SystemTime>)
-> Result<Vec<crypto::KeyPair>>
{
let mut keys = Vec::new();
'next_cert: for tsk in certs {
- for key in tsk.keys().policy(None).alive().revoked(false)
+ for key in tsk.keys().policy(timestamp).alive().revoked(false)
.for_signing()
.map(|ka| ka.key())
{
@@ -81,8 +82,8 @@ pub fn encrypt(mapping: &mut store::Mapping,
input: &mut dyn io::Read, output: &mut dyn io::Write,
npasswords: usize, recipients: Vec<&str>,
mut certs: Vec<openpgp::Cert>, signers: Vec<openpgp::Cert>,
- mode: openpgp::types::KeyFlags,
- compression: &str)
+ mode: openpgp::types::KeyFlags, compression: &str,
+ time: Option<SystemTime>)
-> Result<()> {
for r in recipients {
certs.push(mapping.lookup(r).context("No such key found")?.cert()?);
@@ -103,7 +104,7 @@ pub fn encrypt(mapping: &mut store::Mapping,
"Neither recipient nor password given"));
}
- let mut signers = get_signing_keys(&signers)?;
+ let mut signers = get_signing_keys(&signers, time)?;
// Build a vector of references to hand to Signer.
let recipients: Vec<&openpgp::Cert> = certs.iter().collect();
@@ -160,6 +161,9 @@ pub fn encrypt(mapping: &mut store::Mapping,
let mut signer = Signer::new(sink, signers.pop().unwrap());
for s in signers {
signer = signer.add_signer(s);
+ if let Some(time) = time {
+ signer = signer.creation_time(time);
+ }
}
for r in recipients {
signer = signer.add_intended_recipient(r);
diff --git a/tool/src/commands/sign.rs b/tool/src/commands/sign.rs
index a2303fba..673c1e51 100644
--- a/tool/src/commands/sign.rs
+++ b/tool/src/commands/sign.rs
@@ -2,6 +2,7 @@ use failure::{self, ResultExt};
use std::fs;
use std::io;
use std::path::PathBuf;
+use std::time::SystemTime;
use tempfile::NamedTempFile;
extern crate sequoia_openpgp as openpgp;
@@ -20,20 +21,22 @@ use crate::create_or_stdout;
pub fn sign(input: &mut dyn io::Read, output_path: Option<&str>,
secrets: Vec<openpgp::Cert>, detached: bool, binary: bool,
- append: bool, notarize: bool, force: bool)
+ append: bool, notarize: bool, time: Option<SystemTime>,
+ force: bool)
-> Result<()> {
match (detached, append|notarize) {
(_, false) | (true, true) =>
sign_data(input, output_path, secrets, detached, binary, append,
- force),
+ time, force),
(false, true) =>
- sign_message(input, output_path, secrets, binary, notarize, force),
+ sign_message(input, output_path, secrets, binary, notarize,
+ time, force),
}
}
fn sign_data(input: &mut dyn io::Read, output_path: Option<&str>,
secrets: Vec<openpgp::Cert>, detached: bool, binary: bool,
- append: bool, force: bool)
+ append: bool, time: Option<SystemTime>, force: bool)
-> Result<()> {
let (mut output, prepend_sigs, tmp_path):
(Box<dyn io::Write>, Vec<Signature>, Option<PathBuf>) =
@@ -80,7 +83,7 @@ fn sign_data(input: &mut dyn io::Read, output_path: Option<&str>,
output
};
- let mut keypairs = super::get_signing_keys(&secrets)?;
+ let mut keypairs = super::get_signing_keys(&secrets, time)?;
if keypairs.is_empty() {
return Err(failure::format_err!("No signing keys found"));
}
@@ -97,6 +100,9 @@ fn sign_data(input: &mut dyn io::Read, output_path: Option<&str>,
let mut signer = Signer::new(sink, keypairs.pop().unwrap());
for s in keypairs {
signer = signer.add_signer(s);
+ if let Some(time) = time {
+ signer = signer.creation_time(time);
+ }
}
if detached {
signer = signer.detached();
@@ -130,7 +136,7 @@ fn sign_data(input: &mut dyn io::Read, output_path: Option<&str>,
fn sign_message(input: &mut dyn io::Read, output_path: Option<&str>,
secrets: Vec<openpgp::Cert>, binary: bool, notarize: bool,
- force: bool)
+ time: Option<SystemTime>, force: bool)
-> Result<()> {
let mut output = create_or_stdout(output_path, force)?;
let output = if ! binary {
@@ -141,7 +147,7 @@ fn sign_message(input: &mut dyn io::Read, output_path: Option<&str>,
output
};
- let mut keypairs = super::get_signing_keys(&secrets)?;
+ let mut keypairs = super::get_signing_keys(&secrets, time)?;
if keypairs.is_empty() {
return Err(failure::format_err!("No signing keys found"));
}
@@ -213,6 +219,9 @@ fn sign_message(input: &mut dyn io::Read, output_path: Option<&str>,
let mut signer = Signer::new(sink, keypairs.pop().unwrap());
for s in keypairs.drain(..) {
signer = signer.add_signer(s);
+ if let Some(time) = time {
+ signer = signer.creation_time(time);
+ }
}
sink = signer.build().context("Failed to create signer")?;
state = State::Signing { signature_count: 0, };