aboutsummaryrefslogtreecommitdiffstats
path: root/g10/keyedit.c
diff options
context:
space:
mode:
authorJustus Winter <[email protected]>2017-03-02 13:14:55 +0000
committerJustus Winter <[email protected]>2017-03-07 12:46:20 +0000
commit591b6a9d879cbcabb089d89a26d3c3e0306054e1 (patch)
tree62b9ab47dda0b0571d85516e92701768badb17dc /g10/keyedit.c
parenttools: Removal of -Icommon. (diff)
downloadgnupg-591b6a9d879cbcabb089d89a26d3c3e0306054e1.tar.gz
gnupg-591b6a9d879cbcabb089d89a26d3c3e0306054e1.zip
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 <[email protected]>
Diffstat (limited to 'g10/keyedit.c')
-rw-r--r--g10/keyedit.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/g10/keyedit.c b/g10/keyedit.c
index c10a011d1..660e8bf98 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -2966,6 +2966,7 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
kbnode_t node;
int modified = 0;
size_t revlen;
+ size_t valid_uids;
#ifdef HAVE_W32_SYSTEM
/* 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);
- 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);
/* 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;
+ /* 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 ();
err = core_revuid (ctrl, keyblock, node, reason, &modified);
release_revocation_reason_info (reason);
@@ -6429,6 +6448,7 @@ menu_revuid (ctrl_t ctrl, kbnode_t pub_keyblock)
int changed = 0;
int rc;
struct revocation_reason_info *reason = NULL;
+ size_t valid_uids;
/* Note that this is correct as per the RFCs, but nevertheless
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;
}
+ /* 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) */
for (node = pub_keyblock; node; node = node->next)
if (node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
{
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);
if (rc)
goto leave;