[PATCH 2/6] Added support for GCM ciphersuites (require DTLS 1.2).

Nikos Mavrogiannopoulos nmav at gnutls.org
Sat Nov 23 12:58:07 EST 2013


The GCM ciphersuites provide several advantages over their CBC counterparts.
They have no issues related to the CBC padding oracle attacks, and furthermore
provide more space for data as they use shorter explicit nonce, shorter MAC
than SHA1, and require no padding.

Signed-off-by: Nikos Mavrogiannopoulos <nmav at gnutls.org>
---
 cstp.c |  9 ++++++++-
 dtls.c | 17 ++++++++++++-----
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/cstp.c b/cstp.c
index bb79e7e..15a28e5 100644
--- a/cstp.c
+++ b/cstp.c
@@ -149,6 +149,13 @@ static void calculate_mtu(struct openconnect_info *vpninfo, int *base_mtu, int *
 		*mtu = 1280;
 }
 
+/* if DTLS 1.2 is supported */
+#if defined(DTLS_GNUTLS) && GNUTLS_VERSION_NUMBER >= 0x030200
+# define DEFAULT_CIPHER_LIST "OC-DTLS1_2-AES256-GCM:OC-DTLS1_2-AES128-GCM:AES256-SHA:AES128-SHA:DES-CBC3-SHA:DES-CBC-SHA"
+#else
+# define DEFAULT_CIPHER_LIST "AES256-SHA:AES128-SHA:DES-CBC3-SHA:DES-CBC-SHA"
+#endif
+
 static int start_cstp_connection(struct openconnect_info *vpninfo)
 {
 	char buf[65536];
@@ -221,7 +228,7 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
 	for (i = 0; i < sizeof(vpninfo->dtls_secret); i++)
 		buf_append(buf, sizeof(buf), "%02X", vpninfo->dtls_secret[i]);
 	buf_append(buf, sizeof(buf), "\r\nX-DTLS-CipherSuite: %s\r\n\r\n",
-			       vpninfo->dtls_ciphers ? : "AES256-SHA:AES128-SHA:DES-CBC3-SHA:DES-CBC-SHA");
+			       vpninfo->dtls_ciphers ? : DEFAULT_CIPHER_LIST);
 
 	openconnect_SSL_write(vpninfo, buf, strlen(buf));
 
diff --git a/dtls.c b/dtls.c
index 27f58bf..5360a9d 100644
--- a/dtls.c
+++ b/dtls.c
@@ -348,16 +348,23 @@ int dtls_try_handshake(struct openconnect_info *vpninfo)
 
 struct {
 	const char *name;
+	gnutls_protocol_t version;
 	gnutls_cipher_algorithm_t cipher;
 	gnutls_mac_algorithm_t mac;
 	const char *prio;
 } gnutls_dtls_ciphers[] = {
-	{ "AES128-SHA", GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1,
+	{ "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:%DISABLE_SAFE_RENEGOTIATION" },
-	{ "AES256-SHA", GNUTLS_CIPHER_AES_256_CBC, GNUTLS_MAC_SHA1,
+	{ "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:%DISABLE_SAFE_RENEGOTIATION" },
-	{ "DES-CBC3-SHA", GNUTLS_CIPHER_3DES_CBC, GNUTLS_MAC_SHA1,
+	{ "DES-CBC3-SHA", GNUTLS_DTLS0_9, GNUTLS_CIPHER_3DES_CBC, GNUTLS_MAC_SHA1,
 	  "NONE:+VERS-DTLS0.9:+COMP-NULL:+3DES-CBC:+SHA1:+RSA:%COMPAT:%DISABLE_SAFE_RENEGOTIATION" },
+#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,
+	  "NONE:+VERS-DTLS1.2:+COMP-NULL:+AES-128-GCM:+AEAD:+RSA:%COMPAT:%DISABLE_SAFE_RENEGOTIATION:+SIGN-ALL" },
+	{ "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:%DISABLE_SAFE_RENEGOTIATION:+SIGN-ALL" },
+#endif
 };
 
 #define DTLS_SEND gnutls_record_send
@@ -392,6 +399,7 @@ static int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd)
 		vpninfo->dtls_attempt_period = 0;
 		return -EINVAL;
 	}
+
 	gnutls_transport_set_ptr(dtls_ssl,
 				 (gnutls_transport_ptr_t)(long) dtls_fd);
 	gnutls_record_disable_padding(dtls_ssl);
@@ -399,7 +407,7 @@ static int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd)
 	master_secret.size = sizeof(vpninfo->dtls_secret);
 	session_id.data = vpninfo->dtls_session_id;
 	session_id.size = sizeof(vpninfo->dtls_session_id);
-	err = gnutls_session_set_premaster(dtls_ssl, GNUTLS_CLIENT, GNUTLS_DTLS0_9,
+	err = gnutls_session_set_premaster(dtls_ssl, GNUTLS_CLIENT, gnutls_dtls_ciphers[cipher].version,
 					   GNUTLS_KX_RSA, gnutls_dtls_ciphers[cipher].cipher,
 					   gnutls_dtls_ciphers[cipher].mac, GNUTLS_COMP_NULL,
 					   &master_secret, &session_id);
@@ -619,7 +627,6 @@ static int dtls_restart(struct openconnect_info *vpninfo)
 	return connect_dtls_socket(vpninfo);
 }
 
-
 int setup_dtls(struct openconnect_info *vpninfo)
 {
 	struct vpn_option *dtls_opt = vpninfo->dtls_options;





More information about the openconnect-devel mailing list