mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
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 <wk@gnupg.org>
This commit is contained in:
parent
6c368533f5
commit
6ab0fac575
@ -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". */
|
||||
};
|
||||
|
||||
|
||||
|
@ -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--;
|
||||
|
@ -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 (*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);
|
||||
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;
|
||||
|
@ -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);
|
||||
|
@ -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"))
|
||||
|
Loading…
x
Reference in New Issue
Block a user