diff options
author | Nora Widdecke <nora@sequoia-pgp.org> | 2022-07-19 11:41:40 +0200 |
---|---|---|
committer | Nora Widdecke <nora@sequoia-pgp.org> | 2022-07-20 10:22:25 +0200 |
commit | 7d76a57c6b372b0549aa7f8750c32cb812ec2fcc (patch) | |
tree | aa942b4a27d7aa2346a2dc142f0ff3f2eb31a424 | |
parent | fd8912e4bf9baf02ea2cf4adddfb6d7258aeadf0 (diff) |
sq: Clean up build.
- Remove the workaround that was required to include help output in
docs.
-rw-r--r-- | .gitlab-ci.yml | 4 | ||||
-rw-r--r-- | sq/Cargo.toml | 2 | ||||
-rw-r--r-- | sq/build.rs | 34 | ||||
-rw-r--r-- | sq/sq-usage.md | 2177 | ||||
-rw-r--r-- | sq/src/sq-usage.rs | 2182 | ||||
-rw-r--r-- | sq/src/sq.rs | 5 |
6 files changed, 2198 insertions, 2206 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ccd35486..77154b5e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -55,7 +55,7 @@ bookworm: - cargo run --manifest-path openpgp/Cargo.toml --no-default-features --features crypto-nettle,compression --example supported-algorithms - $MAKE_TOP test - if ! git diff --quiet Cargo.lock ; then echo "Cargo.lock changed. Please add the change to the corresponding commit." ; git diff ; false ; fi - - if ! git diff --quiet sq ; then echo "Please commit the changes to sq/src/sq-usage.rs." ; false ; fi + - if ! git diff --quiet sq ; then echo "Please commit the changes to sq/sq-usage.md." ; false ; fi - if ! git diff --quiet ; then echo "The build changed the source. Please investigate." ; git diff ; fi variables: CARGO_TARGET_DIR: /target @@ -74,7 +74,7 @@ bookworm:arm64: script: - $MAKE_TOP test - if ! git diff --quiet Cargo.lock ; then echo "Cargo.lock changed. Please add the change to the corresponding commit." ; false ; fi - - if ! git diff --quiet sq ; then echo "Please commit the changes to sq/src/sq-usage.rs." ; false ; fi + - if ! git diff --quiet sq ; then echo "Please commit the changes to sq/src/sq-usage.md." ; false ; fi - if ! git diff --quiet ; then echo "The build changed the source. Please investigate." ; git diff ; fi variables: CARGO_TARGET_DIR: /target diff --git a/sq/Cargo.toml b/sq/Cargo.toml index 6ec451c6..dec36b47 100644 --- a/sq/Cargo.toml +++ b/sq/Cargo.toml @@ -59,7 +59,7 @@ predicates = "2" [[bin]] name = "sq" -path = "src/sq-usage.rs" +path = "src/sq.rs" bench = false [features] diff --git a/sq/build.rs b/sq/build.rs index 2264c000..218144d7 100644 --- a/sq/build.rs +++ b/sq/build.rs @@ -11,23 +11,17 @@ pub mod sq_cli { fn main() { println!("cargo:rerun-if-changed=build.rs"); - // XXX: Revisit once - // https://github.com/rust-lang/rust/issues/44732 is stabilized. - + // Generate subplot tests. subplot_build::codegen(Path::new("sq-subplot.md")) .expect("failed to generate code with Subplot"); + // Dump help output of all commands and subcommands, for inlcusion in docs let mut sq = sq_cli::build().term_width(80); - let mut main = fs::File::create("src/sq-usage.rs").unwrap(); + let mut main = fs::File::create("sq-usage.md").unwrap(); dump_help(&mut main, &mut sq, vec![], "#").unwrap(); - writeln!(main, "\n#![doc(html_favicon_url = \"https://docs.sequoia-pgp.org/favicon.png\")]") - .unwrap(); - writeln!(main, "#![doc(html_logo_url = \"https://docs.sequoia-pgp.org/logo.svg\")]") - .unwrap(); - writeln!(main, "\ninclude!(\"sq.rs\");").unwrap(); let outdir = match env::var_os("CARGO_TARGET_DIR") { None => return, @@ -43,7 +37,7 @@ fn main() { }; } -fn dump_help(sink: &mut dyn io::Write, +fn dump_help(sink: &mut dyn Write, sq: &mut clap::Command, cmd: Vec<String>, heading: &str) @@ -51,15 +45,15 @@ fn dump_help(sink: &mut dyn io::Write, { if cmd.is_empty() { - writeln!(sink, "//! A command-line frontend for Sequoia.")?; - writeln!(sink, "//!")?; - writeln!(sink, "//! # Usage")?; + writeln!(sink, "A command-line frontend for Sequoia.")?; + writeln!(sink, "")?; + writeln!(sink, "# Usage")?; } else { - writeln!(sink, "//!")?; - writeln!(sink, "//! {} Subcommand {}", heading, cmd.join(" "))?; + writeln!(sink, "")?; + writeln!(sink, "{} Subcommand {}", heading, cmd.join(" "))?; } - writeln!(sink, "//!")?; + writeln!(sink, "")?; let args = std::iter::once("sq") .chain(cmd.iter().map(|s| s.as_str())) @@ -69,15 +63,15 @@ fn dump_help(sink: &mut dyn io::Write, let help = sq.try_get_matches_from_mut(&args) .unwrap_err().to_string(); - writeln!(sink, "//! ```text")?; + writeln!(sink, "```text")?; for line in help.trim_end().split('\n').skip(1) { if line.is_empty() { - writeln!(sink, "//!")?; + writeln!(sink, "")?; } else { - writeln!(sink, "//! {}", line.trim_end())?; + writeln!(sink, "{}", line.trim_end())?; } } - writeln!(sink, "//! ```")?; + writeln!(sink, "```")?; // Recurse. let mut found_subcommands = false; diff --git a/sq/sq-usage.md b/sq/sq-usage.md new file mode 100644 index 00000000..5f0cf511 --- /dev/null +++ b/sq/sq-usage.md @@ -0,0 +1,2177 @@ +A command-line frontend for Sequoia. + +# Usage + +```text +A command-line frontend for Sequoia, an implementation of OpenPGP + +Functionality is grouped and available using subcommands. Currently, +this interface is completely stateless. Therefore, you need to supply +all configuration and certificates explicitly on each invocation. + +OpenPGP data can be provided in binary or ASCII armored form. This +will be handled automatically. Emitted OpenPGP data is ASCII armored +by default. + +We use the term "certificate", or cert for short, to refer to OpenPGP +keys that do not contain secrets. Conversely, we use the term "key" +to refer to OpenPGP keys that do contain secrets. + +USAGE: + sq [OPTIONS] <SUBCOMMAND> + +OPTIONS: + -f, --force + Overwrites existing files + + -h, --help + Print help information + + --known-notation <NOTATION> + Adds NOTATION to the list of known notations. This is used when + validating signatures. Signatures that have unknown notations with + the critical bit set are considered invalid. + + --output-format <FORMAT> + Produces output in FORMAT, if possible + + [env: SQ_OUTPUT_FORMAT=] + [default: human-readable] + [possible values: human-readable, json] + + --output-version <VERSION> + Produces output variant VERSION + + [env: SQ_OUTPUT_VERSION=] + + -V, --version + Print version information + +SUBCOMMANDS: + encrypt + Encrypts a message + decrypt + Decrypts a message + sign + Signs messages or data files + verify + Verifies signed messages or detached signatures + key + Manages keys + keyring + Manages collections of keys or certs + certify + Certifies a User ID for a Certificate + autocrypt + Communicates certificates using Autocrypt + keyserver + Interacts with keyservers + wkd + Interacts with Web Key Directories + armor + Converts binary to ASCII + dearmor + Converts ASCII to binary + inspect + Inspects data, like file(1) + packet + Low-level packet manipulation + revoke + Generates revocation certificates + help + Print this message or the help of the given subcommand(s) +``` + +## Subcommand encrypt + +```text +Encrypts a message + +Encrypts a message for any number of recipients and with any number of +passwords, optionally signing the message in the process. + +The converse operation is "sq decrypt". + +USAGE: + sq encrypt [OPTIONS] [FILE] + +ARGS: + <FILE> + Reads from FILE or stdin if omitted + +OPTIONS: + -B, --binary + Emits binary data + + --compression <KIND> + Selects compression scheme to use + + [default: pad] + [possible values: none, pad, zip, zlib, bzip2] + + -h, --help + Print help information + + --mode <MODE> + Selects what kind of keys are considered for encryption. Transport + select subkeys marked as suitable for transport encryption, rest + selects those for encrypting data at rest, and all selects all + encryption-capable subkeys. + + [default: all] + [possible values: transport, rest, all] + + -o, --output <FILE> + Writes to FILE or stdout if omitted + + --private-key-store <KEY_STORE> + Provides parameters for private key store + + --recipient-cert <CERT-RING> + Encrypts for all recipients in CERT-RING + + -s, --symmetric + Adds a password to encrypt with. The message can be decrypted with + either one of the recipient's keys, or any password. + + --signer-key <KEY> + Signs the message with KEY + + -t, --time <TIME> + Chooses keys valid at the specified time and sets the signature's + creation time + + --use-expired-subkey + If a certificate has only expired encryption-capable subkeys, falls + back to using the one that expired last + +EXAMPLES: + +# Encrypt a file using a certificate +$ sq encrypt --recipient-cert romeo.pgp message.txt + +# Encrypt a file creating a signature in the process +$ sq encrypt --recipient-cert romeo.pgp --signer-key juliet.pgp message.txt + +# Encrypt a file using a password +$ sq encrypt --symmetric message.txt +``` + +## Subcommand decrypt + +```text +Decrypts a message + +Decrypts a message using either supplied keys, or by prompting for a +password. If message tampering is detected, an error is returned. +See below for details. + +If certificates are supplied using the "--signer-cert" option, any +signatures that are found are checked using these certificates. +Verification is only successful if there is no bad signature, and the +number of successfully verified signatures reaches the threshold +configured with the "--signatures" parameter. + +If the signature verification fails, or if message tampering is +detected, the program terminates with an exit status indicating +failure. In addition to that, the last 25 MiB of the message are +withheld, i.e. if the message is smaller than 25 MiB, no output is +produced, and if it is larger, then the output will be truncated. + +The converse operation is "sq encrypt". + +USAGE: + sq decrypt [OPTIONS] [FILE] + +ARGS: + <FILE> + Reads from FILE or stdin if omitted + +OPTIONS: + --dump + Prints a packet dump to stderr + + --dump-session-key + Prints the session key to stderr + + -h, --help + Print help information + + -n, --signatures <N> + Sets the threshold of valid signatures to N. The message will only + be considered verified if this threshold is reached. [default: 1 if + at least one signer cert file is given, 0 otherwise] + + -o, --output <FILE> + Writes to FILE or stdout if omitted + + --private-key-store <KEY_STORE> + Provides parameters for private key store + + --recipient-key <KEY> + Decrypts with KEY + + --session-key <SESSION-KEY> + Decrypts an encrypted message using SESSION-KEY + + --signer-cert <CERT> + Verifies signatures with CERT + + -x, --hex + Prints a hexdump (implies --dump) + +EXAMPLES: + +# Decrypt a file using a secret key +$ sq decrypt --recipient-key juliet.pgp ciphertext.pgp + +# Decrypt a file verifying signatures +$ sq decrypt --recipient-key juliet.pgp --signer-cert romeo.pgp ciphertext.pgp + +# Decrypt a file using a password +$ sq decrypt ciphertext.pgp +``` + +## Subcommand sign + +```text +Signs messages or data files + +Creates signed messages or detached signatures. Detached signatures +are often used to sign software packages. + +The converse operation is "sq verify". + +USAGE: + sq sign [OPTIONS] [--] [FILE] + +ARGS: + <FILE> + Reads from FILE or stdin if omitted + +OPTIONS: + -a, --append + Appends a signature to existing signature + + -B, --binary + Emits binary data + + --cleartext-signature + Creates a cleartext signature + + --detached + Creates a detached signature + + -h, --help + Print help information + + --merge <SIGNED-MESSAGE> + Merges signatures from the input and SIGNED-MESSAGE + + -n, --notarize + Signs a message and all existing signatures + + --notation <NAME> <VALUE> + Adds a notation to the certification. A user-defined notation's + name must be of the form "name@a.domain.you.control.org". If the + notation's name starts with a !, then the notation is marked as + being critical. If a consumer of a signature doesn't understand a + critical notation, then it will ignore the signature. The notation + is marked as being human readable. + + -o, --output <FILE> + Writes to FILE or stdout if omitted + + --private-key-store <KEY_STORE> + Provides parameters for private key store + + --signer-key <KEY> + Signs using KEY + + -t, --time <TIME> + Chooses keys valid at the specified time and sets the signature's + creation time + +EXAMPLES: + +# Create a signed message +$ sq sign --signer-key juliet.pgp message.txt + +# Create a detached signature +$ sq sign --detached --signer-key juliet.pgp message.txt +``` + +## Subcommand verify + +```text +Verifies signed messages or detached signatures + +When verifying signed messages, the message is written to stdout or +the file given to --output. + +When a detached message is verified, no output is produced. Detached +signatures are often used to sign software packages. + +Verification is only successful if there is no bad signature, and the +number of successfully verified signatures reaches the threshold +configured with the "--signatures" parameter. If the verification +fails, the program terminates with an exit status indicating failure. +In addition to that, the last 25 MiB of the message are withheld, +i.e. if the message is smaller than 25 MiB, no output is produced, and +if it is larger, then the output will be truncated. + +The converse operation is "sq sign". + +USAGE: + sq verify [OPTIONS] [FILE] + +ARGS: + <FILE> + Reads from FILE or stdin if omitted + +OPTIONS: + --detached <SIG> + Verifies a detached signature + + -h, --help + Print help information + + -n, --signatures <N> + Sets the threshold of valid signatures to N. If this threshold is + not reached, the message will not be considered verified. + + [default: 1] + + -o, --output <FILE> + Writes to FILE or stdout if omitted + + --signer-cert <CERT> + Verifies signatures with CERT + +EXAMPLES: + +# Verify a signed message +$ sq verify --signer-cert juliet.pgp signed-message.pgp + +# Verify a detached message +$ sq verify --signer-cert juliet.pgp --detached message.sig message.txt + +SEE ALSO: + +If you are looking for a standalone program to verify detached +signatures, consider using sequoia-sqv. +``` + +## Subcommand key + +```text +Manages keys + +We use the term "key" to refer to OpenPGP keys that do contain +secrets. This subcommand provides primitives to generate and +otherwise manipulate keys. + +Conversely, we use the term "certificate", or cert for short, to refer +to OpenPGP keys that do not contain secrets. See "sq keyring" for +operations on certificates. + +USAGE: + sq key <SUBCOMMAND> + +OPTIONS: + -h, --help + Print help information + +SUBCOMMANDS: + generate + Generates a new key + password + Changes password protecting secrets + userid + Manages User IDs + extract-cert + Converts a key to a cert + attest-certifications + Attests to third-party certifications + adopt + Binds keys from one certificate to another + help + Print this message or the help of the given subcommand(s) +``` + +### Subcommand key generate + +```text +Generates a new key + +Generating a key is the prerequisite to receiving encrypted messages +and creating signatures. There are a few parameters to this process, +but we provide reasonable defaults for most users. + +When generating a key, we also generate a revocation certificate. +This can be used in case the key is superseded, lost, or compromised. +It is a good idea to keep a copy of this in a safe place. + +After generating a key, use "sq key extract-cert" to get the +certificate corresponding to the key. The key must be kept secure, +while the certificate should be handed out to correspondents, e.g. by +uploading it to a keyserver. + +USAGE: + sq key generate [OPTIONS] + +OPTIONS: + -c, --cipher-suite <CIPHER-SUITE> + Selects the cryptographic algorithms for the key + + [default: cv25519] + [possible values: rsa3k, rsa4k, cv25519] + + --can-authenticate + Adds an authentication-capable subkey (default) + + --can-encrypt <PURPOSE> + Adds an encryption-capable subkey. Encryption-capable subkeys can be + marked as suitable for transport encryption, storage encryption, or + both. [default: universal] + + [possible values: transport, storage, universal] + + --can-sign + Adds a signing-capable subkey (default) + + --cannot-authenticate + Adds no authentication-capable subkey + + --cannot-encrypt + Adds no encryption-capable subkey + + --cannot-sign + Adds no signing-capable subkey + + --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 + + -e, --export <OUTFILE> + Writes the key to OUTFILE + + --expires <TIME> + Makes the key expire at TIME (as ISO 8601). Use "never" to create + keys that do not expire. + + --expires-in <DURATION> + Makes the key expire after DURATION. Either "N[ymwds]", for N years, + months, weeks, days, seconds, or "never". + + -h, --help + Print help information + + --rev-cert <FILE or -> + Writes the revocation certificate to FILE. mandatory if OUTFILE is + "-". [default: <OUTFILE>.rev] + + -u, --userid <EMAIL> + Adds a userid to the key + + --with-password + Protects the key with a password + +EXAMPLES: + +# First, this generates a key +$ sq key generate --userid "<juliet@example.org>" --export juliet.key.pgp + +# Then, this extracts the certificate for distribution +$ sq key extract-cert --output juliet.cert.pgp juliet.key.pgp + +# Generates a key protecting it with a password +$ sq key generate --userid "<juliet@example.org>" --with-password + +# Generates a key with multiple userids +$ sq key generate --userid "<juliet@example.org>" --userid "Juliet Capulet" +``` + +### Subcommand key password + +```text +Changes password protecting secrets + +Secret key material in keys can be protected by a password. This +subcommand changes or clears this encryption password. + +To emit the key with unencrypted secrets, either use `--clear` or +supply a zero-length password when prompted for the new password. + +USAGE: + sq key password [OPTIONS] [FILE] + +ARGS: + <FILE> + Reads from FILE or stdin if omitted + +OPTIONS: + -B, --binary + Emits binary data + + --clear + Emit a key with unencrypted secrets + + -h, --help + Print help information + + -o, --output <FILE> + Writes to FILE or stdout if omitted + +EXAMPLES: + +# First, generate a key +$ sq key generate --userid "<juliet@example.org>" --export juliet.key.pgp + +# Then, encrypt the secrets in the key with a password. +$ sq key password < juliet.key.pgp > juliet.encrypted_key.pgp + +# And remove the password again. +$ sq key password --clear < juliet.encrypted_key.pgp > juliet.decrypted_key.pgp +``` + +### Subcommand key userid + +```text +Manages User IDs + +Add User IDs to, or strip User IDs from a key. + +USAGE: + sq key userid <SUBCOMMAND> + +OPTIONS: + -h, --help + Print help information + +SUBCOMMANDS: + add + Adds a User ID + strip + Strips a User ID + help + Print this message or the help of the given subcommand(s) +``` + +#### Subcommand key userid add + +```text +Adds a User ID + +A User ID can contain a name, like "Juliet" or an email address, like +"<juliet@example.org>". Historically, a name and email address were often +combined as a single User ID, like "Juliet <juliet@example.org>". + +USAGE: + sq key userid add [OPTIONS] [FILE] + +ARGS: + <FILE> + Reads from FILE or stdin if omitted + +OPTIONS: + -B, --binary + Emits binary data + + --creation-time <CREATION_TIME> + Sets the creation time of this User ID's binding signature to TIME. + TIME is interpreted as an ISO 8601 timestamp. To set the creation + time to June 28, 2022 at midnight UTC, you can do: + + $ sq key userid add --userid "Juliet" --creation-time 20210628 \ + juliet.key.pgp --output juliet-new.key.pgp + + To include a time, add a T, the time and optionally the timezone + (the + default timezone is UTC): + + $ sq key userid add --userid "Juliet" --creation-time + 20210628T1137+0200 \ + juliet.key.pgp --output juliet-new.key.pgp + + -h, --help + Print help information + + -o, --output <FILE> + Writes to FILE or stdout if omitted + + --private-key-store <KEY_STORE> + Provides parameters for private key store + + -u, --userid <USERID> + User ID to add + +EXAMPLES: + +# First, this generates a key +$ sq key generate --userid "<juliet@example.org>" --export juliet.key.pgp + +# Then, this adds a User ID +$ sq key userid add --userid "Juliet" juliet.key.pgp \ + --output juliet-new.key.pgp +``` + +#### Subcommand key userid strip + +```text +Strips a User ID + +Note that this operation does not reliably remove User IDs from a +certificate that has already been disseminated! (OpenPGP software +typically appends new information it receives about a certificate +to its local copy of that certificate. Systems that have obtained +a copy of your certificate with the User ID that you are trying to +strip will not drop that User ID from their copy.) + +In most cases, you will want to use the 'sq revoke userid' operation +instead. That issues a revocation for a User ID, which can be used to mark +the User ID as invalidated. + +However, this operation can be useful in very specific cases, in particular: +to remove a mistakenly added User ID before it has been uploaded to key +servers or otherwise shared. + +Stripping a User ID may change how a certificate is interpreted. This +is because information about the certificate like algorithm preferences, +the primary key's key flags, etc. is stored in the User ID's binding +signature. + +USAGE: + sq key userid strip [OPTIONS] [FILE] + +ARGS: + <FILE> + Reads from FILE or stdin if omitted + +OPTIONS: + -B, --binary + Emits binary data + + -h, --help + Print help information + + -o, --output <FILE> + Writes to FILE or stdout if omitted + + -u, --userid <USERID> + The User IDs to strip. Values must exactly match a User ID. + +EXAMPLES: + +# First, this generates a key +$ sq key generate --userid "<juliet@example.org>" --export juliet.key.pgp + +# Then, this strips a User ID +$ sq key userid strip --userid "<juliet@example.org>" \ + --output juliet-new.key.pgp juliet.key.pgp +``` + +### Subcommand key extract-cert + +```text +Converts a key to a cert + +After generating a key, use this command to get the certificate +corresponding to the key. The key must be kept secure, while the +certificate should be handed out to correspondents, e.g. by uploading +it to a keyserver. + +USAGE: + sq key extract-cert [OPTIONS] [FILE] + +ARGS: + <FILE> + Reads from FILE or stdin if omitted + +OPTIONS: + -B, --binary + Emits binary data + + -h, --help + Print help information + + -o, --output <FILE> + Writes to FILE or stdout if omitted + +EXAMPLES: + +# First, this generates a key +$ sq key generate --userid "<juliet@example.org>" --export juliet.key.pgp + +# Then, this extracts the certificate for distribution +$ sq key extract-cert --output juliet.cert.pgp juliet.key.pgp +``` + +### Subcommand key attest-certifications + +```text + +Attests to third-party certifications allowing for their distribution + +To prevent certificate flooding attacks, modern key servers prevent +uncontrolled distribution of third-party certifications on +certificates. To make the key holder the sovereign over the +information over what information is distributed with the certificate, +the key holder needs to explicitly attest to third-party +certifications. + +After the attestation has been created, the certificate has to be +distributed, e.g. by uploading it to a keyserver. + +USAGE: + sq key attest-certifications [OPTIONS] [KEY] |