From 6dbbc17b1f3d29ce4db772e792cbae6a9c8e87be Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Mon, 24 Jun 2019 10:42:33 -0700 Subject: [PATCH] openconnect: Fix DTLS with OpenSSL Backported upstream patches that fix this. Removed local patch that fixes libp11 with version 0.4.7, which is not used anymore. Upstream has a different solution. License fixes and Makefile cleanups. Signed-off-by: Rosen Penev --- net/openconnect/Makefile | 10 +- ...ompilation-with-libp11-version-0.4.7.patch | 50 ------- ...-without-deprecated-OpenSSL-1.1-APIs.patch | 75 ++++++++++ ...TLS-bug-when-lacking-deprecated-APIs.patch | 139 ++++++++++++++++++ ...then-mac-where-possible-with-DTLS-an.patch | 38 +++++ 5 files changed, 258 insertions(+), 54 deletions(-) delete mode 100644 net/openconnect/patches/0001-Fix-compilation-with-libp11-version-0.4.7.patch create mode 100644 net/openconnect/patches/010-Fix-compilation-without-deprecated-OpenSSL-1.1-APIs.patch create mode 100644 net/openconnect/patches/020-Fix-DTLS-bug-when-lacking-deprecated-APIs.patch create mode 100644 net/openconnect/patches/030-Disable-encrypt-then-mac-where-possible-with-DTLS-an.patch diff --git a/net/openconnect/Makefile b/net/openconnect/Makefile index d75d2af01..4ed174001 100644 --- a/net/openconnect/Makefile +++ b/net/openconnect/Makefile @@ -9,18 +9,20 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openconnect PKG_VERSION:=8.03 -PKG_RELEASE:=1 -PKG_USE_MIPS16:=0 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=ftp://ftp.infradead.org/pub/openconnect/ PKG_HASH:=908cff9b1ce266b6bb7f969a7f62723543ab94719ba3c95a150fe3894cbc9ef2 -PKG_LICENSE:=LGPLv2.1+ + +PKG_LICENSE:=LGPL-2.1-or-later +PKG_LICENSE_FILES:=COPYING.LGPL PKG_CONFIG_DEPENDS:= \ CONFIG_OPENCONNECT_GNUTLS \ CONFIG_OPENCONNECT_OPENSSL \ +PKG_USE_MIPS16:=0 include $(INCLUDE_DIR)/package.mk @@ -34,7 +36,7 @@ define Package/openconnect DEPENDS:=+libxml2 +kmod-tun +resolveip +vpnc-scripts +OPENCONNECT_OPENSSL:libopenssl +OPENCONNECT_OPENSSL:p11-kit +OPENCONNECT_OPENSSL:libp11 +OPENCONNECT_GNUTLS:libgnutls +OPENCONNECT_GNUTLS:libtasn1 +OPENCONNECT_STOKEN:libstoken TITLE:=OpenConnect VPN client (Cisco AnyConnect and Juniper/Pulse compatible) MAINTAINER:=Nikos Mavrogiannopoulos - URL:=http://www.infradead.org/openconnect/ + URL:=https://www.infradead.org/openconnect/ SUBMENU:=VPN endef diff --git a/net/openconnect/patches/0001-Fix-compilation-with-libp11-version-0.4.7.patch b/net/openconnect/patches/0001-Fix-compilation-with-libp11-version-0.4.7.patch deleted file mode 100644 index c6e139a4c..000000000 --- a/net/openconnect/patches/0001-Fix-compilation-with-libp11-version-0.4.7.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 03ecd34e0137b3f0bf0d2fc3ab7f7d8b3682785e Mon Sep 17 00:00:00 2001 -From: Yousong Zhou -Date: Thu, 14 Dec 2017 18:03:35 +0800 -Subject: [PATCH] Fix compilation with libp11 version >= 0.4.7 - -libp11 0.4.7 renamed then dropped macro definition in commits - - 4f0fce4: Error reporting fixes - e4c641b: PKCS11 errors separated into P11 and CKR - -This change assumes that libp11 will restore compatibility by bringing -back old forms of macro definition - -Signed-off-by: Yousong Zhou ---- - openssl-pkcs11.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/openssl-pkcs11.c b/openssl-pkcs11.c -index 61da123..ba7e491 100644 ---- a/openssl-pkcs11.c -+++ b/openssl-pkcs11.c -@@ -30,6 +30,24 @@ - #include - #include - -+#ifndef ERR_LIB_PKCS11 -+# if defined(ERR_LIB_CKR) -+# define ERR_LIB_PKCS11 ERR_LIB_CKR -+# elif defined(ERR_LIB_USER) -+# define ERR_LIB_PKCS11 ERR_LIB_USER -+# else -+# error undefined macro ERR_LIB_PKCS11 -+# endif -+#endif -+ -+#ifndef PKCS11_F_PKCS11_LOGIN -+# if defined(CKR_F_PKCS11_LOGIN) -+# define PKCS11_F_PKCS11_LOGIN CKR_F_PKCS11_LOGIN -+# else -+# error undefined macro PKCS11_F_PKCS11_LOGIN -+# endif -+#endif -+ - static PKCS11_CTX *pkcs11_ctx(struct openconnect_info *vpninfo) - { - PKCS11_CTX *ctx; --- -1.8.3.1 - diff --git a/net/openconnect/patches/010-Fix-compilation-without-deprecated-OpenSSL-1.1-APIs.patch b/net/openconnect/patches/010-Fix-compilation-without-deprecated-OpenSSL-1.1-APIs.patch new file mode 100644 index 000000000..7321bb684 --- /dev/null +++ b/net/openconnect/patches/010-Fix-compilation-without-deprecated-OpenSSL-1.1-APIs.patch @@ -0,0 +1,75 @@ +From 460c060dda115bc8066bb4b955453c673459b6cc Mon Sep 17 00:00:00 2001 +From: Rosen Penev +Date: Sun, 9 Jun 2019 23:36:53 -0700 +Subject: [PATCH] Fix compilation without deprecated OpenSSL 1.1 APIs + +Initialization and deinitialization is deprecated. + +Signed-off-by: Rosen Penev +--- + library.c | 4 ++++ + openssl.c | 2 ++ + tests/bad_dtls_test.c | 4 ++++ + 3 files changed, 10 insertions(+) + +diff --git a/library.c b/library.c +index 0e3d05e6..e45e93a2 100644 +--- a/library.c ++++ b/library.c +@@ -38,6 +38,10 @@ + #include "gnutls.h" + #endif + ++#if defined(OPENCONNECT_OPENSSL) ++#include ++#endif ++ + struct openconnect_info *openconnect_vpninfo_new(const char *useragent, + openconnect_validate_peer_cert_vfn validate_peer_cert, + openconnect_write_new_config_vfn write_new_config, +diff --git a/openssl.c b/openssl.c +index 2b1f07bd..e505f49a 100644 +--- a/openssl.c ++++ b/openssl.c +@@ -1879,10 +1879,12 @@ int openconnect_init_ssl(void) + if (ret) + return ret; + #endif ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + SSL_library_init(); + ERR_clear_error(); + SSL_load_error_strings(); + OpenSSL_add_all_algorithms(); ++#endif + return 0; + } + +diff --git a/tests/bad_dtls_test.c b/tests/bad_dtls_test.c +index ac8d3f1e..c123c8f8 100644 +--- a/tests/bad_dtls_test.c ++++ b/tests/bad_dtls_test.c +@@ -752,8 +752,10 @@ int main(int argc, char *argv[]) + int ret; + int i; + ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + SSL_library_init(); + SSL_load_error_strings(); ++#endif + + RAND_bytes(session_id, sizeof(session_id)); + RAND_bytes(master_secret, sizeof(master_secret)); +@@ -910,8 +912,10 @@ int main(int argc, char *argv[]) + printf("Cisco BadDTLS test: FAILED\n"); + } + ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + ERR_free_strings(); + EVP_cleanup(); ++#endif + + return testresult?0:1; + } +-- +2.17.1 + diff --git a/net/openconnect/patches/020-Fix-DTLS-bug-when-lacking-deprecated-APIs.patch b/net/openconnect/patches/020-Fix-DTLS-bug-when-lacking-deprecated-APIs.patch new file mode 100644 index 000000000..e29f801cf --- /dev/null +++ b/net/openconnect/patches/020-Fix-DTLS-bug-when-lacking-deprecated-APIs.patch @@ -0,0 +1,139 @@ +From afb6442533dc7475ed61642c3f5b295db1e6f561 Mon Sep 17 00:00:00 2001 +From: Rosen Penev +Date: Sun, 9 Jun 2019 23:40:21 -0700 +Subject: [PATCH] Fix DTLS bug when lacking deprecated APIs + +HAVE_DTLS12 is for DTLSv1_method. This causes dtls_method to be NULL and +crash. + +[dwmw2: Rework it quite a bit more] + +Signed-off-by: Rosen Penev +Signed-off-by: David Woodhouse +--- + configure.ac | 17 ++++++++++++++--- + openssl-dtls.c | 49 ++++++++++++++++++++++++++----------------------- + 2 files changed, 40 insertions(+), 26 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 02096c51..f7557933 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -455,11 +455,22 @@ case "$ssl_library" in + AC_DEFINE(HAVE_DTLS1_STOP_TIMER, [1], [OpenSSL has dtls1_stop_timer() function])], + [AC_MSG_RESULT(no)]) + +- AC_MSG_CHECKING([for DTLSv1_2_client_method() in OpenSSL]) ++ # DTLS_client_method() and DTLSv1_2_client_method() were both added between ++ # OpenSSL v1.0.1 and v1.0.2. DTLSV1.2_client_method() was later deprecated ++ # in v1.1.0 so we use DTLS_client_method() as our check for DTLSv1.2 support ++ # and that's what we actually use in openssl-dtls.c too. ++ AC_MSG_CHECKING([for DTLS_client_method() in OpenSSL]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], +- [DTLSv1_2_client_method();])], ++ [DTLS_client_method();])], + [AC_MSG_RESULT(yes) +- AC_DEFINE(HAVE_DTLS12, [1], [OpenSSL has DTLSv1_2_client_method() function])], ++ AC_DEFINE(HAVE_DTLS12, [1], [OpenSSL has DTLS_client_method() function])], ++ [AC_MSG_RESULT(no)]) ++ ++ AC_MSG_CHECKING([for SSL_CTX_set_min_proto_version() in OpenSSL]) ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], ++ [SSL_CTX_set_min_proto_version((void *)0, 0);])], ++ [AC_MSG_RESULT(yes) ++ AC_DEFINE(HAVE_SSL_CTX_PROTOVER, [1], [OpenSSL has SSL_CTX_set_min_proto_version() function])], + [AC_MSG_RESULT(no)]) + + AC_CHECK_FUNC(HMAC_CTX_copy, +diff --git a/openssl-dtls.c b/openssl-dtls.c +index 5086440f..9e3c5d46 100644 +--- a/openssl-dtls.c ++++ b/openssl-dtls.c +@@ -332,6 +332,7 @@ int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd) + const char *cipher = vpninfo->dtls_cipher; + + #ifdef HAVE_DTLS12 ++ /* These things should never happen unless they're supported */ + if (vpninfo->cisco_dtls12) { + dtlsver = DTLS1_2_VERSION; + } else if (!strcmp(cipher, "OC-DTLS1_2-AES128-GCM")) { +@@ -349,16 +350,16 @@ int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd) + + if (!vpninfo->dtls_ctx) { + #ifdef HAVE_DTLS12 ++ /* If we can use SSL_CTX_set_min_proto_version, do so. */ + dtls_method = DTLS_client_method(); + #endif +-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++#ifndef HAVE_SSL_CTX_PROTOVER ++ /* If !HAVE_DTLS12, dtlsver *MUST* be DTLS1_BAD_VER because it's set ++ * at the top of the function and nothing can change it. */ + if (dtlsver == DTLS1_BAD_VER) + dtls_method = DTLSv1_client_method(); +-#ifdef HAVE_DTLS12 +- else if (dtlsver == DTLS1_2_VERSION) +- dtls_method = DTLSv1_2_client_method(); +-#endif + #endif ++ + vpninfo->dtls_ctx = SSL_CTX_new(dtls_method); + if (!vpninfo->dtls_ctx) { + vpn_progress(vpninfo, PRG_ERR, +@@ -367,24 +368,26 @@ int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd) + vpninfo->dtls_attempt_period = 0; + return -EINVAL; + } +- if (dtlsver) { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) +- if (dtlsver == DTLS1_BAD_VER) +- SSL_CTX_set_options(vpninfo->dtls_ctx, SSL_OP_CISCO_ANYCONNECT); +-#else +- if (!SSL_CTX_set_min_proto_version(vpninfo->dtls_ctx, dtlsver) || +- !SSL_CTX_set_max_proto_version(vpninfo->dtls_ctx, dtlsver)) { +- vpn_progress(vpninfo, PRG_ERR, +- _("Set DTLS CTX version failed\n")); +- openconnect_report_ssl_errors(vpninfo); +- SSL_CTX_free(vpninfo->dtls_ctx); +- vpninfo->dtls_ctx = NULL; +- vpninfo->dtls_attempt_period = 0; +- return -EINVAL; +- } ++#ifdef HAVE_SSL_CTX_PROTOVER ++ if (dtlsver && ++ (!SSL_CTX_set_min_proto_version(vpninfo->dtls_ctx, dtlsver) || ++ !SSL_CTX_set_max_proto_version(vpninfo->dtls_ctx, dtlsver))) { ++ vpn_progress(vpninfo, PRG_ERR, ++ _("Set DTLS CTX version failed\n")); ++ openconnect_report_ssl_errors(vpninfo); ++ SSL_CTX_free(vpninfo->dtls_ctx); ++ vpninfo->dtls_ctx = NULL; ++ vpninfo->dtls_attempt_period = 0; ++ return -EINVAL; ++ } ++#else /* !HAVE_SSL_CTX_PROTOVER */ ++ /* If we used the legacy version-specific methods, we need the special ++ * way to make TLSv1_client_method() do DTLS1_BAD_VER. */ ++ if (dtlsver == DTLS1_BAD_VER) ++ SSL_CTX_set_options(vpninfo->dtls_ctx, SSL_OP_CISCO_ANYCONNECT); + #endif + #if defined (HAVE_DTLS12) && !defined(OPENSSL_NO_PSK) +- } else { ++ if (!dtlsver) { + SSL_CTX_set_psk_client_callback(vpninfo->dtls_ctx, psk_callback); + /* For PSK we override the DTLS master secret with one derived + * from the HTTPS session. */ +@@ -401,9 +404,9 @@ int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd) + } + /* For SSL_CTX_set_cipher_list() */ + cipher = "PSK"; +- +-#endif + } ++#endif /* OPENSSL_NO_PSK */ ++ + /* If we don't readahead, then we do short reads and throw + away the tail of data packets. */ + SSL_CTX_set_read_ahead(vpninfo->dtls_ctx, 1); +-- +2.17.1 + diff --git a/net/openconnect/patches/030-Disable-encrypt-then-mac-where-possible-with-DTLS-an.patch b/net/openconnect/patches/030-Disable-encrypt-then-mac-where-possible-with-DTLS-an.patch new file mode 100644 index 000000000..bf5d10b24 --- /dev/null +++ b/net/openconnect/patches/030-Disable-encrypt-then-mac-where-possible-with-DTLS-an.patch @@ -0,0 +1,38 @@ +From 97cafd182f5a5c2d13f57d7faeac8432aea9bbf8 Mon Sep 17 00:00:00 2001 +From: David Woodhouse +Date: Mon, 10 Jun 2019 12:34:43 +0100 +Subject: [PATCH] Disable encrypt-then-mac where possible with DTLS and OpenSSL + +There is pain here. Just don't bother. + +Signed-off-by: David Woodhouse +--- + openssl-dtls.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/openssl-dtls.c b/openssl-dtls.c +index 9e3c5d46..646bf71c 100644 +--- a/openssl-dtls.c ++++ b/openssl-dtls.c +@@ -406,7 +406,17 @@ int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd) + cipher = "PSK"; + } + #endif /* OPENSSL_NO_PSK */ +- ++#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC ++ /* I'm fairly sure I wasn't lying when I said I had tested ++ * https://github.com/openssl/openssl/commit/e23d5071ec4c7aa6bb2b ++ * against GnuTLS both with and without EtM in 2016. ++ * Nevertheless, in 2019 it seems to be failing to negotiate ++ * at least for DTLS1_BAD_VER against ocserv with GnuTLS 3.6.7. ++ * Just turn it off. Real Cisco servers don't do it for ++ * DTLS1_BAD_VER, and we should be using GCM ciphersuites in ++ * newer versions of DTLS anyway so it's irrelevant. */ ++ SSL_CTX_set_options(vpninfo->dtls_ctx, SSL_OP_NO_ENCRYPT_THEN_MAC); ++#endif + /* If we don't readahead, then we do short reads and throw + away the tail of data packets. */ + SSL_CTX_set_read_ahead(vpninfo->dtls_ctx, 1); +-- +2.17.1 +