To revoke a user ID, require the cert be valid under the current policy.

- Change `sq key userid revoke` to require the certificate be valid
    under the current policy.  If the certificate is not valid under
    the current policy, the user should revoke the whole certificate,
    or fix it using `sq cert lint` after verifying the certificate's
    integrity.  If the certificate is valid under the current policy,
    but the user ID to revoke isn't, it can still be revoked using
    `--userid-or-add`.

  - See #375.
This commit is contained in:
Neal H. Walfield 2024-11-23 20:35:01 +01:00
parent 99ad920c43
commit bfc843bc52
No known key found for this signature in database
GPG Key ID: 6863C9AD5B4D22D3
3 changed files with 30 additions and 9 deletions

View File

@ -197,6 +197,13 @@ the certificate that is being revoked, this results in a third-party \
revocation. This is normally only useful if the owner of the \
certificate designated the key to be a designated revoker.
To revoke a user ID, the certificate must be valid under the current \
policy. If the certificate is not valid under the current policy, \
consider revoking the whole certificate, or fixing it using `sq cert \
lint` after verifying the certificate's integrity. If the certificate \
is valid under the current policy, but the user ID you want to revoke \
isn't, you can still revoke the user ID using `--userid-or-add`.
`sq key userid revoke` respects the reference time set by the top-level \
`--time` argument. When set, it uses the specified time instead of \
the current time when determining what keys are valid, and it sets \

View File

@ -28,7 +28,6 @@ use crate::cli::types::userid_designator::ResolvedUserID;
use crate::cli;
use crate::common::RevocationOutput;
use crate::common::get_secret_signer;
use crate::sq::NULL_POLICY;
use crate::common::userid::{
lint_emails,
lint_names,
@ -303,12 +302,18 @@ pub fn userid_revoke(
) -> Result<()> {
let cert =
sq.resolve_cert(&command.cert, sequoia_wot::FULLY_TRUSTED)?.0;
// We require the User ID to have a valid self signature under the
// Null policy. We use the Null policy and not the standard
// policy, because it is still useful to revoke a User ID whose
// self signature is no longer valid. For instance, the binding
// signature may use SHA-1.
let vcert = cert.with_policy(&NULL_POLICY, sq.time)?;
// To revoke a user ID, we require the certificate be valid under
// the current policy. Users can still revoke user IDs whose
// binding signature relies on weak cryptography using
// `--user-or-add`.
let vcert = cert.with_policy(sq.policy, sq.time)
.with_context(|| {
format!("The certificate is not valid under the current \
policy. Consider revoking the whole certificate \
using `sq key revoke`, or fixing it using \
`sq cert lint` after verifying the certificate's \
integrity.")
})?;
let userids = command.userids.resolve(&vcert)?;
assert_eq!(userids.len(), 1, "exactly one user ID enforced by clap");
let userid = userids.into_iter().next().unwrap();

View File

@ -42,9 +42,18 @@ fn sha1_userid() {
= String::from_utf8_lossy(weak_userids[0].value()).to_string();
let updated_path = sq.scratch_file("updated");
assert!(
sq.key_userid_revoke_maybe(&[],
&cert_path,
&weak_userid,
"retired",
"bye, bye",
updated_path.as_path())
.is_err());
sq.key_userid_revoke(&[],
cert_path,
&weak_userid,
&cert_path,
UserIDArg::AddUserID(&weak_userid),
"retired",
"bye, bye",
updated_path.as_path());