summaryrefslogtreecommitdiffstats
path: root/sq
diff options
context:
space:
mode:
authorNora Widdecke <nora@sequoia-pgp.org>2022-06-03 11:26:16 +0200
committerNora Widdecke <nora@sequoia-pgp.org>2022-06-08 14:49:43 +0200
commit73bd7bf210e28b7385213adf9634d55e3ad31619 (patch)
treeb97dea648ea588b58bbbca44cee8b22593928a88 /sq
parent207d4ba7b7fe9844ddc54c8962a4ce0c7f6fb0ba (diff)
sq: Derive packet subcommand.
- This is part of the effort of moving to clap3's derive API and profit from the added type safety.
Diffstat (limited to 'sq')
-rw-r--r--sq/src/sq-usage.rs1
-rw-r--r--sq/src/sq_cli.rs396
2 files changed, 225 insertions, 172 deletions
diff --git a/sq/src/sq-usage.rs b/sq/src/sq-usage.rs
index 96e63f09..9515aac6 100644
--- a/sq/src/sq-usage.rs
+++ b/sq/src/sq-usage.rs
@@ -1396,7 +1396,6 @@
//! ## Subcommand packet
//!
//! ```text
-//!
//! Low-level packet manipulation
//!
//! An OpenPGP data stream consists of packets. These tools allow working
diff --git a/sq/src/sq_cli.rs b/sq/src/sq_cli.rs
index b1e81529..e867d243 100644
--- a/sq/src/sq_cli.rs
+++ b/sq/src/sq_cli.rs
@@ -962,176 +962,6 @@ $ sq certify --time 20130721T0550+0200 neal.pgp ada.pgp ada
.required(true)
.index(3)
.help("Certifies USERID for CERTIFICATE."))
- )
-
- .subcommand(Command::new("packet")
- .display_order(610)
- .about("Low-level packet manipulation")
- .long_about(
-"
-Low-level packet manipulation
-
-An OpenPGP data stream consists of packets. These tools allow working
-with packet streams. They are mostly of interest to developers, but
-\"sq packet dump\" may be helpful to a wider audience both to provide
-valuable information in bug reports to OpenPGP-related software, and
-as a learning tool.
-")
- .subcommand_required(true)
- .arg_required_else_help(true)
- .subcommand(Command::new("dump")
- .display_order(100)
- .about("Lists packets")
- .long_about(
-"
-Lists packets
-
-Creates a human-readable description of the packet sequence.
-Additionally, it can print cryptographic artifacts, and print the raw
-octet stream similar to hexdump(1), annotating specifically which
-bytes are parsed into OpenPGP values.
-
-To inspect encrypted messages, either supply the session key, or see
-\"sq decrypt --dump\" or \"sq packet decrypt\".
-")
- .after_help(
-"EXAMPLES:
-
-# Prints the packets of a certificate
-$ sq packet dump juliet.pgp
-
-# Prints cryptographic artifacts of a certificate
-$ sq packet dump --mpis juliet.pgp
-
-# Prints a hexdump of a certificate
-$ sq packet dump --hex juliet.pgp
-
-# Prints the packets of an encrypted message
-$ sq packet dump --session-key AAAABBBBCCCC... ciphertext.pgp
-")
- .arg(Arg::new("input")
- .value_name("FILE")
- .help("Reads from FILE or stdin if omitted"))
- .arg(Arg::new("output")
- .short('o').long("output").value_name("FILE")
- .help("Writes to FILE or stdout if omitted"))
- .arg(Arg::new("session-key")
- .long("session-key").value_name("SESSION-KEY")
- .help("Decrypts an encrypted message using \
- SESSION-KEY"))
- .arg(Arg::new("mpis")
- .long("mpis")
- .help("Prints cryptographic artifacts"))
- .arg(Arg::new("hex")
- .short('x').long("hex")
- .help("Prints a hexdump"))
- )
- .subcommand(Command::new("decrypt")
- .display_order(200)
- .about("Unwraps an encryption container")
- .long_about(
-"
-Unwraps an encryption container
-
-Decrypts a message, dumping the content of the encryption container
-without further processing. The result is a valid OpenPGP message
-that can, among other things, be inspected using \"sq packet dump\".
-")
- .after_help(
-"EXAMPLES:
-
-# Unwraps the encryption revealing the signed message
-$ sq packet decrypt --recipient-key juliet.pgp ciphertext.pgp
-")
- .arg(Arg::new("input")
- .value_name("FILE")
- .help("Reads from FILE or stdin if omitted"))
- .arg(Arg::new("output")
- .short('o').long("output").value_name("FILE")
- .help("Writes to FILE or stdout if omitted"))
- .arg(Arg::new("binary")
- .short('B').long("binary")
- .help("Emits binary data"))
- .arg(Arg::new("secret-key-file")
- .long("recipient-key").value_name("KEY")
- .multiple_occurrences(true)
- .help("Decrypts the message with KEY"))
- .arg(Arg::new("private-key-store")
- .long("private-key-store").value_name("KEY_STORE")
- .help("Provides parameters for private key store"))
- .arg(Arg::new("dump-session-key")
- .long("dump-session-key")
- .help("Prints the session key to stderr"))
- )
- .subcommand(Command::new("split")
- .display_order(300)
- .about("Splits a message into packets")
- .long_about(
-"
-Splits a message into packets
-
-Splitting a packet sequence into individual packets, then recombining
-them freely with \"sq packet join\" is a great way to experiment with
-OpenPGP data.
-
-The converse operation is \"sq packet join\".
-")
- .after_help(
-"EXAMPLES:
-
-# Split a certificate into individual packets
-$ sq packet split juliet.pgp
-")
- .arg(Arg::new("input")
- .value_name("FILE")
- .help("Reads from FILE or stdin if omitted"))
- .arg(Arg::new("prefix")
- .short('p').long("prefix").value_name("PREFIX")
- .help("Writes to files with PREFIX \
- [defaults: FILE a dash, \
- or \"output\" if read from stdin)"))
- )
- .subcommand(Command::new("join")
- .display_order(310)
- .about("Joins packets split across \
- files")
- .long_about(
-"
-Joins packets split across files
-
-Splitting a packet sequence into individual packets, then recombining
-them freely with \"sq packet join\" is a great way to experiment with
-OpenPGP data.
-
-The converse operation is \"sq packet split\".
-")
- .after_help(
-"EXAMPLES:
-
-# Split a certificate into individual packets
-$ sq packet split juliet.pgp
-
-# Then join only a subset of these packets
-$ sq packet join juliet.pgp-[0-3]*
-")
- .arg(Arg::new("input")
- .value_name("FILE")
- .multiple_occurrences(true)
- .help("Reads from FILE or stdin if omitted"))
- .arg(Arg::new("output")
- .short('o').long("output").value_name("FILE")
- .help("Writes to FILE or stdout if omitted"))
- .arg(Arg::new("kind")
- .long("label").value_name("LABEL")
- .possible_values(&["auto", "message",
- "cert", "key", "sig",
- "file"])
- .default_value("auto")
- .conflicts_with("binary")
- .help("Selects the kind of armor header"))
- .arg(Arg::new("binary")
- .short('B').long("binary")
- .help("Emits binary data")))
);
let app = if ! feature_autocrypt {
@@ -1147,7 +977,8 @@ $ sq packet join juliet.pgp-[0-3]*
.subcommand(VerifyCommand::command())
.subcommand(WkdCommand::command())
.subcommand(KeyserverCommand::command())
- .subcommand(RevokeCommand::command());
+ .subcommand(RevokeCommand::command())
+ .subcommand(PacketCommand::command());
app
}
@@ -1462,6 +1293,229 @@ pub struct SignCommand {
#[derive(Parser, Debug)]
#[clap(
+ name = "packet",
+ display_order = 610,
+ about = "Low-level packet manipulation",
+ long_about =
+"Low-level packet manipulation
+
+An OpenPGP data stream consists of packets. These tools allow working
+with packet streams. They are mostly of interest to developers, but
+\"sq packet dump\" may be helpful to a wider audience both to provide
+valuable information in bug reports to OpenPGP-related software, and
+as a learning tool.
+",
+ subcommand_required = true,
+ arg_required_else_help = true,
+ )]
+pub struct PacketCommand {
+ #[clap(subcommand)]
+ pub subcommand: PacketSubcommands,
+}
+
+#[derive(Debug, Subcommand)]
+pub enum PacketSubcommands {
+ Dump(PacketDumpCommand),
+ Decrypt(PacketDecryptCommand),
+ Split(PacketSplitCommand),
+ Join(PacketJoinCommand),
+}
+
+#[derive(Debug, Args)]
+#[clap(
+ display_order = 100,
+ about = "Lists packets",
+ long_about =
+"
+Lists packets
+
+Creates a human-readable description of the packet sequence.
+Additionally, it can print cryptographic artifacts, and print the raw
+octet stream similar to hexdump(1), annotating specifically which
+bytes are parsed into OpenPGP values.
+
+To inspect encrypted messages, either supply the session key, or see
+\"sq decrypt --dump\" or \"sq packet decrypt\".
+",
+ after_help =
+"EXAMPLES:
+
+# Prints the packets of a certificate
+$ sq packet dump juliet.pgp
+
+# Prints cryptographic artifacts of a certificate
+$ sq packet dump --mpis juliet.pgp
+
+# Prints a hexdump of a certificate
+$ sq packet dump --hex juliet.pgp
+
+# Prints the packets of an encrypted message
+$ sq packet dump --session-key AAAABBBBCCCC... ciphertext.pgp
+",
+)]
+pub struct PacketDumpCommand {
+ #[clap(flatten)]
+ pub io: IoArgs,
+ #[clap(
+ long = "session-key",
+ value_name = "SESSION-KEY",
+ help = "Decrypts an encrypted message using SESSION-KEY",
+ )]
+ pub session_key: Option<String>,
+ #[clap(
+ long = "mpis",
+ help = "Prints cryptographic artifacts",
+ )]
+ pub mpis: bool,
+ #[clap(
+ short = 'x',
+ long = "hex",
+ help = "Prints a hexdump",
+ )]
+ pub hex: bool,
+}
+
+#[derive(Debug, Args)]
+#[clap(
+ display_order = 200,
+ about = "Unwraps an encryption container",
+ long_about = "
+Unwraps an encryption container
+
+Decrypts a message, dumping the content of the encryption container
+without further processing. The result is a valid OpenPGP message
+that can, among other things, be inspected using \"sq packet dump\".
+",
+ after_help =
+"EXAMPLES:
+
+# Unwraps the encryption revealing the signed message
+$ sq packet decrypt --recipient-key juliet.pgp ciphertext.pgp
+",
+)]
+pub struct PacketDecryptCommand {
+ #[clap(flatten)]
+ pub io: IoArgs,
+ #[clap(
+ short = 'B',
+ long,
+ help = "Emits binary data",
+ )]
+ pub binary: bool,
+ #[clap(
+ long = "recipient-key",
+ value_name = "KEY",
+ help = "Decrypts the message with KEY",
+ )]
+ pub secret_key_file: Vec<String>,
+ #[clap(
+ long = "private-key-store",
+ value_name = "KEY_STORE",
+ help = "Provides parameters for private key store",
+ )]
+ pub private_key_store: Option<String>,
+ #[clap(
+ long = "dump-session-key",
+ help = "Prints the session key to stderr",
+ )]
+ pub dump_session_key: bool,
+}
+
+#[derive(Debug, Args)]
+#[clap(
+ display_order = 300,
+ about = "Splits a message into packets",
+ long_about = "
+Splits a message into packets
+
+Splitting a packet sequence into individual packets, then recombining
+them freely with \"sq packet join\" is a great way to experiment with
+OpenPGP data.
+
+The converse operation is \"sq packet join\".
+",
+ after_help =
+"EXAMPLES:
+
+# Split a certificate into individual packets
+$ sq packet split juliet.pgp
+",
+)]
+pub struct PacketSplitCommand {
+ #[clap(value_name = "FILE", help = "Reads from FILE or stdin if omitted")]
+ pub input: Option<String>,
+ #[clap(
+ short = 'p',
+ long = "prefix",
+ value_name = "PREFIX",
+ help = "Writes to files with PREFIX \
+ [defaults: FILE a dash, or \"output\" if read from stdin)",
+ )]
+ pub prefix: Option<String>,
+}
+
+#[derive(Debug, Args)]
+#[clap(
+ display_order = 310,
+ about = "Joins packets split across files",
+ long_about = "
+Joins packets split across files
+
+Splitting a packet sequence into individual packets, then recombining
+them freely with \"sq packet join\" is a great way to experiment with
+OpenPGP data.
+
+The converse operation is \"sq packet split\".
+",
+ after_help =
+"EXAMPLES:
+
+# Split a certificate into individual packets
+$ sq packet split juliet.pgp
+
+# Then join only a subset of these packets
+$ sq packet join juliet.pgp-[0-3]*
+",
+)]
+pub struct PacketJoinCommand {
+ #[clap(value_name = "FILE", help = "Reads from FILE or stdin if omitted")]
+ pub input: Vec<String>,
+ #[clap(
+ short,
+ long,
+ value_name = "FILE",
+ help = "Writes to FILE or stdout if omitted"
+ )]
+ pub output: Option<String>,
+ #[clap(
+ long = "label",
+ value_name = "LABEL",
+ default_value_t = PacketKind::Auto,
+ conflicts_with = "binary",
+ help = "Selects the kind of armor header",
+ arg_enum,
+ )]
+ pub kind: PacketKind,
+ #[clap(
+ short = 'B',
+ long,
+ help = "Emits binary data",
+ )]
+ pub binary: bool,
+}
+// TODO: reuse CliArmorKind, requires changes in sq.rs
+#[derive(ArgEnum, Clone, Debug)]
+pub enum PacketKind {
+ Auto,
+ Message,
+ Cert,
+ Key,
+ Sig,
+ File
+}
+
+#[derive(Parser, Debug)]
+#[clap(
name = "revoke",
display_order = 700,
about = "Generates revocation certificates",