=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/ssh-agent.c,v retrieving revision 1.168 retrieving revision 1.169 diff -u -r1.168 -r1.169 --- src/usr.bin/ssh/ssh-agent.c 2010/08/16 04:06:06 1.168 +++ src/usr.bin/ssh/ssh-agent.c 2010/08/31 11:54:45 1.169 @@ -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 * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -452,8 +452,10 @@ 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; @@ -476,7 +478,6 @@ 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); @@ -495,6 +496,57 @@ 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); @@ -520,9 +572,11 @@ 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 */