[openconnect] Enforce the system wide crypto policies

Nikos Mavrogiannopoulos nmav at fedoraproject.org
Wed Mar 11 09:49:07 UTC 2015


commit 899aba1c02a5664550e669e6369d897829084d7a
Author: Nikos Mavrogiannopoulos <nmav at redhat.com>
Date:   Wed Mar 11 10:48:51 2015 +0100

    Enforce the system wide crypto policies
    
    Resolves: rhbz#1179331

 ....05-ensure-dtls-ciphers-match-the-allowed.patch | 200 +++++++++++++++++++++
 ...connect-7.05-override-default-prio-string.patch |  64 +++++++
 openconnect.spec                                   |  13 +-
 3 files changed, 276 insertions(+), 1 deletion(-)
---
diff --git a/openconnect-7.05-ensure-dtls-ciphers-match-the-allowed.patch b/openconnect-7.05-ensure-dtls-ciphers-match-the-allowed.patch
new file mode 100644
index 0000000..b7d6088
--- /dev/null
+++ b/openconnect-7.05-ensure-dtls-ciphers-match-the-allowed.patch
@@ -0,0 +1,200 @@
+From 4892c7a53bb0adec98c4540a0b127b209625f82a Mon Sep 17 00:00:00 2001
+From: Nikos Mavrogiannopoulos <nmav at redhat.com>
+Date: Wed, 4 Mar 2015 10:29:06 +0100
+Subject: [PATCH 2/2] when using gnutls enable only the DTLS ciphersuites that
+ were available during TLS
+
+Signed-off-by: Nikos Mavrogiannopoulos <nmav at redhat.com>
+---
+ cstp.c                 |  3 ++
+ dtls.c                 | 79 ++++++++++++++++++++++++++++++++++++++++++++++----
+ gnutls.c               |  7 ++---
+ openconnect-internal.h |  2 ++
+ 4 files changed, 81 insertions(+), 10 deletions(-)
+
+diff --git a/cstp.c b/cstp.c
+index d0d7eff..a06ca34 100644
+--- a/cstp.c
++++ b/cstp.c
+@@ -202,6 +202,9 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
+ 	vpninfo->ip_info.domain = vpninfo->ip_info.proxy_pac = NULL;
+ 	vpninfo->banner = NULL;
+ 
++	if (!vpninfo->dtls_ciphers)
++		vpninfo->dtls_ciphers = dtls_ciphers_from_conn(vpninfo);
++
+ 	for (i = 0; i < 3; i++)
+ 		vpninfo->ip_info.dns[i] = vpninfo->ip_info.nbns[i] = NULL;
+ 	free_split_routes(vpninfo);
+diff --git a/dtls.c b/dtls.c
+index abffbf1..6ac537d 100644
+--- a/dtls.c
++++ b/dtls.c
+@@ -222,6 +222,11 @@ static SSL_SESSION *generate_dtls_session(struct openconnect_info *vpninfo,
+ }
+ #endif
+ 
++char *dtls_ciphers_from_conn(struct openconnect_info *vpninfo)
++{
++	return NULL;
++}
++
+ static int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd)
+ {
+ 	STACK_OF(SSL_CIPHER) *ciphers;
+@@ -438,27 +443,89 @@ void dtls_shutdown(struct openconnect_info *vpninfo)
+ #include <gnutls/dtls.h>
+ #include "gnutls.h"
+ 
++#define SSTR(x) x,sizeof(x)
+ struct {
+ 	const char *name;
++	unsigned name_len;
+ 	gnutls_protocol_t version;
+ 	gnutls_cipher_algorithm_t cipher;
+ 	gnutls_mac_algorithm_t mac;
+ 	const char *prio;
++	unsigned disabled;
+ } gnutls_dtls_ciphers[] = {
+-	{ "AES128-SHA", GNUTLS_DTLS0_9, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1,
++	{ SSTR("AES128-SHA"), GNUTLS_DTLS0_9, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1,
+ 	  "NONE:+VERS-DTLS0.9:+COMP-NULL:+AES-128-CBC:+SHA1:+RSA:%COMPAT" },
+-	{ "AES256-SHA", GNUTLS_DTLS0_9, GNUTLS_CIPHER_AES_256_CBC, GNUTLS_MAC_SHA1,
++	{ SSTR("AES256-SHA"), GNUTLS_DTLS0_9, GNUTLS_CIPHER_AES_256_CBC, GNUTLS_MAC_SHA1,
+ 	  "NONE:+VERS-DTLS0.9:+COMP-NULL:+AES-256-CBC:+SHA1:+RSA:%COMPAT" },
+-	{ "DES-CBC3-SHA", GNUTLS_DTLS0_9, GNUTLS_CIPHER_3DES_CBC, GNUTLS_MAC_SHA1,
++	{ SSTR("DES-CBC3-SHA"), GNUTLS_DTLS0_9, GNUTLS_CIPHER_3DES_CBC, GNUTLS_MAC_SHA1,
+ 	  "NONE:+VERS-DTLS0.9:+COMP-NULL:+3DES-CBC:+SHA1:+RSA:%COMPAT" },
+ #if GNUTLS_VERSION_NUMBER >= 0x030207 /* if DTLS 1.2 is supported (and a bug in gnutls is solved) */
+-	{ "OC-DTLS1_2-AES128-GCM", GNUTLS_DTLS1_2, GNUTLS_CIPHER_AES_128_GCM, GNUTLS_MAC_AEAD,
++	{ SSTR("OC-DTLS1_2-AES128-GCM"), GNUTLS_DTLS1_2, GNUTLS_CIPHER_AES_128_GCM, GNUTLS_MAC_AEAD,
+ 	  "NONE:+VERS-DTLS1.2:+COMP-NULL:+AES-128-GCM:+AEAD:+RSA:%COMPAT:+SIGN-ALL" },
+-	{ "OC-DTLS1_2-AES256-GCM", GNUTLS_DTLS1_2, GNUTLS_CIPHER_AES_256_GCM, GNUTLS_MAC_AEAD,
++	{ SSTR("OC-DTLS1_2-AES256-GCM"), GNUTLS_DTLS1_2, GNUTLS_CIPHER_AES_256_GCM, GNUTLS_MAC_AEAD,
+ 	  "NONE:+VERS-DTLS1.2:+COMP-NULL:+AES-256-GCM:+AEAD:+RSA:%COMPAT:+SIGN-ALL" },
+ #endif
+ };
+ 
++char *dtls_ciphers_from_conn(struct openconnect_info *vpninfo)
++{
++	/* only enable the ciphers that would have been negotiated in the TLS channel */
++	unsigned i, j;
++	int ret;
++	unsigned idx;
++	gnutls_cipher_algorithm_t cipher;
++	gnutls_mac_algorithm_t mac;
++	struct oc_text_buf *buf;
++	gnutls_priority_t cache;
++	char *p;
++
++	/* everything is disabled by default */
++	for (i = 0; i < sizeof(gnutls_dtls_ciphers)/sizeof(gnutls_dtls_ciphers[0]); i++) {
++		gnutls_dtls_ciphers[i].disabled = 1;
++	}
++
++	ret = gnutls_priority_init(&cache, vpninfo->gnutls_default_prio, NULL);
++	if (ret < 0)
++		return NULL;
++
++	for (j=0;;j++) {
++		ret = gnutls_priority_get_cipher_suite_index(cache, j, &idx);
++		if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE)
++			continue;
++		else if (ret < 0)
++			break;
++
++		if (gnutls_cipher_suite_info(idx, NULL, NULL, &cipher, &mac, NULL) != NULL) {
++			for (i = 0; i < sizeof(gnutls_dtls_ciphers)/sizeof(gnutls_dtls_ciphers[0]); i++) {
++				if (gnutls_dtls_ciphers[i].mac == mac && gnutls_dtls_ciphers[i].cipher == cipher) {
++					gnutls_dtls_ciphers[i].disabled = 0;
++					break;
++				}
++			}
++		}
++	}
++
++	buf = buf_alloc();
++
++	for (i = 0; i < sizeof(gnutls_dtls_ciphers)/sizeof(gnutls_dtls_ciphers[0]); i++) {
++		if (!gnutls_dtls_ciphers[i].disabled) {
++			if (buf->buf_len == 0) {
++				buf_append(buf, "%s", gnutls_dtls_ciphers[i].name);
++			} else {
++				buf_append(buf, ":%s", gnutls_dtls_ciphers[i].name);
++			}
++		}
++	}
++
++	/* steal buffer */
++	p = buf->data;
++	buf->data = NULL;
++
++	buf_free(buf);
++ 	gnutls_priority_deinit(cache);
++	return p;
++}
++
+ #define DTLS_SEND gnutls_record_send
+ #define DTLS_RECV gnutls_record_recv
+ #define DTLS_FREE gnutls_deinit
+@@ -470,7 +537,7 @@ static int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd)
+ 	int cipher;
+ 
+ 	for (cipher = 0; cipher < sizeof(gnutls_dtls_ciphers)/sizeof(gnutls_dtls_ciphers[0]); cipher++) {
+-		if (!strcmp(vpninfo->dtls_cipher, gnutls_dtls_ciphers[cipher].name))
++		if (!strcmp(vpninfo->dtls_cipher, gnutls_dtls_ciphers[cipher].name) && !gnutls_dtls_ciphers[cipher].disabled)
+ 			goto found_cipher;
+ 	}
+ 	vpn_progress(vpninfo, PRG_ERR, _("Unknown DTLS parameters for requested CipherSuite '%s'\n"),
+diff --git a/gnutls.c b/gnutls.c
+index 34119da..e121842 100644
+--- a/gnutls.c
++++ b/gnutls.c
+@@ -2070,7 +2070,6 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
+ {
+ 	int ssl_sock = -1;
+ 	int err;
+-	const char * prio;
+ 
+ 	if (vpninfo->https_sess)
+ 		return 0;
+@@ -2196,13 +2195,13 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
+ 				       strlen(vpninfo->hostname));
+ 
+ 	if (vpninfo->pfs) {
+-		prio = DEFAULT_PRIO":-RSA";
++		vpninfo->gnutls_default_prio = DEFAULT_PRIO":-RSA";
+ 	} else {
+-		prio = DEFAULT_PRIO;
++		vpninfo->gnutls_default_prio = DEFAULT_PRIO;
+ 	}
+ 
+ 	err = gnutls_priority_set_direct(vpninfo->https_sess,
+-					prio, NULL);
++					vpninfo->gnutls_default_prio, NULL);
+ 	if (err) {
+ 		vpn_progress(vpninfo, PRG_ERR,
+ 			     _("Failed to set TLS priority string: %s\n"),
+diff --git a/openconnect-internal.h b/openconnect-internal.h
+index 04cb226..7b7161c 100644
+--- a/openconnect-internal.h
++++ b/openconnect-internal.h
+@@ -469,6 +469,7 @@ struct openconnect_info {
+ 	gnutls_session_t https_sess;
+ 	gnutls_certificate_credentials_t https_cred;
+ 	char local_cert_md5[MD5_SIZE * 2 + 1]; /* For CSD */
++	const char *gnutls_default_prio;
+ #ifdef HAVE_TROUSERS
+ 	TSS_HCONTEXT tpm_context;
+ 	TSS_HKEY srk;
+@@ -765,6 +766,7 @@ int dtls_setup(struct openconnect_info *vpninfo, int dtls_attempt_period);
+ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout);
+ void dtls_close(struct openconnect_info *vpninfo);
+ void dtls_shutdown(struct openconnect_info *vpninfo);
++char *dtls_ciphers_from_conn(struct openconnect_info *vpninfo);
+ 
+ /* cstp.c */
+ void cstp_common_headers(struct openconnect_info *vpninfo, struct oc_text_buf *buf);
+-- 
+2.1.0
+
diff --git a/openconnect-7.05-override-default-prio-string.patch b/openconnect-7.05-override-default-prio-string.patch
new file mode 100644
index 0000000..2e5c906
--- /dev/null
+++ b/openconnect-7.05-override-default-prio-string.patch
@@ -0,0 +1,64 @@
+From db955eceff87ecc7994348c952029ae012fc5b6a Mon Sep 17 00:00:00 2001
+From: Nikos Mavrogiannopoulos <nmav at redhat.com>
+Date: Tue, 3 Mar 2015 16:57:51 +0100
+Subject: [PATCH 1/2] Allow overriding the default GnuTLS priority string
+
+Signed-off-by: Nikos Mavrogiannopoulos <nmav at redhat.com>
+---
+ configure.ac |  9 +++++++++
+ gnutls.c     | 18 ++++++++++--------
+ 2 files changed, 19 insertions(+), 8 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index e5b5e80..ddb5c48 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -417,6 +417,15 @@ if test "$with_gnutls" = "yes"; then
+     LIBS="$oldlibs"
+     CFLAGS="$oldcflags"
+ fi
++
++AC_ARG_WITH([default-gnutls-priority],
++	AS_HELP_STRING([--with-default-gnutls-priority=STRING],
++	[Provide a default string as GnuTLS priority string]),
++	default_gnutls_priority=$withval)
++if test -n "$default_gnutls_priority"; then
++   AC_DEFINE_UNQUOTED([DEFAULT_PRIO], ["$default_gnutls_priority"], [The GnuTLS priority string])
++fi
++
+ if test "$with_openssl" = "yes" || test "$with_openssl" = "" || test "$ssl_library" = "both"; then
+     PKG_CHECK_MODULES(OPENSSL, openssl, [],
+ 	[oldLIBS="$LIBS"
+diff --git a/gnutls.c b/gnutls.c
+index 3f79a22..34119da 100644
+--- a/gnutls.c
++++ b/gnutls.c
+@@ -2052,15 +2052,17 @@ static int verify_peer(gnutls_session_t session)
+  * >= 3.2.9 as there the %COMPAT keyword ensures that the client hello
+  * will be outside that range.
+  */
+-#if GNUTLS_VERSION_NUMBER >= 0x030209
+-# define DEFAULT_PRIO "NORMAL:-VERS-SSL3.0:%COMPAT"
+-#else
+-# define _DEFAULT_PRIO "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:" \
++#ifndef DEFAULT_PRIO
++# if GNUTLS_VERSION_NUMBER >= 0x030209
++#  define DEFAULT_PRIO "NORMAL:-VERS-SSL3.0:%COMPAT"
++# else
++#  define _DEFAULT_PRIO "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:" \
+ 	"%COMPAT:%DISABLE_SAFE_RENEGOTIATION:%LATEST_RECORD_VERSION"
+-# if GNUTLS_VERSION_MAJOR >= 3
+-#  define DEFAULT_PRIO _DEFAULT_PRIO":-CURVE-ALL:-ECDHE-RSA:-ECDHE-ECDSA"
+-#else
+-#  define DEFAULT_PRIO _DEFAULT_PRIO
++#  if GNUTLS_VERSION_MAJOR >= 3
++#   define DEFAULT_PRIO _DEFAULT_PRIO":-CURVE-ALL:-ECDHE-RSA:-ECDHE-ECDSA"
++# else
++#   define DEFAULT_PRIO _DEFAULT_PRIO
++#  endif
+ # endif
+ #endif
+ 
+-- 
+2.1.0
+
diff --git a/openconnect.spec b/openconnect.spec
index 4ad901a..d422caf 100644
--- a/openconnect.spec
+++ b/openconnect.spec
@@ -21,13 +21,16 @@
 
 Name:		openconnect
 Version:	7.05
-Release:	1%{?relsuffix}%{?dist}
+Release:	2%{?relsuffix}%{?dist}
 Summary:	Open client for Cisco AnyConnect VPN
 
 Group:		Applications/Internet
 License:	LGPLv2+
 URL:		http://www.infradead.org/openconnect.html
 Source0:	ftp://ftp.infradead.org/pub/openconnect/openconnect-%{version}%{?gitsuffix}.tar.gz
+Patch1:		openconnect-7.05-override-default-prio-string.patch
+Patch2:		openconnect-7.05-ensure-dtls-ciphers-match-the-allowed.patch
+
 BuildRoot:	%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 BuildRequires:	pkgconfig(openssl) pkgconfig(libxml-2.0)
@@ -70,8 +73,13 @@ for NetworkManager etc.
 %prep
 %setup -q -n openconnect-%{version}%{?gitsuffix}
 
+%patch1 -p1 -b .prio
+%patch2 -p1 -b .ciphers
+
 %build
+autoreconf -fvi
 %configure	--with-vpnc-script=/etc/vpnc/vpnc-script \
+		--with-default-gnutls-priority="@SYSTEM" \
 %if !%{use_gnutls}
 		--with-openssl --without-openssl-version-check \
 %endif
@@ -106,6 +114,9 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/pkgconfig/openconnect.pc
 
 %changelog
+* Wed Mar 11 2015 Nikos Mavrogiannopoulos <nmav at redhat.com> - 7.05-2
+- Utilize and enforce system-wide policies (#1179331)
+
 * Sun Jan 25 2015 David Woodhouse <David.Woodhouse at intel.com> - 7.05-1
 - Update to 7.05 release
 


More information about the scm-commits mailing list