summaryrefslogtreecommitdiffstats
path: root/ssh-agent.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-agent.c')
-rw-r--r--ssh-agent.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/ssh-agent.c b/ssh-agent.c
index e6725ea88..fbfd79c13 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.168 2010/08/16 04:06:06 djm Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.169 2010/08/31 11:54:45 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -466,8 +466,10 @@ process_add_identity(SocketEntry *e, int version)
Idtab *tab = idtab_lookup(version);
Identity *id;
int type, success = 0, death = 0, confirm = 0;
- char *type_name, *comment;
+ char *type_name, *comment, *curve;
Key *k = NULL;
+ BIGNUM *exponent;
+ EC_POINT *q;
u_char *cert;
u_int len;
@@ -490,7 +492,6 @@ process_add_identity(SocketEntry *e, int version)
case 2:
type_name = buffer_get_string(&e->request, NULL);
type = key_type_from_name(type_name);
- xfree(type_name);
switch (type) {
case KEY_DSA:
k = key_new_private(type);
@@ -509,6 +510,57 @@ process_add_identity(SocketEntry *e, int version)
key_add_private(k);
buffer_get_bignum2(&e->request, k->dsa->priv_key);
break;
+ case KEY_ECDSA:
+ k = key_new_private(type);
+ k->ecdsa_nid = key_ecdsa_nid_from_name(type_name);
+ curve = buffer_get_string(&e->request, NULL);
+ if (k->ecdsa_nid != key_curve_name_to_nid(curve))
+ fatal("%s: curve names mismatch", __func__);
+ xfree(curve);
+ k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
+ if (k->ecdsa == NULL)
+ fatal("%s: EC_KEY_new_by_curve_name failed",
+ __func__);
+ q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa));
+ if (q == NULL)
+ fatal("%s: BN_new failed", __func__);
+ if ((exponent = BN_new()) == NULL)
+ fatal("%s: BN_new failed", __func__);
+ buffer_get_ecpoint(&e->request,
+ EC_KEY_get0_group(k->ecdsa), q);
+ buffer_get_bignum2(&e->request, exponent);
+ if (EC_KEY_set_public_key(k->ecdsa, q) != 1)
+ fatal("%s: EC_KEY_set_public_key failed",
+ __func__);
+ if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
+ fatal("%s: EC_KEY_set_private_key failed",
+ __func__);
+ if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
+ EC_KEY_get0_public_key(k->ecdsa)) != 0)
+ fatal("%s: bad ECDSA public key", __func__);
+ if (key_ec_validate_private(k->ecdsa) != 0)
+ fatal("%s: bad ECDSA private key", __func__);
+ BN_clear_free(exponent);
+ EC_POINT_free(q);
+ break;
+ case KEY_ECDSA_CERT:
+ cert = buffer_get_string(&e->request, &len);
+ if ((k = key_from_blob(cert, len)) == NULL)
+ fatal("Certificate parse failed");
+ xfree(cert);
+ key_add_private(k);
+ if ((exponent = BN_new()) == NULL)
+ fatal("%s: BN_new failed", __func__);
+ buffer_get_bignum2(&e->request, exponent);
+ if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
+ fatal("%s: EC_KEY_set_private_key failed",
+ __func__);
+ if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
+ EC_KEY_get0_public_key(k->ecdsa)) != 0 ||
+ key_ec_validate_private(k->ecdsa) != 0)
+ fatal("%s: bad ECDSA key", __func__);
+ BN_clear_free(exponent);
+ break;
case KEY_RSA:
k = key_new_private(type);
buffer_get_bignum2(&e->request, k->rsa->n);
@@ -534,9 +586,11 @@ process_add_identity(SocketEntry *e, int version)
buffer_get_bignum2(&e->request, k->rsa->q);
break;
default:
+ xfree(type_name);
buffer_clear(&e->request);
goto send;
}
+ xfree(type_name);
break;
}
/* enable blinding */