aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Frank <frankfa@yahoo-inc.com>2014-01-19 00:47:31 -0800
committerDaniel Stenberg <daniel@haxx.se>2014-01-20 11:32:55 +0100
commit39f7e80a52c3b23b36015dcf0d3655af43a70f49 (patch)
tree4a32816b539ae9daa3bf0c856252e4884370ec14
parentb0fa530c98d8f83437b2897d52eba93cf3898422 (diff)
disable GnuTLS insecure ciphers
Make GnuTLS old and new consistent, specify the desired protocol, cipher and certificate type in always in both modes. Disable insecure ciphers as reported by howsmyssl.com. Honor not only --sslv3, but also the --tlsv1[.N] switches. Related Bug: http://curl.haxx.se/bug/view.cgi?id=1323
-rw-r--r--lib/vtls/gtls.c110
1 files changed, 87 insertions, 23 deletions
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index 425b0f817..cd410551c 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -350,9 +350,6 @@ static CURLcode
gtls_connect_step1(struct connectdata *conn,
int sockindex)
{
-#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
- static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
-#endif
struct SessionHandle *data = conn->data;
gnutls_session session;
int rc;
@@ -364,6 +361,19 @@ gtls_connect_step1(struct connectdata *conn,
#else
struct in_addr addr;
#endif
+#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
+ static int cipher_priority[] = { GNUTLS_CIPHER_AES_128_GCM,
+ GNUTLS_CIPHER_AES_256_GCM, GNUTLS_CIPHER_AES_128_CBC,
+ GNUTLS_CIPHER_AES_256_CBC, GNUTLS_CIPHER_CAMELLIA_128_CBC,
+ GNUTLS_CIPHER_CAMELLIA_256_CBC, GNUTLS_CIPHER_3DES_CBC,
+ };
+ static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
+ static int protocol_priority[] = { 0, 0, 0, 0 };
+#else
+#define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
+ const char* prioritylist;
+ const char *err;
+#endif
if(conn->ssl[sockindex].state == ssl_connection_complete)
/* to make us tolerant against being called more than once for the
@@ -471,34 +481,88 @@ gtls_connect_step1(struct connectdata *conn,
if(rc != GNUTLS_E_SUCCESS)
return CURLE_SSL_CONNECT_ERROR;
- if(data->set.ssl.version == CURL_SSLVERSION_SSLv3) {
#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
- static const int protocol_priority[] = { GNUTLS_SSL3, 0 };
- rc = gnutls_protocol_set_priority(session, protocol_priority);
-#else
- const char *err;
- /* the combination of the cipher ARCFOUR with SSL 3.0 and TLS 1.0 is not
- vulnerable to attacks such as the BEAST, why this code now explicitly
- asks for that
- */
- rc = gnutls_priority_set_direct(session,
- "NORMAL:-VERS-TLS-ALL:+VERS-SSL3.0:"
- "-CIPHER-ALL:+ARCFOUR-128",
- &err);
-#endif
- if(rc != GNUTLS_E_SUCCESS)
- return CURLE_SSL_CONNECT_ERROR;
- }
+ rc = gnutls_cipher_set_priority(session, cipher_priority);
+ if(rc != GNUTLS_E_SUCCESS)
+ return CURLE_SSL_CONNECT_ERROR;
-#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
/* Sets the priority on the certificate types supported by gnutls. Priority
- is higher for types specified before others. After specifying the types
- you want, you must append a 0. */
+ is higher for types specified before others. After specifying the types
+ you want, you must append a 0. */
rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
if(rc != GNUTLS_E_SUCCESS)
return CURLE_SSL_CONNECT_ERROR;
+
+ if(data->set.ssl.cipher_list != NULL) {
+ failf(data, "can't pass a custom cipher list to older GnuTLS"
+ " versions");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+ switch (data->set.ssl.version) {
+ case CURL_SSLVERSION_SSLv3:
+ protocol_priority[0] = GNUTLS_SSL3;
+ break;
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ protocol_priority[0] = GNUTLS_TLS1_0;
+ protocol_priority[1] = GNUTLS_TLS1_1;
+ protocol_priority[2] = GNUTLS_TLS1_2;
+ break;
+ case CURL_SSLVERSION_TLSv1_0:
+ protocol_priority[0] = GNUTLS_TLS1_0;
+ break;
+ case CURL_SSLVERSION_TLSv1_1:
+ protocol_priority[0] = GNUTLS_TLS1_1;
+ break;
+ case CURL_SSLVERSION_TLSv1_2:
+ protocol_priority[0] = GNUTLS_TLS1_2;
+ break;
+ case CURL_SSLVERSION_SSLv2:
+ default:
+ failf(data, "GnuTLS does not support SSLv2");
+ return CURLE_SSL_CONNECT_ERROR;
+ break;
+ }
+ rc = gnutls_protocol_set_priority(session, protocol_priority);
+#else
+ switch (data->set.ssl.version) {
+ case CURL_SSLVERSION_SSLv3:
+ prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0";
+ sni = false;
+ break;
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0";
+ break;
+ case CURL_SSLVERSION_TLSv1_0:
+ prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+ "+VERS-TLS1.0";
+ break;
+ case CURL_SSLVERSION_TLSv1_1:
+ prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+ "+VERS-TLS1.1";
+ break;
+ case CURL_SSLVERSION_TLSv1_2:
+ prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+ "+VERS-TLS1.2";
+ break;
+ case CURL_SSLVERSION_SSLv2:
+ default:
+ failf(data, "GnuTLS does not support SSLv2");
+ return CURLE_SSL_CONNECT_ERROR;
+ break;
+ }
+ rc = gnutls_priority_set_direct(session, prioritylist, &err);
#endif
+
+ if(rc != GNUTLS_E_SUCCESS) {
+ failf(data, "Did you pass a valid GnuTLS cipher list?");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
+
if(data->set.str[STRING_CERT]) {
if(gnutls_certificate_set_x509_key_file(
conn->ssl[sockindex].cred,