summaryrefslogtreecommitdiffstats
path: root/agent/command.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-05-22 10:50:12 +0200
committerWerner Koch <wk@gnupg.org>2013-05-22 10:14:57 +0200
commit7777e68d0482c942f527e91c04adbcfb40bc8bef (patch)
treea739b575f0495cf34116f11abaa1f85e86f747e2 /agent/command.c
parentNew debug functions log_printcanon and log_printsexp. (diff)
downloadgnupg2-7777e68d0482c942f527e91c04adbcfb40bc8bef.tar.xz
gnupg2-7777e68d0482c942f527e91c04adbcfb40bc8bef.zip
Implement unattended OpenPGP secret key import.
* agent/command.c (cmd_import_key): Add option --unattended. * agent/cvt-openpgp.c (convert_transfer_key): New. (do_unprotect): Factor some code out to ... (prepare_unprotect): new function. (convert_from_openpgp): Factor all code out to ... (convert_from_openpgp_main): this. Add arg 'passphrase'. Implement openpgp-native protection modes. (convert_from_openpgp_native): New. * agent/t-protect.c (convert_from_openpgp_native): New dummy fucntion * agent/protect-tool.c (convert_from_openpgp_native): Ditto. * agent/protect.c (agent_unprotect): Add arg CTRL. Adjust all callers. Support openpgp-native protection. * g10/call-agent.c (agent_import_key): Add arg 'unattended'. * g10/import.c (transfer_secret_keys): Use unattended in batch mode. -- With the gpg-agent taking care of the secret keys, the user needs to migrate existing keys from secring.gpg to the agent. This and also the standard import of secret keys required the user to unprotect the secret keys first, so that gpg-agent was able to re-protected them using its own scheme. With many secret keys this is quite some usability hurdle. In particular if a passphrase is not instantly available. To make this migration smoother, this patch implements an unattended key import/migration which delays the conversion to the gpg-agent format until the key is actually used. For example: gpg2 --batch --import mysecretkey.gpg works without any user interaction due to the use of --batch. Now if a key is used (e.g. "gpg2 -su USERID_FROM_MYSECRETKEY foo"), gpg-agent has to ask for the passphrase anyway, converts the key from the openpgp format to the internal format, signs, re-encrypts the key and tries to store it in the gpg-agent format to the disk. The next time, the internal format of the key is used. This patch has only been tested with the old demo keys, more tests with other protection formats and no protection are needed. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'agent/command.c')
-rw-r--r--agent/command.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/agent/command.c b/agent/command.c
index e57c69d05..036486856 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -1,6 +1,7 @@
/* command.c - gpg-agent command handler
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010,
* 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013 Werner Koch
*
* This file is part of GnuPG.
*
@@ -1807,18 +1808,21 @@ cmd_keywrap_key (assuan_context_t ctx, char *line)
static const char hlp_import_key[] =
- "IMPORT_KEY [<cache_nonce>]\n"
+ "IMPORT_KEY [--unattended] [<cache_nonce>]\n"
"\n"
"Import a secret key into the key store. The key is expected to be\n"
"encrypted using the current session's key wrapping key (cf. command\n"
"KEYWRAP_KEY) using the AESWRAP-128 algorithm. This function takes\n"
"no arguments but uses the inquiry \"KEYDATA\" to ask for the actual\n"
- "key data. The unwrapped key must be a canonical S-expression.";
+ "key data. The unwrapped key must be a canonical S-expression. The\n"
+ "option --unattended tries to import the key as-is without any\n"
+ "re-encryption";
static gpg_error_t
cmd_import_key (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
gpg_error_t err;
+ int opt_unattended;
unsigned char *wrappedkey = NULL;
size_t wrappedkeylen;
gcry_cipher_hd_t cipherhd = NULL;
@@ -1838,6 +1842,9 @@ cmd_import_key (assuan_context_t ctx, char *line)
goto leave;
}
+ opt_unattended = has_option (line, "--unattended");
+ line = skip_options (line);
+
p = line;
for (p=line; *p && *p != ' ' && *p != '\t'; p++)
;
@@ -1921,7 +1928,7 @@ cmd_import_key (assuan_context_t ctx, char *line)
key = NULL;
err = convert_from_openpgp (ctrl, openpgp_sexp, grip,
ctrl->server_local->keydesc, cache_nonce,
- &key, &passphrase);
+ &key, opt_unattended? NULL : &passphrase);
if (err)
goto leave;
realkeylen = gcry_sexp_canon_len (key, 0, NULL, &err);
@@ -1929,6 +1936,7 @@ cmd_import_key (assuan_context_t ctx, char *line)
goto leave; /* Invalid canonical encoded S-expression. */
if (passphrase)
{
+ assert (!opt_unattended);
if (!cache_nonce)
{
char buf[12];
@@ -1941,6 +1949,12 @@ cmd_import_key (assuan_context_t ctx, char *line)
assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
}
}
+ else if (opt_unattended)
+ {
+ err = set_error (GPG_ERR_ASS_PARAMETER,
+ "\"--unattended\" may only be used with OpenPGP keys");
+ goto leave;
+ }
else
{
if (!agent_key_available (grip))
@@ -1957,7 +1971,7 @@ cmd_import_key (assuan_context_t ctx, char *line)
if (passphrase)
{
err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
- ctrl->s2k_count);
+ ctrl->s2k_count);
if (!err)
err = agent_write_private_key (grip, finalkey, finalkeylen, 0);
}