Skip to content

Commit

Permalink
Added support for GCM ciphersuites (require DTLS 1.2).
Browse files Browse the repository at this point in the history
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@gnutls.org>
  • Loading branch information
nmav authored and Nikos Mavrogiannopoulos committed Feb 3, 2014
1 parent bb7929b commit 12bf8a0
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 6 deletions.
9 changes: 8 additions & 1 deletion cstp.c
Expand Up @@ -172,6 +172,13 @@ void cstp_free_splits(struct openconnect_info *vpninfo)
vpninfo->ip_info.split_excludes = NULL;
}

/* 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];
Expand Down Expand Up @@ -228,7 +235,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));

Expand Down
17 changes: 12 additions & 5 deletions dtls.c
Expand Up @@ -326,16 +326,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
Expand Down Expand Up @@ -371,14 +378,15 @@ 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);
master_secret.data = vpninfo->dtls_secret;
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);
Expand Down Expand Up @@ -584,7 +592,6 @@ static int dtls_restart(struct openconnect_info *vpninfo)
return connect_dtls_socket(vpninfo);
}


int openconnect_setup_dtls(struct openconnect_info *vpninfo, int dtls_attempt_period)
{
struct oc_vpn_option *dtls_opt = vpninfo->dtls_options;
Expand Down

0 comments on commit 12bf8a0

Please sign in to comment.