]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added %DUMBFW priority string option.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 10 Nov 2013 10:09:49 +0000 (11:09 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 10 Nov 2013 10:09:52 +0000 (11:09 +0100)
This works around issues when connecting behind some firewalls.

NEWS
doc/cha-gtls-app.texi
lib/ext/Makefile.am
lib/ext/dumbfw.c [new file with mode: 0644]
lib/ext/dumbfw.h [new file with mode: 0644]
lib/gnutls_extensions.c
lib/gnutls_int.h
lib/gnutls_priority.c

diff --git a/NEWS b/NEWS
index 99bc1205c7daa453b198f16b827d676275367a0b..5638f9340ae8c6fa27e5dbf91c97734e3b1bf06b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,10 @@ PKCS #11 URL with a certificate, will attempt to load the whole chain.
 ** libgnutls: When traversing PKCS #11 tokens looking for an object, avoid
 looking in unrelated to the object tokens.
 
+** libgnutls: Added %DUMBFW option for priority strings. This avoids a black
+hole behavior in some firewalls by sending a large client hello. See
+http://www.ietf.org/mail-archive/web/tls/current/msg10423.html
+
 ** certtool: When exporting an encrypted PEM private key do not output the key
 parameters.
 
index 24301753ae0a10e14cabf12f51ec90c43da922a6..8b96ec7c5e44b6c5a5b216c58c8aa90b79dad0a0 100644 (file)
@@ -1029,6 +1029,11 @@ problematic clients and servers is achieved. More specifically this
 string would disable TLS record random padding and tolerate packets
 over the maximum allowed TLS record.
 
+@item %DUMBFW @tab
+will add a private extension with bogus data that make the client
+hello exceed 512 bytes. This avoids a black hole behavior in some
+firewalls.
+
 @item %NO_EXTENSIONS @tab
 will prevent the sending of any TLS extensions in client side. Note
 that TLS 1.2 requires extensions to be used, as well as safe
index 47e4df9450a9cdd1a7be8ee7aff203e9e8053ce1..0fcda0143906cf5494c1327392bb7a81dea2ac92 100644 (file)
@@ -40,7 +40,7 @@ libgnutls_ext_la_SOURCES = max_record.c cert_type.c \
        session_ticket.h signature.h safe_renegotiation.h \
        session_ticket.c srp.c ecc.c ecc.h heartbeat.c heartbeat.h \
        status_request.h status_request.c new_record_padding.c \
-       new_record_padding.h
+       new_record_padding.h dumbfw.c dumbfw.h
 
 if ENABLE_ALPN
 libgnutls_ext_la_SOURCES += alpn.c alpn.h
diff --git a/lib/ext/dumbfw.c b/lib/ext/dumbfw.c
new file mode 100644 (file)
index 0000000..10f7227
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2013 Nikos Mavrogiannopoulos
+ * 
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "gnutls_int.h"
+#include "gnutls_auth.h"
+#include "gnutls_errors.h"
+#include "gnutls_num.h"
+#include <ext/dumbfw.h>
+
+static int _gnutls_dumbfw_send_params(gnutls_session_t session,
+                                   gnutls_buffer_st * extdata);
+
+extension_entry_st ext_mod_dumbfw = {
+       .name = "DUMBFW",
+       .type = GNUTLS_EXTENSION_DUMBFW,
+       .parse_type = GNUTLS_EXT_APPLICATION,
+
+       .recv_func = NULL,
+       .send_func = _gnutls_dumbfw_send_params,
+       .pack_func = NULL,
+       .unpack_func = NULL,
+       .deinit_func = NULL,
+};
+
+static int
+_gnutls_dumbfw_send_params(gnutls_session_t session,
+                        gnutls_buffer_st * extdata)
+{
+       int total_size = 0, ret;
+       uint8_t pad[DUMBFW_PADDING_SIZE];
+
+       if (session->security_parameters.entity == GNUTLS_SERVER ||
+           session->internals.priorities.dumbfw == 0) {
+               return 0;
+       } else {
+               memset(pad, 0, sizeof(pad));
+
+               ret =
+                   _gnutls_buffer_append_data_prefix(extdata, 16,
+                                                             pad,
+                                                             sizeof(pad)-2);
+               if (ret < 0)
+                       return gnutls_assert_val(ret);
+
+               total_size += sizeof(pad);
+       }
+
+       return total_size;
+}
+
diff --git a/lib/ext/dumbfw.h b/lib/ext/dumbfw.h
new file mode 100644 (file)
index 0000000..ce8f21e
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+#ifndef EXT_DUMBFW_H
+#define EXT_DUMBFW_H
+
+#include <gnutls_extensions.h>
+
+#define DUMBFW_PADDING_SIZE 465
+
+extern extension_entry_st ext_mod_dumbfw;
+
+#endif
index 3633a5c84dcedf9b9f24a5283598ace96bf58d3e..a0dae49f0998066a0530b781091f76b5fdbebc3c 100644 (file)
@@ -41,6 +41,7 @@
 #include <ext/status_request.h>
 #include <ext/srtp.h>
 #include <ext/alpn.h>
+#include <ext/dumbfw.h>
 #include <ext/new_record_padding.h>
 #include <gnutls_num.h>
 
@@ -368,6 +369,10 @@ int _gnutls_ext_init(void)
                return ret;
 #endif
 
+       ret = _gnutls_ext_register(&ext_mod_dumbfw);
+       if (ret != GNUTLS_E_SUCCESS)
+               return ret;
+
        return GNUTLS_E_SUCCESS;
 }
 
index a095be190e6ea0e7b1c165431e9f9ac6286738c2..9e879ecc060c471485797cdee3386bd909fd7dfb 100644 (file)
@@ -265,6 +265,7 @@ typedef enum extensions_t {
        GNUTLS_EXTENSION_ALPN = 16,
        GNUTLS_EXTENSION_SESSION_TICKET = 35,
        GNUTLS_EXTENSION_NEW_RECORD_PADDING = 48015,    /* aka: 0xbeaf */
+       GNUTLS_EXTENSION_DUMBFW = 48016,
        GNUTLS_EXTENSION_SAFE_RENEGOTIATION = 65281     /* aka: 0xff01 */
 } extensions_t;
 
@@ -634,6 +635,7 @@ struct gnutls_priority_st {
        unsigned int allow_large_records:1;
        unsigned int new_record_padding:1;
        unsigned int max_empty_records;
+       unsigned int dumbfw;
        safe_renegotiation_t sr;
        unsigned int ssl3_record_version:1;
        unsigned int server_precedence:1;
index 7745a96918f4d0e315b12a606778243ad2b60afa..30ba5e05599a3aa7404726f72957ff25051e840f 100644 (file)
@@ -991,6 +991,9 @@ gnutls_priority_init(gnutls_priority_t * priority_cache,
                } else if (broken_list[i][0] == '%') {
                        if (strcasecmp(&broken_list[i][1], "COMPAT") == 0) {
                                ENABLE_COMPAT((*priority_cache));
+                       } else
+                         if (strcasecmp(&broken_list[i][1], "DUMBFW") == 0) {
+                               (*priority_cache)->dumbfw = 1;
                        } else
                            if (strcasecmp
                                (&broken_list[i][1],