aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2015-01-29 15:26:07 +0000
committerWerner Koch <[email protected]>2015-01-29 15:26:07 +0000
commit6ab0fac575a8b04152a199cb300a08436b096753 (patch)
tree8a7309b2ef2a8493c1762963fc58049740a60a19
parentpo: Update Japanese Translation. (diff)
downloadgnupg-6ab0fac575a8b04152a199cb300a08436b096753.tar.gz
gnupg-6ab0fac575a8b04152a199cb300a08436b096753.zip
agent: Fix use of imported but unprotected openpgp keys.
* agent/agent.h (PRIVATE_KEY_OPENPGP_NONE): New. * agent/command.c (do_one_keyinfo): Implement it. * agent/findkey.c (agent_key_from_file): Ditto. (agent_key_info_from_file): Ditto. (agent_delete_key): Ditto. * agent/protect.c (agent_private_key_type): Add detection for openpgp "none" method. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--agent/agent.h3
-rw-r--r--agent/command.c8
-rw-r--r--agent/cvt-openpgp.c26
-rw-r--r--agent/findkey.c18
-rw-r--r--agent/protect.c79
5 files changed, 119 insertions, 15 deletions
diff --git a/agent/agent.h b/agent/agent.h
index 45362421d..f60061e6f 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -248,7 +248,8 @@ enum
PRIVATE_KEY_PROTECTED = 2, /* The key is protected. */
PRIVATE_KEY_SHADOWED = 3, /* The key is a stub for a smartcard
based key. */
- PROTECTED_SHARED_SECRET = 4 /* RFU. */
+ PROTECTED_SHARED_SECRET = 4, /* RFU. */
+ PRIVATE_KEY_OPENPGP_NONE = 5 /* openpgp-native with protection "none". */
};
diff --git a/agent/command.c b/agent/command.c
index d5644cbac..ca28e9ba2 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -1163,7 +1163,9 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
{
switch (keytype)
{
- case PRIVATE_KEY_CLEAR: protectionstr = "C"; keytypestr = "D";
+ case PRIVATE_KEY_CLEAR:
+ case PRIVATE_KEY_OPENPGP_NONE:
+ protectionstr = "C"; keytypestr = "D";
break;
case PRIVATE_KEY_PROTECTED: protectionstr = "P"; keytypestr = "D";
break;
@@ -1801,12 +1803,12 @@ cmd_passwd (assuan_context_t ctx, char *line)
}
}
if (!err && opt_preset)
- {
+ {
char hexgrip[40+1];
bin2hex(grip, 20, hexgrip);
err = agent_put_cache (hexgrip, CACHE_MODE_ANY, newpass,
ctrl->cache_ttl_opt_preset);
- }
+ }
xfree (newpass);
}
ctrl->in_passwd--;
diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c
index 8cf00233e..5f944934a 100644
--- a/agent/cvt-openpgp.c
+++ b/agent/cvt-openpgp.c
@@ -1051,13 +1051,25 @@ convert_from_openpgp_native (ctrl_t ctrl,
/* On success try to re-write the key. */
if (!err)
{
- unsigned char *protectedkey = NULL;
- size_t protectedkeylen;
-
- if (!agent_protect (*r_key, passphrase, &protectedkey, &protectedkeylen,
- ctrl->s2k_count))
- agent_write_private_key (grip, protectedkey, protectedkeylen, 1);
- xfree (protectedkey);
+ if (*passphrase)
+ {
+ unsigned char *protectedkey = NULL;
+ size_t protectedkeylen;
+
+ if (!agent_protect (*r_key, passphrase,
+ &protectedkey, &protectedkeylen,
+ ctrl->s2k_count))
+ agent_write_private_key (grip, protectedkey, protectedkeylen, 1);
+ xfree (protectedkey);
+ }
+ else
+ {
+ /* Empty passphrase: write key without protection. */
+ agent_write_private_key (grip,
+ *r_key,
+ gcry_sexp_canon_len (*r_key, 0, NULL,NULL),
+ 1);
+ }
}
return err;
diff --git a/agent/findkey.c b/agent/findkey.c
index 156102b4e..6f01789cd 100644
--- a/agent/findkey.c
+++ b/agent/findkey.c
@@ -664,6 +664,22 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
{
case PRIVATE_KEY_CLEAR:
break; /* no unprotection needed */
+ case PRIVATE_KEY_OPENPGP_NONE:
+ {
+ unsigned char *buf_new;
+ size_t buf_newlen;
+
+ rc = agent_unprotect (ctrl, buf, "", NULL, &buf_new, &buf_newlen);
+ if (rc)
+ log_error ("failed to convert unprotected openpgp key: %s\n",
+ gpg_strerror (rc));
+ else
+ {
+ xfree (buf);
+ buf = buf_new;
+ }
+ }
+ break;
case PRIVATE_KEY_PROTECTED:
{
char *desc_text_final;
@@ -1159,6 +1175,7 @@ agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
switch (keytype)
{
case PRIVATE_KEY_CLEAR:
+ case PRIVATE_KEY_OPENPGP_NONE:
break;
case PRIVATE_KEY_PROTECTED:
/* If we ever require it we could retrieve the comment fields
@@ -1230,6 +1247,7 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text,
switch (agent_private_key_type (buf))
{
case PRIVATE_KEY_CLEAR:
+ case PRIVATE_KEY_OPENPGP_NONE:
case PRIVATE_KEY_PROTECTED:
{
bin2hex (grip, 20, hexgrip);
diff --git a/agent/protect.c b/agent/protect.c
index 01e72c2ee..cdb39fd13 100644
--- a/agent/protect.c
+++ b/agent/protect.c
@@ -1,6 +1,6 @@
/* protect.c - Un/Protect a secret key
* Copyright (C) 1998-2003, 2007, 2009, 2011 Free Software Foundation, Inc.
- * Copyright (C) 1998-2003, 2007, 2009, 2011, 2013 Werner Koch
+ * Copyright (C) 1998-2003, 2007, 2009, 2011, 2013-2015 Werner Koch
*
* This file is part of GnuPG.
*
@@ -1101,13 +1101,16 @@ agent_unprotect (ctrl_t ctrl,
PRIVATE_KEY_UNKNOWN if we can't figure out the type (this is the
value 0), PRIVATE_KEY_CLEAR for an unprotected private key.
PRIVATE_KEY_PROTECTED for an protected private key or
- PRIVATE_KEY_SHADOWED for a sub key where the secret parts are stored
- elsewhere. */
+ PRIVATE_KEY_SHADOWED for a sub key where the secret parts are
+ stored elsewhere. Finally PRIVATE_KEY_OPENPGP_NONE may be returned
+ is the key is still in the openpgp-native format but without
+ protection. */
int
agent_private_key_type (const unsigned char *privatekey)
{
const unsigned char *s;
size_t n;
+ int i;
s = privatekey;
if (*s != '(')
@@ -1117,7 +1120,75 @@ agent_private_key_type (const unsigned char *privatekey)
if (!n)
return PRIVATE_KEY_UNKNOWN;
if (smatch (&s, n, "protected-private-key"))
- return PRIVATE_KEY_PROTECTED;
+ {
+ /* We need to check whether this is openpgp-native protected
+ with the protection method "none". In that case we return a
+ different key type so that the caller knows that there is no
+ need to ask for a passphrase. */
+ if (*s != '(')
+ return PRIVATE_KEY_PROTECTED; /* Unknown sexp - assume protected. */
+ s++;
+ n = snext (&s);
+ if (!n)
+ return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
+ s += n; /* Skip over the algo */
+
+ /* Find the (protected ...) list. */
+ for (;;)
+ {
+ if (*s != '(')
+ return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
+ s++;
+ n = snext (&s);
+ if (!n)
+ return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
+ if (smatch (&s, n, "protected"))
+ break;
+ s += n;
+ i = 1;
+ if (sskip (&s, &i))
+ return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
+ }
+ /* Found - Is this openpgp-native? */
+ n = snext (&s);
+ if (!n)
+ return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
+ if (smatch (&s, n, "openpgp-native")) /* Yes. */
+ {
+ if (*s != '(')
+ return PRIVATE_KEY_UNKNOWN; /* Unknown sexp. */
+ s++;
+ n = snext (&s);
+ if (!n)
+ return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
+ s += n; /* Skip over "openpgp-private-key". */
+ /* Find the (protection ...) list. */
+ for (;;)
+ {
+ if (*s != '(')
+ return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
+ s++;
+ n = snext (&s);
+ if (!n)
+ return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
+ if (smatch (&s, n, "protection"))
+ break;
+ s += n;
+ i = 1;
+ if (sskip (&s, &i))
+ return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
+ }
+ /* Found - Is the mode "none"? */
+ n = snext (&s);
+ if (!n)
+ return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
+ log_debug ("openpgp-native protection '%.*s'\n", (int)n, s);
+ if (smatch (&s, n, "none"))
+ return PRIVATE_KEY_OPENPGP_NONE; /* Yes. */
+ }
+
+ return PRIVATE_KEY_PROTECTED;
+ }
if (smatch (&s, n, "shadowed-private-key"))
return PRIVATE_KEY_SHADOWED;
if (smatch (&s, n, "private-key"))