summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2022-01-20 16:49:23 +0100
committerNeal H. Walfield <neal@pep.foundation>2022-01-24 00:26:30 +0100
commitbebae0525cce6f31a93e0619007cc6b4720f7f53 (patch)
treea2c5388fde30a2451191f687c4948000226753a5
parent827ee8254d194106809aea25090921c8d7802de7 (diff)
sq: Add a --creation-time option to sq key generate.
- Allow the user to explicitly set the key's creation time. - This is useful for: - obscuring the actual creation time. - testing.
-rw-r--r--sq/src/commands/key.rs7
-rw-r--r--sq/src/sq-usage.rs15
-rw-r--r--sq/src/sq_cli.rs16
-rw-r--r--sq/tests/sq-key-generate.rs45
4 files changed, 83 insertions, 0 deletions
diff --git a/sq/src/commands/key.rs b/sq/src/commands/key.rs
index 23cae863..f597d6ac 100644
--- a/sq/src/commands/key.rs
+++ b/sq/src/commands/key.rs
@@ -50,6 +50,13 @@ fn generate(config: Config, m: &ArgMatches) -> Result<()> {
}
}
+ // Creation time.
+ if let Some(t) = m.value_of("creation-time") {
+ builder = builder.set_creation_time(SystemTime::from(
+ crate::parse_iso8601(t, chrono::NaiveTime::from_hms(0, 0, 0))
+ .context(format!("Parsing --creation-time {}", t))?));
+ };
+
// Expiration.
match (m.value_of("expires"), m.value_of("expires-in")) {
(None, None) => // Default expiration.
diff --git a/sq/src/sq-usage.rs b/sq/src/sq-usage.rs
index c928c0de..6b05ad16 100644
--- a/sq/src/sq-usage.rs
+++ b/sq/src/sq-usage.rs
@@ -416,6 +416,21 @@
//! -c, --cipher-suite <CIPHER-SUITE>
//! Selects the cryptographic algorithms for the key [default: cv25519]
//! [possible values: rsa3k, rsa4k, cv25519]
+//! --creation-time <CREATION_TIME>
+//! Sets the key's creation time to TIME. TIME is interpreted as an ISO
+//! 8601
+//! timestamp. To set the creation time to June 9, 2011 at midnight
+//! UTC,
+//! you can do:
+//!
+//! $ sq key generate --creation-time 20110609 --export noam.pgp
+//!
+//! To include a time, add a T, the time and optionally the timezone
+//! (the
+//! default timezone is UTC):
+//!
+//! $ sq key generate --creation-time 20110609T1938+0200 --export
+//! noam.pgp
//! --expires <TIME>
//! Makes the key expire at TIME (as ISO 8601). Use "never" to create
//! keys that do not expire.
diff --git a/sq/src/sq_cli.rs b/sq/src/sq_cli.rs
index 865d8184..e46c1e0a 100644
--- a/sq/src/sq_cli.rs
+++ b/sq/src/sq_cli.rs
@@ -538,6 +538,22 @@ $ sq key generate --userid \"<juliet@example.org>\" --userid \"Juliet Capulet\"
.long("with-password")
.help("Protects the key with a password"))
+ .arg(Arg::with_name("creation-time")
+ .long("creation-time").value_name("CREATION_TIME")
+ .help("Sets the key's creation time to TIME (as ISO 8601)")
+ .long_help("\
+Sets the key's creation time to TIME. TIME is interpreted as an ISO 8601
+timestamp. To set the creation time to June 9, 2011 at midnight UTC,
+you can do:
+
+$ sq key generate --creation-time 20110609 --export noam.pgp
+
+To include a time, add a T, the time and optionally the timezone (the
+default timezone is UTC):
+
+$ sq key generate --creation-time 20110609T1938+0200 --export noam.pgp
+"))
+
.group(ArgGroup::with_name("expiration-group")
.args(&["expires", "expires-in"]))
diff --git a/sq/tests/sq-key-generate.rs b/sq/tests/sq-key-generate.rs
new file mode 100644
index 00000000..89f78648
--- /dev/null
+++ b/sq/tests/sq-key-generate.rs
@@ -0,0 +1,45 @@
+use std::time;
+
+use assert_cmd::Command;
+use tempfile::TempDir;
+
+use sequoia_openpgp as openpgp;
+use openpgp::Result;
+use openpgp::cert::prelude::*;
+use openpgp::parse::Parse;
+use openpgp::policy::StandardPolicy;
+
+mod integration {
+ use super::*;
+
+ const P: &StandardPolicy = &StandardPolicy::new();
+
+ #[test]
+ fn sq_key_generate_creation_time() -> Result<()>
+ {
+ // $ date +'%Y%m%dT%H%M%S%z'; date +'%s'
+ let iso8601 = "20220120T163236+0100";
+ let t = 1642692756;
+
+ let dir = TempDir::new()?;
+ let key_pgp = dir.path().join("key.pgp");
+
+ // Build up the command line.
+ let mut cmd = Command::cargo_bin("sq")?;
+ cmd.args(["key", "generate",
+ "--creation-time", iso8601,
+ "--expires", "never",
+ "--export", &*key_pgp.to_string_lossy()]);
+
+ cmd.assert().success();
+
+ let result = Cert::from_file(key_pgp)?;
+ let vc = result.with_policy(P, None)?;
+
+ assert_eq!(vc.primary_key().creation_time(),
+ time::UNIX_EPOCH + time::Duration::new(t, 0));
+ assert!(vc.primary_key().key_expiration_time().is_none());
+
+ Ok(())
+ }
+}