diff options
Diffstat (limited to 'ssh-agent.c')
-rw-r--r-- | ssh-agent.c | 60 |
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 */ |