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 <rosenp@gmail.com>lilik-openwrt-22.03
@ -1,50 +0,0 @@ | |||||
From 03ecd34e0137b3f0bf0d2fc3ab7f7d8b3682785e Mon Sep 17 00:00:00 2001 | |||||
From: Yousong Zhou <yszhou4tech@gmail.com> | |||||
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 <yszhou4tech@gmail.com> | |||||
--- | |||||
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 <libp11.h> | |||||
#include <p11-kit/pkcs11.h> | |||||
+#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 | |||||
@ -0,0 +1,75 @@ | |||||
From 460c060dda115bc8066bb4b955453c673459b6cc Mon Sep 17 00:00:00 2001 | |||||
From: Rosen Penev <rosenp@gmail.com> | |||||
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 <rosenp@gmail.com> | |||||
--- | |||||
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 <openssl/bio.h> | |||||
+#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 | |||||
@ -0,0 +1,139 @@ | |||||
From afb6442533dc7475ed61642c3f5b295db1e6f561 Mon Sep 17 00:00:00 2001 | |||||
From: Rosen Penev <rosenp@gmail.com> | |||||
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 <rosenp@gmail.com> | |||||
Signed-off-by: David Woodhouse <dwmw2@infradead.org> | |||||
--- | |||||
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 <openssl/ssl.h>], | |||||
- [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 <openssl/ssl.h>], | |||||
+ [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 | |||||
@ -0,0 +1,38 @@ | |||||
From 97cafd182f5a5c2d13f57d7faeac8432aea9bbf8 Mon Sep 17 00:00:00 2001 | |||||
From: David Woodhouse <dwmw2@infradead.org> | |||||
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 <dwmw2@infradead.org> | |||||
--- | |||||
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 | |||||