mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
gpg: Improve speed of secret key listing.
* agent/command.c (cmd_keyinfo): Factor some code out to ... (get_keyinfo_on_cards): ... new. (cmd_havekey): Add --list mode. * g10/gpg.h (struct server_control_s): Add new caching vars. * g10/gpg.c (gpg_deinit_default_ctrl): Release cache. * g10/call-agent.c (agent_probe_any_secret_key): Init and try to use the keygrip cache. (agent_genkey): Clear the cache. (agent_import_key): Ditto. * g10/keylist.c (list_all, list_one): Pass ctrl to agent_probe_any_secret_key. * g10/getkey.c (lookup): Ditto. -- With this change we first ask the agent for a list of all secret keygrips and use that list instead of asking the agent for each public key. Speeds up my "gpg -K" with a lot of secret and public keys by more than 25%. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
b8e6e485ee
commit
40da61b89b
6 changed files with 246 additions and 55 deletions
102
g10/call-agent.c
102
g10/call-agent.c
|
@ -2236,13 +2236,50 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
|
|||
char line[ASSUAN_LINELENGTH];
|
||||
char *p;
|
||||
kbnode_t kbctx, node;
|
||||
int nkeys;
|
||||
int nkeys; /* (always zero in secret_keygrips mode) */
|
||||
unsigned char grip[KEYGRIP_LEN];
|
||||
const unsigned char *s;
|
||||
unsigned int n;
|
||||
|
||||
err = start_agent (ctrl, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* If we have not yet issued a "HAVEKEY --list" do that now. We use
|
||||
* a more or less arbitray limit of 1000 keys. */
|
||||
if (ctrl && !ctrl->secret_keygrips && !ctrl->no_more_secret_keygrips)
|
||||
{
|
||||
membuf_t data;
|
||||
|
||||
init_membuf (&data, 4096);
|
||||
err = assuan_transact (agent_ctx, "HAVEKEY --list=1000",
|
||||
put_membuf_cb, &data,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (err)
|
||||
xfree (get_membuf (&data, NULL));
|
||||
else
|
||||
{
|
||||
ctrl->secret_keygrips = get_membuf (&data,
|
||||
&ctrl->secret_keygrips_len);
|
||||
if (!ctrl->secret_keygrips)
|
||||
err = gpg_error_from_syserror ();
|
||||
if ((ctrl->secret_keygrips_len % 20))
|
||||
{
|
||||
err = gpg_error (GPG_ERR_INV_DATA);
|
||||
xfree (ctrl->secret_keygrips);
|
||||
ctrl->secret_keygrips = NULL;
|
||||
}
|
||||
}
|
||||
if (err)
|
||||
{
|
||||
log_info ("problem with fast path key listing: %s - ignored\n",
|
||||
gpg_strerror (err));
|
||||
err = 0;
|
||||
}
|
||||
/* We want to do this only once. */
|
||||
ctrl->no_more_secret_keygrips = 1;
|
||||
}
|
||||
|
||||
err = gpg_error (GPG_ERR_NO_SECKEY); /* Just in case no key was
|
||||
found in KEYBLOCK. */
|
||||
p = stpcpy (line, "HAVEKEY");
|
||||
|
@ -2252,23 +2289,42 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
|
|||
|| node->pkt->pkttype == PKT_SECRET_KEY
|
||||
|| node->pkt->pkttype == PKT_SECRET_SUBKEY)
|
||||
{
|
||||
if (nkeys && ((p - line) + 41) > (ASSUAN_LINELENGTH - 2))
|
||||
if (ctrl && ctrl->secret_keygrips)
|
||||
{
|
||||
err = assuan_transact (agent_ctx, line,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (err != gpg_err_code (GPG_ERR_NO_SECKEY))
|
||||
break; /* Seckey available or unexpected error - ready. */
|
||||
p = stpcpy (line, "HAVEKEY");
|
||||
nkeys = 0;
|
||||
/* We got an array with all secret keygrips. Check this. */
|
||||
err = keygrip_from_pk (node->pkt->pkt.public_key, grip);
|
||||
if (err)
|
||||
return err;
|
||||
for (s=ctrl->secret_keygrips, n = 0;
|
||||
n < ctrl->secret_keygrips_len;
|
||||
s += 20, n += 20)
|
||||
{
|
||||
if (!memcmp (s, grip, 20))
|
||||
return 0;
|
||||
}
|
||||
err = gpg_error (GPG_ERR_NO_SECKEY);
|
||||
/* Keep on looping over the keyblock. Never bump nkeys. */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nkeys && ((p - line) + 41) > (ASSUAN_LINELENGTH - 2))
|
||||
{
|
||||
err = assuan_transact (agent_ctx, line,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (err != gpg_err_code (GPG_ERR_NO_SECKEY))
|
||||
break; /* Seckey available or unexpected error - ready. */
|
||||
p = stpcpy (line, "HAVEKEY");
|
||||
nkeys = 0;
|
||||
}
|
||||
|
||||
err = keygrip_from_pk (node->pkt->pkt.public_key, grip);
|
||||
if (err)
|
||||
return err;
|
||||
*p++ = ' ';
|
||||
bin2hex (grip, 20, p);
|
||||
p += 40;
|
||||
nkeys++;
|
||||
err = keygrip_from_pk (node->pkt->pkt.public_key, grip);
|
||||
if (err)
|
||||
return err;
|
||||
*p++ = ' ';
|
||||
bin2hex (grip, 20, p);
|
||||
p += 40;
|
||||
nkeys++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!err && nkeys)
|
||||
|
@ -2419,6 +2475,14 @@ agent_genkey (ctrl_t ctrl, char **cache_nonce_addr, char **passwd_nonce_addr,
|
|||
return err;
|
||||
dfltparm.ctx = agent_ctx;
|
||||
|
||||
/* Do not use our cache of secret keygrips anymore - this command
|
||||
* would otherwise requiring to update that cache. */
|
||||
if (ctrl && ctrl->secret_keygrips)
|
||||
{
|
||||
xfree (ctrl->secret_keygrips);
|
||||
ctrl->secret_keygrips = 0;
|
||||
}
|
||||
|
||||
if (timestamp)
|
||||
{
|
||||
strcpy (timestamparg, " --timestamp=");
|
||||
|
@ -2876,6 +2940,14 @@ agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
|
|||
return err;
|
||||
dfltparm.ctx = agent_ctx;
|
||||
|
||||
/* Do not use our cache of secret keygrips anymore - this command
|
||||
* would otherwise requiring to update that cache. */
|
||||
if (ctrl && ctrl->secret_keygrips)
|
||||
{
|
||||
xfree (ctrl->secret_keygrips);
|
||||
ctrl->secret_keygrips = 0;
|
||||
}
|
||||
|
||||
if (timestamp)
|
||||
{
|
||||
strcpy (timestamparg, " --timestamp=");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue