commit b9006acee3649600226652a8361f13c859726cf2 from: Alexander Barton date: Sun Sep 15 15:57:47 2013 UTC Cipher list selection for GnuTLS This patch implements the missing functionality for cipher list selection using GnuTLS (our OpenSSL code has this already). commit - 51231ac8d45bf329f4724a145e6bc7a3ea118570 commit + b9006acee3649600226652a8361f13c859726cf2 blob - a4dbf8695987fc2cf117f4d05f1adae33b19654f blob + 1bdf01ee4f2b7309ec864ea75a389694b368e352 --- doc/sample-ngircd.conf.tmpl +++ 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 blob - 263dec047d5e6ebcbefc85571593e7fe075b22f0 blob + 862c142403327a0560161e586ec6de8fe854e22a --- man/ngircd.conf.5.tmpl +++ man/ngircd.conf.5.tmpl @@ -367,11 +367,13 @@ when it is compiled with support for SSL using OpenSSL 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 blob - a97896758cc30c2f63724ab5396e797e064763da blob + b16c6b94e35299a54091ae9bb60dba9e1880c174 --- src/ngircd/conn-ssl.c +++ src/ngircd/conn-ssl.c @@ -58,6 +58,7 @@ static bool ConnSSL_LoadServerKey_openssl PARAMS(( SSL 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;