summaryrefslogtreecommitdiffstats
path: root/tool
diff options
context:
space:
mode:
authorJustus Winter <justus@pep-project.org>2018-01-09 16:44:35 +0100
committerJustus Winter <justus@pep-project.org>2018-01-09 17:02:08 +0100
commit31ae5bf9fb5234395fc2116b73476101a04abfa3 (patch)
treeefa7ec0b8b32c2caf0eb1783122882e1476927b4 /tool
parente9aa30a49abd89adacc26033cb0f737e9d3592ec (diff)
tool: Add key store commands.
- Add commands to add, import, export keys, and to get binding and key stats.
Diffstat (limited to 'tool')
-rw-r--r--tool/Cargo.toml1
-rw-r--r--tool/src/main.rs101
-rw-r--r--tool/src/usage.rs97
3 files changed, 198 insertions, 1 deletions
diff --git a/tool/Cargo.toml b/tool/Cargo.toml
index c1db4614..3becea63 100644
--- a/tool/Cargo.toml
+++ b/tool/Cargo.toml
@@ -7,6 +7,7 @@ authors = ["Justus Winter <justus@pep-project.org>"]
openpgp = { path = "../openpgp" }
sequoia-core = { path = "../core" }
sequoia-net = { path = "../net" }
+sequoia-store = { path = "../store" }
clap = "2.27.1"
[[bin]]
diff --git a/tool/src/main.rs b/tool/src/main.rs
index d38b1299..33c611f0 100644
--- a/tool/src/main.rs
+++ b/tool/src/main.rs
@@ -10,11 +10,13 @@ use std::process::exit;
extern crate openpgp;
extern crate sequoia_core;
extern crate sequoia_net;
+extern crate sequoia_store;
-use openpgp::armor;
+use openpgp::{armor, Fingerprint};
use openpgp::tpk::TPK;
use sequoia_core::{Context, Result, NetworkPolicy};
use sequoia_net::KeyServer;
+use sequoia_store::Store;
fn open_or_stdin(f: Option<&str>) -> Box<io::Read> {
match f {
@@ -106,6 +108,50 @@ fn real_main() -> Result<()> {
.long("dearmor")
.short("A")
.help("Remove ASCII Armor from input"))))
+ .subcommand(SubCommand::with_name("store")
+ .about("Interacts with key stores")
+ .arg(Arg::with_name("name").value_name("NAME")
+ .required(true)
+ .help("Name of the store"))
+ .subcommand(SubCommand::with_name("add")
+ .about("Add a key identified by fingerprint")
+ .arg(Arg::with_name("label").value_name("LABEL")
+ .required(true)
+ .help("Label to use"))
+ .arg(Arg::with_name("fingerprint").value_name("FINGERPRINT")
+ .required(true)
+ .help("Key to add")))
+ .subcommand(SubCommand::with_name("import")
+ .about("Imports a key")
+ .arg(Arg::with_name("label").value_name("LABEL")
+ .required(true)
+ .help("Label to use"))
+ .arg(Arg::with_name("input").value_name("FILE")
+ .long("input")
+ .short("i")
+ .help("Sets the input file to use"))
+ .arg(Arg::with_name("dearmor")
+ .long("dearmor")
+ .short("A")
+ .help("Remove ASCII Armor from input")))
+ .subcommand(SubCommand::with_name("export")
+ .about("Exports a key")
+ .arg(Arg::with_name("label").value_name("LABEL")
+ .required(true)
+ .help("Label to use"))
+ .arg(Arg::with_name("output").value_name("FILE")
+ .long("output")
+ .short("o")
+ .help("Sets the output file to use"))
+ .arg(Arg::with_name("armor")
+ .long("armor")
+ .short("A")
+ .help("Write armored data to file")))
+ .subcommand(SubCommand::with_name("stats")
+ .about("Get stats for the given label")
+ .arg(Arg::with_name("label").value_name("LABEL")
+ .required(true)
+ .help("Label to use"))))
.get_matches();
let policy = match matches.value_of("policy") {
@@ -212,6 +258,59 @@ fn real_main() -> Result<()> {
},
}
},
+ ("store", Some(m)) => {
+ let mut store = Store::open(&ctx, m.value_of("name").unwrap())
+ .expect("Failed to open store");
+
+ match m.subcommand() {
+ ("add", Some(m)) => {
+ let fp = Fingerprint::from_hex(m.value_of("fingerprint").unwrap())
+ .expect("Malformed fingerprint");
+ store.add(m.value_of("label").unwrap(), &fp)
+ .expect("Failed to add key");
+ },
+ ("import", Some(m)) => {
+ let mut input = open_or_stdin(m.value_of("input"));
+ let mut input = if m.is_present("dearmor") {
+ Box::new(armor::Reader::new(&mut input, armor::Kind::Any))
+ } else {
+ input
+ };
+
+ let tpk = TPK::from_reader(&mut input).
+ expect("Malformed key");
+ store.import(m.value_of("label").unwrap(), &tpk)
+ .expect("Failed to import key");
+ },
+ ("export", Some(m)) => {
+ let tpk = store.lookup(m.value_of("label").unwrap())
+ .expect("Failed to get the key")
+ .tpk()
+ .expect("Failed to get the key");
+
+ let mut output = create_or_stdout(m.value_of("output"));
+ let mut output = if m.is_present("armor") {
+ Box::new(armor::Writer::new(&mut output, armor::Kind::PublicKey))
+ } else {
+ output
+ };
+
+ tpk.serialize(&mut output)
+ .expect("Failed to write the key");
+ },
+ ("stats", Some(m)) => {
+ let binding = store.lookup(m.value_of("label").unwrap())
+ .expect("Failed to get key");
+ println!("Binding {:?}", binding.stats().expect("Failed to get stats"));
+ let key = binding.key().expect("Failed to get key");
+ println!("Key {:?}", key.stats().expect("Failed to get stats"));
+ },
+ _ => {
+ eprintln!("No store subcommand given.");
+ exit(1);
+ },
+ }
+ },
_ => {
eprintln!("No subcommand given.");
exit(1);
diff --git a/tool/src/usage.rs b/tool/src/usage.rs
index 3c5645bd..07cdc099 100644
--- a/tool/src/usage.rs
+++ b/tool/src/usage.rs
@@ -22,6 +22,7 @@
//! enarmor Applies ASCII Armor to a file
//! help Prints this message or the help of the given subcommand(s)
//! keyserver Interacts with keyservers
+//! store Interacts with key stores
//! ```
//!
//! ## Subcommand dearmor
@@ -133,5 +134,101 @@
//! OPTIONS:
//! -i, --input <FILE> Sets the input file to use
//! ```
+//!
+//! ## Subcommand store
+//!
+//! ```text
+//! Interacts with key stores
+//!
+//! USAGE:
+//! sq store <NAME> [SUBCOMMAND]
+//!
+//! FLAGS:
+//! -h, --help Prints help information
+//! -V, --version Prints version information
+//!
+//! ARGS:
+//! <NAME> Name of the store
+//!
+//! SUBCOMMANDS:
+//! add Add a key identified by fingerprint
+//! export Exports a key
+//! help Prints this message or the help of the given subcommand(s)
+//! import Imports a key
+//! stats Get stats for the given label
+//! ```
+//!
+//! ### Subcommand store add
+//!
+//! ```text
+//! Add a key identified by fingerprint
+//!
+//! USAGE:
+//! sq store <NAME> add <LABEL> <FINGERPRINT>
+//!
+//! FLAGS:
+//! -h, --help Prints help information
+//! -V, --version Prints version information
+//!
+//! ARGS:
+//! <LABEL> Label to use
+//! <FINGERPRINT> Key to add
+//! ```
+//!
+//! ### Subcommand store export
+//!
+//! ```text
+//! Exports a key
+//!
+//! USAGE:
+//! sq store <NAME> export [FLAGS] [OPTIONS] <LABEL>
+//!
+//! FLAGS:
+//! -A, --armor Write armored data to file
+//! -h, --help Prints help information
+//! -V, --version Prints version information
+//!
+//! OPTIONS:
+//! -o, --output <FILE> Sets the output file to use
+//!
+//! ARGS:
+//! <LABEL> Label to use
+//! ```
+//!
+//! ### Subcommand store import
+//!
+//! ```text
+//! Imports a key
+//!
+//! USAGE:
+//! sq store <NAME> import [FLAGS] [OPTIONS] <LABEL>
+//!
+//! FLAGS:
+//! -A, --dearmor Remove ASCII Armor from input
+//! -h, --help Prints help information
+//! -V, --version Prints version information
+//!
+//! OPTIONS:
+//! -i, --input <FILE> Sets the input file to use
+//!
+//! ARGS:
+//! <LABEL> Label to use
+//! ```
+//!
+//! ### Subcommand store stats
+//!
+//! ```text
+//! Get stats for the given label
+//!
+//! USAGE:
+//! sq store <NAME> stats <LABEL>
+//!
+//! FLAGS:
+//! -h, --help Prints help information
+//! -V, --version Prints version information
+//!
+//! ARGS:
+//! <LABEL> Label to use
+//! ```
include!("main.rs");