Move sq import and export to sq cert.

This commit is contained in:
Justus Winter 2024-01-19 11:24:21 +01:00
parent 9394f6292d
commit b7ef68ca35
No known key found for this signature in database
GPG Key ID: 686F55B4AB2B3386
17 changed files with 91 additions and 44 deletions

35
src/cli/cert.rs Normal file
View File

@ -0,0 +1,35 @@
//! Command-line parser for `sq cert`.
use clap::{Parser, Subcommand};
pub mod export;
pub mod import;
#[derive(Parser, Debug)]
#[clap(
name = "cert",
about = "Manages certificates",
long_about =
"Manages certificates
We use the term \"certificate\", or \"cert\" for short, to refer to
OpenPGP keys that do not contain secrets. This subcommand provides
primitives to generate and otherwise manipulate certs.
Conversely, we use the term \"key\" to refer to OpenPGP keys that do
contain secrets. See `sq key` for operations on keys.
",
subcommand_required = true,
arg_required_else_help = true,
)]
pub struct Command {
#[clap(subcommand)]
pub subcommand: Subcommands,
}
#[derive(Debug, Subcommand)]
pub enum Subcommands {
Import(import::Command),
Export(export::Command),
}

View File

@ -29,29 +29,29 @@ no search criteria are specified, then this will return success.",
"EXAMPLES:
# Exports all certificates.
$ sq export > all.pgp
$ sq cert export > all.pgp
# Exports certificates with a matching User ID packet. The binding
# signatures are checked, but the User IDs are not authenticated.
# Note: this check is case sensitive.
$ sq export --userid 'Alice <alice@example.org>'
$ sq cert export --userid 'Alice <alice@example.org>'
# Exports certificates with a User ID containing the email address.
# The binding signatures are checked, but the User IDs are not
# authenticated. Note: this check is case insensitive.
$ sq export --email 'alice@example.org'
$ sq cert export --email 'alice@example.org'
# Exports certificates where the certificate (i.e., the primary key)
# has the specified Key ID.
$ sq export --cert 1234567812345678
$ sq cert export --cert 1234567812345678
# Exports certificates where the primary key or a subkey matches the
# specified Key ID.
$ sq export --key 1234567812345678
$ sq cert export --key 1234567812345678
# Exports certificates that contain a User ID with *either* (not
# both!) email address. Note: this check is case insensitive.
$ sq export --email alice@example.org --email bob@example.org
$ sq cert export --email alice@example.org --email bob@example.org
",
)]
pub struct Command {

View File

@ -13,7 +13,7 @@ use clap::Parser;
"EXAMPLES:
# Imports a certificate.
$ sq import < juliet.pgp
$ sq cert import < juliet.pgp
",
)]
pub struct Command {

View File

@ -64,7 +64,7 @@ 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
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.
",

View File

@ -87,11 +87,10 @@ use sequoia_openpgp as openpgp;
use openpgp::Fingerprint;
pub mod armor;
pub mod cert;
pub mod dearmor;
pub mod decrypt;
pub mod encrypt;
pub mod export;
pub mod import;
pub mod inspect;
pub mod key;
pub mod keyring;
@ -351,10 +350,9 @@ pub enum SqSubcommands {
Inspect(inspect::Command),
Cert(cert::Command),
Key(key::Command),
Keyring(keyring::Command),
Import(import::Command),
Export(export::Command),
Pki(pki::Command),
Autocrypt(autocrypt::Command),

View File

@ -124,7 +124,7 @@ $ sq pki link add 0123456789ABCDEF '<romeo@example.org>'
# The user examines 0123456789ABCDEF and then accepts the certificate
# 0123456789ABCDEF with its current set of self-signed User IDs.
$ sq export --cert 0123456789ABCDEF | sq inspect
$ sq cert export --cert 0123456789ABCDEF | sq inspect
...
$ sq pki link add 0123456789ABCDEF --all

View File

@ -29,14 +29,13 @@ use crate::cli::encrypt::CompressionMode;
use crate::cli::types::FileOrStdout;
pub mod autocrypt;
pub mod cert;
pub mod decrypt;
pub mod encrypt;
pub mod sign;
pub mod inspect;
pub mod key;
pub mod keyring;
pub mod import;
pub mod export;
pub mod net;
pub mod packet;
pub mod verify;

21
src/commands/cert.rs Normal file
View File

@ -0,0 +1,21 @@
//! Operations on certs.
use crate::{
Config,
Result,
cli::cert::{Command, Subcommands},
};
pub mod import;
pub mod export;
pub fn dispatch(config: Config, command: Command) -> Result<()>
{
match command.subcommand {
Subcommands::Import(command) =>
import::dispatch(config, command),
Subcommands::Export(command) =>
export::dispatch(config, command),
}
}

View File

@ -19,7 +19,7 @@ use crate::{
print_error_chain,
};
use crate::cli::export;
use crate::cli::cert::export;
pub fn dispatch(config: Config, cmd: export::Command) -> Result<()> {
let cert_store = config.cert_store_or_else()?;

View File

@ -17,7 +17,7 @@ use crate::{
best_effort_primary_uid,
output::sanitize::Safe,
};
use crate::cli::import;
use crate::cli::cert::import;
use crate::cli::types::FileOrStdin;

View File

@ -1128,18 +1128,12 @@ fn main() -> Result<()> {
commands::keyring::dispatch(config, command)?
},
SqSubcommands::Import(command) => {
commands::import::dispatch(config, command)?
},
SqSubcommands::Export(command) => {
commands::export::dispatch(config, command)?
},
SqSubcommands::Packet(command) => {
commands::packet::dispatch(config, command)?
},
SqSubcommands::Cert(command) =>
commands::cert::dispatch(config, command)?,
SqSubcommands::Key(command) => {
commands::key::dispatch(config, command)?
}

View File

@ -569,7 +569,7 @@ fn sq_certify_using_cert_store() -> Result<()>
// Import bob's (but not alice's!).
let mut cmd = Command::cargo_bin("sq")?;
cmd.args(["--cert-store", &certd,
"import", &bob_pgp]);
"cert", "import", &bob_pgp]);
cmd.assert().success();

View File

@ -47,7 +47,7 @@ mod integration {
// Import the key.
let mut cmd = Command::cargo_bin("sq")?;
cmd.args(["--cert-store", &certd,
"import", &key_pgp]);
"cert", "import", &key_pgp]);
cmd.assert().success();
const MESSAGE: &str = "\na secret message\n\nor two\n";
@ -140,12 +140,12 @@ mod integration {
// Import the certificates.
let mut cmd = Command::cargo_bin("sq")?;
cmd.args(["--cert-store", &certd,
"import", &alice_pgp]);
"cert", "import", &alice_pgp]);
cmd.assert().success();
let mut cmd = Command::cargo_bin("sq")?;
cmd.args(["--cert-store", &certd,
"import", &bob_pgp]);
"cert", "import", &bob_pgp]);
cmd.assert().success();
const MESSAGE: &[u8] = &[0x42; 24 * 1024 + 23];
@ -238,7 +238,7 @@ mod integration {
userid, stdout, stderr);
let mut cmd = Command::cargo_bin("sq")?;
cmd.args(["--cert-store", &certd,
"import"])
"cert", "import"])
.write_stdin(stdout.as_bytes());
cmd.assert().success();
}
@ -397,7 +397,7 @@ mod integration {
// Import Alice's certificate.
let mut cmd = Command::cargo_bin("sq")?;
cmd.args(["--cert-store", &certd,
"import", &alice_pgp]);
"cert", "import", &alice_pgp]);
let output = cmd.output().expect("success");
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);

View File

@ -75,7 +75,7 @@ mod integration {
let mut cmd = Command::cargo_bin("sq")?;
cmd.args(["--cert-store", &certd,
"import",
"cert", "import",
&data.filename]);
cmd.assert().success();
}
@ -126,14 +126,14 @@ mod integration {
let call = |args: &[&str], success: bool, data: &[&Data]| {
let mut cmd = Command::cargo_bin("sq").unwrap();
cmd.args(["--cert-store", &certd,
"export"]);
"cert", "export"]);
cmd.args(args);
let args = args.iter()
.map(|s| format!("{:?}", s))
.collect::<Vec<_>>()
.join(" ");
eprintln!("sq export {}...", args);
eprintln!("sq cert export {}...", args);
let output = cmd.output().expect("success");
let stdout = String::from_utf8_lossy(&output.stdout);
@ -141,13 +141,13 @@ mod integration {
if success {
assert!(output.status.success(),
"sq export {} should succeed\n\
"sq cert export {} should succeed\n\
stdout:\n{}\nstderr:\n{}",
args, stdout, stderr);
check(data, stdout, stderr);
} else {
assert!(! output.status.success(),
"sq export {} should fail\n\
"sq cert export {} should fail\n\
stdout:\n{}\nstderr:\n{}",
args, stdout, stderr);
check(&[], stdout, stderr);

View File

@ -58,12 +58,12 @@ fn sq_import() -> Result<()>
// Import.
let mut cmd = Command::cargo_bin("sq").unwrap();
cmd.args(["--cert-store", &certd, "import"]);
cmd.args(["--cert-store", &certd, "cert", "import"]);
cmd.args(files);
if let Some(stdin) = stdin {
cmd.write_stdin(stdin);
}
eprintln!("sq import {}{}",
eprintln!("sq cert import {}{}",
files.join(" "),
if stdin.is_some() { "<BYTES" } else { "" });
cmd.assert().success();
@ -71,16 +71,16 @@ fn sq_import() -> Result<()>
// Export.
let mut cmd = Command::cargo_bin("sq").unwrap();
cmd.args(["--cert-store", &certd, "export"]);
cmd.args(["--cert-store", &certd, "cert", "export"]);
eprintln!("sq export...");
eprintln!("sq cert export...");
let output = cmd.output().expect("success");
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(output.status.success(),
"sq export should succeed\n\
"sq cert export should succeed\n\
stdout:\n{}\nstderr:\n{}",
stdout, stderr);

View File

@ -41,7 +41,7 @@ fn now() -> chrono::DateTime<chrono::Utc> {
fn sq_import(cert_store: &str, files: &[&str], stdin: Option<&str>)
{
let mut cmd = Command::cargo_bin("sq").expect("have sq");
cmd.args(["--cert-store", cert_store, "import"]);
cmd.args(["--cert-store", cert_store, "cert", "import"]);
for file in files {
cmd.arg(file);
}

View File

@ -949,7 +949,7 @@ fn sq_sign_using_cert_store() -> Result<()> {
// Import it.
let mut cmd = Command::cargo_bin("sq")?;
cmd.args(["--cert-store", &certd,
"import", &alice_pgp]);
"cert", "import", &alice_pgp]);
cmd.assert().success();
@ -1079,7 +1079,7 @@ fn sq_verify_wot() -> Result<()> {
// Imports a certificate.
let sq_import = |cert_store: &str, files: &[&str], stdin: Option<&str>| {
let mut cmd = Command::cargo_bin("sq").expect("have sq");
cmd.args(["--cert-store", cert_store, "import"]);
cmd.args(["--cert-store", cert_store, "cert", "import"]);
for file in files {
cmd.arg(file);
}