Cipher list selection for OpenSSL

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.
This commit is contained in:
Alexander Barton 2013-09-15 15:09:36 +02:00
parent 849f85a05c
commit 84ed46d4c1
5 changed files with 48 additions and 1 deletions

View File

@ -248,6 +248,13 @@
# 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

View 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
\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

View File

@ -117,6 +117,9 @@ ConfSSL_Init(void)
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 : "");
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
@ -1869,6 +1874,11 @@ Handle_SSL(const char *File, int Line, char *Var, char *Arg)
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");
}

View 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 *CipherList; /**< Set SSL cipher list to use */
};
#endif

View File

@ -305,6 +305,19 @@ ConnSSL_InitLibrary( void )
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,
@ -328,6 +341,14 @@ 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",
@ -339,6 +360,7 @@ out:
array_free(&Conf_SSLOptions.ListenPorts);
return false;
}
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,
"Ignoring KeyFilePassword: Not supported by GnuTLS.");
"Ignoring SSL \"KeyFilePassword\": Not supported by GnuTLS.");
if (!Load_DH_params())
return false;