mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
card: Cache the results from gpg and gpgsm.
* tools/card-tool-keys.c (keyblock_cache): New var. (release_keyblock): Factor code out to a new do_release_keyblock. Add a cache. (flush_keyblock_cache): New. (get_matching_keys): Use the cache. * tools/gpg-card-tool.c (cmds): Add command "reset". (interactive_loop): Implement reset. -- Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
833f27a6a7
commit
0107984f9f
@ -30,9 +30,22 @@
|
|||||||
#include "../common/openpgpdefs.h"
|
#include "../common/openpgpdefs.h"
|
||||||
#include "card-tool.h"
|
#include "card-tool.h"
|
||||||
|
|
||||||
/* Release a keyblocm object. */
|
|
||||||
void
|
/* It is quite common that all keys of an OpenPGP card belong to the
|
||||||
release_keyblock (keyblock_t keyblock)
|
* the same OpenPGP keyblock. To avoid running several queries
|
||||||
|
* despite that we already got the information with the previous
|
||||||
|
* keyblock, we keep a small cache of of previous done queries. */
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
unsigned int lru;
|
||||||
|
keyblock_t keyblock;
|
||||||
|
} keyblock_cache[5];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper for release_keyblock. */
|
||||||
|
static void
|
||||||
|
do_release_keyblock (keyblock_t keyblock)
|
||||||
{
|
{
|
||||||
pubkey_t pubkey;
|
pubkey_t pubkey;
|
||||||
userid_t uid;
|
userid_t uid;
|
||||||
@ -61,6 +74,62 @@ release_keyblock (keyblock_t keyblock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Release a keyblock object. */
|
||||||
|
void
|
||||||
|
release_keyblock (keyblock_t keyblock)
|
||||||
|
{
|
||||||
|
static unsigned int lru_counter;
|
||||||
|
unsigned int lru;
|
||||||
|
int i, lru_idx;
|
||||||
|
|
||||||
|
if (!keyblock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lru = (unsigned int)(-1);
|
||||||
|
lru_idx = 0;
|
||||||
|
for (i=0; i < DIM (keyblock_cache); i++)
|
||||||
|
{
|
||||||
|
if (!keyblock_cache[i].keyblock)
|
||||||
|
{
|
||||||
|
keyblock_cache[i].keyblock = keyblock;
|
||||||
|
keyblock_cache[i].lru = ++lru_counter;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
if (keyblock_cache[i].lru < lru)
|
||||||
|
{
|
||||||
|
lru = keyblock_cache[i].lru;
|
||||||
|
lru_idx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No free slot. Replace one. */
|
||||||
|
do_release_keyblock (keyblock_cache[lru_idx].keyblock);
|
||||||
|
keyblock_cache[lru_idx].keyblock = keyblock;
|
||||||
|
keyblock_cache[lru_idx].lru = ++lru_counter;
|
||||||
|
|
||||||
|
leave:
|
||||||
|
if (!lru_counter)
|
||||||
|
{
|
||||||
|
/* Wrapped around. We simply clear the entire cache. */
|
||||||
|
flush_keyblock_cache ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Flush the enire keyblock cache. */
|
||||||
|
void
|
||||||
|
flush_keyblock_cache (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i < DIM (keyblock_cache); i++)
|
||||||
|
{
|
||||||
|
do_release_keyblock (keyblock_cache[i].keyblock);
|
||||||
|
keyblock_cache[i].keyblock = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Object to communicate with the status_cb. */
|
/* Object to communicate with the status_cb. */
|
||||||
struct status_cb_s
|
struct status_cb_s
|
||||||
@ -127,6 +196,7 @@ get_matching_keys (const unsigned char *keygrip, int protocol,
|
|||||||
char **fields = NULL;
|
char **fields = NULL;
|
||||||
int nfields;
|
int nfields;
|
||||||
int first_seen;
|
int first_seen;
|
||||||
|
int i;
|
||||||
keyblock_t keyblock_head, *keyblock_tail, kb;
|
keyblock_t keyblock_head, *keyblock_tail, kb;
|
||||||
pubkey_t pubkey, pk;
|
pubkey_t pubkey, pk;
|
||||||
size_t n;
|
size_t n;
|
||||||
@ -168,6 +238,18 @@ get_matching_keys (const unsigned char *keygrip, int protocol,
|
|||||||
if (protocol != GNUPG_PROTOCOL_OPENPGP && protocol != GNUPG_PROTOCOL_CMS)
|
if (protocol != GNUPG_PROTOCOL_OPENPGP && protocol != GNUPG_PROTOCOL_CMS)
|
||||||
return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
|
return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
|
||||||
|
|
||||||
|
/* Try to get it from our cache. */
|
||||||
|
for (i=0; i < DIM (keyblock_cache); i++)
|
||||||
|
for (kb = keyblock_cache[i].keyblock; kb; kb = kb->next)
|
||||||
|
if (kb->protocol == protocol)
|
||||||
|
for (pk = kb->keys; pk; pk = pk->next)
|
||||||
|
if (pk->grip_valid && !memcmp (pk->grip, keygrip, KEYGRIP_LEN))
|
||||||
|
{
|
||||||
|
*r_keyblock = keyblock_cache[i].keyblock;
|
||||||
|
keyblock_cache[i].keyblock = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Open a memory stream. */
|
/* Open a memory stream. */
|
||||||
listing = es_fopenmem (0, "w+b");
|
listing = es_fopenmem (0, "w+b");
|
||||||
if (!listing)
|
if (!listing)
|
||||||
|
@ -181,6 +181,7 @@ typedef struct card_info_s *card_info_t;
|
|||||||
|
|
||||||
/*-- card-tool-keys.c --*/
|
/*-- card-tool-keys.c --*/
|
||||||
void release_keyblock (keyblock_t keyblock);
|
void release_keyblock (keyblock_t keyblock);
|
||||||
|
void flush_keyblock_cache (void);
|
||||||
gpg_error_t get_matching_keys (const unsigned char *keygrip, int protocol,
|
gpg_error_t get_matching_keys (const unsigned char *keygrip, int protocol,
|
||||||
keyblock_t *r_keyblock);
|
keyblock_t *r_keyblock);
|
||||||
gpg_error_t test_get_matching_keys (const char *hexgrip);
|
gpg_error_t test_get_matching_keys (const char *hexgrip);
|
||||||
|
@ -312,6 +312,8 @@ main (int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flush_keyblock_cache ();
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
gnupg_status_printf (STATUS_FAILURE, "- %u", err);
|
gnupg_status_printf (STATUS_FAILURE, "- %u", err);
|
||||||
else if (log_get_errorcount (0))
|
else if (log_get_errorcount (0))
|
||||||
@ -2639,6 +2641,7 @@ static struct
|
|||||||
{ "passwd" , cmdPASSWD, 0, N_("menu to change or unblock the PIN")},
|
{ "passwd" , cmdPASSWD, 0, N_("menu to change or unblock the PIN")},
|
||||||
{ "verify" , cmdVERIFY, 0, N_("verify the PIN and list all data")},
|
{ "verify" , cmdVERIFY, 0, N_("verify the PIN and list all data")},
|
||||||
{ "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code")},
|
{ "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code")},
|
||||||
|
{ "reset" , cmdRESET, 0, N_("send a reset to the card daemon")},
|
||||||
{ "factory-reset", cmdFACTORYRESET, 1, N_("destroy all keys and data")},
|
{ "factory-reset", cmdFACTORYRESET, 1, N_("destroy all keys and data")},
|
||||||
{ "kdf-setup", cmdKDFSETUP, 1, N_("setup KDF for PIN authentication")},
|
{ "kdf-setup", cmdKDFSETUP, 1, N_("setup KDF for PIN authentication")},
|
||||||
{ "key-attr", cmdKEYATTR, 1, N_("change the key attribute")},
|
{ "key-attr", cmdKEYATTR, 1, N_("change the key attribute")},
|
||||||
@ -2834,6 +2837,7 @@ interactive_loop (void)
|
|||||||
"Send a RESET to the card daemon.", 0);
|
"Send a RESET to the card daemon.", 0);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
flush_keyblock_cache ();
|
||||||
err = scd_apdu (NULL, NULL);
|
err = scd_apdu (NULL, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user