tags 700399 +patch
thanks

Hi,

Attached is a proposed update for squeeze-security to address this issue.

Upstream's patch for client side renegotiation also fixed the SSL compression
issue in the same commit. The SSL compression fix however only works with
openssl >= 1. Therefore, I had to backport another fix (the same one as used 
by Apache) to this version in a second patch. I didn't think it was worthwhile 
to remove upstream's fix from the renegotiation patch as it's a no-op on 
squeeze.

I have not backported the commit that updates the example configuration file 
to add an example for the renegotiation option, as this would introduce a 
config file prompt in stable.

I've built the package and we're currently running this on our test 
environment. It works fine. Also, all compliance tests are now green again.
Built packages for amd64 are available at 
https://lissers.uvt.nl/~thijs/lighttpd/

Do you agree on the approach? Barring any objections I'm planning to release 
this as a DSA after the weekend.


Cheers,
Thijs


-- 
Thijs Kinkhorst <th...@uvt.nl> – LIS Unix

Universiteit van Tilburg – Library and IT Services • Postbus 90153, 5000 LE
Bezoekadres > Warandelaan 2 • Tel. 013 466 3035 • G 236 • http://www.uvt.nl
diff -Nru lighttpd-1.4.28/debian/changelog lighttpd-1.4.28/debian/changelog
--- lighttpd-1.4.28/debian/changelog	2011-12-20 21:53:07.000000000 +0100
+++ lighttpd-1.4.28/debian/changelog	2013-02-12 14:32:01.000000000 +0100
@@ -1,3 +1,14 @@
+lighttpd (1.4.28-2+squeeze1.1) stable-security; urgency=high
+
+  * Non-maintainer upload by the security team.
+  * Backport upstream fixes for SSL attacks:
+    + Disable client triggered renegotiation by default (CVE-2009-3555).
+      Can be re-enabled with ssl.disable-client-renegotiation = "false".
+    + Disable SSL compression at build time (CVE-2012-4929, 'CRIME').
+    (closes: #700399)
+
+ -- Thijs Kinkhorst <th...@debian.org>  Tue, 12 Feb 2013 13:56:53 +0100
+
 lighttpd (1.4.28-2+squeeze1) stable-security; urgency=high
 
   * Backport security issues from 1.4.30:
diff -Nru lighttpd-1.4.28/debian/patches/series lighttpd-1.4.28/debian/patches/series
--- lighttpd-1.4.28/debian/patches/series	2011-12-20 21:53:07.000000000 +0100
+++ lighttpd-1.4.28/debian/patches/series	2013-02-12 15:24:13.000000000 +0100
@@ -2,3 +2,5 @@
 fix-CVE-2011-4362.patch
 ssl-mitigate-beast.patch
 debian-changes-1.4.28-2
+ssl-reneg.patch
+ssl-crime.patch
diff -Nru lighttpd-1.4.28/debian/patches/ssl-crime.patch lighttpd-1.4.28/debian/patches/ssl-crime.patch
--- lighttpd-1.4.28/debian/patches/ssl-crime.patch	1970-01-01 01:00:00.000000000 +0100
+++ lighttpd-1.4.28/debian/patches/ssl-crime.patch	2013-02-12 15:22:26.000000000 +0100
@@ -0,0 +1,20 @@
+Description: Disable SSL compression.
+ Mitigates the SSL CRIME (CVE-2012-4929) attacks.
+ Upstream patch uses option only present in wheezy openssl, so
+ this code is needed to actually disable compression in squeeze.
+Forwarded: not-needed
+Bug-Debian: http://bugs.debian.org/700399
+
+diff -Nur lighttpd-1.4.28/src/network.c lighttpd-1.4.28.new/src/network.c
+--- lighttpd-1.4.28/src/network.c	2013-02-12 15:20:23.000000000 +0100
++++ lighttpd-1.4.28.new/src/network.c	2013-02-12 15:19:51.954559635 +0100
+@@ -566,6 +566,9 @@
+ 			}
+ 		}
+ 
++		/* Debian: disable ssl compression to mitigate CRIME attack. */
++		sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
++
+ 		if (!buffer_is_empty(s->ssl_cipher_list)) {
+ 			/* Disable support for low encryption ciphers */
+ 			if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) {
diff -Nru lighttpd-1.4.28/debian/patches/ssl-reneg.patch lighttpd-1.4.28/debian/patches/ssl-reneg.patch
--- lighttpd-1.4.28/debian/patches/ssl-reneg.patch	1970-01-01 01:00:00.000000000 +0100
+++ lighttpd-1.4.28/debian/patches/ssl-reneg.patch	2013-02-12 15:23:49.000000000 +0100
@@ -0,0 +1,182 @@
+Description: Disable SSL renegotiation.
+ Mitigates the SSL renegotiation (CVE-2009-3555) attacks.
+ Introduces a new configuration option: ssl.disable-client-renegotiation,
+ default true. Upstream also included code to disable SSL compression
+ in the same commit. This does not work on the openssl in squeeze but
+ doesn't hurt.
+Forwarded: not-needed
+Origin: upstream, r2808 r2809 r2812
+Bug-Debian: http://bugs.debian.org/700399
+
+Index: b/src/network.c
+===================================================================
+--- a/src/network.c	2013-02-12 14:30:59.713970364 +0100
++++ b/src/network.c	2013-02-12 14:31:00.189958247 +0100
+@@ -27,6 +27,19 @@
+ # include <openssl/rand.h>
+ #endif
+ 
++#ifdef USE_OPENSSL
++static void ssl_info_callback(const SSL *ssl, int where, int ret) {
++	UNUSED(ret);
++
++	if (0 != (where & SSL_CB_HANDSHAKE_START)) {
++		connection *con = SSL_get_app_data(ssl);
++		++con->renegotiations;
++	} else if (0 != (where & SSL_CB_HANDSHAKE_DONE)) {
++		ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;
++	}
++}
++#endif
++
+ static handler_t network_server_handle_fdevent(server *srv, void *context, int revents) {
+ 	server_socket *srv_socket = (server_socket *)context;
+ 	connection *con;
+@@ -504,6 +517,11 @@
+ 	/* load SSL certificates */
+ 	for (i = 0; i < srv->config_context->used; i++) {
+ 		specific_config *s = srv->config_storage[i];
++#ifndef SSL_OP_NO_COMPRESSION
++# define SSL_OP_NO_COMPRESSION 0
++#endif
++		long ssloptions =
++			SSL_OP_ALL | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_NO_COMPRESSION;
+ 
+ 		if (buffer_is_empty(s->ssl_pemfile)) continue;
+ 
+@@ -536,6 +554,9 @@
+ 			return -1;
+ 		}
+ 
++		SSL_CTX_set_options(s->ssl_ctx, ssloptions);
++		SSL_CTX_set_info_callback(s->ssl_ctx, ssl_info_callback);
++
+ 		if (!s->ssl_use_sslv2) {
+ 			/* disable SSLv2 */
+ 			if (!(SSL_OP_NO_SSLv2 & SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2))) {
+Index: b/src/base.h
+===================================================================
+--- a/src/base.h	2013-02-12 14:30:59.709970466 +0100
++++ b/src/base.h	2013-02-12 14:31:00.193958145 +0100
+@@ -282,6 +282,7 @@
+ 	unsigned short ssl_verifyclient_depth;
+ 	buffer *ssl_verifyclient_username;
+ 	unsigned short ssl_verifyclient_export_cert;
++	unsigned short ssl_disable_client_renegotiation;
+ 
+ 	unsigned short use_ipv6, set_v6only; /* set_v6only is only a temporary option */
+ 	unsigned short defer_accept;
+@@ -435,6 +436,7 @@
+ # ifndef OPENSSL_NO_TLSEXT
+ 	buffer *tlsext_server_name;
+ # endif
++	unsigned int renegotiations; /* count of SSL_CB_HANDSHAKE_START */
+ #endif
+ 	/* etag handling */
+ 	etag_flags_t etag_flags;
+Index: b/src/network_openssl.c
+===================================================================
+--- a/src/network_openssl.c	2013-02-12 14:30:56.810044291 +0100
++++ b/src/network_openssl.c	2013-02-12 14:31:00.193958145 +0100
+@@ -87,7 +87,14 @@
+ 			 */
+ 
+ 			ERR_clear_error();
+-			if ((r = SSL_write(ssl, offset, toSend)) <= 0) {
++			r = SSL_write(ssl, offset, toSend);
++
++			if (con->renegotiations > 1 && con->conf.ssl_disable_client_renegotiation) {
++				log_error_write(srv, __FILE__, __LINE__, "s", "SSL: renegotiation initiated by client");
++				return -1;
++			}
++
++			if (r <= 0) {
+ 				unsigned long err;
+ 
+ 				switch ((ssl_r = SSL_get_error(ssl, r))) {
+@@ -190,7 +197,14 @@
+ 				close(ifd);
+ 
+ 				ERR_clear_error();
+-				if ((r = SSL_write(ssl, s, toSend)) <= 0) {
++				r = SSL_write(ssl, s, toSend);
++
++				if (con->renegotiations > 1 && con->conf.ssl_disable_client_renegotiation) {
++					log_error_write(srv, __FILE__, __LINE__, "s", "SSL: renegotiation initiated by client");
++					return -1;
++				}
++
++				if (r <= 0) {
+ 					unsigned long err;
+ 
+ 					switch ((ssl_r = SSL_get_error(ssl, r))) {
+Index: b/src/connections.c
+===================================================================
+--- a/src/connections.c	2013-02-12 14:30:59.285981260 +0100
++++ b/src/connections.c	2013-02-12 14:31:00.193958145 +0100
+@@ -223,6 +223,12 @@
+ 
+ 		len = SSL_read(con->ssl, b->ptr + read_offset, toread);
+ 
++		if (con->renegotiations > 1 && con->conf.ssl_disable_client_renegotiation) {
++			connection_set_state(srv, con, CON_STATE_ERROR);
++			log_error_write(srv, __FILE__, __LINE__, "s", "SSL: renegotiation initiated by client");
++			return -1;
++		}
++
+ 		if (len > 0) {
+ 			if (b->used > 0) b->used--;
+ 			b->used += len;
+@@ -1352,6 +1358,7 @@
+ 				return NULL;
+ 			}
+ 
++			con->renegotiations = 0;
+ #ifndef OPENSSL_NO_TLSEXT
+ 			SSL_set_app_data(con->ssl, con);
+ #endif
+Index: b/src/configfile.c
+===================================================================
+--- a/src/configfile.c	2013-02-12 14:30:59.713970364 +0100
++++ b/src/configfile.c	2013-02-12 14:31:00.193958145 +0100
+@@ -103,6 +103,7 @@
+ 
+ 		{ "server.set-v6only",           NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 61 */
+ 		{ "ssl.honor-cipher-order",      NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER},      /* 62 */
++		{ "ssl.disable-client-renegotiation", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },/* 65 */
+ 
+ 		{ "server.host",                 "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
+ 		{ "server.docroot",              "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
+@@ -195,6 +196,7 @@
+ 		s->ssl_verifyclient_username = buffer_init();
+ 		s->ssl_verifyclient_depth = 9;
+ 		s->ssl_verifyclient_export_cert = 0;
++		s->ssl_disable_client_renegotiation = 1;
+ 
+ 		cv[2].destination = s->errorfile_prefix;
+ 
+@@ -249,6 +251,7 @@
+ 		cv[59].destination = s->ssl_verifyclient_username;
+ 		cv[60].destination = &(s->ssl_verifyclient_export_cert);
+ 		cv[62].destination = &(s->ssl_honor_cipher_order);
++		cv[65].destination = &(s->ssl_disable_client_renegotiation);
+ 
+ 		srv->config_storage[i] = s;
+ 
+@@ -338,6 +341,7 @@
+ 	PATCH(ssl_verifyclient_depth);
+ 	PATCH(ssl_verifyclient_username);
+ 	PATCH(ssl_verifyclient_export_cert);
++	PATCH(ssl_disable_client_renegotiation);
+ 
+ 	return 0;
+ }
+@@ -442,6 +446,8 @@
+ 				PATCH(ssl_verifyclient_username);
+ 			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.verifyclient.exportcert"))) {
+ 				PATCH(ssl_verifyclient_export_cert);
++			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.disable-client-renegotiation"))) {
++				PATCH(ssl_disable_client_renegotiation);
+ 			}
+ 		}
+ 	}

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to