summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kex.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/kex.c b/kex.c
index 5100c661d..5f72f2e9f 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.c,v 1.109 2015/07/30 00:01:34 djm Exp $ */ 1/* $OpenBSD: kex.c,v 1.110 2015/08/21 23:57:48 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -67,6 +67,19 @@ extern const EVP_MD *evp_ssh_sha256(void);
67static int kex_choose_conf(struct ssh *); 67static int kex_choose_conf(struct ssh *);
68static int kex_input_newkeys(int, u_int32_t, void *); 68static int kex_input_newkeys(int, u_int32_t, void *);
69 69
70static const char *proposal_names[PROPOSAL_MAX] = {
71 "KEX algorithms",
72 "host key algorithms",
73 "ciphers ctos",
74 "ciphers stoc",
75 "MACs ctos",
76 "MACs stoc",
77 "compression ctos",
78 "compression stoc",
79 "languages ctos",
80 "languages stoc",
81};
82
70struct kexalg { 83struct kexalg {
71 char *name; 84 char *name;
72 u_int type; 85 u_int type;
@@ -267,7 +280,7 @@ kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
267 for (i = 0; i < PROPOSAL_MAX; i++) { 280 for (i = 0; i < PROPOSAL_MAX; i++) {
268 if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0) 281 if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0)
269 goto out; 282 goto out;
270 debug2("kex_parse_kexinit: %s", proposal[i]); 283 debug2("%s: %s", proposal_names[i], proposal[i]);
271 } 284 }
272 /* first kex follows / reserved */ 285 /* first kex follows / reserved */
273 if ((r = sshbuf_get_u8(b, &v)) != 0 || 286 if ((r = sshbuf_get_u8(b, &v)) != 0 ||
@@ -275,8 +288,8 @@ kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
275 goto out; 288 goto out;
276 if (first_kex_follows != NULL) 289 if (first_kex_follows != NULL)
277 *first_kex_follows = i; 290 *first_kex_follows = i;
278 debug2("kex_parse_kexinit: first_kex_follows %d ", v); 291 debug2("first_kex_follows %d ", v);
279 debug2("kex_parse_kexinit: reserved %u ", i); 292 debug2("reserved %u ", i);
280 r = 0; 293 r = 0;
281 *propp = proposal; 294 *propp = proposal;
282 out: 295 out:
@@ -593,6 +606,7 @@ choose_kex(struct kex *k, char *client, char *server)
593 606
594 k->name = match_list(client, server, NULL); 607 k->name = match_list(client, server, NULL);
595 608
609 debug("kex: algorithm: %s", k->name ? k->name : "(no match)");
596 if (k->name == NULL) 610 if (k->name == NULL)
597 return SSH_ERR_NO_KEX_ALG_MATCH; 611 return SSH_ERR_NO_KEX_ALG_MATCH;
598 if ((kexalg = kex_alg_by_name(k->name)) == NULL) 612 if ((kexalg = kex_alg_by_name(k->name)) == NULL)
@@ -608,6 +622,8 @@ choose_hostkeyalg(struct kex *k, char *client, char *server)
608{ 622{
609 char *hostkeyalg = match_list(client, server, NULL); 623 char *hostkeyalg = match_list(client, server, NULL);
610 624
625 debug("kex: host key algorithm: %s",
626 hostkeyalg ? hostkeyalg : "(no match)");
611 if (hostkeyalg == NULL) 627 if (hostkeyalg == NULL)
612 return SSH_ERR_NO_HOSTKEY_ALG_MATCH; 628 return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
613 k->hostkey_type = sshkey_type_from_name(hostkeyalg); 629 k->hostkey_type = sshkey_type_from_name(hostkeyalg);
@@ -653,8 +669,11 @@ kex_choose_conf(struct ssh *ssh)
653 u_int mode, ctos, need, dh_need, authlen; 669 u_int mode, ctos, need, dh_need, authlen;
654 int r, first_kex_follows; 670 int r, first_kex_follows;
655 671
656 if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0 || 672 debug2("local %s KEXINIT proposal", kex->server ? "server" : "client");
657 (r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0) 673 if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0)
674 goto out;
675 debug2("peer %s KEXINIT proposal", kex->server ? "client" : "server");
676 if ((r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0)
658 goto out; 677 goto out;
659 678
660 if (kex->server) { 679 if (kex->server) {
@@ -677,6 +696,18 @@ kex_choose_conf(struct ssh *ssh)
677 } 696 }
678 697
679 /* Algorithm Negotiation */ 698 /* Algorithm Negotiation */
699 if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
700 sprop[PROPOSAL_KEX_ALGS])) != 0) {
701 kex->failed_choice = peer[PROPOSAL_KEX_ALGS];
702 peer[PROPOSAL_KEX_ALGS] = NULL;
703 goto out;
704 }
705 if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
706 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) {
707 kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS];
708 peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL;
709 goto out;
710 }
680 for (mode = 0; mode < MODE_MAX; mode++) { 711 for (mode = 0; mode < MODE_MAX; mode++) {
681 if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) { 712 if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) {
682 r = SSH_ERR_ALLOC_FAIL; 713 r = SSH_ERR_ALLOC_FAIL;
@@ -709,24 +740,12 @@ kex_choose_conf(struct ssh *ssh)
709 peer[ncomp] = NULL; 740 peer[ncomp] = NULL;
710 goto out; 741 goto out;
711 } 742 }
712 debug("kex: %s %s %s %s", 743 debug("kex: %s cipher: %s MAC: %s compression: %s",
713 ctos ? "client->server" : "server->client", 744 ctos ? "client->server" : "server->client",
714 newkeys->enc.name, 745 newkeys->enc.name,
715 authlen == 0 ? newkeys->mac.name : "<implicit>", 746 authlen == 0 ? newkeys->mac.name : "<implicit>",
716 newkeys->comp.name); 747 newkeys->comp.name);
717 } 748 }
718 if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
719 sprop[PROPOSAL_KEX_ALGS])) != 0) {
720 kex->failed_choice = peer[PROPOSAL_KEX_ALGS];
721 peer[PROPOSAL_KEX_ALGS] = NULL;
722 goto out;
723 }
724 if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
725 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) {
726 kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS];
727 peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL;
728 goto out;
729 }
730 need = dh_need = 0; 749 need = dh_need = 0;
731 for (mode = 0; mode < MODE_MAX; mode++) { 750 for (mode = 0; mode < MODE_MAX; mode++) {
732 newkeys = kex->newkeys[mode]; 751 newkeys = kex->newkeys[mode];