From: Nikos Mavrogiannopoulos Date: Sun, 10 Nov 2013 10:09:49 +0000 (+0100) Subject: Added %DUMBFW priority string option. X-Git-Tag: gnutls_3_2_7~69 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b6d29bb1737f96ac44a8ef9cc9fe7f9837e20465;p=thirdparty%2Fgnutls.git Added %DUMBFW priority string option. This works around issues when connecting behind some firewalls. --- diff --git a/NEWS b/NEWS index 99bc1205c7..5638f9340a 100644 --- 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. diff --git a/doc/cha-gtls-app.texi b/doc/cha-gtls-app.texi index 24301753ae..8b96ec7c5e 100644 --- a/doc/cha-gtls-app.texi +++ b/doc/cha-gtls-app.texi @@ -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 diff --git a/lib/ext/Makefile.am b/lib/ext/Makefile.am index 47e4df9450..0fcda01439 100644 --- a/lib/ext/Makefile.am +++ b/lib/ext/Makefile.am @@ -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 index 0000000000..10f72270b6 --- /dev/null +++ b/lib/ext/dumbfw.c @@ -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 + * + */ + +#include "gnutls_int.h" +#include "gnutls_auth.h" +#include "gnutls_errors.h" +#include "gnutls_num.h" +#include + +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 index 0000000000..ce8f21e812 --- /dev/null +++ b/lib/ext/dumbfw.h @@ -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 + * + */ +#ifndef EXT_DUMBFW_H +#define EXT_DUMBFW_H + +#include + +#define DUMBFW_PADDING_SIZE 465 + +extern extension_entry_st ext_mod_dumbfw; + +#endif diff --git a/lib/gnutls_extensions.c b/lib/gnutls_extensions.c index 3633a5c84d..a0dae49f09 100644 --- a/lib/gnutls_extensions.c +++ b/lib/gnutls_extensions.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -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; } diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index a095be190e..9e879ecc06 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -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; diff --git a/lib/gnutls_priority.c b/lib/gnutls_priority.c index 7745a96918..30ba5e0559 100644 --- a/lib/gnutls_priority.c +++ b/lib/gnutls_priority.c @@ -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],