mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-02 12:01:32 +01:00
gpg: Do not allow the user to revoke the last valid UID.
* g10/keyedit.c (keyedit_quick_revuid): Merge self signatures, then make sure that we do not revoke the last valid UID. (menu_revuid): Make sure that we do not revoke the last valid UID. * tests/openpgp/quick-key-manipulation.scm: Demonstrate that '--quick-revoke-uid' can not be used to revoke the last valid UID. GnuPG-bug-id: 2960 Signed-off-by: Justus Winter <justus@g10code.com>
This commit is contained in:
parent
80fb1a8a05
commit
591b6a9d87
@ -2966,6 +2966,7 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
|
|||||||
kbnode_t node;
|
kbnode_t node;
|
||||||
int modified = 0;
|
int modified = 0;
|
||||||
size_t revlen;
|
size_t revlen;
|
||||||
|
size_t valid_uids;
|
||||||
|
|
||||||
#ifdef HAVE_W32_SYSTEM
|
#ifdef HAVE_W32_SYSTEM
|
||||||
/* See keyedit_menu for why we need this. */
|
/* See keyedit_menu for why we need this. */
|
||||||
@ -3019,7 +3020,16 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fix_keyblock (&keyblock);
|
fix_keyblock (&keyblock);
|
||||||
setup_main_keyids (keyblock);
|
merge_keys_and_selfsig (keyblock);
|
||||||
|
|
||||||
|
/* Too 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)
|
||||||
|
valid_uids +=
|
||||||
|
node->pkt->pkttype == PKT_USER_ID
|
||||||
|
&& ! node->pkt->pkt.user_id->is_revoked
|
||||||
|
&& ! node->pkt->pkt.user_id->is_expired;
|
||||||
|
|
||||||
revlen = strlen (uidtorev);
|
revlen = strlen (uidtorev);
|
||||||
/* find the right UID */
|
/* find the right UID */
|
||||||
@ -3031,6 +3041,15 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
|
|||||||
{
|
{
|
||||||
struct revocation_reason_info *reason;
|
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->is_revoked
|
||||||
|
&& ! node->pkt->pkt.user_id->is_expired)
|
||||||
|
{
|
||||||
|
log_error (_("Cannot revoke the last valid user ID.\n"));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
reason = get_default_uid_revocation_reason ();
|
reason = get_default_uid_revocation_reason ();
|
||||||
err = core_revuid (ctrl, keyblock, node, reason, &modified);
|
err = core_revuid (ctrl, keyblock, node, reason, &modified);
|
||||||
release_revocation_reason_info (reason);
|
release_revocation_reason_info (reason);
|
||||||
@ -6429,6 +6448,7 @@ menu_revuid (ctrl_t ctrl, kbnode_t pub_keyblock)
|
|||||||
int changed = 0;
|
int changed = 0;
|
||||||
int rc;
|
int rc;
|
||||||
struct revocation_reason_info *reason = NULL;
|
struct revocation_reason_info *reason = NULL;
|
||||||
|
size_t valid_uids;
|
||||||
|
|
||||||
/* Note that this is correct as per the RFCs, but nevertheless
|
/* Note that this is correct as per the RFCs, but nevertheless
|
||||||
somewhat meaningless in the real world. 1991 did define the 0x30
|
somewhat meaningless in the real world. 1991 did define the 0x30
|
||||||
@ -6445,11 +6465,30 @@ menu_revuid (ctrl_t ctrl, kbnode_t pub_keyblock)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Too 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 = pub_keyblock; node; node = node->next)
|
||||||
|
valid_uids +=
|
||||||
|
node->pkt->pkttype == PKT_USER_ID
|
||||||
|
&& ! node->pkt->pkt.user_id->is_revoked
|
||||||
|
&& ! node->pkt->pkt.user_id->is_expired;
|
||||||
|
|
||||||
reloop: /* (better this way because we are modifying the keyring) */
|
reloop: /* (better this way because we are modifying the keyring) */
|
||||||
for (node = pub_keyblock; node; node = node->next)
|
for (node = pub_keyblock; node; node = node->next)
|
||||||
if (node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
|
if (node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
|
||||||
{
|
{
|
||||||
int modified = 0;
|
int modified = 0;
|
||||||
|
|
||||||
|
/* Make sure that we do not revoke the last valid UID. */
|
||||||
|
if (valid_uids == 1
|
||||||
|
&& ! node->pkt->pkt.user_id->is_revoked
|
||||||
|
&& ! node->pkt->pkt.user_id->is_expired)
|
||||||
|
{
|
||||||
|
log_error (_("Cannot revoke the last valid user ID.\n"));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
rc = core_revuid (ctrl, pub_keyblock, node, reason, &modified);
|
rc = core_revuid (ctrl, pub_keyblock, node, reason, &modified);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
@ -81,6 +81,11 @@
|
|||||||
(call-check `(,@GPG --quick-revoke-uid ,(exact bravo) ,charlie))
|
(call-check `(,@GPG --quick-revoke-uid ,(exact bravo) ,charlie))
|
||||||
(error "Expected an error, but get none."))
|
(error "Expected an error, but get none."))
|
||||||
|
|
||||||
|
(info "Checking that we get an error revoking the last valid user ID.")
|
||||||
|
(catch '()
|
||||||
|
(call-check `(,@GPG --quick-revoke-uid ,(exact bravo) ,bravo))
|
||||||
|
(error "Expected an error, but get none."))
|
||||||
|
|
||||||
(assert (= 1 (count-uids-of-secret-key bravo)))
|
(assert (= 1 (count-uids-of-secret-key bravo)))
|
||||||
|
|
||||||
(info "Checking that we can change the expiration time.")
|
(info "Checking that we can change the expiration time.")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user