mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg: Look up user ID to revoke by UID hash
* g10/keyedit.c (find_userid_by_namehash, find_userid): New. (keyedit_quick_revuid): Use find_userid() instead of iterating over the nodes of the keyblock. * tests/openpgp/quick-key-manipulation.scm: Add test for revoking a user ID specified by its hash. -- This makes it possible to specify the user ID to revoke as UID hash when calling --quick-revoke-uid. GnuPG-bug-id: 5936
This commit is contained in:
parent
f27a70ecc2
commit
35b1755070
120
g10/keyedit.c
120
g10/keyedit.c
@ -2447,6 +2447,68 @@ keyedit_quick_adduid (ctrl_t ctrl, const char *username, const char *newuid)
|
||||
}
|
||||
|
||||
|
||||
/* Helper to find the UID node for namehash. On success, returns the UID node.
|
||||
Otherwise, return NULL. */
|
||||
kbnode_t
|
||||
find_userid_by_namehash (kbnode_t keyblock, const char *namehash)
|
||||
{
|
||||
byte hash[NAMEHASH_LEN];
|
||||
kbnode_t node = NULL;
|
||||
|
||||
if (!namehash)
|
||||
goto leave;
|
||||
|
||||
if (strlen (namehash) != NAMEHASH_LEN * 2)
|
||||
goto leave;
|
||||
|
||||
if (hex2bin (namehash, hash, NAMEHASH_LEN) < 0)
|
||||
goto leave;
|
||||
|
||||
for (node = keyblock; node; node = node->next)
|
||||
{
|
||||
if (node->pkt->pkttype == PKT_USER_ID)
|
||||
{
|
||||
namehash_from_uid (node->pkt->pkt.user_id);
|
||||
if (!memcmp (node->pkt->pkt.user_id->namehash, hash, NAMEHASH_LEN))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
leave:
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/* Helper to find the UID node for uid. On success, returns the UID node.
|
||||
Otherwise, return NULL. */
|
||||
kbnode_t
|
||||
find_userid (kbnode_t keyblock, const char *uid)
|
||||
{
|
||||
kbnode_t node = NULL;
|
||||
size_t uidlen;
|
||||
|
||||
if (!keyblock || !uid)
|
||||
goto leave;
|
||||
|
||||
/* First try to find UID by namehash. */
|
||||
node = find_userid_by_namehash (keyblock, uid);
|
||||
if (node)
|
||||
goto leave;
|
||||
|
||||
uidlen = strlen (uid);
|
||||
for (node = keyblock; node; node = node->next)
|
||||
{
|
||||
if (node->pkt->pkttype == PKT_USER_ID
|
||||
&& uidlen == node->pkt->pkt.user_id->len
|
||||
&& !memcmp (node->pkt->pkt.user_id->name, uid, uidlen))
|
||||
break;
|
||||
}
|
||||
|
||||
leave:
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/* Unattended revocation of a keyid. USERNAME specifies the
|
||||
key. UIDTOREV is the user id revoke from the key. */
|
||||
void
|
||||
@ -2457,7 +2519,6 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
|
||||
kbnode_t keyblock = NULL;
|
||||
kbnode_t node;
|
||||
int modified = 0;
|
||||
size_t revlen;
|
||||
size_t valid_uids;
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
@ -2470,7 +2531,7 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
/* Too make sure that we do not revoke the last valid UID, we first
|
||||
/* To make sure that we do not revoke the last valid UID, we first
|
||||
count how many valid UIDs there are. */
|
||||
valid_uids = 0;
|
||||
for (node = keyblock; node; node = node->next)
|
||||
@ -2479,40 +2540,35 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
|
||||
&& !node->pkt->pkt.user_id->flags.expired);
|
||||
|
||||
/* Find the right UID. */
|
||||
revlen = strlen (uidtorev);
|
||||
for (node = keyblock; node; node = node->next)
|
||||
node = find_userid (keyblock, uidtorev);
|
||||
if (node)
|
||||
{
|
||||
if (node->pkt->pkttype == PKT_USER_ID
|
||||
&& revlen == node->pkt->pkt.user_id->len
|
||||
&& !memcmp (node->pkt->pkt.user_id->name, uidtorev, revlen))
|
||||
struct revocation_reason_info *reason;
|
||||
|
||||
/* Make sure that we do not revoke the last valid UID. */
|
||||
if (valid_uids == 1
|
||||
&& ! node->pkt->pkt.user_id->flags.revoked
|
||||
&& ! node->pkt->pkt.user_id->flags.expired)
|
||||
{
|
||||
struct revocation_reason_info *reason;
|
||||
|
||||
/* Make sure that we do not revoke the last valid UID. */
|
||||
if (valid_uids == 1
|
||||
&& ! node->pkt->pkt.user_id->flags.revoked
|
||||
&& ! node->pkt->pkt.user_id->flags.expired)
|
||||
{
|
||||
log_error (_("cannot revoke the last valid user ID.\n"));
|
||||
err = gpg_error (GPG_ERR_INV_USER_ID);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
reason = get_default_uid_revocation_reason ();
|
||||
err = core_revuid (ctrl, keyblock, node, reason, &modified);
|
||||
release_revocation_reason_info (reason);
|
||||
if (err)
|
||||
goto leave;
|
||||
err = keydb_update_keyblock (ctrl, kdbhd, keyblock);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("update failed: %s\n"), gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
revalidation_mark (ctrl);
|
||||
log_error (_("cannot revoke the last valid user ID.\n"));
|
||||
err = gpg_error (GPG_ERR_INV_USER_ID);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
reason = get_default_uid_revocation_reason ();
|
||||
err = core_revuid (ctrl, keyblock, node, reason, &modified);
|
||||
release_revocation_reason_info (reason);
|
||||
if (err)
|
||||
goto leave;
|
||||
err = keydb_update_keyblock (ctrl, kdbhd, keyblock);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("update failed: %s\n"), gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
revalidation_mark (ctrl);
|
||||
goto leave;
|
||||
}
|
||||
err = gpg_error (GPG_ERR_NO_USER_ID);
|
||||
|
||||
|
@ -34,6 +34,8 @@
|
||||
(define alpha "Alpha <alpha@invalid.example.net>")
|
||||
(define bravo "Bravo <bravo@invalid.example.net>")
|
||||
(define charlie "Charlie <charlie@invalid.example.net>")
|
||||
(define delta "Delta <delta@invalid.example.net>")
|
||||
(define deltahash "359DC5EFF98B14A58AAA615C638E8BD0CEDA537B")
|
||||
|
||||
(define (key-data key)
|
||||
(filter (lambda (x) (or (string=? (car x) "pub")
|
||||
@ -87,6 +89,10 @@
|
||||
(info "Checking that we can revoke a user ID...")
|
||||
(call-check `(,@GPG --quick-revoke-uid ,(exact bravo) ,alpha))
|
||||
|
||||
(info "Checking that we can revoke a user ID by its hash...")
|
||||
(call-check `(,@GPG --quick-add-uid ,(exact bravo) ,delta))
|
||||
(call-check `(,@GPG --quick-revoke-uid ,(exact bravo) ,deltahash))
|
||||
|
||||
(info "Checking that we get an error revoking a non-existent user ID.")
|
||||
(catch '()
|
||||
(call-check `(,@GPG --quick-revoke-uid ,(exact bravo) ,charlie))
|
||||
|
Loading…
x
Reference in New Issue
Block a user