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:
parent
83c2d2396c
commit
457bce5cd3
6 changed files with 81 additions and 9 deletions
|
@ -372,6 +372,8 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
|||
rc = agent_unprotect (ctrl, *keybuf, pw, NULL, &result, &resultlen);
|
||||
if (!rc)
|
||||
{
|
||||
if (cache_mode == CACHE_MODE_NORMAL)
|
||||
agent_store_cache_hit (hexgrip);
|
||||
if (r_passphrase)
|
||||
*r_passphrase = pw;
|
||||
else
|
||||
|
@ -383,6 +385,45 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
|||
xfree (pw);
|
||||
rc = 0;
|
||||
}
|
||||
else if (cache_mode == CACHE_MODE_NORMAL)
|
||||
{
|
||||
/* The standard use of GPG keys is to have a signing and an
|
||||
encryption subkey. Commonly both use the same
|
||||
passphrase. We try to help the user to enter the
|
||||
passphrase only once by silently trying the last
|
||||
correctly entered passphrase. Checking one additional
|
||||
passphrase should be acceptable; despite the S2K
|
||||
introduced delays. The assumed workflow is:
|
||||
|
||||
1. Read encrypted message in a MUA and thus enter a
|
||||
passphrase for the encryption subkey.
|
||||
|
||||
2. Reply to that mail with an encrypted and signed
|
||||
mail, thus entering the passphrase for the signing
|
||||
subkey.
|
||||
|
||||
We can often avoid the passphrase entry in the second
|
||||
step. We do this only in normal mode, so not to
|
||||
interfere with unrelated cache entries. */
|
||||
pw = agent_get_cache (NULL, cache_mode);
|
||||
if (pw)
|
||||
{
|
||||
rc = agent_unprotect (ctrl, *keybuf, pw, NULL,
|
||||
&result, &resultlen);
|
||||
if (!rc)
|
||||
{
|
||||
if (r_passphrase)
|
||||
*r_passphrase = pw;
|
||||
else
|
||||
xfree (pw);
|
||||
xfree (*keybuf);
|
||||
*keybuf = result;
|
||||
return 0;
|
||||
}
|
||||
xfree (pw);
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the pinentry is currently in use, we wait up to 60 seconds
|
||||
for it to close and check the cache again. This solves a common
|
||||
|
@ -460,6 +501,7 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
|
|||
{
|
||||
agent_put_cache (hexgrip, cache_mode, pi->pin,
|
||||
lookup_ttl? lookup_ttl (hexgrip) : 0);
|
||||
agent_store_cache_hit (hexgrip);
|
||||
if (r_passphrase && *pi->pin)
|
||||
*r_passphrase = xtrystrdup (pi->pin);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue