/* * Copyright (C) 2013-2018 Nikos Mavrogiannopoulos * Copyright (C) 2018 Red Hat, Inc. * * 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 "auth.h" #include "errors.h" #include "num.h" #include /* This extension adds additional padding data in the TLS client hello. * There is an issue with some firewalls [0] rejecting TLS client hello * data that are between 256 and 511 bytes, and this extension will * make sure that client hello isn't in this range. * * [0]. https://www.ietf.org/mail-archive/web/tls/current/msg10423.html */ static int _gnutls_dumbfw_send_params(gnutls_session_t session, gnutls_buffer_st * extdata); const hello_ext_entry_st ext_mod_dumbfw = { .name = "ClientHello Padding", .tls_id = 21, .gid = GNUTLS_EXTENSION_DUMBFW, .client_parse_point = GNUTLS_EXT_APPLICATION, .server_parse_point = GNUTLS_EXT_APPLICATION, .validity = GNUTLS_EXT_FLAG_TLS | GNUTLS_EXT_FLAG_CLIENT_HELLO, .recv_func = NULL, .send_func = _gnutls_dumbfw_send_params, .pack_func = NULL, .unpack_func = NULL, .deinit_func = NULL, .cannot_be_overriden = 0 }; static int _gnutls_dumbfw_send_params(gnutls_session_t session, gnutls_buffer_st * extdata) { int total_size = 0, ret; uint8_t pad[257]; unsigned pad_size; ssize_t len = extdata->length - sizeof(mbuffer_st); if (session->security_parameters.entity == GNUTLS_SERVER || session->internals.dumbfw == 0 || IS_DTLS(session) != 0 || (len < 256 || len >= 512)) { return 0; } else { /* 256 <= extdata->length < 512 */ pad_size = 512 - len; memset(pad, 0, pad_size); ret = gnutls_buffer_append_data(extdata, pad, pad_size); if (ret < 0) return gnutls_assert_val(ret); total_size += pad_size; } return total_size; }