summaryrefslogtreecommitdiffstats
path: root/sq/src/sq_cli/packet.rs
blob: 1672e613f89003cd0eca81115503c268b1727944 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
use clap::{Args, Parser, Subcommand};

use super::{IoArgs, CliSessionKey, PacketKind};

#[derive(Parser, Debug)]
#[clap(
    name = "packet",
    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,
    setting(clap::AppSettings::DeriveDisplayOrder),
    )]
pub struct Command {
    #[clap(subcommand)]
    pub subcommand: Subcommands,
}

#[derive(Debug, Subcommand)]
pub enum Subcommands {
    Dump(DumpCommand),
    Decrypt(DecryptCommand),
    Split(SplitCommand),
    Join(JoinCommand),
}

#[derive(Debug, Args)]
#[clap(
    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 DumpCommand {
    #[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<CliSessionKey>,
    #[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(
    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 DecryptCommand {
    #[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 = "session-key",
        value_name = "SESSION-KEY",
        help = "Decrypts an encrypted message using SESSION-KEY",
    )]
    pub session_key: Vec<CliSessionKey>,
    #[clap(
            long = "dump-session-key",
            help = "Prints the session key to stderr",
    )]
    pub dump_session_key: bool,
}

#[derive(Debug, Args)]
#[clap(
    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 SplitCommand {
    #[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-\" if FILE is set, or \"output-\" if read from stdin]",
    )]
    pub prefix: Option<String>,
}

#[derive(Debug, Args)]
#[clap(
    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 JoinCommand {
    #[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,
}