aboutsummaryrefslogtreecommitdiffstats
path: root/agent/protect.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--agent/protect.c79
1 files changed, 75 insertions, 4 deletions
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"))