aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorРоман Донченко <dpb@corrigendum.ru>2016-12-09 00:19:25 +0300
committerAnders Broman <a.broman58@gmail.com>2016-12-13 09:00:59 +0000
commit9d85c4f0b75ac40409423f1e82e82b4a154c0870 (patch)
tree788555a5edcbaddeee458f527894bc17cc09cc91
parent79babc6f22879763d49ea2e802a44ace0e89bd53 (diff)
ssh: add dissection for Elliptic Curve Diffie-Hellman KEX
The protocol is actually nearly identical to ordinary Diffie-Hellman, but the names are different, and the ephemeral keys are bytestrings rather than integers. Change-Id: I261b6426137dae12fe53686e74517080abd80bb3 Reviewed-on: https://code.wireshark.org/review/19210 Reviewed-by: Michael Mann <mmann78@netscape.net> Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r--epan/dissectors/packet-ssh.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/epan/dissectors/packet-ssh.c b/epan/dissectors/packet-ssh.c
index b03225e034..26004943e9 100644
--- a/epan/dissectors/packet-ssh.c
+++ b/epan/dissectors/packet-ssh.c
@@ -136,6 +136,7 @@ static int hf_ssh_msg_code = -1;
static int hf_ssh2_msg_code = -1;
static int hf_ssh2_kex_dh_msg_code = -1;
static int hf_ssh2_kex_dh_gex_msg_code = -1;
+static int hf_ssh2_kex_ecdh_msg_code = -1;
/* Algorithm negotiation */
static int hf_ssh_cookie = -1;
@@ -190,6 +191,12 @@ static int hf_ssh_dh_gex_max = -1;
static int hf_ssh_dh_gex_p = -1;
static int hf_ssh_dh_gex_g = -1;
+/* Key exchange: Elliptic Curve Diffie-Hellman */
+static int hf_ssh_ecdh_q_c = -1;
+static int hf_ssh_ecdh_q_c_length = -1;
+static int hf_ssh_ecdh_q_s = -1;
+static int hf_ssh_ecdh_q_s_length = -1;
+
/* Miscellaneous */
static int hf_ssh_mpint_length = -1;
@@ -233,6 +240,9 @@ static dissector_handle_t ssh_handle;
#define SSH_MSG_KEX_DH_GEX_REPLY 33
#define SSH_MSG_KEX_DH_GEX_REQUEST 34
+#define SSH_MSG_KEX_ECDH_INIT 30
+#define SSH_MSG_KEX_ECDH_REPLY 31
+
/* User authentication protocol: generic (50-59) */
#define SSH_MSG_USERAUTH_REQUEST 50
#define SSH_MSG_USERAUTH_FAILURE 51
@@ -307,6 +317,12 @@ static const value_string ssh2_kex_dh_gex_msg_vals[] = {
{ 0, NULL }
};
+static const value_string ssh2_kex_ecdh_msg_vals[] = {
+ { SSH_MSG_KEX_ECDH_INIT, "Elliptic Curve Diffie-Hellman Key Exchange Init" },
+ { SSH_MSG_KEX_ECDH_REPLY, "Elliptic Curve Diffie-Hellman Key Exchange Reply" },
+ { 0, NULL }
+};
+
static const value_string ssh1_msg_vals[] = {
{SSH1_MSG_NONE, "No Message"},
{SSH1_MSG_DISCONNECT, "Disconnect"},
@@ -906,6 +922,31 @@ static int ssh_dissect_kex_dh_gex(guint8 msg_code, tvbuff_t *tvb,
}
static int
+ssh_dissect_kex_ecdh(guint8 msg_code, tvbuff_t *tvb,
+ packet_info *pinfo, int offset, proto_tree *tree)
+{
+ proto_tree_add_item(tree, hf_ssh2_kex_ecdh_msg_code, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
+ val_to_str(msg_code, ssh2_kex_ecdh_msg_vals, "Unknown (%u)"));
+
+ switch (msg_code) {
+ case SSH_MSG_KEX_ECDH_INIT:
+ offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_ecdh_q_c, hf_ssh_ecdh_q_c_length);
+ break;
+
+ case SSH_MSG_KEX_ECDH_REPLY:
+ offset += ssh_tree_add_hostkey(tvb, offset, tree, "KEX host key", ett_key_exchange_host_key);
+ offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_ecdh_q_s, hf_ssh_ecdh_q_s_length);
+ offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_kex_h_sig, hf_ssh_kex_h_sig_length);
+ break;
+ }
+
+ return offset;
+}
+
+static int
ssh_dissect_encrypted_packet(tvbuff_t *tvb, packet_info *pinfo,
struct ssh_peer_data *peer_data,
int offset, proto_tree *tree)
@@ -1070,6 +1111,11 @@ static void ssh_set_kex_specific_dissector(struct ssh_flow_data *global_data)
{
global_data->kex_specific_dissector = ssh_dissect_kex_dh_gex;
}
+ else if (g_str_has_prefix(kex_name, "ecdh-sha2-") ||
+ strcmp(kex_name, "curve25519-sha256@libssh.org") == 0)
+ {
+ global_data->kex_specific_dissector = ssh_dissect_kex_ecdh;
+ }
}
static gint
@@ -1277,6 +1323,11 @@ proto_register_ssh(void)
FT_UINT8, BASE_DEC, VALS(ssh2_kex_dh_gex_msg_vals), 0x0,
NULL, HFILL }},
+ { &hf_ssh2_kex_ecdh_msg_code,
+ { "Message Code", "ssh.message_code",
+ FT_UINT8, BASE_DEC, VALS(ssh2_kex_ecdh_msg_vals), 0x0,
+ NULL, HFILL }},
+
{ &hf_ssh_cookie,
{ "Cookie", "ssh.cookie",
FT_BYTES, BASE_NONE, NULL, 0x0,
@@ -1502,6 +1553,26 @@ proto_register_ssh(void)
FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL }},
+ { &hf_ssh_ecdh_q_c,
+ { "ECDH client's ephemeral public key (Q_C)", "ssh.ecdh.q_c",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_ecdh_q_c_length,
+ { "ECDH client's ephemeral public key length", "ssh.ecdh.q_c_length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_ecdh_q_s,
+ { "ECDH server's ephemeral public key (Q_S)", "ssh.ecdh.q_s",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }},
+
+ { &hf_ssh_ecdh_q_s_length,
+ { "ECDH server's ephemeral public key length", "ssh.ecdh.q_s_length",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+
{ &hf_ssh_mpint_length,
{ "Multi Precision Integer Length", "ssh.mpint_length",
FT_UINT32, BASE_DEC, NULL, 0x0,