]> arthur.barton.de Git - ngircd-alex.git/commitdiff
Cipher list selection for OpenSSL
authorAlexander Barton <alex@barton.de>
Sun, 15 Sep 2013 13:09:36 +0000 (15:09 +0200)
committerAlexander Barton <alex@barton.de>
Sun, 15 Sep 2013 13:09:36 +0000 (15:09 +0200)
This patch introduces the possibility to arbitrarily select ciphers which
should be promoted resp. declined when establishing a SSL connection
with a client by implementing the new configuration option "CipherList".

By default, OpenSSL would accept low and medium strength and RC-4 ciphers,
which nowadays are known to be broken.

This patch only implements the feature for OpenSSL. A GnuTLS counterpart
has to be implemented in another patch ...

Original patch by Bastian <bastian-ngircd@t6l.de>.

Closes bug #162.

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

index ae1b213950b8484ed4ab0ac92e9c9c03d86cea47..a4dbf8695987fc2cf117f4d05f1adae33b19654f 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:
+       ;CipherList = HIGH:!aNULL:@STRENGTH
+
        # Diffie-Hellman parameters
        ;DHFile = :ETCDIR:/ssl/dhparams.pem
 
        # Diffie-Hellman parameters
        ;DHFile = :ETCDIR:/ssl/dhparams.pem
 
index cf926f9a3b80845f1b45715664a66f1709fddb94..263dec047d5e6ebcbefc85571593e7fe075b22f0 100644 (file)
@@ -366,6 +366,13 @@ when it is compiled with support for SSL using OpenSSL or GnuTLS!
 \fBCertFile\fR (string)
 SSL Certificate file of the private server key.
 .TP
 \fBCertFile\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".
+.TP
 \fBDHFile\fR (string)
 Name of the Diffie-Hellman Parameter file. Can be created with GnuTLS
 "certtool \-\-generate-dh-params" or "openssl dhparam". If this file is not
 \fBDHFile\fR (string)
 Name of the Diffie-Hellman Parameter file. Can be created with GnuTLS
 "certtool \-\-generate-dh-params" or "openssl dhparam". If this file is not
index b10f4905c9ec7befb08b5b5717cc6397cc48bea9..9ab66e54cf194b3c7afe68c90104d62e309e8ae1 100644 (file)
@@ -117,6 +117,9 @@ ConfSSL_Init(void)
        array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
 
        array_free(&Conf_SSLOptions.ListenPorts);
        array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
 
        array_free(&Conf_SSLOptions.ListenPorts);
+
+       free(Conf_SSLOptions.CipherList);
+       Conf_SSLOptions.CipherList = NULL;
 }
 
 /**
 }
 
 /**
@@ -432,6 +435,8 @@ Conf_Test( void )
        puts("[SSL]");
        printf("  CertFile = %s\n", Conf_SSLOptions.CertFile
                                        ? Conf_SSLOptions.CertFile : "");
        puts("[SSL]");
        printf("  CertFile = %s\n", Conf_SSLOptions.CertFile
                                        ? Conf_SSLOptions.CertFile : "");
+       printf("  CipherList = %s\n", Conf_SSLOptions.CipherList
+                                       ? Conf_SSLOptions.CipherList : "");
        printf("  DHFile = %s\n", Conf_SSLOptions.DHFile
                                        ? Conf_SSLOptions.DHFile : "");
        printf("  KeyFile = %s\n", Conf_SSLOptions.KeyFile
        printf("  DHFile = %s\n", Conf_SSLOptions.DHFile
                                        ? Conf_SSLOptions.DHFile : "");
        printf("  KeyFile = %s\n", Conf_SSLOptions.KeyFile
@@ -1869,6 +1874,11 @@ Handle_SSL(const char *File, int Line, char *Var, char *Arg)
                ports_parse(&Conf_SSLOptions.ListenPorts, Line, Arg);
                return;
        }
                ports_parse(&Conf_SSLOptions.ListenPorts, Line, Arg);
                return;
        }
+       if (strcasecmp(Var, "CipherList") == 0) {
+               assert(Conf_SSLOptions.CipherList == NULL);
+               Conf_SSLOptions.CipherList = strdup_warn(Arg);
+               return;
+       }
 
        Config_Error_Section(File, Line, Var, "SSL");
 }
 
        Config_Error_Section(File, Line, Var, "SSL");
 }
index 948749de617bc433b6302edac2633eb1fc6e2bbe..02d23315552b0915020cb8690f1c084e97d69133 100644 (file)
@@ -75,6 +75,7 @@ struct SSLOptions {
        char *DHFile;                   /**< File containing DH parameters */
        array ListenPorts;              /**< Array of listening SSL ports */
        array KeyFilePassword;          /**< Key file password */
        char *DHFile;                   /**< File containing DH parameters */
        array ListenPorts;              /**< Array of listening SSL ports */
        array KeyFilePassword;          /**< Key file password */
+       char *CipherList;               /**< Set SSL cipher list to use */
 };
 #endif
 
 };
 #endif
 
index 595cb615e6e78ed192f154a016c5ea5d3778e2d2..059e871ddaa38af341e995f577225fad84940091 100644 (file)
@@ -305,6 +305,19 @@ ConnSSL_InitLibrary( void )
        if (!ConnSSL_LoadServerKey_openssl(newctx))
                goto out;
 
        if (!ConnSSL_LoadServerKey_openssl(newctx))
                goto out;
 
+       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\"!",
+                           Conf_SSLOptions.CipherList);
+                       goto out;
+               } else {
+                       Log(LOG_INFO,
+                           "Successfully applied SSL cipher list: \"%s\".",
+                           Conf_SSLOptions.CipherList);
+               }
+       }
+
        SSL_CTX_set_options(newctx, SSL_OP_SINGLE_DH_USE|SSL_OP_NO_SSLv2);
        SSL_CTX_set_mode(newctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
        SSL_CTX_set_verify(newctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
        SSL_CTX_set_options(newctx, SSL_OP_SINGLE_DH_USE|SSL_OP_NO_SSLv2);
        SSL_CTX_set_mode(newctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
        SSL_CTX_set_verify(newctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
@@ -328,6 +341,14 @@ 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",
        err = gnutls_global_init();
        if (err) {
                Log(LOG_ERR, "Failed to initialize GnuTLS: %s",
@@ -339,6 +360,7 @@ out:
                array_free(&Conf_SSLOptions.ListenPorts);
                return false;
        }
                array_free(&Conf_SSLOptions.ListenPorts);
                return false;
        }
+
        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;
@@ -368,7 +390,7 @@ ConnSSL_LoadServerKey_gnutls(void)
 
        if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
                Log(LOG_WARNING,
 
        if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
                Log(LOG_WARNING,
-                   "Ignoring KeyFilePassword: Not supported by GnuTLS.");
+                   "Ignoring SSL \"KeyFilePassword\": Not supported by GnuTLS.");
 
        if (!Load_DH_params())
                return false;
 
        if (!Load_DH_params())
                return false;