From 3505b0888ab94c90468bd6f41f82770d46677342 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Iniesta Date: Thu, 22 Jun 2017 13:19:58 +0200 Subject: Refresh patches for 2.4.3 --- debian/patches/CVE-2017-7478.patch | 55 --- debian/patches/CVE-2017-7479-prereq.patch | 443 --------------------- debian/patches/CVE-2017-7479.patch | 193 --------- debian/patches/kfreebsd_support.patch | 44 +- .../patches/match-manpage-and-command-help.patch | 13 +- debian/patches/openvpn-pkcs11warn.patch | 6 +- debian/patches/series | 5 - debian/patches/upstream-issue-879.patch | 87 ---- debian/patches/wipe_tokens_on_de-auth.patch | 118 ------ 9 files changed, 30 insertions(+), 934 deletions(-) delete mode 100644 debian/patches/CVE-2017-7478.patch delete mode 100644 debian/patches/CVE-2017-7479-prereq.patch delete mode 100644 debian/patches/CVE-2017-7479.patch delete mode 100644 debian/patches/upstream-issue-879.patch delete mode 100644 debian/patches/wipe_tokens_on_de-auth.patch diff --git a/debian/patches/CVE-2017-7478.patch b/debian/patches/CVE-2017-7478.patch deleted file mode 100644 index e301cf1..0000000 --- a/debian/patches/CVE-2017-7478.patch +++ /dev/null @@ -1,55 +0,0 @@ -From be66408610a52f81c9c895a8973958ead55a4e57 Mon Sep 17 00:00:00 2001 -From: Steffan Karger -Date: Tue, 9 May 2017 15:40:25 +0300 -Subject: [PATCH] Don't assert out on receiving too-large control packets - (CVE-2017-xxx) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Commit 3c1b19e0 changed the maximum size of accepted control channel -packets. This was needed for crypto negotiation (which is needed for a -nice transition to a new default cipher), but exposed a DoS -vulnerability. The vulnerability was found during the OpenVPN 2.4 code -audit by Quarkslab (commisioned by OSTIF). - -To fix the issue, we should not ASSERT() on external input (in this case -the received packet size), but instead gracefully error out and drop the -invalid packet. - -Signed-off-by: Steffan Karger -Signed-off-by: Samuli Seppänen - -CVE-2017-7478 - - Security - -------- - - This release fixes a pre-authentication denial-of-service attack on both - clients and servers. By sending a too-large control packet, OpenVPN 2.4.0 or - 2.4.1 can be forced to hit an ASSERT() and stop the process. If - ``--tls-auth`` or ``--tls-crypt`` is used, only attackers that have the - ``--tls-auth`` or ``--tls-crypt`` key can mount an attack. (CVE-2017-xxx) - ---- - Changes.rst | 8 ++++++++ - src/openvpn/ssl.c | 7 ++++++- - 2 files changed, 14 insertions(+), 1 deletion(-) - -Index: openvpn-2.4.0/src/openvpn/ssl.c -=================================================================== ---- openvpn-2.4.0.orig/src/openvpn/ssl.c -+++ openvpn-2.4.0/src/openvpn/ssl.c -@@ -3708,7 +3708,12 @@ tls_pre_decrypt(struct tls_multi *multi, - /* Save incoming ciphertext packet to reliable buffer */ - struct buffer *in = reliable_get_buf(ks->rec_reliable); - ASSERT(in); -- ASSERT(buf_copy(in, buf)); -+ if(!buf_copy(in, buf)) -+ { -+ msg(D_MULTI_DROPPED, -+ "Incoming control channel packet too big, dropping."); -+ goto error; -+ } - reliable_mark_active_incoming(ks->rec_reliable, in, id, op); - } - diff --git a/debian/patches/CVE-2017-7479-prereq.patch b/debian/patches/CVE-2017-7479-prereq.patch deleted file mode 100644 index e3c94d7..0000000 --- a/debian/patches/CVE-2017-7479-prereq.patch +++ /dev/null @@ -1,443 +0,0 @@ -From a87e1431baccd49a9344cfc63ab7446c4317fa2f Mon Sep 17 00:00:00 2001 -From: Steffan Karger -Date: Fri, 5 May 2017 19:44:51 +0200 -Subject: [PATCH] cleanup: merge packet_id_alloc_outgoing() into - packet_id_write() - -The functions packet_id_alloc_outgoing() and packet_id_write() were -always called in tandem. Instead of forcing the caller to allocate a -packet_id_net to do so, merge the two functions. This simplifies the API -and reduces the chance on mistakes in the future. - -This patch adds unit tests to verify the behaviour of packet_id_write(). -Verifying that we assert out correctly required the change to mock_msg.c. - -Signed-off-by: Steffan Karger -Acked-by: Gert Doering -Acked-by: David Sommerseth -Message-Id: <1494006291-3522-1-git-send-email-steffan.karger@fox-it.com> -URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14541.html -Signed-off-by: Gert Doering - -[prerequisite for CVE-2017-7479. Adjusted to apply to 2.4.0 release -- sbeattie] - ---- - src/openvpn/crypto.c | 20 ++-- - src/openvpn/packet_id.c | 24 ++++- - src/openvpn/packet_id.h | 35 +++---- - src/openvpn/tls_crypt.c | 6 +- - tests/unit_tests/openvpn/Makefile.am | 13 ++- - tests/unit_tests/openvpn/mock_msg.c | 15 ++- - tests/unit_tests/openvpn/test_packet_id.c | 168 ++++++++++++++++++++++++++++++ - 7 files changed, 228 insertions(+), 53 deletions(-) - create mode 100644 tests/unit_tests/openvpn/test_packet_id.c - -Index: openvpn-2.4.0/src/openvpn/crypto.c -=================================================================== ---- openvpn-2.4.0.orig/src/openvpn/crypto.c -+++ openvpn-2.4.0/src/openvpn/crypto.c -@@ -85,7 +85,6 @@ openvpn_encrypt_aead(struct buffer *buf, - /* Prepare IV */ - { - struct buffer iv_buffer; -- struct packet_id_net pin; - uint8_t iv[OPENVPN_MAX_IV_LENGTH] = {0}; - const int iv_len = cipher_ctx_iv_length(ctx->cipher); - -@@ -94,8 +93,7 @@ openvpn_encrypt_aead(struct buffer *buf, - buf_set_write(&iv_buffer, iv, iv_len); - - /* IV starts with packet id to make the IV unique for packet */ -- packet_id_alloc_outgoing(&opt->packet_id.send, &pin, false); -- ASSERT(packet_id_write(&pin, &iv_buffer, false, false)); -+ ASSERT(packet_id_write(&opt->packet_id.send, &iv_buffer, false, false)); - - /* Remainder of IV consists of implicit part (unique per session) */ - ASSERT(buf_write(&iv_buffer, ctx->implicit_iv, ctx->implicit_iv_len)); -@@ -198,23 +196,21 @@ openvpn_encrypt_v1(struct buffer *buf, s - /* Put packet ID in plaintext buffer */ - if (packet_id_initialized(&opt->packet_id)) - { -- struct packet_id_net pin; -- packet_id_alloc_outgoing(&opt->packet_id.send, &pin, BOOL_CAST(opt->flags & CO_PACKET_ID_LONG_FORM)); -- ASSERT(packet_id_write(&pin, buf, BOOL_CAST(opt->flags & CO_PACKET_ID_LONG_FORM), true)); -+ ASSERT(packet_id_write(&opt->packet_id.send, buf, -+ opt->flags & CO_PACKET_ID_LONG_FORM, -+ true)); - } - } - else if (cipher_kt_mode_ofb_cfb(cipher_kt)) - { -- struct packet_id_net pin; - struct buffer b; - - /* IV and packet-ID required for this mode. */ - ASSERT(opt->flags & CO_USE_IV); - ASSERT(packet_id_initialized(&opt->packet_id)); - -- packet_id_alloc_outgoing(&opt->packet_id.send, &pin, true); - buf_set_write(&b, iv_buf, iv_size); -- ASSERT(packet_id_write(&pin, &b, true, false)); -+ ASSERT(packet_id_write(&opt->packet_id.send, &b, true, false)); - } - else /* We only support CBC, CFB, or OFB modes right now */ - { -@@ -264,9 +260,9 @@ openvpn_encrypt_v1(struct buffer *buf, s - { - if (packet_id_initialized(&opt->packet_id)) - { -- struct packet_id_net pin; -- packet_id_alloc_outgoing(&opt->packet_id.send, &pin, BOOL_CAST(opt->flags & CO_PACKET_ID_LONG_FORM)); -- ASSERT(packet_id_write(&pin, buf, BOOL_CAST(opt->flags & CO_PACKET_ID_LONG_FORM), true)); -+ ASSERT(packet_id_write(&opt->packet_id.send, buf, -+ BOOL_CAST(opt->flags & CO_PACKET_ID_LONG_FORM), -+ true)); - } - if (ctx->hmac) - { -Index: openvpn-2.4.0/src/openvpn/packet_id.c -=================================================================== ---- openvpn-2.4.0.orig/src/openvpn/packet_id.c -+++ openvpn-2.4.0/src/openvpn/packet_id.c -@@ -325,12 +325,30 @@ packet_id_read(struct packet_id_net *pin - return true; - } - -+static void -+packet_id_send_update(struct packet_id_send *p, bool long_form) -+{ -+ if (!p->time) -+ { -+ p->time = now; -+ } -+ p->id++; -+ if (!p->id) -+ { -+ ASSERT(long_form); -+ p->time = now; -+ p->id = 1; -+ } -+} -+ - bool --packet_id_write(const struct packet_id_net *pin, struct buffer *buf, bool long_form, bool prepend) -+packet_id_write(struct packet_id_send *p, struct buffer *buf, bool long_form, -+ bool prepend) - { -- packet_id_type net_id = htonpid(pin->id); -- net_time_t net_time = htontime(pin->time); -+ packet_id_send_update(p, long_form); - -+ const packet_id_type net_id = htonpid(p->id); -+ const net_time_t net_time = htontime(p->time); - if (prepend) - { - if (long_form) -Index: openvpn-2.4.0/src/openvpn/packet_id.h -=================================================================== ---- openvpn-2.4.0.orig/src/openvpn/packet_id.h -+++ openvpn-2.4.0/src/openvpn/packet_id.h -@@ -254,7 +254,18 @@ const char *packet_id_persist_print(cons - - bool packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form); - --bool packet_id_write(const struct packet_id_net *pin, struct buffer *buf, bool long_form, bool prepend); -+/** -+ * Write a packet ID to buf, and update the packet ID state. -+ * -+ * @param p Packet ID state. -+ * @param buf Buffer to write the packet ID too -+ * @param long_form If true, also update and write time_t to buf -+ * @param prepend If true, prepend to buffer, otherwise apppend. -+ * -+ * @return true if successful, false otherwise. -+ */ -+bool packet_id_write(struct packet_id_send *p, struct buffer *buf, -+ bool long_form, bool prepend); - - /* - * Inline functions. -@@ -304,28 +315,6 @@ packet_id_close_to_wrapping(const struct - return p->id >= PACKET_ID_WRAP_TRIGGER; - } - --/* -- * Allocate an outgoing packet id. -- * Sequence number ranges from 1 to 2^32-1. -- * In long_form, a time_t is added as well. -- */ --static inline void --packet_id_alloc_outgoing(struct packet_id_send *p, struct packet_id_net *pin, bool long_form) --{ -- if (!p->time) -- { -- p->time = now; -- } -- pin->id = ++p->id; -- if (!pin->id) -- { -- ASSERT(long_form); -- p->time = now; -- pin->id = p->id = 1; -- } -- pin->time = p->time; --} -- - static inline bool - check_timestamp_delta(time_t remote, unsigned int max_delta) - { -Index: openvpn-2.4.0/src/openvpn/tls_crypt.c -=================================================================== ---- openvpn-2.4.0.orig/src/openvpn/tls_crypt.c -+++ openvpn-2.4.0/src/openvpn/tls_crypt.c -@@ -95,11 +95,7 @@ tls_crypt_wrap(const struct buffer *src, - format_hex(BPTR(src), BLEN(src), 80, &gc)); - - /* Get packet ID */ -- { -- struct packet_id_net pin; -- packet_id_alloc_outgoing(&opt->packet_id.send, &pin, true); -- packet_id_write(&pin, dst, true, false); -- } -+ ASSERT(packet_id_write(&opt->packet_id.send, dst, true, false)); - - dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP AD: %s", - format_hex(BPTR(dst), BLEN(dst), 0, &gc)); -Index: openvpn-2.4.0/tests/unit_tests/openvpn/Makefile.am -=================================================================== ---- openvpn-2.4.0.orig/tests/unit_tests/openvpn/Makefile.am -+++ openvpn-2.4.0/tests/unit_tests/openvpn/Makefile.am -@@ -1,6 +1,6 @@ - AUTOMAKE_OPTIONS = foreign - --check_PROGRAMS = argv_testdriver buffer_testdriver -+check_PROGRAMS = argv_testdriver buffer_testdriver packet_id_testdriver - - if ENABLE_CRYPTO - check_PROGRAMS += tls_crypt_testdriver -@@ -27,6 +27,17 @@ buffer_testdriver_SOURCES = test_buffer. - $(openvpn_srcdir)/buffer.c \ - $(openvpn_srcdir)/platform.c - -+packet_id_testdriver_CFLAGS = @TEST_CFLAGS@ \ -+ -I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \ -+ $(OPTIONAL_CRYPTO_CFLAGS) -+packet_id_testdriver_LDFLAGS = @TEST_LDFLAGS@ \ -+ $(OPTIONAL_CRYPTO_LIBS) -+packet_id_testdriver_SOURCES = test_packet_id.c mock_msg.c \ -+ $(openvpn_srcdir)/buffer.c \ -+ $(openvpn_srcdir)/otime.c \ -+ $(openvpn_srcdir)/packet_id.c \ -+ $(openvpn_srcdir)/platform.c -+ - tls_crypt_testdriver_CFLAGS = @TEST_CFLAGS@ \ - -I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \ - $(OPTIONAL_CRYPTO_CFLAGS) -Index: openvpn-2.4.0/tests/unit_tests/openvpn/mock_msg.c -=================================================================== ---- openvpn-2.4.0.orig/tests/unit_tests/openvpn/mock_msg.c -+++ openvpn-2.4.0/tests/unit_tests/openvpn/mock_msg.c -@@ -29,9 +29,12 @@ - #endif - - #include --#include -+#include - #include - #include -+#include -+#include -+ - - #include "errlevel.h" - #include "error.h" -@@ -70,14 +73,8 @@ x_msg(const unsigned int flags, const ch - void - assert_failed(const char *filename, int line, const char *condition) - { -- if (condition) -- { -- printf("Assertion failed at %s:%d (%s)", filename, line, condition); -- } -- else -- { -- printf("Assertion failed at %s:%d", filename, line); -- } -+ mock_assert(false, condition ? condition : "", filename, line); -+ /* Keep compiler happy. Should not happen, mock_assert() does not return */ - exit(1); - } - -Index: openvpn-2.4.0/tests/unit_tests/openvpn/test_packet_id.c -=================================================================== ---- /dev/null -+++ openvpn-2.4.0/tests/unit_tests/openvpn/test_packet_id.c -@@ -0,0 +1,168 @@ -+/* -+ * OpenVPN -- An application to securely tunnel IP networks -+ * over a single UDP port, with support for SSL/TLS-based -+ * session authentication and key exchange, -+ * packet encryption, packet authentication, and -+ * packet compression. -+ * -+ * Copyright (C) 2016 Fox Crypto B.V. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program (see the file COPYING included with this -+ * distribution); if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#elif defined(_MSC_VER) -+#include "config-msvc.h" -+#endif -+ -+#include "syshead.h" -+ -+#include -+#include -+#include -+#include -+ -+#include "packet_id.h" -+ -+#include "mock_msg.h" -+ -+struct test_packet_id_write_data { -+ struct { -+ uint32_t buf_id; -+ uint32_t buf_time; -+ } test_buf_data; -+ struct buffer test_buf; -+ struct packet_id_send pis; -+}; -+ -+static int -+test_packet_id_write_setup(void **state) { -+ struct test_packet_id_write_data *data = -+ calloc(1, sizeof(struct test_packet_id_write_data)); -+ -+ if (!data) -+ { -+ return -1; -+ } -+ -+ data->test_buf.data = (void *) &data->test_buf_data; -+ data->test_buf.capacity = sizeof(data->test_buf_data); -+ -+ *state = data; -+ return 0; -+} -+ -+static int -+test_packet_id_write_teardown(void **state) { -+ free(*state); -+ return 0; -+} -+ -+static void -+test_packet_id_write_short(void **state) -+{ -+ struct test_packet_id_write_data *data = *state; -+ -+ now = 5010; -+ assert_true(packet_id_write(&data->pis, &data->test_buf, false, false)); -+ assert_true(data->pis.id == 1); -+ assert_true(data->test_buf_data.buf_id == htonl(1)); -+ assert_true(data->test_buf_data.buf_time == 0); -+} -+ -+static void -+test_packet_id_write_long(void **state) -+{ -+ struct test_packet_id_write_data *data = *state; -+ -+ now = 5010; -+ assert_true(packet_id_write(&data->pis, &data->test_buf, true, false)); -+ assert(data->pis.id == 1); -+ assert(data->pis.time == now); -+ assert_true(data->test_buf_data.buf_id == htonl(1)); -+ assert_true(data->test_buf_data.buf_time == htonl(now)); -+} -+ -+static void -+test_packet_id_write_short_prepend(void **state) -+{ -+ struct test_packet_id_write_data *data = *state; -+ -+ data->test_buf.offset = sizeof(packet_id_type); -+ now = 5010; -+ assert_true(packet_id_write(&data->pis, &data->test_buf, false, true)); -+ assert_true(data->pis.id == 1); -+ assert_true(data->test_buf_data.buf_id == htonl(1)); -+ assert_true(data->test_buf_data.buf_time == 0); -+} -+ -+static void -+test_packet_id_write_long_prepend(void **state) -+{ -+ struct test_packet_id_write_data *data = *state; -+ -+ data->test_buf.offset = sizeof(data->test_buf_data); -+ now = 5010; -+ assert_true(packet_id_write(&data->pis, &data->test_buf, true, true)); -+ assert(data->pis.id == 1); -+ assert(data->pis.time == now); -+ assert_true(data->test_buf_data.buf_id == htonl(1)); -+ assert_true(data->test_buf_data.buf_time == htonl(now)); -+} -+ -+static void -+test_packet_id_write_short_wrap(void **state) -+{ -+ struct test_packet_id_write_data *data = *state; -+ -+ data->pis.id = ~0; -+ expect_assert_failure( -+ packet_id_write(&data->pis, &data->test_buf, false, false)); -+} -+ -+static void -+test_packet_id_write_long_wrap(void **state) -+{ -+ struct test_packet_id_write_data *data = *state; -+ -+ data->pis.id = ~0; -+ now = 5010; -+ assert_true(packet_id_write(&data->pis, &data->test_buf, true, false)); -+ assert(data->pis.id == 1); -+ assert(data->pis.time == now); -+ assert_true(data->test_buf_data.buf_id == htonl(1)); -+ assert_true(data->test_buf_data.buf_time == htonl(now)); -+} -+ -+int -+main(void) { -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test_setup_teardown(test_packet_id_write_short, -+ test_packet_id_write_setup, test_packet_id_write_teardown), -+ cmocka_unit_test_setup_teardown(test_packet_id_write_long, -+ test_packet_id_write_setup, test_packet_id_write_teardown), -+ cmocka_unit_test_setup_teardown(test_packet_id_write_short_prepend, -+ test_packet_id_write_setup, test_packet_id_write_teardown), -+ cmocka_unit_test_setup_teardown(test_packet_id_write_long_prepend, -+ test_packet_id_write_setup, test_packet_id_write_teardown), -+ cmocka_unit_test_setup_teardown(test_packet_id_write_short_wrap, -+ test_packet_id_write_setup, test_packet_id_write_teardown), -+ cmocka_unit_test_setup_teardown(test_packet_id_write_long_wrap, -+ test_packet_id_write_setup, test_packet_id_write_teardown), -+ }; -+ -+ return cmocka_run_group_tests_name("packet_id tests", tests, NULL, NULL); -+} diff --git a/debian/patches/CVE-2017-7479.patch b/debian/patches/CVE-2017-7479.patch deleted file mode 100644 index 9f75d31..0000000 --- a/debian/patches/CVE-2017-7479.patch +++ /dev/null @@ -1,193 +0,0 @@ -From ac08b27cfa693d9be592bb2597c260635aee9e68 Mon Sep 17 00:00:00 2001 -From: Steffan Karger -Date: Tue, 25 Apr 2017 10:00:44 +0200 -Subject: [PATCH 2/2] Drop packets instead of asserting out if packet id rolls - over -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Previously, if a mode was selected where packet ids are not allowed to roll -over, but renegotiation does not succeed for some reason (e.g. no password -entered in time, certificate expired or a malicious peer that refuses the -renegotiaion on purpose) we would continue to use the old keys. Until the -packet ID would roll over and we would ASSERT() out. - -Given that this can be triggered on purpose by an authenticated peer, this -is a fix for an authenticated remote DoS vulnerability. An attack is -rather inefficient though; a peer would need to get us to send 2^32 -packets (min-size packet is IP+UDP+OPCODE+PID+TAG (no payload), results in -(20+8+1+4+16)×2^32 bytes, or approx. 196 GB). - -Signed-off-by: Steffan Karger - -CVE-2017-7479 - ---- - src/openvpn/crypto.c | 25 ++++++++++++++++--------- - src/openvpn/packet_id.c | 22 ++++++++++++++++------ - src/openvpn/packet_id.h | 1 + - src/openvpn/tls_crypt.c | 6 +++++- - tests/unit_tests/openvpn/test_packet_id.c | 11 +++++++++-- - 5 files changed, 47 insertions(+), 18 deletions(-) - -Index: openvpn-2.4.0/src/openvpn/crypto.c -=================================================================== ---- openvpn-2.4.0.orig/src/openvpn/crypto.c -+++ openvpn-2.4.0/src/openvpn/crypto.c -@@ -93,7 +93,11 @@ openvpn_encrypt_aead(struct buffer *buf, - buf_set_write(&iv_buffer, iv, iv_len); - - /* IV starts with packet id to make the IV unique for packet */ -- ASSERT(packet_id_write(&opt->packet_id.send, &iv_buffer, false, false)); -+ if (!packet_id_write(&opt->packet_id.send, &iv_buffer, false, false)) -+ { -+ msg(D_CRYPT_ERRORS, "ENCRYPT ERROR: packet ID roll over"); -+ goto err; -+ } - - /* Remainder of IV consists of implicit part (unique per session) */ - ASSERT(buf_write(&iv_buffer, ctx->implicit_iv, ctx->implicit_iv_len)); -@@ -194,11 +198,13 @@ openvpn_encrypt_v1(struct buffer *buf, s - } - - /* Put packet ID in plaintext buffer */ -- if (packet_id_initialized(&opt->packet_id)) -+ if (packet_id_initialized(&opt->packet_id) -+ && !packet_id_write(&opt->packet_id.send, buf, -+ opt->flags & CO_PACKET_ID_LONG_FORM, -+ true)) - { -- ASSERT(packet_id_write(&opt->packet_id.send, buf, -- opt->flags & CO_PACKET_ID_LONG_FORM, -- true)); -+ msg(D_CRYPT_ERRORS, "ENCRYPT ERROR: packet ID roll over"); -+ goto err; - } - } - else if (cipher_kt_mode_ofb_cfb(cipher_kt)) -@@ -258,11 +264,12 @@ openvpn_encrypt_v1(struct buffer *buf, s - } - else /* No Encryption */ - { -- if (packet_id_initialized(&opt->packet_id)) -+ if (packet_id_initialized(&opt->packet_id) -+ && !packet_id_write(&opt->packet_id.send, buf, -+ opt->flags & CO_PACKET_ID_LONG_FORM, true)) - { -- ASSERT(packet_id_write(&opt->packet_id.send, buf, -- BOOL_CAST(opt->flags & CO_PACKET_ID_LONG_FORM), -- true)); -+ msg(D_CRYPT_ERRORS, "ENCRYPT ERROR: packet ID roll over"); -+ goto err; - } - if (ctx->hmac) - { -Index: openvpn-2.4.0/src/openvpn/packet_id.c -=================================================================== ---- openvpn-2.4.0.orig/src/openvpn/packet_id.c -+++ openvpn-2.4.0/src/openvpn/packet_id.c -@@ -325,27 +325,37 @@ packet_id_read(struct packet_id_net *pin - return true; - } - --static void -+static bool - packet_id_send_update(struct packet_id_send *p, bool long_form) - { - if (!p->time) - { - p->time = now; - } -- p->id++; -- if (!p->id) -+ if (p->id == PACKET_ID_MAX) - { -- ASSERT(long_form); -+ /* Packet ID only allowed to roll over if using long form and time has -+ * moved forward since last roll over. -+ */ -+ if (!long_form || now <= p->time) -+ { -+ return false; -+ } - p->time = now; -- p->id = 1; -+ p->id = 0; - } -+ p->id++; -+ return true; - } - - bool - packet_id_write(struct packet_id_send *p, struct buffer *buf, bool long_form, - bool prepend) - { -- packet_id_send_update(p, long_form); -+ if (!packet_id_send_update(p, long_form)) -+ { -+ return false; -+ } - - const packet_id_type net_id = htonpid(p->id); - const net_time_t net_time = htontime(p->time); -Index: openvpn-2.4.0/src/openvpn/packet_id.h -=================================================================== ---- openvpn-2.4.0.orig/src/openvpn/packet_id.h -+++ openvpn-2.4.0/src/openvpn/packet_id.h -@@ -50,6 +50,7 @@ - * to for network transmission. - */ - typedef uint32_t packet_id_type; -+#define PACKET_ID_MAX UINT32_MAX - typedef uint32_t net_time_t; - - /* -Index: openvpn-2.4.0/src/openvpn/tls_crypt.c -=================================================================== ---- openvpn-2.4.0.orig/src/openvpn/tls_crypt.c -+++ openvpn-2.4.0/src/openvpn/tls_crypt.c -@@ -95,7 +95,11 @@ tls_crypt_wrap(const struct buffer *src, - format_hex(BPTR(src), BLEN(src), 80, &gc)); - - /* Get packet ID */ -- ASSERT(packet_id_write(&opt->packet_id.send, dst, true, false)); -+ if (!packet_id_write(&opt->packet_id.send, dst, true, false)) -+ { -+ msg(D_CRYPT_ERRORS, "TLS-CRYPT ERROR: packet ID roll over."); -+ goto err; -+ } - - dmsg(D_PACKET_CONTENT, "TLS-CRYPT WRAP AD: %s", - format_hex(BPTR(dst), BLEN(dst), 0, &gc)); -Index: openvpn-2.4.0/tests/unit_tests/openvpn/test_packet_id.c -=================================================================== ---- openvpn-2.4.0.orig/tests/unit_tests/openvpn/test_packet_id.c -+++ openvpn-2.4.0/tests/unit_tests/openvpn/test_packet_id.c -@@ -129,8 +129,7 @@ test_packet_id_write_short_wrap(void **s - struct test_packet_id_write_data *data = *state; - - data->pis.id = ~0; -- expect_assert_failure( -- packet_id_write(&data->pis, &data->test_buf, false, false)); -+ assert_false(packet_id_write(&data->pis, &data->test_buf, false, false)); - } - - static void -@@ -139,8 +138,16 @@ test_packet_id_write_long_wrap(void **st - struct test_packet_id_write_data *data = *state; - - data->pis.id = ~0; -+ data->pis.time = 5006; -+ -+ /* Write fails if time did not change */ -+ now = 5006; -+ assert_false(packet_id_write(&data->pis, &data->test_buf, true, false)); -+ -+ /* Write succeeds if time moved forward */ - now = 5010; - assert_true(packet_id_write(&data->pis, &data->test_buf, true, false)); -+ - assert(data->pis.id == 1); - assert(data->pis.time == now); - assert_true(data->test_buf_data.buf_id == htonl(1)); diff --git a/debian/patches/kfreebsd_support.patch b/debian/patches/kfreebsd_support.patch index 0c8165b..4445e0d 100644 --- a/debian/patches/kfreebsd_support.patch +++ b/debian/patches/kfreebsd_support.patch @@ -3,9 +3,9 @@ Author: Gonéri Le Bouder Bug-Debian: http://bugs.debian.org/626062 Index: openvpn/src/openvpn/route.c =================================================================== ---- openvpn.orig/src/openvpn/route.c 2016-12-27 19:01:52.704942715 +0100 -+++ openvpn/src/openvpn/route.c 2016-12-27 19:08:24.717996310 +0100 -@@ -1670,7 +1670,7 @@ +--- openvpn.orig/src/openvpn/route.c 2017-06-22 13:17:05.754630908 +0200 ++++ openvpn/src/openvpn/route.c 2017-06-22 13:17:05.750630880 +0200 +@@ -1689,7 +1689,7 @@ argv_msg(D_ROUTE, &argv); status = openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route add command failed"); @@ -14,7 +14,7 @@ Index: openvpn/src/openvpn/route.c argv_printf(&argv, "%s add", ROUTE_PATH); -@@ -1856,7 +1856,7 @@ +@@ -1875,7 +1875,7 @@ network = print_in6_addr( r6->network, 0, &gc); gateway = print_in6_addr( r6->gateway, 0, &gc); @@ -23,7 +23,7 @@ Index: openvpn/src/openvpn/route.c || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \ || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) -@@ -2032,7 +2032,7 @@ +@@ -2043,7 +2043,7 @@ argv_msg(D_ROUTE, &argv); status = openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route add -inet6 command failed"); @@ -32,7 +32,7 @@ Index: openvpn/src/openvpn/route.c argv_printf(&argv, "%s add -inet6 %s/%d", ROUTE_PATH, -@@ -2216,7 +2216,7 @@ +@@ -2227,7 +2227,7 @@ argv_msg(D_ROUTE, &argv); openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route delete command failed"); @@ -41,7 +41,7 @@ Index: openvpn/src/openvpn/route.c argv_printf(&argv, "%s delete -net %s %s %s", ROUTE_PATH, -@@ -2323,7 +2323,7 @@ +@@ -2334,7 +2334,7 @@ network = print_in6_addr( r6->network, 0, &gc); gateway = print_in6_addr( r6->gateway, 0, &gc); @@ -50,7 +50,7 @@ Index: openvpn/src/openvpn/route.c || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \ || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) -@@ -2458,7 +2458,7 @@ +@@ -2469,7 +2469,7 @@ argv_msg(D_ROUTE, &argv); openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route delete -inet6 command failed"); @@ -59,7 +59,7 @@ Index: openvpn/src/openvpn/route.c argv_printf(&argv, "%s delete -inet6 %s/%d", ROUTE_PATH, -@@ -3499,7 +3499,8 @@ +@@ -3514,7 +3514,8 @@ #elif defined(TARGET_DARWIN) || defined(TARGET_SOLARIS) \ || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \ @@ -71,9 +71,9 @@ Index: openvpn/src/openvpn/route.c #include Index: openvpn/src/openvpn/tun.c =================================================================== ---- openvpn.orig/src/openvpn/tun.c 2016-12-27 19:01:52.704942715 +0100 -+++ openvpn/src/openvpn/tun.c 2016-12-27 19:05:14.585486719 +0100 -@@ -840,7 +840,7 @@ +--- openvpn.orig/src/openvpn/tun.c 2017-06-22 13:17:05.754630908 +0200 ++++ openvpn/src/openvpn/tun.c 2017-06-22 13:17:05.750630880 +0200 +@@ -843,7 +843,7 @@ #endif /* if defined(_WIN32) || defined(TARGET_DARWIN) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) */ #if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \ @@ -82,7 +82,7 @@ Index: openvpn/src/openvpn/tun.c /* we can't use true subnet mode on tun on all platforms, as that * conflicts with IPv6 (wants to use ND then, which we don't do), * but the OSes want "a remote address that is different from ours" -@@ -1408,7 +1408,7 @@ +@@ -1412,7 +1412,7 @@ add_route_connected_v6_net(tt, es); } @@ -91,7 +91,7 @@ Index: openvpn/src/openvpn/tun.c in_addr_t remote_end; /* for "virtual" subnet topology */ -@@ -2762,7 +2762,7 @@ +@@ -2770,7 +2770,7 @@ } } @@ -102,8 +102,8 @@ Index: openvpn/src/openvpn/tun.c freebsd_modify_read_write_return(int len) Index: openvpn/src/openvpn/lladdr.c =================================================================== ---- openvpn.orig/src/openvpn/lladdr.c 2016-12-27 19:01:52.704942715 +0100 -+++ openvpn/src/openvpn/lladdr.c 2016-12-27 19:09:07.286110127 +0100 +--- openvpn.orig/src/openvpn/lladdr.c 2017-06-22 13:17:05.754630908 +0200 ++++ openvpn/src/openvpn/lladdr.c 2017-06-22 13:17:05.750630880 +0200 @@ -50,7 +50,7 @@ "%s %s lladdr %s", IFCONFIG_PATH, @@ -115,9 +115,9 @@ Index: openvpn/src/openvpn/lladdr.c IFCONFIG_PATH, Index: openvpn/src/openvpn/syshead.h =================================================================== ---- openvpn.orig/src/openvpn/syshead.h 2016-12-27 19:01:52.704942715 +0100 -+++ openvpn/src/openvpn/syshead.h 2016-12-27 19:01:52.700942705 +0100 -@@ -294,7 +294,7 @@ +--- openvpn.orig/src/openvpn/syshead.h 2017-06-22 13:17:05.754630908 +0200 ++++ openvpn/src/openvpn/syshead.h 2017-06-22 13:17:05.750630880 +0200 +@@ -297,7 +297,7 @@ #endif /* TARGET_OPENBSD */ @@ -128,9 +128,9 @@ Index: openvpn/src/openvpn/syshead.h #include Index: openvpn/src/openvpn/ssl.c =================================================================== ---- openvpn.orig/src/openvpn/ssl.c 2016-12-27 19:01:52.704942715 +0100 -+++ openvpn/src/openvpn/ssl.c 2016-12-27 19:03:13.433160691 +0100 -@@ -2247,7 +2247,7 @@ +--- openvpn.orig/src/openvpn/ssl.c 2017-06-22 13:17:05.754630908 +0200 ++++ openvpn/src/openvpn/ssl.c 2017-06-22 13:17:05.750630880 +0200 +@@ -2269,7 +2269,7 @@ buf_printf(&out, "IV_PLAT=mac\n"); #elif defined(TARGET_NETBSD) buf_printf(&out, "IV_PLAT=netbsd\n"); diff --git a/debian/patches/match-manpage-and-command-help.patch b/debian/patches/match-manpage-and-command-help.patch index 34ed3cd..39b899c 100644 --- a/debian/patches/match-manpage-and-command-help.patch +++ b/debian/patches/match-manpage-and-command-help.patch @@ -7,11 +7,11 @@ Subject: [PATCH] Change command help to match man page and implementation src/openvpn/options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/src/openvpn/options.c b/src/openvpn/options.c -index bfedb6a..80143e6 100644 ---- a/src/openvpn/options.c -+++ b/src/openvpn/options.c -@@ -198,7 +198,7 @@ static const char usage_message[] = +Index: openvpn/src/openvpn/options.c +=================================================================== +--- openvpn.orig/src/openvpn/options.c 2017-06-22 13:17:12.806680520 +0200 ++++ openvpn/src/openvpn/options.c 2017-06-22 13:17:12.802680492 +0200 +@@ -197,7 +197,7 @@ " is established. Multiple routes can be specified.\n" " netmask default: 255.255.255.255\n" " gateway default: taken from --route-gateway or --ifconfig\n" @@ -20,6 +20,3 @@ index bfedb6a..80143e6 100644 "--route-ipv6 network/bits [gateway] [metric] :\n" " Add IPv6 route to routing table after connection\n" " is established. Multiple routes can be specified.\n" --- -2.10.1 (Apple Git-78) - diff --git a/debian/patches/openvpn-pkcs11warn.patch b/debian/patches/openvpn-pkcs11warn.patch index 0ec934f..1fabddd 100644 --- a/debian/patches/openvpn-pkcs11warn.patch +++ b/debian/patches/openvpn-pkcs11warn.patch @@ -3,9 +3,9 @@ Author: Florian Kulzer Bug-Debian: http://bugs.debian.org/475353 Index: openvpn/src/openvpn/options.c =================================================================== ---- openvpn.orig/src/openvpn/options.c 2016-12-27 18:46:18.362320774 +0100 -+++ openvpn/src/openvpn/options.c 2016-12-27 18:46:18.362320774 +0100 -@@ -6789,6 +6789,20 @@ +--- openvpn.orig/src/openvpn/options.c 2017-06-22 13:16:58.862582114 +0200 ++++ openvpn/src/openvpn/options.c 2017-06-22 13:16:58.862582114 +0200 +@@ -6818,6 +6818,20 @@ options->port_share_port = p[2]; options->port_share_journal_dir = p[3]; } diff --git a/debian/patches/series b/debian/patches/series index 907dc15..50b527d 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -3,8 +3,3 @@ debian_nogroup_for_sample_files.patch openvpn-pkcs11warn.patch kfreebsd_support.patch match-manpage-and-command-help.patch -CVE-2017-7478.patch -CVE-2017-7479-prereq.patch -CVE-2017-7479.patch -wipe_tokens_on_de-auth.patch -upstream-issue-879.patch diff --git a/debian/patches/upstream-issue-879.patch b/debian/patches/upstream-issue-879.patch deleted file mode 100644 index 2139afc..0000000 --- a/debian/patches/upstream-issue-879.patch +++ /dev/null @@ -1,87 +0,0 @@ -Index: openvpn/src/openvpn/forward.c -=================================================================== ---- openvpn.orig/src/openvpn/forward.c 2017-05-22 14:59:09.634938195 +0200 -+++ openvpn/src/openvpn/forward.c 2017-05-22 14:59:09.630937170 +0200 -@@ -866,9 +866,16 @@ - * will load crypto_options with the correct encryption key - * and return false. - */ -+ uint8_t opcode = *BPTR(&c->c2.buf) >> P_OPCODE_SHIFT; - if (tls_pre_decrypt(c->c2.tls_multi, &c->c2.from, &c->c2.buf, &co, - floated, &ad_start)) - { -+ /* Restore pre-NCP frame parameters */ -+ if (is_hard_reset(opcode, c->options.key_method)) -+ { -+ c->c2.frame = c->c2.frame_initial; -+ } -+ - interval_action(&c->c2.tmp_int); - - /* reset packet received timer if TLS packet */ -Index: openvpn/src/openvpn/init.c -=================================================================== ---- openvpn.orig/src/openvpn/init.c 2017-05-22 14:59:09.634938195 +0200 -+++ openvpn/src/openvpn/init.c 2017-05-22 14:59:09.634938195 +0200 -@@ -4055,6 +4055,8 @@ - c->c2.did_open_tun = do_open_tun(c); - } - -+ c->c2.frame_initial = c->c2.frame; -+ - /* print MTU info */ - do_print_data_channel_mtu_parms(c); - -Index: openvpn/src/openvpn/openvpn.h -=================================================================== ---- openvpn.orig/src/openvpn/openvpn.h 2017-05-22 14:59:09.634938195 +0200 -+++ openvpn/src/openvpn/openvpn.h 2017-05-22 14:59:09.634938195 +0200 -@@ -263,7 +263,8 @@ - struct link_socket_actual from; /* address of incoming datagram */ - - /* MTU frame parameters */ -- struct frame frame; -+ struct frame frame; /* Active frame parameters */ -+ struct frame frame_initial; /* Restored on new session */ - - #ifdef ENABLE_FRAGMENT - /* Object to handle advanced MTU negotiation and datagram fragmentation */ -Index: openvpn/src/openvpn/ssl.c -=================================================================== ---- openvpn.orig/src/openvpn/ssl.c 2017-05-22 14:59:09.634938195 +0200 -+++ openvpn/src/openvpn/ssl.c 2017-05-22 14:59:09.634938195 +0200 -@@ -830,14 +830,7 @@ - return BSTR(&out); - } - --/* -- * Given a key_method, return true if op -- * represents the required form of hard_reset. -- * -- * If key_method = 0, return true if any -- * form of hard reset is used. -- */ --static bool -+bool - is_hard_reset(int op, int key_method) - { - if (!key_method || key_method == 1) -Index: openvpn/src/openvpn/ssl.h -=================================================================== ---- openvpn.orig/src/openvpn/ssl.h 2017-05-22 14:59:09.634938195 +0200 -+++ openvpn/src/openvpn/ssl.h 2017-05-22 14:59:09.634938195 +0200 -@@ -591,6 +591,14 @@ - /*#define EXTRACT_X509_FIELD_TEST*/ - void extract_x509_field_test(void); - -+/** -+ * Given a key_method, return true if opcode represents the required form of -+ * hard_reset. -+ * -+ * If key_method == 0, return true if any form of hard reset is used. -+ */ -+bool is_hard_reset(int op, int key_method); -+ - #endif /* ENABLE_CRYPTO */ - - #endif /* ifndef OPENVPN_SSL_H */ diff --git a/debian/patches/wipe_tokens_on_de-auth.patch b/debian/patches/wipe_tokens_on_de-auth.patch deleted file mode 100644 index 8db560f..0000000 --- a/debian/patches/wipe_tokens_on_de-auth.patch +++ /dev/null @@ -1,118 +0,0 @@ -From daab0a9fa8ff4f40e8a34707db0ac156d49fbfcb Mon Sep 17 00:00:00 2001 -From: David Sommerseth -Date: Tue, 28 Mar 2017 22:53:46 +0200 -Subject: [PATCH] auth-token: Ensure tokens are always wiped on de-auth - -If tls_deauthenticate() was called, it could in some scenarios leave the -authentication token for a session in memory. This change just ensures -auth-tokens are always wiped as soon as a TLS session is considered -broken. - -Signed-off-by: David Sommerseth - -Acked-by: Steffan Karger -Message-Id: <20170328205346.18844-1-davids@openvpn.net> -URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14344.html -Signed-off-by: David Sommerseth ---- - src/openvpn/ssl_verify.c | 47 +++++++++++++++++++++++++++-------------------- - 1 file changed, 27 insertions(+), 20 deletions(-) - -Index: openvpn-2.4.0/src/openvpn/ssl_verify.c -=================================================================== ---- openvpn-2.4.0.orig/src/openvpn/ssl_verify.c -+++ openvpn-2.4.0/src/openvpn/ssl_verify.c -@@ -80,6 +80,28 @@ setenv_untrusted(struct tls_session *ses - setenv_link_socket_actual(session->opt->es, "untrusted", &session->untrusted_addr, SA_IP_PORT); - } - -+ -+/** -+ * Wipes the authentication token out of the memory, frees and cleans up related buffers and flags -+ * -+ * @param multi Pointer to a multi object holding the auth_token variables -+ */ -+static void -+wipe_auth_token(struct tls_multi *multi) -+{ -+ if(multi) -+ { -+ if (multi->auth_token) -+ { -+ secure_memzero(multi->auth_token, AUTH_TOKEN_SIZE); -+ free(multi->auth_token); -+ } -+ multi->auth_token = NULL; -+ multi->auth_token_sent = false; -+ } -+} -+ -+ - /* - * Remove authenticated state from all sessions in the given tunnel - */ -@@ -88,10 +110,14 @@ tls_deauthenticate(struct tls_multi *mul - { - if (multi) - { -- int i, j; -- for (i = 0; i < TM_SIZE; ++i) -- for (j = 0; j < KS_SIZE; ++j) -+ wipe_auth_token(multi); -+ for (int i = 0; i < TM_SIZE; ++i) -+ { -+ for (int j = 0; j < KS_SIZE; ++j) -+ { - multi->session[i].key[j].authenticated = false; -+ } -+ } - } - } - -@@ -1213,21 +1239,6 @@ verify_user_pass_management(struct tls_s - } - #endif /* ifdef MANAGEMENT_DEF_AUTH */ - --/** -- * Wipes the authentication token out of the memory, frees and cleans up related buffers and flags -- * -- * @param multi Pointer to a multi object holding the auth_token variables -- */ --static void --wipe_auth_token(struct tls_multi *multi) --{ -- secure_memzero(multi->auth_token, AUTH_TOKEN_SIZE); -- free(multi->auth_token); -- multi->auth_token = NULL; -- multi->auth_token_sent = false; --} -- -- - /* - * Main username/password verification entry point - */ -@@ -1279,7 +1290,7 @@ verify_user_pass(struct user_pass *up, s - /* Ensure that the username has not changed */ - if (!tls_lock_username(multi, up->username)) - { -- wipe_auth_token(multi); -+ /* auth-token cleared in tls_lock_username() on failure */ - ks->authenticated = false; - goto done; - } -@@ -1300,7 +1311,6 @@ verify_user_pass(struct user_pass *up, s - if (memcmp_constant_time(multi->auth_token, up->password, - strlen(multi->auth_token)) != 0) - { -- wipe_auth_token(multi); - ks->authenticated = false; - tls_deauthenticate(multi); - -@@ -1472,6 +1482,7 @@ verify_final_auth_checks(struct tls_mult - if (!cn || !strcmp(cn, CCD_DEFAULT) || !test_file(path)) - { - ks->authenticated = false; -+ wipe_auth_token(multi); - msg(D_TLS_ERRORS, "TLS Auth Error: --client-config-dir authentication failed for common name '%s' file='%s'", - session->common_name, - path ? path : "UNDEF"); -- cgit v1.2.3