diff options
Diffstat (limited to 'debian/patches/ssl-reneg.patch')
-rw-r--r-- | debian/patches/ssl-reneg.patch | 182 |
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); + } + } + } |