From 5118beeec18f731fe3c0084b181eff9531181be6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 15 Mar 2023 09:36:36 +0100 Subject: [PATCH] gpg: Delete secret key after "keytocard". * g10/card-util.c (card_store_subkey): Add arg processed_keys. * g10/keyedit.c (keyedit_menu): Delete secret key. -- This used to work using the gpg-agent: learn we called at "save" time. However, the recent change inhibited the creation of a shadow key by learn if a regular key still exists. Now we do an explicit delete key at save time. This syncs the behaviour with the description of the man page. GnuPG-bug-id: 6378 --- g10/card-util.c | 17 +++++++++++------ g10/keyedit.c | 38 ++++++++++++++++++++++++++++++++++++-- g10/main.h | 2 +- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/g10/card-util.c b/g10/card-util.c index 02de241f2..6451b31e7 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -1781,12 +1781,13 @@ card_generate_subkey (ctrl_t ctrl, kbnode_t pub_keyblock) } -/* Store the key at NODE into the smartcard and modify NODE to - carry the serialno stuff instead of the actual secret key - parameters. USE is the usage for that key; 0 means any - usage. */ +/* Store the key at NODE into the smartcard and modify NODE to carry + the serialno stuff instead of the actual secret key parameters. + USE is the usage for that key; 0 means any usage. If + PROCESSED_KEYS is not NULL it is a poiter to an strlist which will + be filled with the keygrips of successfully stored keys. */ int -card_store_subkey (KBNODE node, int use) +card_store_subkey (KBNODE node, int use, strlist_t *processed_keys) { struct agent_card_info_s info; int okay = 0; @@ -1875,7 +1876,11 @@ card_store_subkey (KBNODE node, int use) if (rc) log_error (_("KEYTOCARD failed: %s\n"), gpg_strerror (rc)); else - okay = 1; + { + okay = 1; + if (processed_keys) + add_to_strlist (processed_keys, hexgrip); + } xfree (hexgrip); leave: diff --git a/g10/keyedit.c b/g10/keyedit.c index 6c45fd640..d21064a21 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1424,6 +1424,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) ; @@ -1500,6 +1502,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); @@ -1872,10 +1882,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; } } } @@ -1952,7 +1964,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; @@ -2262,6 +2274,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); @@ -2291,6 +2324,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); diff --git a/g10/main.h b/g10/main.h index f66f3ef0c..dbaa0c6f3 100644 --- a/g10/main.h +++ b/g10/main.h @@ -516,7 +516,7 @@ void change_pin (int no, int allow_admin); void card_status (ctrl_t ctrl, estream_t fp, const char *serialno); void card_edit (ctrl_t ctrl, strlist_t commands); gpg_error_t card_generate_subkey (ctrl_t ctrl, kbnode_t pub_keyblock); -int card_store_subkey (KBNODE node, int use); +int card_store_subkey (KBNODE node, int use, strlist_t *processed_keys); #endif /*-- migrate.c --*/