summaryrefslogtreecommitdiff
path: root/ssh-agent.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2010-08-31 22:41:14 +1000
committerDamien Miller <djm@mindrot.org>2010-08-31 22:41:14 +1000
commiteb8b60e320cdade9f4c07e2abacfb92c52e01348 (patch)
tree4e5bc25790566402e5b7ae00cefd2c57e867ef09 /ssh-agent.c
parentda108ece6843f1268aa36d7c8ed0030dc53acd15 (diff)
- djm@cvs.openbsd.org 2010/08/31 11:54:45
[PROTOCOL PROTOCOL.agent PROTOCOL.certkeys auth2-jpake.c authfd.c] [authfile.c buffer.h dns.c kex.c kex.h key.c key.h monitor.c] [monitor_wrap.c myproposal.h packet.c packet.h pathnames.h readconf.c] [ssh-add.1 ssh-add.c ssh-agent.1 ssh-agent.c ssh-keygen.1 ssh-keygen.c] [ssh-keyscan.1 ssh-keyscan.c ssh-keysign.8 ssh.1 ssh.c ssh2.h] [ssh_config.5 sshconnect.c sshconnect2.c sshd.8 sshd.c sshd_config.5] [uuencode.c uuencode.h bufec.c kexecdh.c kexecdhc.c kexecdhs.c ssh-ecdsa.c] Implement Elliptic Curve Cryptography modes for key exchange (ECDH) and host/user keys (ECDSA) as specified by RFC5656. ECDH and ECDSA offer better performance than plain DH and DSA at the same equivalent symmetric key length, as well as much shorter keys. Only the mandatory sections of RFC5656 are implemented, specifically the three REQUIRED curves nistp256, nistp384 and nistp521 and only ECDH and ECDSA. Point compression (optional in RFC5656 is NOT implemented). Certificate host and user keys using the new ECDSA key types are supported. Note that this code has not been tested for interoperability and may be subject to change. feedback and ok markus@
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 @@
1/* $OpenBSD: ssh-agent.c,v 1.168 2010/08/16 04:06:06 djm Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.169 2010/08/31 11:54:45 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -466,8 +466,10 @@ process_add_identity(SocketEntry *e, int version)
466 Idtab *tab = idtab_lookup(version); 466 Idtab *tab = idtab_lookup(version);
467 Identity *id; 467 Identity *id;
468 int type, success = 0, death = 0, confirm = 0; 468 int type, success = 0, death = 0, confirm = 0;
469 char *type_name, *comment; 469 char *type_name, *comment, *curve;
470 Key *k = NULL; 470 Key *k = NULL;
471 BIGNUM *exponent;
472 EC_POINT *q;
471 u_char *cert; 473 u_char *cert;
472 u_int len; 474 u_int len;
473 475
@@ -490,7 +492,6 @@ process_add_identity(SocketEntry *e, int version)
490 case 2: 492 case 2:
491 type_name = buffer_get_string(&e->request, NULL); 493 type_name = buffer_get_string(&e->request, NULL);
492 type = key_type_from_name(type_name); 494 type = key_type_from_name(type_name);
493 xfree(type_name);
494 switch (type) { 495 switch (type) {
495 case KEY_DSA: 496 case KEY_DSA:
496 k = key_new_private(type); 497 k = key_new_private(type);
@@ -509,6 +510,57 @@ process_add_identity(SocketEntry *e, int version)
509 key_add_private(k); 510 key_add_private(k);
510 buffer_get_bignum2(&e->request, k->dsa->priv_key); 511 buffer_get_bignum2(&e->request, k->dsa->priv_key);
511 break; 512 break;
513 case KEY_ECDSA:
514 k = key_new_private(type);
515 k->ecdsa_nid = key_ecdsa_nid_from_name(type_name);
516 curve = buffer_get_string(&e->request, NULL);
517 if (k->ecdsa_nid != key_curve_name_to_nid(curve))
518 fatal("%s: curve names mismatch", __func__);
519 xfree(curve);
520 k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
521 if (k->ecdsa == NULL)
522 fatal("%s: EC_KEY_new_by_curve_name failed",
523 __func__);
524 q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa));
525 if (q == NULL)
526 fatal("%s: BN_new failed", __func__);
527 if ((exponent = BN_new()) == NULL)
528 fatal("%s: BN_new failed", __func__);
529 buffer_get_ecpoint(&e->request,
530 EC_KEY_get0_group(k->ecdsa), q);
531 buffer_get_bignum2(&e->request, exponent);
532 if (EC_KEY_set_public_key(k->ecdsa, q) != 1)
533 fatal("%s: EC_KEY_set_public_key failed",
534 __func__);
535 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
536 fatal("%s: EC_KEY_set_private_key failed",
537 __func__);
538 if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
539 EC_KEY_get0_public_key(k->ecdsa)) != 0)
540 fatal("%s: bad ECDSA public key", __func__);
541 if (key_ec_validate_private(k->ecdsa) != 0)
542 fatal("%s: bad ECDSA private key", __func__);
543 BN_clear_free(exponent);
544 EC_POINT_free(q);
545 break;
546 case KEY_ECDSA_CERT:
547 cert = buffer_get_string(&e->request, &len);
548 if ((k = key_from_blob(cert, len)) == NULL)
549 fatal("Certificate parse failed");
550 xfree(cert);
551 key_add_private(k);
552 if ((exponent = BN_new()) == NULL)
553 fatal("%s: BN_new failed", __func__);
554 buffer_get_bignum2(&e->request, exponent);
555 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
556 fatal("%s: EC_KEY_set_private_key failed",
557 __func__);
558 if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
559 EC_KEY_get0_public_key(k->ecdsa)) != 0 ||
560 key_ec_validate_private(k->ecdsa) != 0)
561 fatal("%s: bad ECDSA key", __func__);
562 BN_clear_free(exponent);
563 break;
512 case KEY_RSA: 564 case KEY_RSA:
513 k = key_new_private(type); 565 k = key_new_private(type);
514 buffer_get_bignum2(&e->request, k->rsa->n); 566 buffer_get_bignum2(&e->request, k->rsa->n);
@@ -534,9 +586,11 @@ process_add_identity(SocketEntry *e, int version)
534 buffer_get_bignum2(&e->request, k->rsa->q); 586 buffer_get_bignum2(&e->request, k->rsa->q);
535 break; 587 break;
536 default: 588 default:
589 xfree(type_name);
537 buffer_clear(&e->request); 590 buffer_clear(&e->request);
538 goto send; 591 goto send;
539 } 592 }
593 xfree(type_name);
540 break; 594 break;
541 } 595 }
542 /* enable blinding */ 596 /* enable blinding */