Align user ID designators in sq pki {link,vouch} {add,authorize}
.
- Align user ID designators across these four commands. Previously, `--all` was implied for the authorize commands if no user ID designator was given. - However, this is problematic for the following reasons: - First, it is inconsistent across the commands. - Second, while CAs can add any name to their cert because they are CAs, those certifications are subject to constraints, such as domain constraints, or the amount. But, the link we add fully authenticates the current user IDs, which may not be what the user wants, so it should require explicit consent. - Third, making this implicit again is easier than going from implicit to explicit, which breaks existing users. - Fixes #442.
This commit is contained in:
parent
1c6bf5d6fd
commit
3b1bd79195
@ -98,6 +98,7 @@ certificate is considered a trusted introducer for example.org.",
|
||||
"sq", "pki", "link", "authorize",
|
||||
"--domain=example.org",
|
||||
"--cert=EB28F26E2739A4870ECC47726F0073F60FD0CBF0",
|
||||
"--all",
|
||||
],
|
||||
}),
|
||||
|
||||
@ -341,8 +342,7 @@ pub struct AuthorizeCommand {
|
||||
|
||||
#[command(flatten)]
|
||||
pub userids: UserIDDesignators<
|
||||
userid_designator::AllExistingAndAddXUserIDEmailArgs,
|
||||
userid_designator::OptionalValue>,
|
||||
userid_designator::AllExistingAndAddXUserIDEmailArgs>,
|
||||
|
||||
#[clap(
|
||||
long = "amount",
|
||||
@ -450,7 +450,8 @@ Add an unconstrained trusted introducer.",
|
||||
command: &[
|
||||
"sq", "pki", "link", "authorize",
|
||||
"--unconstrained",
|
||||
"--cert=EB28F26E2739A4870ECC47726F0073F60FD0CBF0"
|
||||
"--cert=EB28F26E2739A4870ECC47726F0073F60FD0CBF0",
|
||||
"--all",
|
||||
],
|
||||
}),
|
||||
|
||||
@ -462,6 +463,7 @@ Add a trusted introducer for example.org and example.com.",
|
||||
"--domain=example.org",
|
||||
"--domain=example.com",
|
||||
"--cert=EB28F26E2739A4870ECC47726F0073F60FD0CBF0",
|
||||
"--all",
|
||||
],
|
||||
}),
|
||||
|
||||
@ -473,6 +475,7 @@ Add a partially trusted introducer.",
|
||||
"--unconstrained",
|
||||
"--amount=60",
|
||||
"--cert=EB28F26E2739A4870ECC47726F0073F60FD0CBF0",
|
||||
"--all",
|
||||
],
|
||||
}),
|
||||
],
|
||||
|
@ -87,6 +87,7 @@ for example.org.",
|
||||
"--certifier=E7FC51AD886BBB5C4F44C3D7A9DA14F3E740F63F",
|
||||
"--cert=EB28F26E2739A4870ECC47726F0073F60FD0CBF0",
|
||||
"--domain=example.org",
|
||||
"--all",
|
||||
],
|
||||
}),
|
||||
],
|
||||
|
@ -98,7 +98,7 @@ pub struct Command {
|
||||
|
||||
#[command(flatten)]
|
||||
pub userids: UserIDDesignators<
|
||||
userid_designator::ExistingAndAddXUserIDEmailArgs>,
|
||||
userid_designator::AllExistingAndAddXUserIDEmailArgs>,
|
||||
|
||||
#[clap(
|
||||
long = "amount",
|
||||
|
@ -41,6 +41,7 @@ for example.org and example.com.",
|
||||
"--cert=E7FC51AD886BBB5C4F44C3D7A9DA14F3E740F63F",
|
||||
"--domain=example.org",
|
||||
"--domain=example.com",
|
||||
"--all",
|
||||
],
|
||||
}),
|
||||
],
|
||||
@ -108,8 +109,7 @@ pub struct Command {
|
||||
|
||||
#[command(flatten)]
|
||||
pub userids: UserIDDesignators<
|
||||
userid_designator::ExistingAndAddXUserIDEmailArgs,
|
||||
userid_designator::OptionalValue>,
|
||||
userid_designator::AllExistingAndAddXUserIDEmailArgs>,
|
||||
|
||||
#[clap(
|
||||
long = "amount",
|
||||
|
@ -798,6 +798,7 @@ impl ResolvedUserID {
|
||||
|
||||
/// Return implicitly resolved user IDs for of a certificate's
|
||||
/// self-signed user IDs.
|
||||
#[allow(dead_code)]
|
||||
pub fn implicit_for_valid_cert(vc: &ValidCert) -> Vec<Self> {
|
||||
vc.userids()
|
||||
.map(|ua| Self::implicit(ua.userid().clone()))
|
||||
|
@ -90,21 +90,7 @@ pub fn authorize(sq: Sq, c: link::AuthorizeCommand)
|
||||
= sq.resolve_cert(&c.cert, sequoia_wot::FULLY_TRUSTED)?;
|
||||
|
||||
let vc = cert.with_policy(sq.policy, Some(sq.time))?;
|
||||
let mut userids = c.userids.resolve(&vc)?;
|
||||
let user_supplied_userids = if userids.is_empty() {
|
||||
// Use all self-signed User IDs.
|
||||
userids = ResolvedUserID::implicit_for_valid_cert(&vc);
|
||||
if userids.is_empty() {
|
||||
return Err(anyhow::anyhow!(
|
||||
"{} has no self-signed user IDs, and you didn't provide \
|
||||
an alternate user ID",
|
||||
vc.fingerprint()));
|
||||
}
|
||||
|
||||
false
|
||||
} else {
|
||||
true
|
||||
};
|
||||
let userids = c.userids.resolve(&vc)?;
|
||||
|
||||
let notations = parse_notations(c.notation)?;
|
||||
|
||||
@ -114,7 +100,7 @@ pub fn authorize(sq: Sq, c: link::AuthorizeCommand)
|
||||
&trust_root,
|
||||
&cert,
|
||||
&userids[..],
|
||||
user_supplied_userids,
|
||||
true, // User supplied user IDs.
|
||||
&[(c.amount, c.expiration.value())][..],
|
||||
c.depth,
|
||||
&c.domain[..],
|
||||
|
@ -3,7 +3,6 @@ use openpgp::Result;
|
||||
|
||||
use crate::Sq;
|
||||
use crate::cli::pki::vouch::authorize;
|
||||
use crate::cli::types::userid_designator::ResolvedUserID;
|
||||
use crate::commands::FileOrStdout;
|
||||
use crate::parse_notations;
|
||||
|
||||
@ -23,22 +22,7 @@ pub fn authorize(sq: Sq, mut c: authorize::Command)
|
||||
}
|
||||
|
||||
let vc = cert.with_policy(sq.policy, Some(sq.time))?;
|
||||
let mut userids = c.userids.resolve(&vc)?;
|
||||
let user_supplied_userids = if userids.is_empty() {
|
||||
// Use all self-signed User IDs.
|
||||
userids = ResolvedUserID::implicit_for_valid_cert(&vc);
|
||||
|
||||
if userids.is_empty() {
|
||||
return Err(anyhow::anyhow!(
|
||||
"{} has no self-signed user IDs, and you didn't provide \
|
||||
an alternate user ID",
|
||||
vc.fingerprint()));
|
||||
}
|
||||
|
||||
false
|
||||
} else {
|
||||
true
|
||||
};
|
||||
let userids = c.userids.resolve(&vc)?;
|
||||
|
||||
let notations = parse_notations(&c.notation)?;
|
||||
|
||||
@ -48,7 +32,7 @@ pub fn authorize(sq: Sq, mut c: authorize::Command)
|
||||
&certifier,
|
||||
&cert,
|
||||
&userids[..],
|
||||
user_supplied_userids,
|
||||
true, // User supplied user IDs.
|
||||
&[(c.amount, c.expiration.value())],
|
||||
c.depth,
|
||||
&c.domain[..],
|
||||
|
@ -497,7 +497,7 @@ fn sq_pki_link_update_detection() -> Result<()> {
|
||||
let bytes = compare(bytes, &alice_cert_pgp, true);
|
||||
|
||||
// Make Alice a CA.
|
||||
sq.pki_link_authorize(&["--time", &tick(), "--unconstrained"],
|
||||
sq.pki_link_authorize(&["--time", &tick(), "--unconstrained", "--all"],
|
||||
alice.key_handle(),
|
||||
NO_USERIDS);
|
||||
let bytes = compare(bytes, &alice_cert_pgp, false);
|
||||
|
@ -6,12 +6,12 @@ use super::common::UserIDArg;
|
||||
fn sq_pki_link_authorize_then_authenticate() {
|
||||
let ca_example_org = "<ca@example.org>";
|
||||
|
||||
for userids in &[
|
||||
&[UserIDArg::UserID(ca_example_org)][..],
|
||||
for (all, userids) in &[
|
||||
(false, &[UserIDArg::UserID(ca_example_org)][..]),
|
||||
// Implicitly use all self-signed user IDs.
|
||||
NO_USERIDS,
|
||||
(true, NO_USERIDS),
|
||||
// Use a non-self signed user ID.
|
||||
&[UserIDArg::AddUserID("frank")],
|
||||
(false, &[UserIDArg::AddUserID("frank")]),
|
||||
] {
|
||||
let mut sq = Sq::new();
|
||||
|
||||
@ -82,6 +82,14 @@ fn sq_pki_link_authorize_then_authenticate() {
|
||||
}
|
||||
};
|
||||
|
||||
let maybe_all = |args: &[&'static str]| {
|
||||
let mut args = args.to_vec();
|
||||
if *all {
|
||||
args.push("--all");
|
||||
}
|
||||
args
|
||||
};
|
||||
|
||||
// No delegation yet.
|
||||
println!("CA: not authorized");
|
||||
check(
|
||||
@ -92,7 +100,7 @@ fn sq_pki_link_authorize_then_authenticate() {
|
||||
|
||||
// The user completely authorizes the CA.
|
||||
sq.tick(1);
|
||||
sq.pki_link_authorize(&["--unconstrained"],
|
||||
sq.pki_link_authorize(&maybe_all(&["--unconstrained"]),
|
||||
ca.key_handle(),
|
||||
userids);
|
||||
|
||||
@ -105,7 +113,7 @@ fn sq_pki_link_authorize_then_authenticate() {
|
||||
|
||||
// The user authorizes the CA with the regex contraint "example".
|
||||
sq.tick(1);
|
||||
sq.pki_link_authorize(&["--regex", "example"],
|
||||
sq.pki_link_authorize(&maybe_all(&["--regex", "example"]),
|
||||
ca.key_handle(),
|
||||
userids);
|
||||
|
||||
@ -119,7 +127,7 @@ fn sq_pki_link_authorize_then_authenticate() {
|
||||
// The user authorizes the CA with the domain contraint
|
||||
// "example.org".
|
||||
sq.tick(1);
|
||||
sq.pki_link_authorize(&["--domain", "example.org"],
|
||||
sq.pki_link_authorize(&maybe_all(&["--domain", "example.org"]),
|
||||
ca.key_handle(),
|
||||
userids);
|
||||
|
||||
@ -132,7 +140,7 @@ fn sq_pki_link_authorize_then_authenticate() {
|
||||
|
||||
// The user authorizes the CA with the regex contraint "other".
|
||||
sq.tick(1);
|
||||
sq.pki_link_authorize(&["--regex", "other"],
|
||||
sq.pki_link_authorize(&maybe_all(&["--regex", "other"]),
|
||||
ca.key_handle(),
|
||||
userids);
|
||||
|
||||
@ -145,7 +153,7 @@ fn sq_pki_link_authorize_then_authenticate() {
|
||||
|
||||
// The user authorizes the CA with the regex contraint "bob".
|
||||
sq.tick(1);
|
||||
sq.pki_link_authorize(&["--regex", "bob"],
|
||||
sq.pki_link_authorize(&maybe_all(&["--regex", "bob"]),
|
||||
ca.key_handle(),
|
||||
userids);
|
||||
|
||||
@ -159,8 +167,8 @@ fn sq_pki_link_authorize_then_authenticate() {
|
||||
// The user authorizes the CA with the regex contraint "bob" or
|
||||
// "alice".
|
||||
sq.tick(1);
|
||||
sq.pki_link_authorize(&["--regex", "bob",
|
||||
"--regex", "alice"],
|
||||
sq.pki_link_authorize(&maybe_all(&["--regex", "bob",
|
||||
"--regex", "alice"]),
|
||||
ca.key_handle(),
|
||||
userids);
|
||||
|
||||
@ -175,8 +183,8 @@ fn sq_pki_link_authorize_then_authenticate() {
|
||||
// The user authorizes the CA for the domains example.org and
|
||||
// other.org.
|
||||
sq.tick(1);
|
||||
sq.pki_link_authorize(&["--domain", "example.org",
|
||||
"--domain", "other.org"],
|
||||
sq.pki_link_authorize(&maybe_all(&["--domain", "example.org",
|
||||
"--domain", "other.org"]),
|
||||
ca.key_handle(),
|
||||
userids);
|
||||
|
||||
@ -191,8 +199,8 @@ fn sq_pki_link_authorize_then_authenticate() {
|
||||
// The user authorizes the CA for the domain example.com and the
|
||||
// regex alice.
|
||||
sq.tick(1);
|
||||
sq.pki_link_authorize(&["--domain", "other.org",
|
||||
"--regex", "alice"],
|
||||
sq.pki_link_authorize(&maybe_all(&["--domain", "other.org",
|
||||
"--regex", "alice"]),
|
||||
ca.key_handle(),
|
||||
userids);
|
||||
|
||||
@ -206,7 +214,7 @@ fn sq_pki_link_authorize_then_authenticate() {
|
||||
|
||||
// The user authorizes the CA with the regex contraint "zoo".
|
||||
sq.tick(1);
|
||||
sq.pki_link_authorize(&["--regex", "zoo"],
|
||||
sq.pki_link_authorize(&maybe_all(&["--regex", "zoo"]),
|
||||
ca.key_handle(),
|
||||
userids);
|
||||
|
||||
@ -219,7 +227,7 @@ fn sq_pki_link_authorize_then_authenticate() {
|
||||
|
||||
// The user authorizes the CA with the domain contraint "example".
|
||||
sq.tick(1);
|
||||
sq.pki_link_authorize(&["--domain", "example"],
|
||||
sq.pki_link_authorize(&maybe_all(&["--domain", "example"]),
|
||||
ca.key_handle(),
|
||||
userids);
|
||||
|
||||
@ -244,8 +252,8 @@ fn retract_explicit() {
|
||||
|
||||
// When authorizing the CA we can either authorize implicitly
|
||||
// (i.e., all self-signed user IDs) or explicitly. Try both.
|
||||
for implicit_all in [true, false] {
|
||||
eprintln!("implicit all = {}", implicit_all);
|
||||
for explicit_all in [true, false] {
|
||||
eprintln!("explicit all = {}", explicit_all);
|
||||
|
||||
let mut sq = Sq::new();
|
||||
let (ca, ca_pgp, _ca_rev)
|
||||
@ -293,9 +301,13 @@ fn retract_explicit() {
|
||||
// Authorize via all user IDs.
|
||||
sq.tick(1);
|
||||
let userids = self_signed_userids;
|
||||
sq.pki_link_authorize(&["--unconstrained"],
|
||||
sq.pki_link_authorize(if explicit_all {
|
||||
&["--unconstrained", "--all"]
|
||||
} else {
|
||||
&["--unconstrained"]
|
||||
},
|
||||
ca.key_handle(),
|
||||
if implicit_all {
|
||||
if explicit_all {
|
||||
&[]
|
||||
} else {
|
||||
userids
|
||||
@ -519,7 +531,7 @@ fn sq_pki_link_all_revoked() {
|
||||
// any user IDs so only valid self-signed user IDs should be used.
|
||||
// That means the revoked user ID should be skipped.
|
||||
sq.tick(1);
|
||||
sq.pki_link_authorize(&["--unconstrained"],
|
||||
sq.pki_link_authorize(&["--unconstrained", "--all"],
|
||||
ca.key_handle(), NO_USERIDS);
|
||||
|
||||
println!("CA: authorized, and unconstrained");
|
||||
|
@ -89,7 +89,7 @@ fn sq_pki_vouch_authorize_then_authenticate() {
|
||||
// Otto authorizes completely to the CA.
|
||||
let certification = sq.scratch_file(None);
|
||||
sq.tick(1);
|
||||
sq.pki_vouch_authorize(&["--unconstrained"],
|
||||
sq.pki_vouch_authorize(&["--unconstrained", "--all"],
|
||||
otto.key_handle(), ca.key_handle(),
|
||||
NO_USERIDS,
|
||||
certification.as_path());
|
||||
@ -105,7 +105,7 @@ fn sq_pki_vouch_authorize_then_authenticate() {
|
||||
// Otto authorizes to the CA with the regex contraint "example".
|
||||
let certification = sq.scratch_file(None);
|
||||
sq.tick(1);
|
||||
sq.pki_vouch_authorize(&["--regex", "example"],
|
||||
sq.pki_vouch_authorize(&["--regex", "example", "--all"],
|
||||
otto.key_handle(), ca.key_handle(),
|
||||
NO_USERIDS,
|
||||
certification.as_path());
|
||||
@ -121,7 +121,7 @@ fn sq_pki_vouch_authorize_then_authenticate() {
|
||||
// Otto authorizes to the CA with the domain contraint "example.org".
|
||||
let certification = sq.scratch_file(None);
|
||||
sq.tick(1);
|
||||
sq.pki_vouch_authorize(&["--domain", "example.org"],
|
||||
sq.pki_vouch_authorize(&["--domain", "example.org", "--all"],
|
||||
otto.key_handle(), ca.key_handle(),
|
||||
NO_USERIDS,
|
||||
certification.as_path());
|
||||
@ -137,7 +137,7 @@ fn sq_pki_vouch_authorize_then_authenticate() {
|
||||
// Otto authorizes to the CA with the regex contraint "other".
|
||||
let certification = sq.scratch_file(None);
|
||||
sq.tick(1);
|
||||
sq.pki_vouch_authorize(&["--regex", "other"],
|
||||
sq.pki_vouch_authorize(&["--regex", "other", "--all"],
|
||||
otto.key_handle(), ca.key_handle(),
|
||||
NO_USERIDS,
|
||||
certification.as_path());
|
||||
@ -153,7 +153,7 @@ fn sq_pki_vouch_authorize_then_authenticate() {
|
||||
// Otto authorizes to the CA with the regex contraint "bob".
|
||||
let certification = sq.scratch_file(None);
|
||||
sq.tick(1);
|
||||
sq.pki_vouch_authorize(&["--regex", "bob"],
|
||||
sq.pki_vouch_authorize(&["--regex", "bob", "--all"],
|
||||
otto.key_handle(), ca.key_handle(),
|
||||
NO_USERIDS,
|
||||
certification.as_path());
|
||||
@ -169,7 +169,7 @@ fn sq_pki_vouch_authorize_then_authenticate() {
|
||||
// Otto authorizes to the CA with the regex contraint "bob" or "alice".
|
||||
let certification = sq.scratch_file(None);
|
||||
sq.tick(1);
|
||||
sq.pki_vouch_authorize(&["--regex", "bob", "--regex", "alice"],
|
||||
sq.pki_vouch_authorize(&["--regex", "bob", "--regex", "alice", "--all"],
|
||||
otto.key_handle(), ca.key_handle(),
|
||||
NO_USERIDS,
|
||||
certification.as_path());
|
||||
@ -187,7 +187,7 @@ fn sq_pki_vouch_authorize_then_authenticate() {
|
||||
let certification = sq.scratch_file(None);
|
||||
sq.tick(1);
|
||||
sq.pki_vouch_authorize(
|
||||
&["--domain", "example.org", "--domain", "other.org"],
|
||||
&["--domain", "example.org", "--domain", "other.org", "--all"],
|
||||
otto.key_handle(), ca.key_handle(),
|
||||
NO_USERIDS,
|
||||
certification.as_path());
|
||||
@ -205,7 +205,7 @@ fn sq_pki_vouch_authorize_then_authenticate() {
|
||||
let certification = sq.scratch_file(None);
|
||||
sq.tick(1);
|
||||
sq.pki_vouch_authorize(
|
||||
&["--domain", "other.org", "--regex", "alice"],
|
||||
&["--domain", "other.org", "--regex", "alice", "--all"],
|
||||
otto.key_handle(), ca.key_handle(),
|
||||
NO_USERIDS,
|
||||
certification.as_path());
|
||||
@ -222,7 +222,7 @@ fn sq_pki_vouch_authorize_then_authenticate() {
|
||||
// Otto authorizes to the CA with the regex contraint "zoo".
|
||||
let certification = sq.scratch_file(None);
|
||||
sq.tick(1);
|
||||
sq.pki_vouch_authorize(&["--regex", "zoo"],
|
||||
sq.pki_vouch_authorize(&["--regex", "zoo", "--all"],
|
||||
otto.key_handle(), ca.key_handle(),
|
||||
NO_USERIDS,
|
||||
certification.as_path());
|
||||
@ -238,7 +238,7 @@ fn sq_pki_vouch_authorize_then_authenticate() {
|
||||
// Otto authorizes to the CA with the domain contraint "example".
|
||||
let certification = sq.scratch_file(None);
|
||||
sq.tick(1);
|
||||
sq.pki_vouch_authorize(&["--domain", "example"],
|
||||
sq.pki_vouch_authorize(&["--domain", "example", "--all"],
|
||||
otto.key_handle(), ca.key_handle(),
|
||||
NO_USERIDS,
|
||||
certification.as_path());
|
||||
@ -326,7 +326,7 @@ fn sq_pki_vouch_authorize_all_revoked() {
|
||||
// That means the revoked user ID should be skipped.
|
||||
let certification = sq.scratch_file(None);
|
||||
sq.tick(1);
|
||||
sq.pki_vouch_authorize(&["--unconstrained"],
|
||||
sq.pki_vouch_authorize(&["--unconstrained", "--all"],
|
||||
otto.key_handle(), ca.key_handle(),
|
||||
NO_USERIDS,
|
||||
certification.as_path());
|
||||
|
Loading…
Reference in New Issue
Block a user