Add support for using a key store.
- Support using keys managed by `sequoia-keystore`. - When decrypting a message, have `sq` automatically ask the key store to decrypt the PKESKs. - Extend `sq sign` and `sq encrypt` with the `--signer-key` parameter to use a key managed by the keystore. - Add two top-level options: `--no-key-store`, which disables the use of the key store, and `--key-store`, which uses an alternate key store instance. - Add `sq key list` to list keys on the key store.
This commit is contained in:
parent
c8567714e5
commit
27093c1709
184
Cargo.lock
generated
184
Cargo.lock
generated
@ -288,6 +288,17 @@ version = "2.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
|
||||
|
||||
[[package]]
|
||||
name = "blanket"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0b121a9fe0df916e362fb3271088d071159cdf11db0e4182d02152850756eff"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
@ -403,6 +414,45 @@ dependencies = [
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "capnp"
|
||||
version = "0.18.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "384b671a5b39eadb909b0c2b81d22a400d446526e651e64be9eb6674b33644a4"
|
||||
dependencies = [
|
||||
"embedded-io",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "capnp-futures"
|
||||
version = "0.18.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8697b857f5b014ff378f02817426d3b6fb90a69f32e330fe010f24fe10cf8f1"
|
||||
dependencies = [
|
||||
"capnp",
|
||||
"futures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "capnp-rpc"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94b87a9e0f74600628e227d39b79ef8652c558a408999ac46ba22b19dbad0010"
|
||||
dependencies = [
|
||||
"capnp",
|
||||
"capnp-futures",
|
||||
"futures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "capnpc"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a642faaaa78187e70bdcc0014c593c213553cfeda3b15054426d0d596048b131"
|
||||
dependencies = [
|
||||
"capnp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cast5"
|
||||
version = "0.11.1"
|
||||
@ -696,6 +746,16 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30d2b3721e861707777e3195b0158f950ae6dc4a27e4d02ff9f67e3eb3de199e"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctr"
|
||||
version = "0.9.2"
|
||||
@ -991,6 +1051,12 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-io"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "658bbadc628dc286b9ae02f0cb0f5411c056eb7487b72f0083203f115de94060"
|
||||
|
||||
[[package]]
|
||||
name = "ena"
|
||||
version = "0.14.2"
|
||||
@ -1234,6 +1300,21 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.30"
|
||||
@ -1241,6 +1322,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1249,6 +1331,17 @@ version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.30"
|
||||
@ -1284,9 +1377,13 @@ version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
@ -2356,6 +2453,12 @@ dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
@ -3043,6 +3146,84 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sequoia-ipc"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94fd8161ea44e9802c622e4cf088a6e9854baa573d1638f40600f76af90a9194"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"buffered-reader",
|
||||
"capnp-rpc",
|
||||
"crossbeam-utils",
|
||||
"ctor",
|
||||
"dirs",
|
||||
"fs2",
|
||||
"futures",
|
||||
"lalrpop",
|
||||
"lalrpop-util",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"memsec",
|
||||
"rand",
|
||||
"sequoia-openpgp",
|
||||
"socket2",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sequoia-keystore"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df8e6116f15b027cc5cc23093985cad774fa72671bf643813f9ef331765e9da6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"capnp",
|
||||
"capnpc",
|
||||
"dirs",
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"paste",
|
||||
"sequoia-ipc",
|
||||
"sequoia-keystore-backend",
|
||||
"sequoia-keystore-softkeys",
|
||||
"sequoia-openpgp",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sequoia-keystore-backend"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aaef68a858310acd7557868cf35ad4a394e155a1d6e5de8e7c651cb07e6f96fb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"blanket",
|
||||
"sequoia-openpgp",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sequoia-keystore-softkeys"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d24b52535e007fdefb5559902cf186fa5c2e4709d65e2ab8a99bf2fc320eccaa"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"dirs",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"sequoia-keystore-backend",
|
||||
"sequoia-openpgp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sequoia-net"
|
||||
version = "0.28.0"
|
||||
@ -3163,12 +3344,14 @@ dependencies = [
|
||||
"indicatif",
|
||||
"itertools",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"predicates",
|
||||
"regex",
|
||||
"roff",
|
||||
"rpassword",
|
||||
"sequoia-autocrypt",
|
||||
"sequoia-cert-store",
|
||||
"sequoia-keystore",
|
||||
"sequoia-net",
|
||||
"sequoia-openpgp",
|
||||
"sequoia-policy-config",
|
||||
@ -3791,6 +3974,7 @@ checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
|
@ -42,7 +42,9 @@ clap = { version = "4", features = ["derive", "env", "string", "wrap_help"] }
|
||||
humantime = "2"
|
||||
indicatif = "0.17"
|
||||
itertools = ">=0.10, <0.13"
|
||||
once_cell = "1.17"
|
||||
sequoia-cert-store = "0.4.2"
|
||||
sequoia-keystore = { version = "0.1" }
|
||||
sequoia-wot = "0.9"
|
||||
tempfile = "3.1"
|
||||
tokio = { version = "1.13.1" }
|
||||
|
12
NEWS
12
NEWS
@ -27,6 +27,18 @@
|
||||
write the assets to a predictable location, set the environment
|
||||
variable `ASSET_OUT_DIR` to a suitable location.
|
||||
|
||||
- `sq` now uses `sequoia-keystore` for secret key operations.
|
||||
|
||||
When decrypting a message, `sq` will automatically ask the
|
||||
keystore to decrypt the message. `sq sign --signer-key` can be
|
||||
used to specify a signing key managed by the key store.
|
||||
|
||||
- New top-level option: `sq --no-key-store`: A new switch to
|
||||
disable the use of the key store.
|
||||
|
||||
- New top-level option: `sq --key-store`: A new option to use an
|
||||
alternate key store.
|
||||
|
||||
* Changes in 0.32.0
|
||||
** New functionality
|
||||
- Support for password-encrypted keys has been improved. For
|
||||
|
554
sq-subplot.md
554
sq-subplot.md
File diff suppressed because it is too large
Load Diff
@ -137,6 +137,12 @@ pub struct Command {
|
||||
help = "Signs the message using the key in KEY_FILE",
|
||||
)]
|
||||
pub signer_key_file: Vec<PathBuf>,
|
||||
#[clap(
|
||||
long = "signer-key",
|
||||
value_name = "KEYID|FINGERPRINT",
|
||||
help = "Signs the message using the specified key on the key store",
|
||||
)]
|
||||
pub signer_key: Vec<KeyHandle>,
|
||||
#[clap(
|
||||
long = "private-key-store",
|
||||
value_name = "KEY_STORE",
|
||||
|
@ -167,6 +167,7 @@ macro_rules! test_examples {
|
||||
Command::cargo_bin(command[0]).unwrap()
|
||||
.current_dir(&tmp_dir)
|
||||
.env("SQ_CERT_STORE", &cert_store)
|
||||
.arg("--no-key-store")
|
||||
.args(&command[1..])
|
||||
.assert()
|
||||
.success();
|
||||
|
@ -18,6 +18,11 @@ use crate::cli::types::FileOrStdin;
|
||||
use crate::cli::types::FileOrStdout;
|
||||
use crate::cli::types::Time;
|
||||
|
||||
use crate::cli::examples;
|
||||
use examples::Action;
|
||||
use examples::Actions;
|
||||
use examples::Example;
|
||||
|
||||
pub mod expire;
|
||||
|
||||
/// The revocation reason for a certificate or subkey
|
||||
@ -80,6 +85,7 @@ pub struct Command {
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum Subcommands {
|
||||
List(ListCommand),
|
||||
Generate(GenerateCommand),
|
||||
Password(PasswordCommand),
|
||||
Expire(expire::Command),
|
||||
@ -93,6 +99,27 @@ pub enum Subcommands {
|
||||
Adopt(AdoptCommand),
|
||||
}
|
||||
|
||||
const LIST_EXAMPLES: Actions = Actions {
|
||||
actions: &[
|
||||
Action::Example(Example {
|
||||
comment: "\
|
||||
Lists the keys managed by the keystore server.",
|
||||
command: &[
|
||||
"sq", "key", "list",
|
||||
],
|
||||
}),
|
||||
]
|
||||
};
|
||||
test_examples!(sq_key_list, LIST_EXAMPLES);
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
#[clap(
|
||||
about = "Lists keys managed by the key store",
|
||||
after_help = LIST_EXAMPLES,
|
||||
)]
|
||||
pub struct ListCommand {
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
#[clap(
|
||||
about = "Generates a new key",
|
||||
|
@ -146,7 +146,9 @@ pub fn build() -> Command {
|
||||
Functionality is grouped and available using subcommands. This
|
||||
interface is not completely stateless. In particular, the user's
|
||||
default certificate store is used. This can be disabled using
|
||||
`--no-cert-store`.
|
||||
`--no-cert-store`. Similarly, a key store is used to manage and
|
||||
protect secret key material. This can be disabled using
|
||||
`--no-key-store`.
|
||||
|
||||
OpenPGP data can be provided in binary or ASCII armored form. This
|
||||
will be handled automatically. Emitted OpenPGP data is ASCII armored
|
||||
@ -172,6 +174,33 @@ pub struct SqCommand {
|
||||
help = "Overwrites existing files"
|
||||
)]
|
||||
pub force: bool,
|
||||
#[clap(
|
||||
long,
|
||||
help = "Disables the use of the key store.",
|
||||
long_help = "\
|
||||
Disables the use of the key store.
|
||||
|
||||
It is still possible to use functionality that does not require the
|
||||
key store."
|
||||
)]
|
||||
pub no_key_store: bool,
|
||||
#[clap(
|
||||
long,
|
||||
value_name = "PATH",
|
||||
env = "SQ_KEY_STORE",
|
||||
conflicts_with_all = &[ "no_key_store" ],
|
||||
help = "Overrides the key store server and its data",
|
||||
long_help = "\
|
||||
A key store server manages and protects secret key material. By
|
||||
default, `sq` connects to the key store server listening on
|
||||
`$XDG_DATA_HOME/sequoia`. If no key store server is running, one is
|
||||
started.
|
||||
|
||||
This option causes `sq` to use an alternate key store server. If
|
||||
necessary, a key store server is started, and configured to look for
|
||||
its data in the specified location."
|
||||
)]
|
||||
pub key_store: Option<PathBuf>,
|
||||
#[clap(
|
||||
long,
|
||||
global = true,
|
||||
|
@ -4,6 +4,9 @@ use std::path::PathBuf;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
use sequoia_openpgp as openpgp;
|
||||
use openpgp::KeyHandle;
|
||||
|
||||
use super::types::ClapData;
|
||||
use super::types::FileOrStdin;
|
||||
use super::types::FileOrStdout;
|
||||
@ -118,6 +121,12 @@ pub struct Command {
|
||||
help = "Signs the message using the key in KEY_FILE",
|
||||
)]
|
||||
pub secret_key_file: Vec<PathBuf>,
|
||||
#[clap(
|
||||
long = "signer-key",
|
||||
value_name = "KEYID|FINGERPRINT",
|
||||
help = "Signs the message using the specified key on the key store",
|
||||
)]
|
||||
pub signer_key: Vec<KeyHandle>,
|
||||
#[clap(
|
||||
long,
|
||||
value_names = &["NAME", "VALUE"],
|
||||
|
@ -19,6 +19,8 @@ use openpgp::parse::stream::{
|
||||
VerificationHelper, DecryptionHelper, DecryptorBuilder, MessageStructure,
|
||||
};
|
||||
|
||||
use sequoia_keystore as keystore;
|
||||
|
||||
use crate::{
|
||||
cli,
|
||||
commands::{
|
||||
@ -200,6 +202,24 @@ impl<'a, 'certdb> Helper<'a, 'certdb> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if a session key can decrypt the packet parser using
|
||||
/// `decrypt`.
|
||||
fn try_session_key<D>(&self, keyid: &KeyID,
|
||||
algo: SymmetricAlgorithm, sk: SessionKey,
|
||||
decrypt: &mut D)
|
||||
-> Option<Option<Fingerprint>>
|
||||
where D: FnMut(SymmetricAlgorithm, &SessionKey) -> bool
|
||||
{
|
||||
if decrypt(algo, &sk) {
|
||||
if self.dump_session_key {
|
||||
wprintln!("Session key: {}", hex::encode(&sk));
|
||||
}
|
||||
Some(self.key_identities.get(keyid).cloned())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Tries to decrypt the given PKESK packet with `keypair` and try
|
||||
/// to decrypt the packet parser using `decrypt`.
|
||||
fn try_decrypt<D>(&self, pkesk: &PKESK,
|
||||
@ -210,19 +230,8 @@ impl<'a, 'certdb> Helper<'a, 'certdb> {
|
||||
where D: FnMut(SymmetricAlgorithm, &SessionKey) -> bool
|
||||
{
|
||||
let keyid = keypair.public().fingerprint().into();
|
||||
match pkesk.decrypt(&mut *keypair, sym_algo)
|
||||
.and_then(|(algo, sk)| {
|
||||
if decrypt(algo, &sk) { Some(sk) } else { None }
|
||||
})
|
||||
{
|
||||
Some(sk) => {
|
||||
if self.dump_session_key {
|
||||
wprintln!("Session key: {}", hex::encode(&sk));
|
||||
}
|
||||
Some(self.key_identities.get(&keyid).cloned())
|
||||
},
|
||||
None => None,
|
||||
}
|
||||
let (sym_algo, sk) = pkesk.decrypt(&mut *keypair, sym_algo)?;
|
||||
self.try_session_key(&keyid, sym_algo, sk, decrypt)
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,6 +270,9 @@ impl<'a, 'certdb> DecryptionHelper for Helper<'a, 'certdb> {
|
||||
}
|
||||
}
|
||||
|
||||
// Now, we try the secret keys that the user supplied on the
|
||||
// command line.
|
||||
|
||||
// First, we try those keys that we can use without prompting
|
||||
// for a password.
|
||||
for pkesk in pkesks {
|
||||
@ -365,6 +377,63 @@ impl<'a, 'certdb> DecryptionHelper for Helper<'a, 'certdb> {
|
||||
}
|
||||
}
|
||||
|
||||
// Try the key store.
|
||||
match self.vhelper.config.key_store_or_else() {
|
||||
Ok(ks) => {
|
||||
let mut ks = ks.lock().unwrap();
|
||||
match ks.decrypt(&pkesks[..]) {
|
||||
// Success!
|
||||
Ok((_i, fpr, sym_algo, sk)) => {
|
||||
if let Some(fp) =
|
||||
self.try_session_key(
|
||||
&KeyID::from(fpr), sym_algo, sk, &mut decrypt)
|
||||
{
|
||||
return Ok(fp);
|
||||
}
|
||||
}
|
||||
|
||||
Err(err) => {
|
||||
match err.downcast() {
|
||||
Ok(keystore::Error::InaccessibleDecryptionKey(keys)) => {
|
||||
for key_status in keys.into_iter() {
|
||||
let pkesk = key_status.pkesk().clone();
|
||||
let mut key = key_status.into_key();
|
||||
let keyid = key.keyid();
|
||||
|
||||
let keypair = loop {
|
||||
let password = rpassword::prompt_password(
|
||||
format!(
|
||||
"Enter password to unlock {}: ",
|
||||
keyid))?
|
||||
.into();
|
||||
|
||||
if let Ok(()) = key.unlock(password) {
|
||||
break Box::new(key);
|
||||
} else {
|
||||
wprintln!("Bad password.");
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(fp) = self.try_decrypt(
|
||||
&pkesk, sym_algo, keypair, &mut decrypt)
|
||||
{
|
||||
return Ok(fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Failed to decrypt using the keystore.
|
||||
Ok(_err) => (),
|
||||
Err(_err) => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
wprintln!("Warning: unable to connect to keystore: {}",
|
||||
err);
|
||||
}
|
||||
}
|
||||
|
||||
if skesks.is_empty() {
|
||||
return
|
||||
Err(anyhow::anyhow!("No key to decrypt message"));
|
||||
|
@ -9,6 +9,9 @@ use sequoia_openpgp as openpgp;
|
||||
use openpgp::armor;
|
||||
use openpgp::cert::amalgamation::ValidAmalgamation;
|
||||
use openpgp::crypto;
|
||||
use openpgp::crypto::Password;
|
||||
use openpgp::KeyHandle;
|
||||
use openpgp::KeyID;
|
||||
use openpgp::policy::Policy;
|
||||
use openpgp::serialize::stream::Compressor;
|
||||
use openpgp::serialize::stream::Encryptor2 as Encryptor;
|
||||
@ -21,6 +24,7 @@ use openpgp::serialize::stream::padding::Padder;
|
||||
use openpgp::types::CompressionAlgorithm;
|
||||
use openpgp::types::KeyFlags;
|
||||
|
||||
use crate::best_effort_primary_uid;
|
||||
use crate::cli;
|
||||
use crate::cli::types::EncryptPurpose;
|
||||
use crate::cli::types::FileOrStdin;
|
||||
@ -61,8 +65,10 @@ pub fn dispatch(config: Config, command: cli::encrypt::Command) -> Result<()> {
|
||||
|
||||
let additional_secrets =
|
||||
load_certs(command.signer_key_file.iter().map(|s| s.as_ref()))?;
|
||||
let signer_keys = &command.signer_key[..];
|
||||
|
||||
encrypt(
|
||||
&config,
|
||||
&config.policy,
|
||||
command.private_key_store.as_deref(),
|
||||
command.input,
|
||||
@ -70,6 +76,7 @@ pub fn dispatch(config: Config, command: cli::encrypt::Command) -> Result<()> {
|
||||
command.symmetric as usize,
|
||||
&recipients,
|
||||
additional_secrets,
|
||||
signer_keys,
|
||||
command.mode,
|
||||
command.compression,
|
||||
Some(config.time),
|
||||
@ -82,6 +89,7 @@ pub fn dispatch(config: Config, command: cli::encrypt::Command) -> Result<()> {
|
||||
}
|
||||
|
||||
pub fn encrypt<'a, 'b: 'a>(
|
||||
config: &Config,
|
||||
policy: &'b dyn Policy,
|
||||
private_key_store: Option<&str>,
|
||||
input: FileOrStdin,
|
||||
@ -89,6 +97,7 @@ pub fn encrypt<'a, 'b: 'a>(
|
||||
npasswords: usize,
|
||||
recipients: &'b [openpgp::Cert],
|
||||
signers: Vec<openpgp::Cert>,
|
||||
signer_keys: &[KeyHandle],
|
||||
mode: EncryptPurpose,
|
||||
compression: CompressionMode,
|
||||
time: Option<SystemTime>,
|
||||
@ -125,6 +134,75 @@ pub fn encrypt<'a, 'b: 'a>(
|
||||
let mut signers = get_signing_keys(
|
||||
&signers, policy, private_key_store, time, None)?;
|
||||
|
||||
let mut signer_keys = if signer_keys.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
let mut ks = config.key_store_or_else()?.lock().unwrap();
|
||||
|
||||
signer_keys.into_iter()
|
||||
.map(|kh| {
|
||||
let keys = ks.find_key(kh.clone())?;
|
||||
|
||||
match keys.len() {
|
||||
0 => return Err(anyhow::anyhow!(
|
||||
"{} is not present on keystore", kh)),
|
||||
1 => (),
|
||||
n => {
|
||||
eprintln!("Warning: {} is present on multiple \
|
||||
({}) devices",
|
||||
kh, n);
|
||||
}
|
||||
}
|
||||
let mut key = keys.into_iter().next().expect("checked for one");
|
||||
|
||||
match key.locked() {
|
||||
Ok(true) => {
|
||||
let fpr = key.fingerprint();
|
||||
let cert = config.lookup_one(
|
||||
&KeyHandle::from(&fpr), None, true);
|
||||
let display = match cert {
|
||||
Ok(cert) => {
|
||||
format!(" ({})",
|
||||
String::from_utf8_lossy(
|
||||
best_effort_primary_uid(
|
||||
&cert, &config.policy,
|
||||
config.time)
|
||||
.value()))
|
||||
}
|
||||
Err(_) => {
|
||||
"".to_string()
|
||||
}
|
||||
};
|
||||
let keyid = KeyID::from(&fpr);
|
||||
|
||||
loop {
|
||||
let password = Password::from(rpassword::prompt_password(
|
||||
format!("Enter password to unlock {}{}: ",
|
||||
keyid, display))?);
|
||||
match key.unlock(password) {
|
||||
Ok(()) => break,
|
||||
Err(err) => {
|
||||
wprintln!("Unlocking {}: {}.", keyid, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(false) => {
|
||||
// Already unlocked, nothing to do.
|
||||
}
|
||||
Err(err) => {
|
||||
// Failed to get the key's locked status. Just print
|
||||
// a warning now. We'll (probably) fail more later.
|
||||
wprintln!("Getting {}'s status: {}",
|
||||
key.keyid(), err);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(key)
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?
|
||||
};
|
||||
|
||||
// Build a vector of recipients to hand to Encryptor.
|
||||
let mut recipient_subkeys: Vec<Recipient> = Vec::new();
|
||||
for cert in recipients.iter() {
|
||||
@ -188,13 +266,20 @@ pub fn encrypt<'a, 'b: 'a>(
|
||||
}
|
||||
|
||||
// Optionally sign message.
|
||||
if ! signers.is_empty() {
|
||||
let mut signer = Signer::new(sink, signers.pop().unwrap().0);
|
||||
if ! signers.is_empty() || ! signer_keys.is_empty() {
|
||||
let mut signer = if ! signers.is_empty() {
|
||||
Signer::new(sink, signers.pop().unwrap().0)
|
||||
} else {
|
||||
Signer::new(sink, signer_keys.pop().unwrap())
|
||||
};
|
||||
if let Some(time) = time {
|
||||
signer = signer.creation_time(time);
|
||||
}
|
||||
for s in signers {
|
||||
signer = signer.add_signer(s.0);
|
||||
if let Some(time) = time {
|
||||
signer = signer.creation_time(time);
|
||||
}
|
||||
}
|
||||
for s in signer_keys {
|
||||
signer = signer.add_signer(s);
|
||||
}
|
||||
for r in recipients.iter() {
|
||||
signer = signer.add_intended_recipient(r);
|
||||
|
@ -11,6 +11,8 @@ use attest_certifications::attest_certifications;
|
||||
mod expire;
|
||||
mod extract_cert;
|
||||
use extract_cert::extract_cert;
|
||||
mod list;
|
||||
use list::list;
|
||||
mod generate;
|
||||
use generate::generate;
|
||||
mod password;
|
||||
@ -24,6 +26,7 @@ pub fn dispatch(config: Config, command: cli::key::Command) -> Result<()>
|
||||
{
|
||||
use cli::key::Subcommands::*;
|
||||
match command.subcommand {
|
||||
List(c) => list(config, c)?,
|
||||
Generate(c) => generate(config, c)?,
|
||||
Password(c) => password(config, c)?,
|
||||
Expire(c) => expire::dispatch(config, c)?,
|
||||
|
79
src/commands/key/list.rs
Normal file
79
src/commands/key/list.rs
Normal file
@ -0,0 +1,79 @@
|
||||
use sequoia_openpgp as openpgp;
|
||||
use openpgp::KeyHandle;
|
||||
|
||||
use crate::best_effort_primary_uid;
|
||||
use crate::cli;
|
||||
use crate::Config;
|
||||
use crate::Result;
|
||||
|
||||
pub fn list(config: Config, _command: cli::key::ListCommand) -> Result<()> {
|
||||
// Start and connect to the keystore.
|
||||
let ks = if let Some(ks) = config.key_store()? {
|
||||
ks
|
||||
} else {
|
||||
// The key store is disabled. Don't fail, just return
|
||||
// nothing.
|
||||
return Ok(());
|
||||
};
|
||||
let mut ks = ks.lock().unwrap();
|
||||
|
||||
let mut backends = ks.backends()?;
|
||||
for backend in &mut backends {
|
||||
let devices = backend.list()?;
|
||||
if devices.len() == 0 {
|
||||
println!(" - Backend {} has no devices.", backend.id()?);
|
||||
} else {
|
||||
println!(" - {}", backend.id()?);
|
||||
}
|
||||
|
||||
for mut device in devices {
|
||||
let keys = device.list()?;
|
||||
if keys.len() == 0 {
|
||||
println!(" - Device {} has no keys.", device.id()?);
|
||||
} else {
|
||||
println!(" - {}", device.id()?);
|
||||
}
|
||||
|
||||
for mut key in keys.into_iter() {
|
||||
let fpr = KeyHandle::from(key.fingerprint());
|
||||
|
||||
let userid = if let Ok(cert) = config.lookup_one(&fpr, None, true) {
|
||||
best_effort_primary_uid(&cert, &config.policy, None).to_string()
|
||||
} else {
|
||||
"(Unknown)".to_string()
|
||||
};
|
||||
|
||||
let signing_capable = key.signing_capable().unwrap_or(false);
|
||||
let decryption_capable = key.decryption_capable().unwrap_or(false);
|
||||
println!(" - {} {} ({}, {}, {})",
|
||||
fpr, userid,
|
||||
if key.available().unwrap_or(false) {
|
||||
"available"
|
||||
} else {
|
||||
"not available"
|
||||
},
|
||||
if key.locked().unwrap_or(false) {
|
||||
"locked"
|
||||
} else {
|
||||
"not locked"
|
||||
},
|
||||
match (signing_capable, decryption_capable) {
|
||||
(true, true) => {
|
||||
"for signing and decryption"
|
||||
}
|
||||
(true, false) => {
|
||||
"for signing"
|
||||
}
|
||||
(false, true) => {
|
||||
"for decryption"
|
||||
}
|
||||
(false, false) => {
|
||||
"unusable"
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
@ -7,6 +7,9 @@ use tempfile::NamedTempFile;
|
||||
|
||||
use sequoia_openpgp as openpgp;
|
||||
use openpgp::armor;
|
||||
use openpgp::crypto::Password;
|
||||
use openpgp::KeyHandle;
|
||||
use openpgp::KeyID;
|
||||
use openpgp::{Packet, Result};
|
||||
use openpgp::packet::prelude::*;
|
||||
use openpgp::packet::signature::subpacket::NotationData;
|
||||
@ -20,6 +23,7 @@ use openpgp::serialize::stream::{
|
||||
};
|
||||
use openpgp::types::SignatureType;
|
||||
|
||||
use crate::best_effort_primary_uid;
|
||||
use crate::Config;
|
||||
use crate::load_certs;
|
||||
use crate::parse_notations;
|
||||
@ -47,6 +51,7 @@ pub fn dispatch(config: Config, command: cli::sign::Command) -> Result<()> {
|
||||
let private_key_store = command.private_key_store.as_deref();
|
||||
let secrets =
|
||||
load_certs(command.secret_key_file.iter().map(|s| s.as_ref()))?;
|
||||
let signer_keys = &command.signer_key[..];
|
||||
let time = Some(config.time);
|
||||
|
||||
let notations = parse_notations(command.notation)?;
|
||||
@ -70,6 +75,7 @@ pub fn dispatch(config: Config, command: cli::sign::Command) -> Result<()> {
|
||||
&mut input,
|
||||
output,
|
||||
secrets,
|
||||
signer_keys,
|
||||
detached,
|
||||
binary,
|
||||
append,
|
||||
@ -87,6 +93,7 @@ pub fn sign<'a, 'certdb>(
|
||||
input: &'a mut (dyn io::Read + Sync + Send),
|
||||
output: &'a FileOrStdout,
|
||||
secrets: Vec<openpgp::Cert>,
|
||||
signer_keys: &[KeyHandle],
|
||||
detached: bool,
|
||||
binary: bool,
|
||||
append: bool,
|
||||
@ -102,6 +109,7 @@ pub fn sign<'a, 'certdb>(
|
||||
input,
|
||||
output,
|
||||
secrets,
|
||||
signer_keys,
|
||||
detached,
|
||||
binary,
|
||||
append,
|
||||
@ -126,6 +134,7 @@ fn sign_data<'a, 'certdb>(
|
||||
input: &'a mut (dyn io::Read + Sync + Send),
|
||||
output_path: &'a FileOrStdout,
|
||||
secrets: Vec<openpgp::Cert>,
|
||||
signer_keys: &[KeyHandle],
|
||||
detached: bool,
|
||||
binary: bool,
|
||||
append: bool,
|
||||
@ -169,7 +178,77 @@ fn sign_data<'a, 'certdb>(
|
||||
|
||||
let mut keypairs = super::get_signing_keys(
|
||||
&secrets, &config.policy, private_key_store, time, None)?;
|
||||
if keypairs.is_empty() {
|
||||
|
||||
let mut signer_keys = if signer_keys.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
let mut ks = config.key_store_or_else()?.lock().unwrap();
|
||||
|
||||
signer_keys.into_iter()
|
||||
.map(|kh| {
|
||||
let keys = ks.find_key(kh.clone())?;
|
||||
|
||||
match keys.len() {
|
||||
0 => return Err(anyhow::anyhow!(
|
||||
"{} is not present on keystore", kh)),
|
||||
1 => (),
|
||||
n => {
|
||||
eprintln!("Warning: {} is present on multiple \
|
||||
({}) devices",
|
||||
kh, n);
|
||||
}
|
||||
}
|
||||
let mut key = keys.into_iter().next().expect("checked for one");
|
||||
|
||||
match key.locked() {
|
||||
Ok(true) => {
|
||||
let fpr = key.fingerprint();
|
||||
let cert = config.lookup_one(
|
||||
&KeyHandle::from(&fpr), None, true);
|
||||
let display = match cert {
|
||||
Ok(cert) => {
|
||||
format!(" ({})",
|
||||
String::from_utf8_lossy(
|
||||
best_effort_primary_uid(
|
||||
&cert, &config.policy,
|
||||
config.time)
|
||||
.value()))
|
||||
}
|
||||
Err(_) => {
|
||||
"".to_string()
|
||||
}
|
||||
};
|
||||
let keyid = KeyID::from(&fpr);
|
||||
|
||||
loop {
|
||||
let password = Password::from(rpassword::prompt_password(
|
||||
format!("Enter password to unlock {}{}: ",
|
||||
keyid, display))?);
|
||||
match key.unlock(password) {
|
||||
Ok(()) => break,
|
||||
Err(err) => {
|
||||
wprintln!("Unlocking {}: {}.", keyid, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(false) => {
|
||||
// Already unlocked, nothing to do.
|
||||
}
|
||||
Err(err) => {
|
||||
// Failed to get the key's locked status. Just print
|
||||
// a warning now. We'll (probably) fail more later.
|
||||
wprintln!("Getting {}'s status: {}",
|
||||
key.keyid(), err);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(key)
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?
|
||||
};
|
||||
|
||||
if keypairs.is_empty() && signer_keys.is_empty() {
|
||||
return Err(anyhow::anyhow!("No signing keys found"));
|
||||
}
|
||||
|
||||
@ -202,14 +281,26 @@ fn sign_data<'a, 'certdb>(
|
||||
*critical)?;
|
||||
}
|
||||
|
||||
let mut signer = Signer::with_template(
|
||||
message, keypairs.pop().unwrap().0, builder);
|
||||
let mut signer = if keypairs.is_empty() {
|
||||
Signer::with_template(
|
||||
message,
|
||||
signer_keys.pop().unwrap(),
|
||||
builder)
|
||||
} else {
|
||||
Signer::with_template(
|
||||
message,
|
||||
keypairs.pop().unwrap().0,
|
||||
builder)
|
||||
};
|
||||
if let Some(time) = time {
|
||||
signer = signer.creation_time(time);
|
||||
}
|
||||
for s in keypairs {
|
||||
signer = signer.add_signer(s.0);
|
||||
}
|
||||
for k in signer_keys {
|
||||
signer = signer.add_signer(k);
|
||||
}
|
||||
if detached {
|
||||
signer = signer.detached();
|
||||
}
|
||||
|
58
src/sq.rs
58
src/sq.rs
@ -9,15 +9,17 @@
|
||||
use anyhow::Context as _;
|
||||
|
||||
use std::borrow::Borrow;
|
||||
use std::cell::OnceCell;
|
||||
use std::collections::btree_map::{BTreeMap, Entry};
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use std::sync::Mutex;
|
||||
use std::time::SystemTime;
|
||||
use std::sync::Arc;
|
||||
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
use sequoia_openpgp as openpgp;
|
||||
|
||||
use openpgp::{
|
||||
@ -48,6 +50,8 @@ use cert_store::store::UserIDQueryParams;
|
||||
use sequoia_wot as wot;
|
||||
use wot::store::Store as _;
|
||||
|
||||
use sequoia_keystore as keystore;
|
||||
|
||||
use clap::FromArgMatches;
|
||||
|
||||
#[macro_use] mod macros;
|
||||
@ -332,6 +336,11 @@ pub struct Config<'a> {
|
||||
trust_roots: Vec<Fingerprint>,
|
||||
// The local trust root, as set in the cert store.
|
||||
trust_root_local: OnceCell<Option<Fingerprint>>,
|
||||
|
||||
// The key store.
|
||||
no_key_store: bool,
|
||||
key_store_path: Option<PathBuf>,
|
||||
key_store: OnceCell<Mutex<keystore::Keystore>>,
|
||||
}
|
||||
|
||||
impl<'store> Config<'store> {
|
||||
@ -542,6 +551,50 @@ impl<'store> Config<'store> {
|
||||
.ok_or_else(|| anyhow::anyhow!(NO_CERTD_ERR))
|
||||
}
|
||||
|
||||
|
||||
/// Returns the key store.
|
||||
///
|
||||
/// If the key store is disabled, returns `Ok(None)`. If it is not yet
|
||||
/// open, opens it.
|
||||
fn key_store(&self) -> Result<Option<&Mutex<keystore::Keystore>>> {
|
||||
if self.no_key_store {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
self.key_store
|
||||
.get_or_try_init(|| {
|
||||
let dir_;
|
||||
let dir = if let Some(dir) = self.key_store_path.as_ref() {
|
||||
dir
|
||||
} else if let Some(dir) = dirs::data_dir() {
|
||||
dir_ = dir.join("sequoia");
|
||||
&dir_
|
||||
} else {
|
||||
return Err(anyhow::anyhow!(
|
||||
"No key store, the XDG data directory is not defined"));
|
||||
};
|
||||
|
||||
let c = keystore::Context::configure()
|
||||
.home(dir)
|
||||
.build()?;
|
||||
let ks = keystore::Keystore::connect(&c)
|
||||
.context("Connecting to key store")?;
|
||||
|
||||
Ok(Mutex::new(ks))
|
||||
})
|
||||
.map(Some)
|
||||
}
|
||||
|
||||
/// Returns the key store.
|
||||
///
|
||||
/// If the key store is disabled, returns an error.
|
||||
fn key_store_or_else(&self) -> Result<&Mutex<keystore::Keystore>> {
|
||||
self.key_store().and_then(|key_store| key_store.ok_or_else(|| {
|
||||
anyhow::anyhow!("Operation requires a key store, \
|
||||
but the key store is disabled")
|
||||
}))
|
||||
}
|
||||
|
||||
/// Looks up an identifier.
|
||||
///
|
||||
/// This matches on both the primary key and the subkeys.
|
||||
@ -1017,6 +1070,9 @@ fn main() -> Result<()> {
|
||||
cert_store: OnceCell::new(),
|
||||
trust_roots: c.trust_roots.clone(),
|
||||
trust_root_local: Default::default(),
|
||||
no_key_store: c.no_key_store,
|
||||
key_store_path: c.key_store.clone(),
|
||||
key_store: OnceCell::new(),
|
||||
};
|
||||
|
||||
commands::dispatch(config, c)
|
||||
|
@ -38,6 +38,7 @@ pub fn sq_key_generate(
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args([
|
||||
"--no-cert-store",
|
||||
"--no-key-store",
|
||||
"key",
|
||||
"generate",
|
||||
"--time",
|
||||
|
@ -76,6 +76,7 @@ mod integration {
|
||||
sq()
|
||||
.current_dir(&dir)
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("cert").arg("lint")
|
||||
.arg("--time").arg(FROZEN_TIME)
|
||||
.arg(filename)
|
||||
@ -110,6 +111,7 @@ mod integration {
|
||||
let mut cmd = cmd.current_dir(&dir)
|
||||
.args(&[
|
||||
"--no-cert-store",
|
||||
"--no-key-store",
|
||||
"cert", "lint",
|
||||
"--time", FROZEN_TIME,
|
||||
"--fix", &format!("{}-{}.pgp", base, suffix)
|
||||
@ -130,6 +132,7 @@ mod integration {
|
||||
Command::cargo_bin("sq").unwrap()
|
||||
.current_dir(&dir)
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("cert").arg("lint")
|
||||
.arg("--time").arg(FROZEN_TIME)
|
||||
.arg("-")
|
||||
@ -428,6 +431,7 @@ mod integration {
|
||||
.current_dir(&dir())
|
||||
.args(&[
|
||||
"--no-cert-store",
|
||||
"--no-key-store",
|
||||
"cert", "lint",
|
||||
"--time", FROZEN_TIME,
|
||||
"--list-keys",
|
||||
@ -448,6 +452,7 @@ mod integration {
|
||||
.current_dir(&dir())
|
||||
.args(&[
|
||||
"--no-cert-store",
|
||||
"--no-key-store",
|
||||
"cert", "lint",
|
||||
"--time", FROZEN_TIME,
|
||||
"msg.sig",
|
||||
|
@ -42,6 +42,7 @@ fn sq_certify() -> Result<()> {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("pki").arg("certify")
|
||||
.arg(alice_pgp.to_str().unwrap())
|
||||
.arg(bob_pgp.to_str().unwrap())
|
||||
@ -81,6 +82,7 @@ fn sq_certify() -> Result<()> {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("pki").arg("certify")
|
||||
.arg(alice_pgp.to_str().unwrap())
|
||||
.arg(bob_pgp.to_str().unwrap())
|
||||
@ -120,6 +122,7 @@ fn sq_certify() -> Result<()> {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("pki").arg("certify")
|
||||
.arg(alice_pgp.to_str().unwrap())
|
||||
.arg(bob_pgp.to_str().unwrap())
|
||||
@ -167,6 +170,7 @@ fn sq_certify() -> Result<()> {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("pki").arg("certify")
|
||||
.arg(alice_pgp.to_str().unwrap())
|
||||
.arg(bob_pgp.to_str().unwrap())
|
||||
@ -178,6 +182,7 @@ fn sq_certify() -> Result<()> {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("pki").arg("certify")
|
||||
.args(["--notation", "foo", "bar"])
|
||||
.args(["--notation", "!foo", "xyzzy"])
|
||||
@ -303,6 +308,7 @@ fn sq_certify_creation_time() -> Result<()>
|
||||
// Build up the command line.
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args(["--no-cert-store",
|
||||
"--no-key-store",
|
||||
"pki", "certify",
|
||||
&alice_pgp.to_string_lossy(),
|
||||
&bob_pgp.to_string_lossy(), bob,
|
||||
@ -389,6 +395,7 @@ fn sq_certify_with_expired_key() -> Result<()>
|
||||
// Make sure using an expired key fails by default.
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args(["--no-cert-store",
|
||||
"--no-key-store",
|
||||
"pki", "certify",
|
||||
&alice_pgp.to_string_lossy(),
|
||||
&bob_pgp.to_string_lossy(), bob ]);
|
||||
@ -398,6 +405,7 @@ fn sq_certify_with_expired_key() -> Result<()>
|
||||
// Try again.
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args(["--no-cert-store",
|
||||
"--no-key-store",
|
||||
"pki", "certify",
|
||||
"--allow-not-alive-certifier",
|
||||
&alice_pgp.to_string_lossy(),
|
||||
@ -483,6 +491,7 @@ fn sq_certify_with_revoked_key() -> Result<()>
|
||||
// Make sure using an expired key fails by default.
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args(["--no-cert-store",
|
||||
"--no-key-store",
|
||||
"pki", "certify",
|
||||
&alice_pgp.to_string_lossy(),
|
||||
&bob_pgp.to_string_lossy(), bob ]);
|
||||
@ -492,6 +501,7 @@ fn sq_certify_with_revoked_key() -> Result<()>
|
||||
// Try again.
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args(["--no-cert-store",
|
||||
"--no-key-store",
|
||||
"pki", "certify",
|
||||
"--allow-revoked-certifier",
|
||||
&alice_pgp.to_string_lossy(),
|
||||
|
@ -20,6 +20,7 @@ mod integration {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("decrypt")
|
||||
.args(["--session-key", "1FE820EC21FB5D7E33D83367106D1D3747DCD48E6320C1AEC57EE7D18FC437D4"])
|
||||
.arg(artifact("messages/rsa.msg.pgp"))
|
||||
@ -34,6 +35,7 @@ mod integration {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("decrypt")
|
||||
.args(["--session-key", "9:1FE820EC21FB5D7E33D83367106D1D3747DCD48E6320C1AEC57EE7D18FC437D4"])
|
||||
.arg(artifact("messages/rsa.msg.pgp"))
|
||||
@ -48,6 +50,7 @@ mod integration {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("decrypt")
|
||||
.args(["--session-key", "2FE820EC21FB5D7E33D83367106D1D3747DCD48E6320C1AEC57EE7D18FC437D4"])
|
||||
.args(["--session-key", "9:1FE820EC21FB5D7E33D83367106D1D3747DCD48E6320C1AEC57EE7D18FC437D4"])
|
||||
@ -64,6 +67,7 @@ mod integration {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("decrypt")
|
||||
.args(["--session-key", "BB9CCB8EDE22DC222C83BD1C63AEB97335DDC7B696DB171BD16EAA5784CC0478"])
|
||||
.arg(artifact("messages/rsa.msg.pgp"))
|
||||
|
@ -189,6 +189,7 @@ mod integration {
|
||||
for key in decryption_keys.iter() {
|
||||
let mut cmd = Command::cargo_bin("sq").unwrap();
|
||||
cmd.args(["--no-cert-store",
|
||||
"--no-key-store",
|
||||
"decrypt",
|
||||
"--recipient-file",
|
||||
&key])
|
||||
@ -375,6 +376,7 @@ mod integration {
|
||||
for key in decryption_keys.iter() {
|
||||
let mut cmd = Command::cargo_bin("sq").unwrap();
|
||||
cmd.args(["--no-cert-store",
|
||||
"--no-key-store",
|
||||
"decrypt",
|
||||
"--recipient-file",
|
||||
&key])
|
||||
|
@ -141,7 +141,10 @@ mod integration {
|
||||
#[test]
|
||||
fn adopt_encryption() -> Result<()> {
|
||||
// Adopt an encryption subkey.
|
||||
Command::cargo_bin("sq").unwrap().arg("--no-cert-store").arg("key").arg("adopt")
|
||||
Command::cargo_bin("sq").unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("key").arg("adopt")
|
||||
.arg(bob())
|
||||
.arg("--keyring").arg(alice())
|
||||
.arg("--key").arg(alice_encryption().0.to_hex())
|
||||
@ -157,7 +160,10 @@ mod integration {
|
||||
#[test]
|
||||
fn adopt_signing() -> Result<()> {
|
||||
// Adopt a signing subkey (subkey has secret key material).
|
||||
Command::cargo_bin("sq").unwrap().arg("--no-cert-store").arg("key").arg("adopt")
|
||||
Command::cargo_bin("sq").unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("key").arg("adopt")
|
||||
.arg(bob())
|
||||
.arg("--keyring").arg(alice())
|
||||
.arg("--key").arg(alice_signing().0.to_hex())
|
||||
@ -173,7 +179,10 @@ mod integration {
|
||||
#[test]
|
||||
fn adopt_certification() -> Result<()> {
|
||||
// Adopt a certification subkey (subkey has secret key material).
|
||||
Command::cargo_bin("sq").unwrap().arg("--no-cert-store").arg("key").arg("adopt")
|
||||
Command::cargo_bin("sq").unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("key").arg("adopt")
|
||||
.arg(carol())
|
||||
.arg("--keyring").arg(alice())
|
||||
.arg("--key").arg(alice_primary().0.to_hex())
|
||||
@ -189,7 +198,10 @@ mod integration {
|
||||
#[test]
|
||||
fn adopt_encryption_and_signing() -> Result<()> {
|
||||
// Adopt an encryption subkey and a signing subkey.
|
||||
Command::cargo_bin("sq").unwrap().arg("--no-cert-store").arg("key").arg("adopt")
|
||||
Command::cargo_bin("sq").unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("key").arg("adopt")
|
||||
.arg(bob())
|
||||
.arg("--keyring").arg(alice())
|
||||
.arg("--key").arg(alice_signing().0.to_hex())
|
||||
@ -209,7 +221,10 @@ mod integration {
|
||||
#[test]
|
||||
fn adopt_twice() -> Result<()> {
|
||||
// Adopt the same an encryption subkey twice.
|
||||
Command::cargo_bin("sq").unwrap().arg("--no-cert-store").arg("key").arg("adopt")
|
||||
Command::cargo_bin("sq").unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("key").arg("adopt")
|
||||
.arg(bob())
|
||||
.arg("--keyring").arg(alice())
|
||||
.arg("--key").arg(alice_encryption().0.to_hex())
|
||||
@ -226,7 +241,10 @@ mod integration {
|
||||
#[test]
|
||||
fn adopt_key_appears_twice() -> Result<()> {
|
||||
// Adopt the an encryption subkey that appears twice.
|
||||
Command::cargo_bin("sq").unwrap().arg("--no-cert-store").arg("key").arg("adopt")
|
||||
Command::cargo_bin("sq").unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("key").arg("adopt")
|
||||
.arg(bob())
|
||||
.arg("--keyring").arg(alice())
|
||||
.arg("--keyring").arg(alice())
|
||||
@ -243,7 +261,10 @@ mod integration {
|
||||
#[test]
|
||||
fn adopt_own_encryption() -> Result<()> {
|
||||
// Adopt its own encryption subkey. This should be a noop.
|
||||
Command::cargo_bin("sq").unwrap().arg("--no-cert-store").arg("key").arg("adopt")
|
||||
Command::cargo_bin("sq").unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("key").arg("adopt")
|
||||
.arg(alice())
|
||||
.arg("--keyring").arg(alice())
|
||||
.arg("--key").arg(alice_encryption().0.to_hex())
|
||||
@ -259,7 +280,10 @@ mod integration {
|
||||
#[test]
|
||||
fn adopt_own_primary() -> Result<()> {
|
||||
// Adopt own primary key.
|
||||
Command::cargo_bin("sq").unwrap().arg("--no-cert-store").arg("key").arg("adopt")
|
||||
Command::cargo_bin("sq").unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("key").arg("adopt")
|
||||
.arg(bob())
|
||||
.arg("--keyring").arg(bob())
|
||||
.arg("--key").arg(bob_primary().0.to_hex())
|
||||
@ -275,7 +299,10 @@ mod integration {
|
||||
#[test]
|
||||
fn adopt_missing() -> Result<()> {
|
||||
// Adopt a key that is not present.
|
||||
Command::cargo_bin("sq").unwrap().arg("--no-cert-store").arg("key").arg("adopt")
|
||||
Command::cargo_bin("sq").unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("key").arg("adopt")
|
||||
.arg(bob())
|
||||
.arg("--keyring").arg(bob())
|
||||
.arg("--key").arg("1234 5678 90AB CDEF 1234 5678 90AB CDEF")
|
||||
@ -288,7 +315,10 @@ mod integration {
|
||||
#[test]
|
||||
fn adopt_from_multiple() -> Result<()> {
|
||||
// Adopt from multiple certificates simultaneously.
|
||||
Command::cargo_bin("sq").unwrap().arg("--no-cert-store").arg("key").arg("adopt")
|
||||
Command::cargo_bin("sq").unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("key").arg("adopt")
|
||||
.arg(bob())
|
||||
.arg("--keyring").arg(alice())
|
||||
.arg("--key").arg(alice_signing().0.to_hex())
|
||||
|
@ -27,6 +27,7 @@ mod integration {
|
||||
// Build up the command line.
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args(["--no-cert-store",
|
||||
"--no-key-store",
|
||||
"key", "generate",
|
||||
"--time", iso8601,
|
||||
"--expiry", "never",
|
||||
|
@ -106,6 +106,7 @@ fn sq_key_revoke() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args([
|
||||
"--no-cert-store",
|
||||
"--no-key-store",
|
||||
"key",
|
||||
"revoke",
|
||||
"--output",
|
||||
@ -278,6 +279,7 @@ fn sq_key_revoke_thirdparty() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args([
|
||||
"--no-cert-store",
|
||||
"--no-key-store",
|
||||
"key",
|
||||
"revoke",
|
||||
"--output",
|
||||
|
@ -23,6 +23,7 @@ fn sq_key_subkey_generate_authentication_subkey() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args([
|
||||
"--no-cert-store",
|
||||
"--no-key-store",
|
||||
"key",
|
||||
"subkey",
|
||||
"add",
|
||||
@ -52,6 +53,7 @@ fn sq_key_subkey_generate_encryption_subkey() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args([
|
||||
"--no-cert-store",
|
||||
"--no-key-store",
|
||||
"key",
|
||||
"subkey",
|
||||
"add",
|
||||
@ -91,6 +93,7 @@ fn sq_key_subkey_generate_signing_subkey() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args([
|
||||
"--no-cert-store",
|
||||
"--no-key-store",
|
||||
"key",
|
||||
"subkey",
|
||||
"add",
|
||||
@ -208,6 +211,7 @@ fn sq_key_subkey_revoke() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args([
|
||||
"--no-cert-store",
|
||||
"--no-key-store",
|
||||
"key",
|
||||
"subkey",
|
||||
"revoke",
|
||||
@ -406,6 +410,7 @@ fn sq_key_subkey_revoke_thirdparty() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args([
|
||||
"--no-cert-store",
|
||||
"--no-key-store",
|
||||
"key",
|
||||
"subkey",
|
||||
"revoke",
|
||||
|
@ -78,6 +78,7 @@ fn sq_key_userid_revoke() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args([
|
||||
"--no-cert-store",
|
||||
"--no-key-store",
|
||||
"key",
|
||||
"userid",
|
||||
"revoke",
|
||||
@ -231,6 +232,7 @@ fn sq_key_userid_revoke_thirdparty() -> Result<()> {
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.args([
|
||||
"--no-cert-store",
|
||||
"--no-key-store",
|
||||
"key",
|
||||
"userid",
|
||||
"revoke",
|
||||
|
@ -60,6 +60,7 @@ fn sq_gen_key(cert_store: Option<&str>, userids: &[&str], file: &str) -> Cert
|
||||
{
|
||||
let mut cmd = Command::cargo_bin("sq").expect("have sq");
|
||||
cmd.args(["--no-cert-store",
|
||||
"--no-key-store",
|
||||
"key", "generate",
|
||||
"--time", &tick(),
|
||||
"--expiry", "never",
|
||||
@ -86,6 +87,7 @@ fn sq_verify(cert_store: Option<&str>,
|
||||
good_sigs: usize, good_checksums: usize)
|
||||
{
|
||||
let mut cmd = Command::cargo_bin("sq").expect("have sq");
|
||||
cmd.arg("--no-key-store");
|
||||
if let Some(cert_store) = cert_store {
|
||||
cmd.args(&["--cert-store", cert_store]);
|
||||
} else {
|
||||
@ -270,6 +272,7 @@ fn sq_link_add_retract() -> Result<()> {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.args(["--signer-file", &data.key_file])
|
||||
.args(["--output", &data.sig_file])
|
||||
@ -403,6 +406,7 @@ fn sq_link_add_retract() -> Result<()> {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.args(["--signer-file", &ed_pgp])
|
||||
.args(["--output", &ed_sig_file])
|
||||
@ -618,6 +622,7 @@ fn sq_link_add_temporary() -> Result<()> {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.args(["--signer-file", &alice_pgp])
|
||||
.args(["--output", &alice_sig_file])
|
||||
|
@ -20,7 +20,9 @@ mod sq_packet_decrypt {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("toolbox")
|
||||
|
||||
.arg("packet")
|
||||
.arg("decrypt")
|
||||
.args(["--session-key", "1FE820EC21FB5D7E33D83367106D1D3747DCD48E6320C1AEC57EE7D18FC437D4"])
|
||||
@ -36,7 +38,9 @@ mod sq_packet_decrypt {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("toolbox")
|
||||
|
||||
.arg("packet")
|
||||
.arg("decrypt")
|
||||
.args(["--session-key", "9:1FE820EC21FB5D7E33D83367106D1D3747DCD48E6320C1AEC57EE7D18FC437D4"])
|
||||
@ -52,7 +56,9 @@ mod sq_packet_decrypt {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("toolbox")
|
||||
|
||||
.arg("packet")
|
||||
.arg("decrypt")
|
||||
.args(["--session-key", "2FE820EC21FB5D7E33D83367106D1D3747DCD48E6320C1AEC57EE7D18FC437D4"])
|
||||
@ -70,7 +76,9 @@ mod sq_packet_decrypt {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("toolbox")
|
||||
|
||||
.arg("packet")
|
||||
.arg("decrypt")
|
||||
.args(["--session-key", "BB9CCB8EDE22DC222C83BD1C63AEB97335DDC7B696DB171BD16EAA5784CC0478"])
|
||||
|
@ -15,6 +15,7 @@ mod sq_packet_dump {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("toolbox")
|
||||
.arg("packet")
|
||||
.arg("dump")
|
||||
@ -31,6 +32,7 @@ mod sq_packet_dump {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("toolbox")
|
||||
.arg("packet")
|
||||
.arg("dump")
|
||||
@ -47,6 +49,7 @@ mod sq_packet_dump {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("toolbox")
|
||||
.arg("packet")
|
||||
.arg("dump")
|
||||
@ -65,6 +68,7 @@ mod sq_packet_dump {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("toolbox")
|
||||
.arg("packet")
|
||||
.arg("dump")
|
||||
@ -78,6 +82,7 @@ mod sq_packet_dump {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("toolbox")
|
||||
.arg("packet")
|
||||
.arg("dump")
|
||||
@ -95,6 +100,7 @@ mod sq_packet_dump {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("toolbox")
|
||||
.arg("packet")
|
||||
.arg("dump")
|
||||
@ -108,6 +114,7 @@ mod sq_packet_dump {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("toolbox")
|
||||
.arg("packet")
|
||||
.arg("dump")
|
||||
@ -124,6 +131,7 @@ mod sq_packet_dump {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("toolbox")
|
||||
.arg("packet")
|
||||
.arg("dump")
|
||||
|
@ -114,6 +114,7 @@ mod integration {
|
||||
let mut cmd = Command::cargo_bin("sq")?;
|
||||
cmd.current_dir(&dir())
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.args(&["--output-format", &format!("{}", outputformat)])
|
||||
.args(&["--keyring", keyring]);
|
||||
if let Some(trust_root) = trust_root {
|
||||
|
@ -35,6 +35,7 @@ fn sq_sign() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.args(["--signer-file", &artifact("keys/dennis-simon-anton-private.pgp")])
|
||||
.args(["--output", &sig.to_string_lossy()])
|
||||
@ -70,6 +71,7 @@ fn sq_sign() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/dennis-simon-anton.pgp")])
|
||||
.arg(&*sig.to_string_lossy())
|
||||
@ -86,6 +88,7 @@ fn sq_sign_with_notations() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.args(["--signer-file", &artifact("keys/dennis-simon-anton-private.pgp")])
|
||||
.args(["--output", &sig.to_string_lossy()])
|
||||
@ -149,6 +152,7 @@ fn sq_sign_with_notations() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.args(["--known-notation", "foo"])
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/dennis-simon-anton.pgp")])
|
||||
@ -166,6 +170,7 @@ fn sq_sign_append() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.args(["--signer-file", &artifact("keys/dennis-simon-anton-private.pgp")])
|
||||
.args(["--output", &sig0.to_string_lossy()])
|
||||
@ -201,6 +206,7 @@ fn sq_sign_append() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/dennis-simon-anton.pgp")])
|
||||
.arg(&*sig0.to_string_lossy())
|
||||
@ -212,6 +218,7 @@ fn sq_sign_append() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.arg("--append")
|
||||
.args(["--signer-file", &artifact("keys/erika-corinna-daniela-simone-antonia-nistp256-private.pgp")])
|
||||
@ -262,6 +269,7 @@ fn sq_sign_append() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/dennis-simon-anton.pgp")])
|
||||
.arg(&*sig1.to_string_lossy())
|
||||
@ -270,6 +278,7 @@ fn sq_sign_append() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/erika-corinna-daniela-simone-antonia-nistp256.pgp")])
|
||||
.arg(&*sig1.to_string_lossy())
|
||||
@ -332,6 +341,7 @@ fn sq_sign_append_on_compress_then_sign() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/dennis-simon-anton.pgp")])
|
||||
.arg(&*sig0.to_string_lossy())
|
||||
@ -343,6 +353,7 @@ fn sq_sign_append_on_compress_then_sign() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.arg("--append")
|
||||
.args(["--signer-file", &artifact("keys/erika-corinna-daniela-simone-antonia-nistp256-private.pgp")])
|
||||
@ -396,6 +407,7 @@ fn sq_sign_append_on_compress_then_sign() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/dennis-simon-anton.pgp")])
|
||||
.arg(&*sig0.to_string_lossy())
|
||||
@ -405,6 +417,7 @@ fn sq_sign_append_on_compress_then_sign() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/erika-corinna-daniela-simone-antonia-nistp256.pgp")])
|
||||
.arg(&*sig0.to_string_lossy())
|
||||
@ -421,6 +434,7 @@ fn sq_sign_detached() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.arg("--detached")
|
||||
.args(["--signer-file", &artifact("keys/dennis-simon-anton-private.pgp")])
|
||||
@ -446,6 +460,7 @@ fn sq_sign_detached() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/dennis-simon-anton.pgp")])
|
||||
.args(["--detached", &sig.to_string_lossy()])
|
||||
@ -463,6 +478,7 @@ fn sq_sign_detached_append() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.arg("--detached")
|
||||
.args(["--signer-file", &artifact("keys/dennis-simon-anton-private.pgp")])
|
||||
@ -488,6 +504,7 @@ fn sq_sign_detached_append() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/dennis-simon-anton.pgp")])
|
||||
.args(["--detached", &sig.to_string_lossy()])
|
||||
@ -499,6 +516,7 @@ fn sq_sign_detached_append() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.arg("--detached")
|
||||
.args(["--signer-file", &artifact("keys/erika-corinna-daniela-simone-antonia-nistp256-private.pgp")])
|
||||
@ -511,6 +529,7 @@ fn sq_sign_detached_append() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.arg("--detached")
|
||||
.arg("--append")
|
||||
@ -542,6 +561,7 @@ fn sq_sign_detached_append() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/dennis-simon-anton.pgp")])
|
||||
.args(["--detached", &sig.to_string_lossy()])
|
||||
@ -552,6 +572,7 @@ fn sq_sign_detached_append() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/erika-corinna-daniela-simone-antonia-nistp256.pgp")])
|
||||
.args(["--detached", &sig.to_string_lossy()])
|
||||
@ -564,6 +585,7 @@ fn sq_sign_detached_append() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.arg("--detached")
|
||||
.arg("--append")
|
||||
@ -602,6 +624,7 @@ fn sq_sign_append_a_notarization() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.arg("--append")
|
||||
.args(["--signer-file", &artifact("keys/erika-corinna-daniela-simone-antonia-nistp256-private.pgp")])
|
||||
@ -663,6 +686,7 @@ fn sq_sign_append_a_notarization() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/neal.pgp")])
|
||||
.arg(&*sig0.to_string_lossy())
|
||||
@ -671,6 +695,7 @@ fn sq_sign_append_a_notarization() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/emmelie-dorothea-dina-samantha-awina-ed25519.pgp")])
|
||||
.arg(&*sig0.to_string_lossy())
|
||||
@ -679,6 +704,7 @@ fn sq_sign_append_a_notarization() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/erika-corinna-daniela-simone-antonia-nistp256.pgp")])
|
||||
.arg(&*sig0.to_string_lossy())
|
||||
@ -696,6 +722,7 @@ fn sq_sign_notarize() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.arg("--notarize")
|
||||
.args(["--signer-file", &artifact("keys/erika-corinna-daniela-simone-antonia-nistp256-private.pgp")])
|
||||
@ -745,6 +772,7 @@ fn sq_sign_notarize() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/neal.pgp")])
|
||||
.arg(&*sig0.to_string_lossy())
|
||||
@ -753,6 +781,7 @@ fn sq_sign_notarize() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/erika-corinna-daniela-simone-antonia-nistp256.pgp")])
|
||||
.arg(&*sig0.to_string_lossy())
|
||||
@ -770,6 +799,7 @@ fn sq_sign_notarize_a_notarization() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.arg("--notarize")
|
||||
.args(["--signer-file", &artifact("keys/erika-corinna-daniela-simone-antonia-nistp256-private.pgp")])
|
||||
@ -831,6 +861,7 @@ fn sq_sign_notarize_a_notarization() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/neal.pgp")])
|
||||
.arg(&*sig0.to_string_lossy())
|
||||
@ -839,6 +870,7 @@ fn sq_sign_notarize_a_notarization() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/emmelie-dorothea-dina-samantha-awina-ed25519.pgp")])
|
||||
.arg(&*sig0.to_string_lossy())
|
||||
@ -847,6 +879,7 @@ fn sq_sign_notarize_a_notarization() {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &artifact("keys/erika-corinna-daniela-simone-antonia-nistp256.pgp")])
|
||||
.arg(&*sig0.to_string_lossy())
|
||||
@ -878,7 +911,7 @@ fn sq_multiple_signers() -> Result<()> {
|
||||
// Sign message.
|
||||
let assertion = Command::cargo_bin("sq")?
|
||||
.args([
|
||||
"--no-cert-store",
|
||||
"--no-cert-store", "--no-key-store",
|
||||
"sign",
|
||||
"--signer-file", alice_pgp.to_str().unwrap(),
|
||||
"--signer-file", &bob_pgp.to_str().unwrap(),
|
||||
@ -957,6 +990,7 @@ fn sq_sign_using_cert_store() -> Result<()> {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.args(["--signer-file", &alice_pgp])
|
||||
.args(["--output", &msg_pgp])
|
||||
@ -998,6 +1032,7 @@ fn sq_sign_using_cert_store() -> Result<()> {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.args(["--signer-file", &alice_pgp])
|
||||
.arg(&msg_pgp)
|
||||
@ -1008,6 +1043,7 @@ fn sq_sign_using_cert_store() -> Result<()> {
|
||||
// certificate or use a certificate store.
|
||||
let mut cmd = Command::cargo_bin("sq").unwrap();
|
||||
cmd.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("verify")
|
||||
.arg(&msg_pgp);
|
||||
let output = cmd.output().expect("success");
|
||||
@ -1098,6 +1134,7 @@ fn sq_verify_wot() -> Result<()> {
|
||||
{
|
||||
let mut cmd = Command::cargo_bin("sq").expect("have sq");
|
||||
cmd.args(["--no-cert-store",
|
||||
"--no-key-store",
|
||||
"key", "generate",
|
||||
"--expiry", "never",
|
||||
"--output", file]);
|
||||
@ -1120,6 +1157,7 @@ fn sq_verify_wot() -> Result<()> {
|
||||
msg_pgp: &str|
|
||||
{
|
||||
let mut cmd = Command::cargo_bin("sq").expect("have sq");
|
||||
cmd.arg("--no-key-store");
|
||||
if let Some(cert_store) = cert_store {
|
||||
cmd.args(&["--cert-store", cert_store]);
|
||||
} else {
|
||||
@ -1186,6 +1224,7 @@ fn sq_verify_wot() -> Result<()> {
|
||||
Command::cargo_bin("sq")
|
||||
.unwrap()
|
||||
.arg("--no-cert-store")
|
||||
.arg("--no-key-store")
|
||||
.arg("sign")
|
||||
.args(["--signer-file", &bob_pgp])
|
||||
.args(["--signer-file", &carol_pgp])
|
||||
|
Loading…
Reference in New Issue
Block a user