1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-03 12:11:33 +01:00

gpg: Re-enable secret key deletion.

* g10/call-agent.c (agent_delete_key): New.
* g10/keydb.h (FORMAT_KEYDESC_DELKEY): New.
* g10/passphrase.c (gpg_format_keydesc): Support new format.
* g10/delkey.c (do_delete_key): Add secret key deletion.
This commit is contained in:
Werner Koch 2014-04-15 16:40:48 +02:00
parent d25d00b89e
commit db3b528239
7 changed files with 121 additions and 6 deletions

View File

@ -818,6 +818,7 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
- 1 :: No such key - 1 :: No such key
- 2 :: Must delete secret key first - 2 :: Must delete secret key first
- 3 :: Ambigious specification - 3 :: Ambigious specification
- 4 :: Key is stored on a smartcard.
*** PROGRESS <what> <char> <cur> <total> *** PROGRESS <what> <char> <cur> <total>
Used by the primegen and Public key functions to indicate Used by the primegen and Public key functions to indicate

View File

@ -2126,6 +2126,44 @@ agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
} }
/* Ask the agent to delete the key identified by HEXKEYGRIP. If DESC
is not NULL, display DESC instead of the default description
message. */
gpg_error_t
agent_delete_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc)
{
gpg_error_t err;
char line[ASSUAN_LINELENGTH];
struct default_inq_parm_s dfltparm;
memset (&dfltparm, 0, sizeof dfltparm);
dfltparm.ctrl = ctrl;
err = start_agent (ctrl, 0);
if (err)
return err;
if (!hexkeygrip || strlen (hexkeygrip) != 40)
return gpg_error (GPG_ERR_INV_VALUE);
if (desc)
{
snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
err = assuan_transact (agent_ctx, line,
NULL, NULL, NULL, NULL, NULL, NULL);
if (err)
return err;
}
snprintf (line, DIM(line)-1, "DELETE_KEY %s", hexkeygrip);
err = assuan_transact (agent_ctx, line, NULL, NULL,
default_inq_cb, &dfltparm,
NULL, NULL);
return err;
}
/* Ask the agent to change the passphrase of the key identified by /* Ask the agent to change the passphrase of the key identified by
HEXKEYGRIP. If DESC is not NULL, display DESC instead of the HEXKEYGRIP. If DESC is not NULL, display DESC instead of the

View File

@ -185,6 +185,10 @@ gpg_error_t agent_export_key (ctrl_t ctrl, const char *keygrip,
const char *desc, char **cache_nonce_addr, const char *desc, char **cache_nonce_addr,
unsigned char **r_result, size_t *r_resultlen); unsigned char **r_result, size_t *r_resultlen);
/* Delete a key from the agent. */
gpg_error_t agent_delete_key (ctrl_t ctrl, const char *hexkeygrip,
const char *desc);
/* Change the passphrase of a key. */ /* Change the passphrase of a key. */
gpg_error_t agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc, gpg_error_t agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
char **cache_nonce_addr, char **passwd_nonce_addr); char **cache_nonce_addr, char **passwd_nonce_addr);

View File

@ -40,6 +40,7 @@
#include "ttyio.h" #include "ttyio.h"
#include "status.h" #include "status.h"
#include "i18n.h" #include "i18n.h"
#include "call-agent.h"
/**************** /****************
@ -52,7 +53,7 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
{ {
gpg_error_t err; gpg_error_t err;
kbnode_t keyblock = NULL; kbnode_t keyblock = NULL;
kbnode_t node; kbnode_t node, kbctx;
KEYDB_HANDLE hd; KEYDB_HANDLE hd;
PKT_public_key *pk = NULL; PKT_public_key *pk = NULL;
u32 keyid[2]; u32 keyid[2];
@ -156,9 +157,47 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
{ {
if (secret) if (secret)
{ {
log_error (_("deleting secret key not implemented\n")); char *prompt;
err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); /* FIXME */ gpg_error_t firsterr = 0;
goto leave; char *hexgrip;
setup_main_keyids (keyblock);
for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
{
if (!(node->pkt->pkttype == PKT_PUBLIC_KEY
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY))
continue;
if (agent_probe_secret_key (NULL, node->pkt->pkt.public_key))
continue; /* No secret key for that public (sub)key. */
prompt = gpg_format_keydesc (node->pkt->pkt.public_key,
FORMAT_KEYDESC_DELKEY, 1);
err = hexkeygrip_from_pk (node->pkt->pkt.public_key, &hexgrip);
if (!err)
err = agent_delete_key (NULL, hexgrip, prompt);
xfree (prompt);
xfree (hexgrip);
if (err)
{
if (gpg_err_code (err) == GPG_ERR_KEY_ON_CARD)
write_status_text (STATUS_DELETE_PROBLEM, "1");
log_error (_("deleting secret %s failed: %s\n"),
(node->pkt->pkttype == PKT_PUBLIC_KEY
? _("key"):_("subkey")),
gpg_strerror (err));
if (!firsterr)
firsterr = err;
if (gpg_err_code (err) == GPG_ERR_CANCELED
|| gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
break;
}
}
err = firsterr;
if (firsterr)
goto leave;
} }
else else
{ {

View File

@ -1237,6 +1237,38 @@ getkey_end (getkey_ctx_t ctx)
************* Merging stuff ******************** ************* Merging stuff ********************
************************************************/ ************************************************/
/* Set the mainkey_id fields for all keys in KEYBLOCK. This is
usually done by merge_selfsigs but at some places we only need the
main_kid but the the full merging. The function also guarantees
that all pk->keyids are computed. */
void
setup_main_keyids (kbnode_t keyblock)
{
u32 kid[2], mainkid[2];
kbnode_t kbctx, node;
PKT_public_key *pk;
if (keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
BUG ();
pk = keyblock->pkt->pkt.public_key;
keyid_from_pk (pk, mainkid);
for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
{
if (!(node->pkt->pkttype == PKT_PUBLIC_KEY
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY))
continue;
pk = node->pkt->pkt.public_key;
keyid_from_pk (pk, kid); /* Make sure pk->keyid is set. */
if (!pk->main_keyid[0] && !pk->main_keyid[1])
{
pk->main_keyid[0] = mainkid[0];
pk->main_keyid[1] = mainkid[1];
}
}
}
/* Merge all self-signatures with the keys. */ /* Merge all self-signatures with the keys. */
void void
merge_keys_and_selfsig (KBNODE keyblock) merge_keys_and_selfsig (KBNODE keyblock)

View File

@ -201,7 +201,7 @@ void emit_status_need_passphrase (u32 *keyid, u32 *mainkeyid, int pubkey_algo);
#define FORMAT_KEYDESC_NORMAL 0 #define FORMAT_KEYDESC_NORMAL 0
#define FORMAT_KEYDESC_IMPORT 1 #define FORMAT_KEYDESC_IMPORT 1
#define FORMAT_KEYDESC_EXPORT 2 #define FORMAT_KEYDESC_EXPORT 2
#define FORMAT_KEYDESC_DELKEY 3
char *gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped); char *gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped);
@ -248,6 +248,7 @@ void getkey_end (getkey_ctx_t ctx);
gpg_error_t enum_secret_keys (void **context, PKT_public_key *pk); gpg_error_t enum_secret_keys (void **context, PKT_public_key *pk);
void setup_main_keyids (kbnode_t keyblock);
void merge_keys_and_selfsig( KBNODE keyblock ); void merge_keys_and_selfsig( KBNODE keyblock );
char*get_user_id_string( u32 *keyid ); char*get_user_id_string( u32 *keyid );
char*get_user_id_string_native( u32 *keyid ); char*get_user_id_string_native( u32 *keyid );

View File

@ -702,7 +702,7 @@ gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped)
(int)uidlen, uid, (int)uidlen, uid,
nbits_from_pk (pk), algo_name, nbits_from_pk (pk), algo_name,
keystr (pk->keyid), timestr, keystr (pk->keyid), timestr,
maink?maink:"", trailer ); maink?maink:"", trailer);
xfree (maink); xfree (maink);
xfree (uid); xfree (uid);