Implement sq pki vouch {add,authorize} --certifier-self
.
- This selects the default certification key controlled by the `pki.vouch.certifier-self` setting. - See #336.
This commit is contained in:
parent
0d37335aad
commit
1fcdd57d93
@ -7,6 +7,9 @@ use clap::{Parser, Subcommand};
|
||||
|
||||
use crate::cli::examples::*;
|
||||
|
||||
/// Key for the help augmentation.
|
||||
pub const CERTIFIER_SELF: &str = "pki.vouch.certifier-self";
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[clap(
|
||||
name = "vouch",
|
||||
|
@ -85,7 +85,7 @@ reference time.
|
||||
}))]
|
||||
pub struct Command {
|
||||
#[command(flatten)]
|
||||
pub certifier: CertDesignators<CertUserIDEmailFileArgs,
|
||||
pub certifier: CertDesignators<CertUserIDEmailFileSelfArgs,
|
||||
CertifierPrefix,
|
||||
OneValue,
|
||||
CertifierDoc>,
|
||||
|
@ -96,7 +96,7 @@ reference time.
|
||||
}))]
|
||||
pub struct Command {
|
||||
#[command(flatten)]
|
||||
pub certifier: CertDesignators<CertUserIDEmailFileArgs,
|
||||
pub certifier: CertDesignators<CertUserIDEmailFileSelfArgs,
|
||||
CertifierPrefix,
|
||||
OneValue,
|
||||
CertifierDoc>,
|
||||
|
@ -14,6 +14,7 @@ use openpgp::packet::UserID;
|
||||
use crate::cli::config;
|
||||
use crate::cli::encrypt::ENCRYPT_FOR_SELF;
|
||||
use crate::cli::sign::SIGNER_SELF;
|
||||
use crate::cli::pki::vouch::CERTIFIER_SELF;
|
||||
use crate::cli::types::SpecialName;
|
||||
|
||||
/// The prefix for the designators.
|
||||
@ -771,6 +772,29 @@ This adds the certificates listed in the configuration file under \
|
||||
}),
|
||||
),
|
||||
|
||||
"certifier" => (
|
||||
"Create the certification using your default certification \
|
||||
key",
|
||||
format!(
|
||||
"Create the certification using your default certification key
|
||||
|
||||
This uses the certificates set in the configuration file under \
|
||||
`{}` as certification key.
|
||||
|
||||
{}
|
||||
",
|
||||
CERTIFIER_SELF,
|
||||
if let Some(cert)
|
||||
= config::get_augmentation(CERTIFIER_SELF)
|
||||
{
|
||||
format!("The following key will be used: {}.",
|
||||
cert)
|
||||
} else {
|
||||
"Currently, there is no default certification key."
|
||||
.into()
|
||||
}),
|
||||
),
|
||||
|
||||
#[cfg(test)]
|
||||
"cert" => (
|
||||
"dummy text for the test",
|
||||
|
@ -54,6 +54,10 @@ pub struct Config {
|
||||
/// The set of signing keys selected using `--signer-self`.
|
||||
sign_signer_self: BTreeSet<Fingerprint>,
|
||||
|
||||
/// The default certification key selected using
|
||||
/// `--certifier-self`.
|
||||
pki_vouch_certifier_self: Option<Fingerprint>,
|
||||
|
||||
policy_path: Option<PathBuf>,
|
||||
policy_inline: Option<Vec<u8>>,
|
||||
cipher_suite: Option<sequoia_openpgp::cert::CipherSuite>,
|
||||
@ -82,6 +86,7 @@ impl Default for Config {
|
||||
hints: None,
|
||||
encrypt_for_self: Default::default(),
|
||||
sign_signer_self: Default::default(),
|
||||
pki_vouch_certifier_self: None,
|
||||
policy_path: None,
|
||||
policy_inline: None,
|
||||
cipher_suite: None,
|
||||
@ -168,6 +173,12 @@ impl Config {
|
||||
&self.sign_signer_self
|
||||
}
|
||||
|
||||
/// Returns the key that should be used as certifier if
|
||||
/// `--certifier-self` is given.
|
||||
pub fn pki_vouch_certifier_self(&self) -> &Option<Fingerprint> {
|
||||
&self.pki_vouch_certifier_self
|
||||
}
|
||||
|
||||
/// Returns the path to the referenced cryptographic policy, if
|
||||
/// any.
|
||||
pub fn policy_path(&self) -> Option<&Path> {
|
||||
@ -289,6 +300,9 @@ impl ConfigFile {
|
||||
[sign]
|
||||
#signer-self = [\"fingerprint of your key\"]
|
||||
|
||||
[pki.vouch]
|
||||
#certifier-self = \"fingerprint of your key\"
|
||||
|
||||
[key.generate]
|
||||
#cipher-suite = <DEFAULT-CIPHER-SUITE>
|
||||
|
||||
@ -704,6 +718,7 @@ const TOP_LEVEL_SCHEMA: Schema = &[
|
||||
("encrypt", apply_encrypt),
|
||||
("key", apply_key),
|
||||
("network", apply_network),
|
||||
("pki", apply_pki),
|
||||
("policy", apply_policy),
|
||||
("servers", apply_servers),
|
||||
("sign", apply_sign),
|
||||
@ -877,6 +892,62 @@ fn apply_sign_signer_self(config: &mut Option<&mut Config>,
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Schema for the `pki` section.
|
||||
const PKI_SCHEMA: Schema = &[
|
||||
("vouch", apply_pki_vouch),
|
||||
];
|
||||
|
||||
/// Validates the `pki` section.
|
||||
fn apply_pki(config: &mut Option<&mut Config>,
|
||||
cli: &mut Option<&mut Augmentations>,
|
||||
path: &str, item: &Item)
|
||||
-> Result<()>
|
||||
{
|
||||
let section = item.as_table_like()
|
||||
.ok_or_else(|| Error::bad_item_type(path, item, "table"))?;
|
||||
apply_schema(config, cli, Some(path), section.iter(), PKI_SCHEMA)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Schema for the `pki.vouch` section.
|
||||
const PKI_VOUCH_SCHEMA: Schema = &[
|
||||
("certifier-self", apply_pki_vouch_certifier_self),
|
||||
];
|
||||
|
||||
/// Validates the `pki.vouch` section.
|
||||
fn apply_pki_vouch(config: &mut Option<&mut Config>,
|
||||
cli: &mut Option<&mut Augmentations>,
|
||||
path: &str, item: &Item)
|
||||
-> Result<()>
|
||||
{
|
||||
let section = item.as_table_like()
|
||||
.ok_or_else(|| Error::bad_item_type(path, item, "table"))?;
|
||||
apply_schema(config, cli, Some(path), section.iter(), PKI_VOUCH_SCHEMA)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Validates the `pki.vouch.certifier-self` value.
|
||||
fn apply_pki_vouch_certifier_self(config: &mut Option<&mut Config>,
|
||||
cli: &mut Option<&mut Augmentations>,
|
||||
path: &str, item: &Item)
|
||||
-> Result<()>
|
||||
{
|
||||
let s = item.as_str()
|
||||
.ok_or_else(|| Error::bad_item_type(path, item, "string"))?;
|
||||
|
||||
let fp = s.parse::<Fingerprint>()?;
|
||||
|
||||
if let Some(cli) = cli {
|
||||
cli.insert("pki.vouch.certifier-self", fp.to_string());
|
||||
}
|
||||
|
||||
if let Some(config) = config {
|
||||
config.pki_vouch_certifier_self = Some(fp);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Schema for the `key` section.
|
||||
const KEY_SCHEMA: Schema = &[
|
||||
("generate", apply_key_generate),
|
||||
|
37
src/sq.rs
37
src/sq.rs
@ -2105,28 +2105,41 @@ impl<'store: 'rstore, 'rstore> Sq<'store, 'rstore> {
|
||||
},
|
||||
|
||||
cert_designator::CertDesignator::Self_ => {
|
||||
let (certs, config) = match Prefix::name() {
|
||||
"for" => (self.config.encrypt_for_self(),
|
||||
cli::encrypt::ENCRYPT_FOR_SELF),
|
||||
"signer" => (self.config.sign_signer_self(),
|
||||
cli::sign::SIGNER_SELF),
|
||||
let (certs, config): (Box<dyn Iterator<Item=&Fingerprint>>, _)
|
||||
= match Prefix::name()
|
||||
{
|
||||
"for" => (
|
||||
Box::new(self.config.encrypt_for_self().iter()),
|
||||
cli::encrypt::ENCRYPT_FOR_SELF,
|
||||
),
|
||||
"signer" => (
|
||||
Box::new(self.config.sign_signer_self().iter()),
|
||||
cli::sign::SIGNER_SELF,
|
||||
),
|
||||
"certifier" => (
|
||||
Box::new(self.config.pki_vouch_certifier_self().iter()),
|
||||
cli::pki::vouch::CERTIFIER_SELF,
|
||||
),
|
||||
_ => return Err(anyhow::anyhow!(
|
||||
"self designator used with unexpected prefix")),
|
||||
};
|
||||
|
||||
if certs.is_empty() {
|
||||
return Err(anyhow::anyhow!(
|
||||
"`--for-self` is given but the list of \
|
||||
certificates in `{}` is empty",
|
||||
config));
|
||||
}
|
||||
|
||||
let mut one = false;
|
||||
for fp in certs {
|
||||
let cert = self.resolve_cert(
|
||||
&openpgp::KeyHandle::from(fp.clone()).into(), 0)?.0;
|
||||
ret(designator,
|
||||
Ok(Arc::new(cert.into())),
|
||||
true, true);
|
||||
one = true;
|
||||
}
|
||||
|
||||
if ! one {
|
||||
return Err(anyhow::anyhow!(
|
||||
"`--{}-self` is given but no default \
|
||||
is set in the configuration file under `{}`",
|
||||
Prefix::name(),
|
||||
config));
|
||||
}
|
||||
},
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user