mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
ssh: Support ECDSA keys.
* agent/command-ssh.c (SPEC_FLAG_IS_ECDSA): New. (struct ssh_key_type_spec): Add fields CURVE_NAME and HASH_ALGO. (ssh_key_types): Add types ecdsa-sha2-nistp{256,384,521}. (ssh_signature_encoder_t): Add arg spec and adjust all callers. (ssh_signature_encoder_ecdsa): New. (sexp_key_construct, sexp_key_extract, ssh_receive_key) (ssh_convert_key_to_blob): Support ecdsa. (ssh_identifier_from_curve_name): New. (ssh_send_key_public): Retrieve and pass the curve_name. (key_secret_to_public): Ditto. (data_sign): Add arg SPEC and change callers to pass it. (ssh_handler_sign_request): Get the hash algo from SPEC. * common/ssh-utils.c (get_fingerprint): Support ecdsa. * agent/protect.c (protect_info): Add flag ECC_HACK. (agent_protect): Allow the use of the "curve" parameter. * agent/t-protect.c (test_agent_protect): Add a test case for ecdsa. * agent/command-ssh.c (ssh_key_grip): Print a better error code. -- The 3 standard curves are now supported in gpg-agent's ssh-agent protocol implementation. I tested this with all 3 curves and keys generated by OpenSSH 5.9p1. Using existing non-ssh generated keys will likely fail for now. To fix this, the code should first undergo some more cleanup; then the fixes are pretty straightforward. And yes, the data structures are way too complicated.
This commit is contained in:
parent
f76a0312c3
commit
649b31c663
4 changed files with 384 additions and 106 deletions
|
@ -51,13 +51,14 @@ static struct {
|
|||
const char *algo;
|
||||
const char *parmlist;
|
||||
int prot_from, prot_to;
|
||||
int ecc_hack;
|
||||
} protect_info[] = {
|
||||
{ "rsa", "nedpqu", 2, 5 },
|
||||
{ "dsa", "pqgyx", 4, 4 },
|
||||
{ "elg", "pgyx", 3, 3 },
|
||||
{ "ecdsa","pabgnqd", 6, 6 },
|
||||
{ "ecdh", "pabgnqd", 6, 6 },
|
||||
{ "ecc", "pabgnqd", 6, 6 },
|
||||
{ "ecdsa","pabgnqd", 6, 6, 1 },
|
||||
{ "ecdh", "pabgnqd", 6, 6, 1 },
|
||||
{ "ecc", "pabgnqd", 6, 6, 1 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -450,6 +451,8 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
|
|||
unsigned long s2k_count)
|
||||
{
|
||||
int rc;
|
||||
const char *parmlist;
|
||||
int prot_from_idx, prot_to_idx;
|
||||
const unsigned char *s;
|
||||
const unsigned char *hash_begin, *hash_end;
|
||||
const unsigned char *prot_begin, *prot_end, *real_end;
|
||||
|
@ -494,10 +497,13 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
|
|||
if (!protect_info[infidx].algo)
|
||||
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
|
||||
|
||||
parmlist = protect_info[infidx].parmlist;
|
||||
prot_from_idx = protect_info[infidx].prot_from;
|
||||
prot_to_idx = protect_info[infidx].prot_to;
|
||||
prot_begin = prot_end = NULL;
|
||||
for (i=0; (c=protect_info[infidx].parmlist[i]); i++)
|
||||
for (i=0; (c=parmlist[i]); i++)
|
||||
{
|
||||
if (i == protect_info[infidx].prot_from)
|
||||
if (i == prot_from_idx)
|
||||
prot_begin = s;
|
||||
if (*s != '(')
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
|
@ -507,7 +513,20 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
|
|||
if (!n)
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
if (n != 1 || c != *s)
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
{
|
||||
if (n == 5 && !memcmp (s, "curve", 5)
|
||||
&& !i && protect_info[infidx].ecc_hack)
|
||||
{
|
||||
/* This is a private ECC key but the first parameter is
|
||||
the name of the curve. We change the parameter list
|
||||
here to the one we expect in this case. */
|
||||
parmlist = "?qd";
|
||||
prot_from_idx = 2;
|
||||
prot_to_idx = 2;
|
||||
}
|
||||
else
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
}
|
||||
s += n;
|
||||
n = snext (&s);
|
||||
if (!n)
|
||||
|
@ -516,7 +535,7 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
|
|||
if (*s != ')')
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
depth--;
|
||||
if (i == protect_info[infidx].prot_to)
|
||||
if (i == prot_to_idx)
|
||||
prot_end = s;
|
||||
s++;
|
||||
}
|
||||
|
@ -533,7 +552,6 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
|
|||
assert (!depth);
|
||||
real_end = s-1;
|
||||
|
||||
|
||||
/* Hash the stuff. Because the timestamp_exp won't get protected,
|
||||
we can't simply hash a continuous buffer but need to use several
|
||||
md_writes. */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue