From: Alexander Barton Date: Sun, 15 Sep 2013 15:57:41 +0000 (+0200) Subject: Cipher list selection for GnuTLS X-Git-Tag: rel-21-rc1~12^2 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=commitdiff_plain;h=b9006acee3649600226652a8361f13c859726cf2 Cipher list selection for GnuTLS This patch implements the missing functionality for cipher list selection using GnuTLS (our OpenSSL code has this already). --- diff --git a/doc/sample-ngircd.conf.tmpl b/doc/sample-ngircd.conf.tmpl index a4dbf869..1bdf01ee 100644 --- a/doc/sample-ngircd.conf.tmpl +++ b/doc/sample-ngircd.conf.tmpl @@ -248,12 +248,16 @@ # SSL Server Key Certificate ;CertFile = :ETCDIR:/ssl/server-cert.pem - # Select cipher suites allowed for SSL/TLS connections (OpenSSL only). - # This defaults to the empty string, so all supported ciphers are - # allowed. Please see 'man 1ssl ciphers' for details. - # The example below only allows "high strength" cipher suites, disables - # the ones without authentication, and sorts by strength: + # Select cipher suites allowed for SSL/TLS connections. This defaults + # to the empty string, so all supported ciphers are allowed. Please + # see 'man 1ssl ciphers' (OpenSSL) and 'man 3 gnutls_priority_init' + # (GnuTLS) for details. + # For example, this setting allows only "high strength" cipher suites, + # disables the ones without authentication, and sorts by strength: + # For OpenSSL: ;CipherList = HIGH:!aNULL:@STRENGTH + # For GnuTLS: + ;CipherList = SECURE128 # Diffie-Hellman parameters ;DHFile = :ETCDIR:/ssl/dhparams.pem diff --git a/man/ngircd.conf.5.tmpl b/man/ngircd.conf.5.tmpl index 263dec04..862c1424 100644 --- a/man/ngircd.conf.5.tmpl +++ b/man/ngircd.conf.5.tmpl @@ -367,11 +367,13 @@ when it is compiled with support for SSL using OpenSSL or GnuTLS! SSL Certificate file of the private server key. .TP \fBCipherList\fR (string) -OpenSSL only: Select cipher suites allowed for SSL/TLS connections. This -defaults to the empty string, so all supported ciphers are allowed. Please see -'man 1ssl ciphers' for details. This setting allows only "high strength" cipher -suites, disables the ones without authentication, and sorts by strength, for -example: "HIGH:!aNULL:@STRENGTH". +Select cipher suites allowed for SSL/TLS connections. This defaults to the +empty string, so all supported ciphers are allowed. +Please see 'man 1ssl ciphers' (OpenSSL) and 'man 3 gnutls_priority_init' +(GnuTLS) for details. +For example, this setting allows only "high strength" cipher suites, disables +the ones without authentication, and sorts by strength: +"HIGH:!aNULL:@STRENGTH" (OpenSSL), "SECURE128" (GnuTLS). .TP \fBDHFile\fR (string) Name of the Diffie-Hellman Parameter file. Can be created with GnuTLS diff --git a/src/ngircd/conn-ssl.c b/src/ngircd/conn-ssl.c index a9789675..b16c6b94 100644 --- a/src/ngircd/conn-ssl.c +++ b/src/ngircd/conn-ssl.c @@ -58,6 +58,7 @@ static bool ConnSSL_LoadServerKey_openssl PARAMS(( SSL_CTX *c )); static gnutls_certificate_credentials_t x509_cred; static gnutls_dh_params_t dh_params; +static gnutls_priority_t priorities_cache; static bool ConnSSL_LoadServerKey_gnutls PARAMS(( void )); #endif @@ -308,12 +309,12 @@ ConnSSL_InitLibrary( void ) if(Conf_SSLOptions.CipherList && *Conf_SSLOptions.CipherList) { if(SSL_CTX_set_cipher_list(newctx, Conf_SSLOptions.CipherList) == 0 ) { Log(LOG_ERR, - "Failed to apply SSL cipher list \"%s\"!", + "Failed to apply OpenSSL cipher list \"%s\"!", Conf_SSLOptions.CipherList); goto out; } else { Log(LOG_INFO, - "Successfully applied SSL cipher list: \"%s\".", + "Successfully applied OpenSSL cipher list \"%s\".", Conf_SSLOptions.CipherList); } } @@ -341,29 +342,43 @@ out: return false; } - if(Conf_SSLOptions.CipherList != NULL) { - Log(LOG_ERR, - "Failed to apply SSL cipher list \"%s\": Not implemented for GnuTLS!", - Conf_SSLOptions.CipherList); - array_free(&Conf_SSLOptions.ListenPorts); - return false; - } - err = gnutls_global_init(); if (err) { Log(LOG_ERR, "Failed to initialize GnuTLS: %s", gnutls_strerror(err)); - array_free(&Conf_SSLOptions.ListenPorts); - return false; + goto out; } - if (!ConnSSL_LoadServerKey_gnutls()) { - array_free(&Conf_SSLOptions.ListenPorts); - return false; + + if (!ConnSSL_LoadServerKey_gnutls()) + goto out; + + if(Conf_SSLOptions.CipherList && *Conf_SSLOptions.CipherList) { + err = gnutls_priority_init(&priorities_cache, + Conf_SSLOptions.CipherList, NULL); + if (err != GNUTLS_E_SUCCESS) { + Log(LOG_ERR, + "Failed to apply GnuTLS cipher list \"%s\"!", + Conf_SSLOptions.CipherList); + goto out; + } + Log(LOG_INFO, + "Successfully applied GnuTLS cipher list \"%s\".", + Conf_SSLOptions.CipherList); + } else { + err = gnutls_priority_init(&priorities_cache, "NORMAL", NULL); + if (err != GNUTLS_E_SUCCESS) { + Log(LOG_ERR, + "Failed to apply GnuTLS cipher list \"NORMAL\"!"); + goto out; + } } Log(LOG_INFO, "GnuTLS %s initialized.", gnutls_check_version(NULL)); initialized = true; return true; +out: + array_free(&Conf_SSLOptions.ListenPorts); + return false; #endif } @@ -489,9 +504,9 @@ ConnSSL_Init_SSL(CONNECTION *c) #endif #ifdef HAVE_LIBGNUTLS Conn_OPTION_ADD(c, CONN_SSL); - ret = gnutls_set_default_priority(c->ssl_state.gnutls_session); + ret = gnutls_priority_set(c->ssl_state.gnutls_session, priorities_cache); if (ret != 0) { - Log(LOG_ERR, "Failed to set GnuTLS default priority: %s", + Log(LOG_ERR, "Failed to set GnuTLS session priorities: %s", gnutls_strerror(ret)); ConnSSL_Free(c); return false;