aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2014-11-02 16:51:30 +0000
committerWerner Koch <[email protected]>2014-11-02 16:51:30 +0000
commitf8c993fbe28bf02f1d7aadec823a9dfc935398fa (patch)
tree25df6f48fa9dc581b98f0d0a33d0506cf9c71e32
parentgpg: Fix endless loop in keylisting with fingerprint. (diff)
downloadgnupg-f8c993fbe28bf02f1d7aadec823a9dfc935398fa.tar.gz
gnupg-f8c993fbe28bf02f1d7aadec823a9dfc935398fa.zip
gpg: Avoid extra pinentries for each subkey in --export-secret-keys.
* agent/command.c (cmd_export_key): Actually implement the cache_nonce feature. * g10/export.c (do_export_stream): Make use of a cache_nonce. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--agent/command.c30
-rw-r--r--g10/call-agent.c6
-rw-r--r--g10/export.c6
3 files changed, 35 insertions, 7 deletions
diff --git a/agent/command.c b/agent/command.c
index 8c6849840..7f8759d22 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -2127,16 +2127,19 @@ cmd_export_key (assuan_context_t ctx, char *line)
char *cache_nonce;
char *passphrase = NULL;
unsigned char *shadow_info = NULL;
+ char *pend;
+ int c;
openpgp = has_option (line, "--openpgp");
cache_nonce = option_value (line, "--cache-nonce");
if (cache_nonce)
{
- for (; *line && !spacep (line); line++)
+ for (pend = cache_nonce; *pend && !spacep (pend); pend++)
;
- if (*line)
- *line++ = '\0';
+ c = *pend;
+ *pend = '\0';
cache_nonce = xtrystrdup (cache_nonce);
+ *pend = c;
if (!cache_nonce)
{
err = gpg_error_from_syserror ();
@@ -2163,7 +2166,8 @@ cmd_export_key (assuan_context_t ctx, char *line)
/* Get the key from the file. With the openpgp flag we also ask for
the passphrase so that we can use it to re-encrypt it. */
- err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
+ err = agent_key_from_file (ctrl, cache_nonce,
+ ctrl->server_local->keydesc, grip,
&shadow_info, CACHE_MODE_IGNORE, NULL, &s_skey,
openpgp ? &passphrase : NULL);
if (err)
@@ -2190,6 +2194,24 @@ cmd_export_key (assuan_context_t ctx, char *line)
goto leave;
}
err = convert_to_openpgp (ctrl, s_skey, passphrase, &key, &keylen);
+ if (!err && passphrase)
+ {
+ if (!cache_nonce)
+ {
+ char buf[12];
+ gcry_create_nonce (buf, 12);
+ cache_nonce = bin2hex (buf, 12, NULL);
+ }
+ if (cache_nonce
+ && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
+ passphrase, CACHE_TTL_NONCE))
+ {
+ assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
+ xfree (ctrl->server_local->last_cache_nonce);
+ ctrl->server_local->last_cache_nonce = cache_nonce;
+ cache_nonce = NULL;
+ }
+ }
}
else
{
diff --git a/g10/call-agent.c b/g10/call-agent.c
index cadc02c6f..bacb9d5e0 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -2152,8 +2152,10 @@ agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
/* Receive a secret key from the agent. HEXKEYGRIP is the hexified
keygrip, DESC a prompt to be displayed with the agent's passphrase
- question (needs to be plus+percent escaped). On success the key is
- stored as a canonical S-expression at R_RESULT and R_RESULTLEN. */
+ question (needs to be plus+percent escaped). If CACHE_NONCE_ADDR
+ is not NULL the agent is advised to first try a passphrase
+ associated with that nonce. On success the key is stored as a
+ canonical S-expression at R_RESULT and R_RESULTLEN. */
gpg_error_t
agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
char **cache_nonce_addr,
diff --git a/g10/export.c b/g10/export.c
index b4f1a2e4d..a92eace12 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -777,6 +777,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
strlist_t sl;
int indent = 0;
gcry_cipher_hd_t cipherhd = NULL;
+ char *cache_nonce = NULL;
*any = 0;
init_packet (&pkt);
@@ -914,6 +915,8 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
clean_key (keyblock, opt.verbose, (options&EXPORT_MINIMAL), NULL, NULL);
/* And write it. */
+ xfree (cache_nonce);
+ cache_nonce = NULL;
for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
{
if (skip_until_subkey)
@@ -1124,7 +1127,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
{
char *prompt = gpg_format_keydesc (pk,
FORMAT_KEYDESC_EXPORT,1);
- err = agent_export_key (ctrl, hexgrip, prompt, NULL,
+ err = agent_export_key (ctrl, hexgrip, prompt, &cache_nonce,
&wrappedkey, &wrappedkeylen);
xfree (prompt);
}
@@ -1246,6 +1249,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
keydb_release (kdbhd);
if (err || !keyblock_out)
release_kbnode( keyblock );
+ xfree (cache_nonce);
if( !*any )
log_info(_("WARNING: nothing exported\n"));
return err;