summaryrefslogtreecommitdiffstats
path: root/g10/keyedit.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/keyedit.c')
-rw-r--r--g10/keyedit.c269
1 files changed, 103 insertions, 166 deletions
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 1cb62de..01de7bb 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -1,7 +1,7 @@
/* keyedit.c - Edit properties of a key
* Copyright (C) 1998-2010 Free Software Foundation, Inc.
* Copyright (C) 1998-2017 Werner Koch
- * Copyright (C) 2015, 2016 g10 Code GmbH
+ * Copyright (C) 2015, 2016, 2022 g10 Code GmbH
*
* This file is part of GnuPG.
*
@@ -78,7 +78,8 @@ static gpg_error_t menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
static int menu_changeusage (ctrl_t ctrl, kbnode_t keyblock);
static int menu_backsign (ctrl_t ctrl, kbnode_t pub_keyblock);
static int menu_set_primary_uid (ctrl_t ctrl, kbnode_t pub_keyblock);
-static int menu_set_preferences (ctrl_t ctrl, kbnode_t pub_keyblock);
+static int menu_set_preferences (ctrl_t ctrl, kbnode_t pub_keyblock,
+ int unattended);
static int menu_set_keyserver_url (ctrl_t ctrl,
const char *url, kbnode_t pub_keyblock);
static int menu_set_notation (ctrl_t ctrl,
@@ -1415,6 +1416,8 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
int sec_shadowing = 0;
int run_subkey_warnings = 0;
int have_commands = !!commands;
+ strlist_t delseckey_list = NULL;
+ int delseckey_list_warn = 0;
if (opt.command_fd != -1)
;
@@ -1454,7 +1457,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
{
have_anyseckey = !agent_probe_any_secret_key (ctrl, keyblock);
if (have_anyseckey
- && !agent_probe_secret_key (ctrl, keyblock->pkt->pkt.public_key))
+ && agent_probe_secret_key (ctrl, keyblock->pkt->pkt.public_key))
{
/* The primary key is also available. */
have_seckey = 1;
@@ -1491,6 +1494,14 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
subkey_expire_warning (keyblock);
}
+ if (delseckey_list_warn)
+ {
+ delseckey_list_warn = 0;
+ tty_printf
+ (_("Note: the local copy of the secret key"
+ " will only be deleted with \"save\".\n"));
+ }
+
do
{
xfree (answer);
@@ -1822,10 +1833,12 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
if (node)
{
PKT_public_key *xxpk = node->pkt->pkt.public_key;
- if (card_store_subkey (node, xxpk ? xxpk->pubkey_usage : 0))
+ if (card_store_subkey (node, xxpk ? xxpk->pubkey_usage : 0,
+ &delseckey_list))
{
redisplay = 1;
sec_shadowing = 1;
+ delseckey_list_warn = 1;
}
}
}
@@ -1902,7 +1915,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
pkt->pkttype = PKT_PUBLIC_KEY;
/* Ask gpg-agent to store the secret key to card. */
- if (card_store_subkey (node, 0))
+ if (card_store_subkey (node, 0, NULL))
{
redisplay = 1;
sec_shadowing = 1;
@@ -2111,7 +2124,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
" for the selected user IDs? (y/N) ")
: _("Really update the preferences? (y/N) ")))
{
- if (menu_set_preferences (ctrl, keyblock))
+ if (menu_set_preferences (ctrl, keyblock, 0))
{
merge_keys_and_selfsig (ctrl, keyblock);
modified = 1;
@@ -2203,6 +2216,27 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
}
}
+ if (delseckey_list)
+ {
+ strlist_t sl;
+ for (err = 0, sl = delseckey_list; sl; sl = sl->next)
+ {
+ if (*sl->d)
+ {
+ err = agent_delete_key (ctrl, sl->d, NULL, 1/*force*/);
+ if (err)
+ break;
+ *sl->d = 0; /* Mark deleted. */
+ }
+ }
+ if (err)
+ {
+ log_error (_("deleting copy of secret key failed: %s\n"),
+ gpg_strerror (err));
+ break; /* the "save". */
+ }
+ }
+
if (sec_shadowing)
{
err = agent_scd_learn (NULL, 1);
@@ -2232,6 +2266,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
} /* End of the main command loop. */
leave:
+ free_strlist (delseckey_list);
release_kbnode (keyblock);
keydb_release (kdbhd);
xfree (answer);
@@ -2324,7 +2359,8 @@ quick_find_keyblock (ctrl_t ctrl, const char *username, int want_secret,
/* We require the secret primary key to set the primary UID. */
node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
log_assert (node);
- err = agent_probe_secret_key (ctrl, node->pkt->pkt.public_key);
+ if (!agent_probe_secret_key (ctrl, node->pkt->pkt.public_key))
+ err = gpg_error (GPG_ERR_NO_SECKEY);
}
}
else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
@@ -2604,6 +2640,45 @@ keyedit_quick_set_primary (ctrl_t ctrl, const char *username,
}
+/* Unattended updating of the preference tro the standard preferences.
+ * USERNAME specifies the key. This is basically the same as
+ * gpg --edit-key <<userif> updpref save
+ */
+void
+keyedit_quick_update_pref (ctrl_t ctrl, const char *username)
+{
+ gpg_error_t err;
+ KEYDB_HANDLE kdbhd = NULL;
+ kbnode_t keyblock = NULL;
+
+#ifdef HAVE_W32_SYSTEM
+ /* See keyedit_menu for why we need this. */
+ check_trustdb_stale (ctrl);
+#endif
+
+ err = quick_find_keyblock (ctrl, username, 1, &kdbhd, &keyblock);
+ if (err)
+ goto leave;
+
+ if (menu_set_preferences (ctrl, keyblock, 1))
+ {
+ merge_keys_and_selfsig (ctrl, keyblock);
+ err = keydb_update_keyblock (ctrl, kdbhd, keyblock);
+ if (err)
+ {
+ log_error (_("update failed: %s\n"), gpg_strerror (err));
+ goto leave;
+ }
+ }
+
+ leave:
+ if (err)
+ write_status_error ("keyedit.updpref", err);
+ release_kbnode (keyblock);
+ keydb_release (kdbhd);
+}
+
+
/* Find a keyblock by fingerprint because only this uniquely
* identifies a key and may thus be used to select a key for
* unattended subkey creation os key signing. */
@@ -2684,7 +2759,7 @@ void
keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
strlist_t locusr, int local)
{
- gpg_error_t err;
+ gpg_error_t err = 0;
kbnode_t keyblock = NULL;
KEYDB_HANDLE kdbhd = NULL;
int modified = 0;
@@ -2722,6 +2797,7 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
if (!opt.verbose)
show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
log_error ("%s%s", _("Key is revoked."), _(" Unable to sign.\n"));
+ err = gpg_error (GPG_ERR_CERT_REVOKED);
goto leave;
}
@@ -2799,6 +2875,7 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
sl->d, gpg_strerror (GPG_ERR_NOT_FOUND));
}
log_error ("%s %s", _("No matching user IDs."), _("Nothing to sign.\n"));
+ err = gpg_error (GPG_ERR_NO_USER_ID);
goto leave;
}
@@ -2821,8 +2898,9 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
if (update_trust)
revalidation_mark (ctrl);
-
leave:
+ if (err)
+ write_status_error ("keyedit.sign-key", err);
release_kbnode (keyblock);
keydb_release (kdbhd);
}
@@ -2838,7 +2916,7 @@ void
keyedit_quick_revsig (ctrl_t ctrl, const char *username, const char *sigtorev,
strlist_t affected_uids)
{
- gpg_error_t err;
+ gpg_error_t err = 0;
int no_signing_key = 0;
KEYDB_HANDLE kdbhd = NULL;
kbnode_t keyblock = NULL;
@@ -3316,146 +3394,12 @@ tty_print_notations (int indent, PKT_signature * sig)
static void
show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose)
{
- const prefitem_t fake = { 0, 0 };
- const prefitem_t *prefs;
- int i;
-
if (!uid)
return;
- if (uid->prefs)
- prefs = uid->prefs;
- else if (verbose)
- prefs = &fake;
- else
- return;
-
if (verbose)
{
- int any, des_seen = 0, sha1_seen = 0, uncomp_seen = 0;
-
- tty_printf (" ");
- tty_printf (_("Cipher: "));
- for (i = any = 0; prefs[i].type; i++)
- {
- if (prefs[i].type == PREFTYPE_SYM)
- {
- if (any)
- tty_printf (", ");
- any = 1;
- /* We don't want to display strings for experimental algos */
- if (!openpgp_cipher_test_algo (prefs[i].value)
- && prefs[i].value < 100)
- tty_printf ("%s", openpgp_cipher_algo_name (prefs[i].value));
- else
- tty_printf ("[%d]", prefs[i].value);
- if (prefs[i].value == CIPHER_ALGO_3DES)
- des_seen = 1;
- }
- }
- if (!des_seen)
- {
- if (any)
- tty_printf (", ");
- tty_printf ("%s", openpgp_cipher_algo_name (CIPHER_ALGO_3DES));
- }
- tty_printf ("\n ");
- tty_printf (_("AEAD: "));
- for (i = any = 0; prefs[i].type; i++)
- {
- if (prefs[i].type == PREFTYPE_AEAD)
- {
- if (any)
- tty_printf (", ");
- any = 1;
- /* We don't want to display strings for experimental algos */
- if (!openpgp_aead_test_algo (prefs[i].value)
- && prefs[i].value < 100)
- tty_printf ("%s", openpgp_aead_algo_name (prefs[i].value));
- else
- tty_printf ("[%d]", prefs[i].value);
- }
- }
- tty_printf ("\n ");
- tty_printf (_("Digest: "));
- for (i = any = 0; prefs[i].type; i++)
- {
- if (prefs[i].type == PREFTYPE_HASH)
- {
- if (any)
- tty_printf (", ");
- any = 1;
- /* We don't want to display strings for experimental algos */
- if (!gcry_md_test_algo (prefs[i].value) && prefs[i].value < 100)
- tty_printf ("%s", gcry_md_algo_name (prefs[i].value));
- else
- tty_printf ("[%d]", prefs[i].value);
- if (prefs[i].value == DIGEST_ALGO_SHA1)
- sha1_seen = 1;
- }
- }
- if (!sha1_seen)
- {
- if (any)
- tty_printf (", ");
- tty_printf ("%s", gcry_md_algo_name (DIGEST_ALGO_SHA1));
- }
- tty_printf ("\n ");
- tty_printf (_("Compression: "));
- for (i = any = 0; prefs[i].type; i++)
- {
- if (prefs[i].type == PREFTYPE_ZIP)
- {
- const char *s = compress_algo_to_string (prefs[i].value);
-
- if (any)
- tty_printf (", ");
- any = 1;
- /* We don't want to display strings for experimental algos */
- if (s && prefs[i].value < 100)
- tty_printf ("%s", s);
- else
- tty_printf ("[%d]", prefs[i].value);
- if (prefs[i].value == COMPRESS_ALGO_NONE)
- uncomp_seen = 1;
- }
- }
- if (!uncomp_seen)
- {
- if (any)
- tty_printf (", ");
- else
- {
- tty_printf ("%s", compress_algo_to_string (COMPRESS_ALGO_ZIP));
- tty_printf (", ");
- }
- tty_printf ("%s", compress_algo_to_string (COMPRESS_ALGO_NONE));
- }
- if (uid->flags.mdc || uid->flags.aead || !uid->flags.ks_modify)
- {
- tty_printf ("\n ");
- tty_printf (_("Features: "));
- any = 0;
- if (uid->flags.mdc)
- {
- tty_printf ("MDC");
- any = 1;
- }
- if (!uid->flags.aead)
- {
- if (any)
- tty_printf (", ");
- tty_printf ("AEAD");
- }
- if (!uid->flags.ks_modify)
- {
- if (any)
- tty_printf (", ");
- tty_printf (_("Keyserver no-modify"));
- }
- }
- tty_printf ("\n");
-
+ show_preferences (uid, 4, -1, 1);
if (selfsig)
{
const byte *pref_ks;
@@ -3481,22 +3425,7 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose)
}
else
{
- tty_printf (" ");
- for (i = 0; prefs[i].type; i++)
- {
- tty_printf (" %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' :
- prefs[i].type == PREFTYPE_AEAD ? 'A' :
- prefs[i].type == PREFTYPE_HASH ? 'H' :
- prefs[i].type == PREFTYPE_ZIP ? 'Z' : '?',
- prefs[i].value);
- }
- if (uid->flags.mdc)
- tty_printf (" [mdc]");
- if (uid->flags.aead)
- tty_printf (" [aead]");
- if (!uid->flags.ks_modify)
- tty_printf (" [no-ks-modify]");
- tty_printf ("\n");
+ show_preferences (uid, 4, -1, 0);
}
}
@@ -3532,7 +3461,7 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
}
keyid_from_pk (pk, keyid);
- have_seckey = !agent_probe_secret_key (ctrl, pk);
+ have_seckey = agent_probe_secret_key (ctrl, pk);
if (node->pkt->pkttype == PKT_PUBLIC_KEY)
es_fputs (have_seckey? "sec:" : "pub:", fp);
@@ -3573,6 +3502,12 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
es_putc ('c', fp);
if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
es_putc ('a', fp);
+ if ((pk->pubkey_usage & PUBKEY_USAGE_RENC))
+ es_putc ('r', fp);
+ if ((pk->pubkey_usage & PUBKEY_USAGE_TIME))
+ es_putc ('t', fp);
+ if ((pk->pubkey_usage & PUBKEY_USAGE_GROUP))
+ es_putc ('g', fp);
es_putc ('\n', fp);
print_fingerprint (ctrl, fp, pk, 0);
@@ -5212,10 +5147,11 @@ menu_set_primary_uid (ctrl_t ctrl, kbnode_t pub_keyblock)
/*
- * Set preferences to new values for the selected user IDs
+ * Set preferences to new values for the selected user IDs.
+ * --quick-update-pred calls this with UNATTENDED set.
*/
static int
-menu_set_preferences (ctrl_t ctrl, kbnode_t pub_keyblock)
+menu_set_preferences (ctrl_t ctrl, kbnode_t pub_keyblock, int unattended)
{
PKT_public_key *main_pk;
PKT_user_id *uid;
@@ -5224,9 +5160,10 @@ menu_set_preferences (ctrl_t ctrl, kbnode_t pub_keyblock)
int selected, select_all;
int modified = 0;
- no_primary_warning (pub_keyblock);
+ if (!unattended)
+ no_primary_warning (pub_keyblock);
- select_all = !count_selected_uids (pub_keyblock);
+ select_all = unattended? 1 : !count_selected_uids (pub_keyblock);
/* Now we can actually change the self signature(s) */
main_pk = NULL;