summaryrefslogtreecommitdiffstats
path: root/tool
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-01-15 14:47:15 +0100
committerJustus Winter <justus@sequoia-pgp.org>2019-01-15 14:48:13 +0100
commitf018afccac5cb21be7d11a9b7072a4e13810e56c (patch)
treeee33892427c185bb55a2dce452bae06b8add1cb3 /tool
parent5bef3bde45f71126cdca3e8ad30b1047287c843a (diff)
tool: Move key generation to a new module.
Diffstat (limited to 'tool')
-rw-r--r--tool/src/commands/key.rs133
-rw-r--r--tool/src/commands/mod.rs1
-rw-r--r--tool/src/sq.rs125
3 files changed, 136 insertions, 123 deletions
diff --git a/tool/src/commands/key.rs b/tool/src/commands/key.rs
new file mode 100644
index 00000000..a1c9777b
--- /dev/null
+++ b/tool/src/commands/key.rs
@@ -0,0 +1,133 @@
+use failure;
+use clap::ArgMatches;
+
+use openpgp::tpk::{TPKBuilder, CipherSuite};
+use openpgp::packet::KeyFlags;
+use openpgp::armor::{Writer, Kind};
+use openpgp::serialize::Serialize;
+
+use ::create_or_stdout;
+
+pub fn generate(m: &ArgMatches, force: bool) -> failure::Fallible<()> {
+ let mut builder = TPKBuilder::default();
+
+ // User ID
+ match m.value_of("userid") {
+ Some(uid) => { builder = builder.add_userid(uid); }
+ None => {
+ eprintln!("No user ID given, using direct key signature");
+ }
+ }
+
+ // Cipher Suite
+ match m.value_of("cipher-suite") {
+ None | Some("rsa3k") => {
+ builder = builder.set_cipher_suite(CipherSuite::RSA3k);
+ }
+ Some("cv25519") => {
+ builder = builder.set_cipher_suite(CipherSuite::Cv25519);
+ }
+ Some(ref cs) => {
+ return Err(format_err!("Unknown cipher suite '{}'", cs));
+ }
+ }
+
+ // Signing Capability
+ match (m.is_present("can-sign"), m.is_present("cannot-sign")) {
+ (false, false) | (true, false) => {
+ builder = builder.add_signing_subkey();
+ }
+ (false, true) => { /* no signing subkey */ }
+ (true, true) => {
+ return Err(
+ format_err!("Conflicting arguments --can-sign and --cannot-sign"));
+ }
+ }
+
+ // Encryption Capability
+ match (m.value_of("can-encrypt"), m.is_present("cannot-encrypt")) {
+ (Some("all"), false) | (None, false) => {
+ builder = builder.add_encryption_subkey();
+ }
+ (Some("rest"), false) => {
+ builder = builder.add_subkey(KeyFlags::default()
+ .set_encrypt_at_rest(true));
+ }
+ (Some("transport"), false) => {
+ builder = builder.add_subkey(KeyFlags::default()
+ .set_encrypt_for_transport(true));
+ }
+ (None, true) => { /* no encryption subkey */ }
+ (Some(_), true) => {
+ return Err(
+ format_err!("Conflicting arguments --can-encrypt and \
+ --cannot-encrypt"));
+ }
+ (Some(ref cap), false) => {
+ return Err(
+ format_err!("Unknown encryption capability '{}'", cap));
+ }
+ }
+
+ if m.is_present("with-password") {
+ let p0 = rpassword::prompt_password_stderr(
+ "Enter password to protect the key: ")?.into();
+ let p1 = rpassword::prompt_password_stderr(
+ "Repeat the password once more: ")?.into();
+
+ if p0 == p1 {
+ builder = builder.set_password(Some(p0));
+ } else {
+ return Err(failure::err_msg("Passwords do not match."));
+ }
+ }
+
+ // Generate the key
+ let (tpk, rev) = builder.generate()?;
+ let tsk = tpk.into_tsk();
+
+ // Export
+ if m.is_present("export") {
+ let (key_path, rev_path) =
+ match (m.value_of("export"), m.value_of("rev-cert")) {
+ (Some("-"), Some("-")) =>
+ ("-".to_string(), "-".to_string()),
+ (Some("-"), Some(ref rp)) =>
+ ("-".to_string(), rp.to_string()),
+ (Some("-"), None) =>
+ return Err(
+ format_err!("Missing arguments: --rev-cert is mandatory \
+ if --export is '-'.")),
+ (Some(ref kp), None) =>
+ (kp.to_string(), format!("{}.rev", kp)),
+ (Some(ref kp), Some("-")) =>
+ (kp.to_string(), "-".to_string()),
+ (Some(ref kp), Some(ref rp)) =>
+ (kp.to_string(), rp.to_string()),
+ _ =>
+ return Err(
+ format_err!("Conflicting arguments --rev-cert and \
+ --export")),
+ };
+
+ // write out key
+ {
+ let w = create_or_stdout(Some(&key_path), force)?;
+ let mut w = Writer::new(w, Kind::SecretKey, &[])?;
+ tsk.serialize(&mut w)?;
+ }
+
+ // write out rev cert
+ {
+ let w = create_or_stdout(Some(&rev_path), force)?;
+ let mut w = Writer::new(w, Kind::Signature, &[])?;
+ rev.serialize(&mut w)?;
+ }
+ } else {
+ return Err(
+ format_err!("Saving generated key to the store isn't implemented \
+ yet."));
+ }
+
+ Ok(())
+}
diff --git a/tool/src/commands/mod.rs b/tool/src/commands/mod.rs
index c84bc788..fbd6e47b 100644
--- a/tool/src/commands/mod.rs
+++ b/tool/src/commands/mod.rs
@@ -30,6 +30,7 @@ mod sign;
pub use self::sign::sign;
mod dump;
pub use self::dump::dump;
+pub mod key;
const TIMEFMT: &'static str = "%Y-%m-%dT%H:%M";
diff --git a/tool/src/sq.rs b/tool/src/sq.rs
index 9add3251..162e8288 100644
--- a/tool/src/sq.rs
+++ b/tool/src/sq.rs
@@ -1,6 +1,7 @@
/// A command-line frontend for Sequoia.
extern crate clap;
+#[macro_use]
extern crate failure;
#[macro_use]
extern crate prettytable;
@@ -412,129 +413,7 @@ fn real_main() -> Result<(), failure::Error> {
}
},
("keygen", Some(m)) => {
- use openpgp::tpk::{TPKBuilder, CipherSuite};
- use openpgp::packet::KeyFlags;
- use openpgp::armor::{Writer, Kind};
- use openpgp::serialize::Serialize;
-
- let mut builder = TPKBuilder::default();
-
- // User ID
- match m.value_of("userid") {
- Some(uid) => { builder = builder.add_userid(uid); }
- None => {
- eprintln!("No user ID given, using direct key signature");
- }
- }
-
- // Cipher Suite
- match m.value_of("cipher-suite") {
- None | Some("rsa3k") => {
- builder = builder.set_cipher_suite(CipherSuite::RSA3k);
- }
- Some("cv25519") => {
- builder = builder.set_cipher_suite(CipherSuite::Cv25519);
- }
- Some(ref cs) => {
- eprintln!("Unknown cipher suite '{}'", cs);
- exit(1);
- }
- }
-
- // Signing Capability
- match (m.is_present("can-sign"), m.is_present("cannot-sign")) {
- (false, false) | (true, false) => {
- builder = builder.add_signing_subkey();
- }
- (false, true) => { /* no signing subkey */ }
- (true, true) => {
- eprintln!("Conflicting arguments --can-sign and --cannot-sign");
- exit(1);
- }
- }
-
- // Encryption Capability
- match (m.value_of("can-encrypt"), m.is_present("cannot-encrypt")) {
- (Some("all"), false) | (None, false) => {
- builder = builder.add_encryption_subkey();
- }
- (Some("rest"), false) => {
- builder = builder.add_subkey(KeyFlags::default()
- .set_encrypt_at_rest(true));
- }
- (Some("transport"), false) => {
- builder = builder.add_subkey(KeyFlags::default()
- .set_encrypt_for_transport(true));
- }
- (None, true) => { /* no encryption subkey */ }
- (Some(_), true) => {
- eprintln!("Conflicting arguments --can-encrypt and --cannot-encrypt");
- exit(1);
- }
- (Some(ref cap), false) => {
- eprintln!("Unknown encryption capability '{}'", cap);
- exit(1);
- }
- }
-
- if m.is_present("with-password") {
- let p0 = rpassword::prompt_password_stderr(
- "Enter password to protect the key: ")?.into();
- let p1 = rpassword::prompt_password_stderr(
- "Repeat the password once more: ")?.into();
-
- if p0 == p1 {
- builder = builder.set_password(Some(p0));
- } else {
- return Err(failure::err_msg("Passwords do not match."));
- }
- }
-
- // Generate the key
- let (tpk, rev) = builder.generate()?;
- let tsk = tpk.into_tsk();
-
- // Export
- if m.is_present("export") {
- let (key_path, rev_path) =
- match (m.value_of("export"), m.value_of("rev-cert")) {
- (Some("-"), Some("-")) =>
- ("-".to_string(), "-".to_string()),
- (Some("-"), Some(ref rp)) =>
- ("-".to_string(), rp.to_string()),
- (Some("-"), None) => {
- eprintln!("Missing arguments: --rev-cert is mandatory if --export is '-'.");
- exit(1);
- }
- (Some(ref kp), None) =>
- (kp.to_string(), format!("{}.rev", kp)),
- (Some(ref kp), Some("-")) =>
- (kp.to_string(), "-".to_string()),
- (Some(ref kp), Some(ref rp)) =>
- (kp.to_string(), rp.to_string()),
- _ => {
- eprintln!("Conflicting arguments --rev-cert and --export");
- exit(1);
- }
- };
-
- // write out key
- {
- let w = create_or_stdout(Some(&key_path), force)?;
- let mut w = Writer::new(w, Kind::SecretKey, &[])?;
- tsk.serialize(&mut w)?;
- }
-
- // write out rev cert
- {
- let w = create_or_stdout(Some(&rev_path), force)?;
- let mut w = Writer::new(w, Kind::Signature, &[])?;
- rev.serialize(&mut w)?;
- }
- } else {
- eprintln!("Saving generated key to the store isn't implemented yet.");
- exit(1);
- }
+ commands::key::generate(m, force)?;
}
_ => {
eprintln!("No subcommand given.");