ssh client auto rekey feature.

Damien Miller djm at mindrot.org
Fri Feb 20 19:29:00 EST 2004


On Fri, 20 Feb 2004, Damien Miller wrote:

> On Fri, 20 Feb 2004, John A Grahor wrote:
> 
> > Since the ssh spec says one should rekey every hour, I plan to patch the ssh
> > client to implement an auto-rekey option.
> 
> We already auto-rekey, though I think it is based on data volume rather 
> than time. I'll make a patch to enable time-based rekeying.

As promised. A couple of notes:

- This deprecates the unadvertised RekeyLimit client configuation option,
  in favour of RekeyTimeLimit and RekeyDataLimit options (and it documents 
  them)
- Time-based rekeying won't actually happen until there is data to send 
  over the connection. If this bothers you, just set ServerAliveInterval

BTW I think the draft-ietf-secsh-transport recommended interval for 
time-based rekeying of 1 hour is complete overkill.

-d

Index: packet.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/packet.c,v
retrieving revision 1.112
diff -u -r1.112 packet.c
--- packet.c	23 Sep 2003 20:17:11 -0000	1.112
+++ packet.c	20 Feb 2004 08:26:18 -0000
@@ -125,7 +125,9 @@
 } p_read, p_send;
 
 static u_int64_t max_blocks_in, max_blocks_out;
-static u_int32_t rekey_limit;
+static time_t rekey_time;
+static time_t rekey_time_limit = 0;
+static u_int32_t rekey_data_limit = 0;
 
 /* Session key for protocol v1 */
 static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
@@ -636,8 +638,10 @@
 		*max_blocks = (u_int64_t)1 << (enc->block_size*2);
 	else
 		*max_blocks = ((u_int64_t)1 << 30) / enc->block_size;
-	if (rekey_limit)
-		*max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size);
+	if (rekey_data_limit)
+		*max_blocks = MIN(*max_blocks, rekey_data_limit / enc->block_size);
+
+	rekey_time  = time(NULL);
 }
 
 /*
@@ -1505,11 +1509,18 @@
 	    (p_send.packets > MAX_PACKETS) ||
 	    (p_read.packets > MAX_PACKETS) ||
 	    (max_blocks_out && (p_send.blocks > max_blocks_out)) ||
-	    (max_blocks_in  && (p_read.blocks > max_blocks_in));
+	    (max_blocks_in  && (p_read.blocks > max_blocks_in)) ||
+	    (rekey_time_limit && (time(NULL) - rekey_time > rekey_time_limit));
+}
+
+void
+packet_set_rekey_data_limit(u_int32_t bytes)
+{
+	rekey_data_limit = bytes;
 }
 
 void
-packet_set_rekey_limit(u_int32_t bytes)
+packet_set_rekey_time_limit(time_t seconds)
 {
-	rekey_limit = bytes;
+	rekey_time_limit = seconds;
 }
Index: packet.h
===================================================================
RCS file: /cvs/src/usr.bin/ssh/packet.h,v
retrieving revision 1.40
diff -u -r1.40 packet.h
--- packet.h	24 Jun 2003 08:23:46 -0000	1.40
+++ packet.h	20 Feb 2004 08:26:18 -0000
@@ -97,6 +97,7 @@
 } while (0)
 
 int	 packet_need_rekeying(void);
-void	 packet_set_rekey_limit(u_int32_t);
+void	 packet_set_rekey_data_limit(u_int32_t);
+void	 packet_set_rekey_time_limit(time_t);
 
 #endif				/* PACKET_H */
Index: readconf.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/readconf.c,v
retrieving revision 1.127
diff -u -r1.127 readconf.c
--- readconf.c	16 Dec 2003 15:49:51 -0000	1.127
+++ readconf.c	20 Feb 2004 08:26:19 -0000
@@ -103,9 +103,10 @@
 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
 	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
-	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
-	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
-	oServerAliveInterval, oServerAliveCountMax,
+	oEnableSSHKeysign, oRekeyDataLimit, oRekeyTimeLimit, 
+	oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, 
+	oGssAuthentication, oGssDelegateCreds, oServerAliveInterval, 
+	oServerAliveCountMax,
 	oDeprecated, oUnsupported
 } OpCodes;
 
@@ -187,7 +188,9 @@
 	{ "enablesshkeysign", oEnableSSHKeysign },
 	{ "verifyhostkeydns", oVerifyHostKeyDNS },
 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
-	{ "rekeylimit", oRekeyLimit },
+	{ "rekeylimit", oDeprecated },
+	{ "rekeydatalimit", oRekeyDataLimit },
+	{ "rekeytimelimit", oRekeyTimeLimit },
 	{ "connecttimeout", oConnectTimeout },
 	{ "addressfamily", oAddressFamily },
 	{ "serveraliveinterval", oServerAliveInterval },
@@ -445,8 +448,8 @@
 		intptr = &options->compression_level;
 		goto parse_int;
 
-	case oRekeyLimit:
-		intptr = &options->rekey_limit;
+	case oRekeyDataLimit:
+		intptr = &options->rekey_data_limit;
 		arg = strdelim(&s);
 		if (!arg || *arg == '\0')
 			fatal("%.200s line %d: Missing argument.", filename, linenum);
@@ -470,6 +473,11 @@
 			*intptr = value;
 		break;
 
+	case oRekeyTimeLimit:
+		intptr = &options->rekey_time_limit;
+		goto parse_time;
+		break;
+
 	case oIdentityFile:
 		arg = strdelim(&s);
 		if (!arg || *arg == '\0')
@@ -867,7 +875,8 @@
 	options->smartcard_device = NULL;
 	options->enable_ssh_keysign = - 1;
 	options->no_host_authentication_for_localhost = - 1;
-	options->rekey_limit = - 1;
+	options->rekey_data_limit = - 1;
+	options->rekey_time_limit = - 1;
 	options->verify_host_key_dns = -1;
 	options->server_alive_interval = -1;
 	options->server_alive_count_max = -1;
@@ -981,8 +990,10 @@
 		options->no_host_authentication_for_localhost = 0;
 	if (options->enable_ssh_keysign == -1)
 		options->enable_ssh_keysign = 0;
-	if (options->rekey_limit == -1)
-		options->rekey_limit = 0;
+	if (options->rekey_data_limit == -1)
+		options->rekey_data_limit = 0;
+	if (options->rekey_time_limit == -1)
+		options->rekey_time_limit = 0;
 	if (options->verify_host_key_dns == -1)
 		options->verify_host_key_dns = 0;
 	if (options->server_alive_interval == -1)
Index: readconf.h
===================================================================
RCS file: /cvs/src/usr.bin/ssh/readconf.h,v
retrieving revision 1.59
diff -u -r1.59 readconf.h
--- readconf.h	16 Dec 2003 15:49:51 -0000	1.59
+++ readconf.h	20 Feb 2004 08:26:20 -0000
@@ -98,7 +98,8 @@
 	int	clear_forwardings;
 
 	int	enable_ssh_keysign;
-	int	rekey_limit;
+	int	rekey_data_limit;
+	int	rekey_time_limit;
 	int	no_host_authentication_for_localhost;
 	int	server_alive_interval; 
 	int	server_alive_count_max;
Index: ssh_config.5
===================================================================
RCS file: /cvs/src/usr.bin/ssh/ssh_config.5,v
retrieving revision 1.28
diff -u -r1.28 ssh_config.5
--- ssh_config.5	16 Dec 2003 15:49:51 -0000	1.28
+++ ssh_config.5	20 Feb 2004 08:26:21 -0000
@@ -518,6 +518,13 @@
 The default is
 .Dq yes .
 This option applies to protocol version 2 only.
+.It Cm RekeyDataLimit
+Specifies the number of maximum number of bytes transmitted or received
+before the session encryption keys are renewed. 
+This option applies to protocol version 2 only.
+.It Cm RekeyTimeLimit
+Specifies the interval at which session encryption keys are renewed.
+This option applies to protocol version 2 only.
 .It Cm RemoteForward
 Specifies that a TCP/IP port on the remote machine be forwarded over
 the secure channel to the specified host and port from the local machine.
Index: sshconnect2.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/sshconnect2.c,v
retrieving revision 1.134
diff -u -r1.134 sshconnect2.c
--- sshconnect2.c	19 Jan 2004 21:25:15 -0000	1.134
+++ sshconnect2.c	20 Feb 2004 08:26:22 -0000
@@ -112,8 +112,10 @@
 		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
 		    options.hostkeyalgorithms;
 
-	if (options.rekey_limit)
-		packet_set_rekey_limit(options.rekey_limit);
+	if (options.rekey_data_limit)
+		packet_set_rekey_data_limit(options.rekey_data_limit);
+	if (options.rekey_time_limit)
+		packet_set_rekey_time_limit(options.rekey_time_limit);
 
 	/* start key exchange */
 	kex = kex_setup(myproposal);




More information about the openssh-unix-dev mailing list