]> arthur.barton.de Git - ngircd-alex.git/commitdiff
Cipher list selection for GnuTLS bug162-SSLCipherList
authorAlexander Barton <alex@barton.de>
Sun, 15 Sep 2013 15:57:41 +0000 (17:57 +0200)
committerAlexander Barton <alex@barton.de>
Sun, 15 Sep 2013 15:57:47 +0000 (17:57 +0200)
This patch implements the missing functionality for cipher list selection
using GnuTLS (our OpenSSL code has this already).

doc/sample-ngircd.conf.tmpl
man/ngircd.conf.5.tmpl
src/ngircd/conn-ssl.c

index a4dbf8695987fc2cf117f4d05f1adae33b19654f..1bdf01ee4f2b7309ec864ea75a389694b368e352 100644 (file)
        # SSL Server Key Certificate
        ;CertFile = :ETCDIR:/ssl/server-cert.pem
 
        # 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
        ;CipherList = HIGH:!aNULL:@STRENGTH
+       # For GnuTLS:
+       ;CipherList = SECURE128
 
        # Diffie-Hellman parameters
        ;DHFile = :ETCDIR:/ssl/dhparams.pem
 
        # Diffie-Hellman parameters
        ;DHFile = :ETCDIR:/ssl/dhparams.pem
index 263dec047d5e6ebcbefc85571593e7fe075b22f0..862c142403327a0560161e586ec6de8fe854e22a 100644 (file)
@@ -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)
 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
 .TP
 \fBDHFile\fR (string)
 Name of the Diffie-Hellman Parameter file. Can be created with GnuTLS
index a97896758cc30c2f63724ab5396e797e064763da..b16c6b94e35299a54091ae9bb60dba9e1880c174 100644 (file)
@@ -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_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
 
 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,
        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,
                            Conf_SSLOptions.CipherList);
                        goto out;
                } else {
                        Log(LOG_INFO,
-                           "Successfully applied SSL cipher list: \"%s\".",
+                           "Successfully applied OpenSSL cipher list \"%s\".",
                            Conf_SSLOptions.CipherList);
                }
        }
                            Conf_SSLOptions.CipherList);
                }
        }
@@ -341,29 +342,43 @@ out:
                return false;
        }
 
                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));
        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;
        }
 
        Log(LOG_INFO, "GnuTLS %s initialized.", gnutls_check_version(NULL));
        initialized = true;
        return true;
+out:
+       array_free(&Conf_SSLOptions.ListenPorts);
+       return false;
 #endif
 }
 
 #endif
 }
 
@@ -489,9 +504,9 @@ ConnSSL_Init_SSL(CONNECTION *c)
 #endif
 #ifdef HAVE_LIBGNUTLS
        Conn_OPTION_ADD(c, CONN_SSL);
 #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) {
        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;
                    gnutls_strerror(ret));
                ConnSSL_Free(c);
                return false;