1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

gpg: Improve passphrase caching.

* agent/cache.c (last_stored_cache_key): New.
(agent_get_cache): Allow NULL for KEY.
(agent_store_cache_hit): New.
* agent/findkey.c (unprotect): Call new function and try to use the
last stored key.

* g10/revoke.c (create_revocation): Add arg CACHE_NONCE and pass to
make_keysig_packet.
(gen_standard_revoke): Add arg CACHE_NONCE and pass to
create_revocation.
* g10/keygen.c (do_generate_keypair): Call gen_standard_revoke with
cache nonce.
--

This patch adds two features:

1. The key for the last passphrase successfully used for unprotecting
a key is stored away.  On a cache miss the stored away passphrase is
tried as well.  This helps for the common GPG use case of having a
signing and encryption (sub)key with the same passphrase.  See the
code for more comments.

2. The now auto-generated revocation certificate does not anymore
popup a passphrase prompt.  Thus for standard key generation the
passphrase needs to be given only once (well, two with the
confirmation).
This commit is contained in:
Werner Koch 2014-09-17 15:12:08 +02:00
parent 83c2d2396c
commit 457bce5cd3
6 changed files with 81 additions and 9 deletions

View file

@ -65,6 +65,9 @@ struct cache_item_s {
/* The cache himself. */
static ITEM thecache;
/* NULL or the last cache key stored by agent_store_cache_hit. */
static char *last_stored_cache_key;
/* This function must be called once to initialize this module. It
has to be done before a second thread is spawned. */
@ -388,12 +391,24 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
ITEM r;
char *value = NULL;
int res;
int last_stored = 0;
if (cache_mode == CACHE_MODE_IGNORE)
return NULL;
if (!key)
{
key = last_stored_cache_key;
if (!key)
return NULL;
last_stored = 1;
}
if (DBG_CACHE)
log_debug ("agent_get_cache '%s' (mode %d) ...\n", key, cache_mode);
log_debug ("agent_get_cache '%s' (mode %d)%s ...\n",
key, cache_mode,
last_stored? " (stored cache key)":"");
housekeeping ();
for (r=thecache; r; r = r->next)
@ -404,6 +419,7 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
|| r->cache_mode == cache_mode)
&& !strcmp (r->key, key))
{
/* Note: To avoid races KEY may not be accessed anymore below. */
r->accessed = gnupg_get_time ();
if (DBG_CACHE)
log_debug ("... hit\n");
@ -442,3 +458,14 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
return NULL;
}
/* Store the key for the last successful cache hit. That value is
used by agent_get_cache if the requested KEY is given as NULL.
NULL may be used to remove that key. */
void
agent_store_cache_hit (const char *key)
{
xfree (last_stored_cache_key);
last_stored_cache_key = key? xtrystrdup (key) : NULL;
}