changeset 745:15999b098cc9 kexguess

Don't usually need to recalculate dh_e for the repeated kexdh_init packet
author Matt Johnston <matt@ucc.asn.au>
date Wed, 03 Apr 2013 00:32:55 +0800
parents 504f33c684b5
children 465fefc4f6e0
files cli-kex.c cli-session.c common-algo.c session.h sysoptions.h
diffstat 5 files changed, 25 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/cli-kex.c	Wed Apr 03 00:32:05 2013 +0800
+++ b/cli-kex.c	Wed Apr 03 00:32:55 2013 +0800
@@ -43,11 +43,19 @@
 
 void send_msg_kexdh_init() {
 	TRACE(("send_msg_kexdh_init()"))	
-	cli_ses.dh_e = (mp_int*)m_malloc(sizeof(mp_int));
-	cli_ses.dh_x = (mp_int*)m_malloc(sizeof(mp_int));
-	m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x, NULL);
+	if ((cli_ses.dh_e && cli_ses.dh_x 
+				&& cli_ses.dh_val_algo == ses.newkeys->algo_kex)) {
+		TRACE(("reusing existing dh_e from first_kex_packet_follows"))
+	} else {
+		if (!cli_ses.dh_e || !cli_ses.dh_e) {
+			cli_ses.dh_e = (mp_int*)m_malloc(sizeof(mp_int));
+			cli_ses.dh_x = (mp_int*)m_malloc(sizeof(mp_int));
+			m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x, NULL);
+		}
 
-	gen_kexdh_vals(cli_ses.dh_e, cli_ses.dh_x);
+		gen_kexdh_vals(cli_ses.dh_e, cli_ses.dh_x);
+		cli_ses.dh_val_algo = ses.newkeys->algo_kex;
+	}
 
 	CHECKCLEARTOWRITE();
 	buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_INIT);
@@ -99,6 +107,7 @@
 	mp_clear_multi(cli_ses.dh_e, cli_ses.dh_x, NULL);
 	m_free(cli_ses.dh_e);
 	m_free(cli_ses.dh_x);
+	cli_ses.dh_val_algo = DROPBEAR_KEX_NONE;
 
 	if (buf_verify(ses.payload, hostkey, ses.hash, SHA1_HASH_SIZE) 
 			!= DROPBEAR_SUCCESS) {
--- a/cli-session.c	Wed Apr 03 00:32:05 2013 +0800
+++ b/cli-session.c	Wed Apr 03 00:32:55 2013 +0800
@@ -182,6 +182,11 @@
 
 	TRACE2(("enter cli_sessionloop"))
 
+	if (ses.lastpacket == 0) {
+		TRACE2(("exit cli_sessionloop: no real packets yet"))
+		return;
+	}
+
 	if (ses.lastpacket == SSH_MSG_KEXINIT && cli_ses.kex_state == KEX_NOTHING) {
 		/* We initiate the KEXDH. If DH wasn't the correct type, the KEXINIT
 		 * negotiation would have failed. */
@@ -206,10 +211,9 @@
 		return;
 	}
 
-	/* We should exit if we haven't donefirstkex: we shouldn't reach here
-	 * in normal operation */
 	if (ses.kexstate.donefirstkex == 0) {
-		TRACE(("XXX XXX might be bad! leave cli_sessionloop: haven't donefirstkex"))
+		/* We might reach here if we have partial packet reads or have
+		 * received SSG_MSG_IGNORE etc. Just skip it */
 		return;
 	}
 
--- a/common-algo.c	Wed Apr 03 00:32:05 2013 +0800
+++ b/common-algo.c	Wed Apr 03 00:32:55 2013 +0800
@@ -214,8 +214,8 @@
 };
 
 algo_type sshkex[] = {
+	{"diffie-hellman-group14-sha1", DROPBEAR_KEX_DH_GROUP14, NULL, 1, NULL},
 	{"diffie-hellman-group1-sha1", DROPBEAR_KEX_DH_GROUP1, NULL, 1, NULL},
-	{"diffie-hellman-group14-sha1", DROPBEAR_KEX_DH_GROUP14, NULL, 1, NULL},
 	{KEXGUESS2_ALGO_NAME, KEXGUESS2_ALGO_ID, NULL, 1, NULL},
 	{NULL, 0, NULL, 0, NULL}
 };
--- a/session.h	Wed Apr 03 00:32:05 2013 +0800
+++ b/session.h	Wed Apr 03 00:32:55 2013 +0800
@@ -241,6 +241,7 @@
 struct clientsession {
 
 	mp_int *dh_e, *dh_x; /* Used during KEX */
+	int dh_val_algo; /* KEX algorithm corresponding to current dh_e and dh_x */
 	cli_kex_state kex_state; /* Used for progressing KEX */
 	cli_state state; /* Used to progress auth/channelsession etc */
 	unsigned donefirstkex : 1; /* Set when we set sentnewkeys, never reset */
--- a/sysoptions.h	Wed Apr 03 00:32:05 2013 +0800
+++ b/sysoptions.h	Wed Apr 03 00:32:55 2013 +0800
@@ -61,8 +61,9 @@
 #define DROPBEAR_FAILURE -1
 
 /* various algorithm identifiers */
-#define DROPBEAR_KEX_DH_GROUP1 0
-#define DROPBEAR_KEX_DH_GROUP14 1
+#define DROPBEAR_KEX_NONE 0
+#define DROPBEAR_KEX_DH_GROUP1 1
+#define DROPBEAR_KEX_DH_GROUP14 2
 
 #define DROPBEAR_SIGNKEY_ANY 0
 #define DROPBEAR_SIGNKEY_RSA 1