summaryrefslogtreecommitdiff
path: root/debian/patches/ssl-reneg.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/ssl-reneg.patch')
-rw-r--r--debian/patches/ssl-reneg.patch182
1 files changed, 182 insertions, 0 deletions
diff --git a/debian/patches/ssl-reneg.patch b/debian/patches/ssl-reneg.patch
new file mode 100644
index 0000000..a967943
--- /dev/null
+++ b/debian/patches/ssl-reneg.patch
@@ -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-16 19:18:04.438541647 +0100
++++ b/src/network.c 2013-02-16 19:18:07.278507389 +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-16 19:18:04.426502421 +0100
++++ b/src/base.h 2013-02-16 19:18:04.466500766 +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-16 19:17:56.758505345 +0100
++++ b/src/network_openssl.c 2013-02-16 19:18:04.486539910 +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-16 19:18:04.402514856 +0100
++++ b/src/connections.c 2013-02-16 19:18:04.490538415 +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-16 19:18:04.430500920 +0100
++++ b/src/configfile.c 2013-02-16 19:18:04.494546359 +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 },/* 63 */
+
+ { "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[63].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);
+ }
+ }
+ }