Hi, Sorry for getting this sent to squid-users instead of the adequate mailing list for patches (squid-dev). We have tried to send the patch to squid-dev without a subscription (as recommended in http://www.squid-cache.org/Support/mailing-lists.html#squid-dev), but perhaps the message did not get to the list administrator. This patch implements two different changes in SSL support: * Adds support for Ephemeral Elliptic Curve Diffie-Hellman (EECDH) key exchange, which allows for forward secrecy with better performance than traditional ephemeral DH. * Disables client-initiated renegotiation, mitigating a DoS attack which might be possible with some versions of the OpenSSL library. We have been warned about this when testing our service with the Qualys SSL Test (https://www.ssllabs.com/ssltest) back when it was running in a Debian wheezy system. Further information is available at: https://community.qualys.com/blogs/securitylabs/2011/10/31/tls-renegotiation-and-denial-of-service-attacks Our solution is similar to the one adopted in pureftpd: https://github.com/jedisct1/pure-ftpd/blob/549e94aaa093a48622efd6d91fdfb3a4236c13f4/src/tls.c#L106 We have been running Squid 3.4.8 in production with a backported patch for two months. So far, we have no complaints from the users (60 to 100 users per day) and the server is running stably. We would be very happy if we could get this integrated into Squid's source code, so please provide us feedback with any suggestions. Our https_port directive also follows, to serve as an example configuration: https_port 3443 cert=/etc/ssl/private/proxy.crt key=/etc/ssl/private/proxy.key options=NO_SSLv3, No_Compression, SINGLE_DH_USE, SINGLE_ECDH_USE, CIPHER_SERVER_PREFERENCE dhparams=/etc/ssl/dhparam/dh2048.pem eecdhcurve=prime256v1 cipher=ECDHE-ECDSA-CHACHA20-POLY1305: ECDHE-RSA-CHACHA20-POLY1305: DHE-RSA-CHACHA20-POLY1305: EECDH+ECDSA+AESGCM: EECDH+aRSA+AESGCM: EDH+aRSA+AESGCM: EECDH+ECDSA+SHA384: EECDH+aRSA+SHA384: EDH+aRSA+SHA384: EECDH+ECDSA+SHA256: EECDH+aRSA+SHA256: EDH+aRSA+SHA256: EECDH:EDH+aRSA: !RC4:!aNULL:!eNULL:!LOW:!3DES: !MD5:!EXP:!PSK:!SRP:!DSS Best regards, Paulo Matias -------------- next part -------------- === modified file 'doc/release-notes/release-4.sgml' --- doc/release-notes/release-4.sgml 2015-03-28 11:12:46 +0000 +++ doc/release-notes/release-4.sgml 2015-05-20 12:28:18 +0000 @@ -133,6 +133,8 @@ <tag>https_port</tag> <p>All <em>version=</em> <em>option=</em> values for SSLv2 configuration or disabling have been removed. + <p>New parameter <em>eecdhcurve</em> for specifying an + elliptic curve for ephemeral ECDH key exchange. <p>Manual squid.conf update may be required on upgrade. <tag>sslcrtd_children</tag> === modified file 'src/anyp/PortCfg.cc' --- src/anyp/PortCfg.cc 2015-01-14 17:10:20 +0000 +++ src/anyp/PortCfg.cc 2015-05-19 14:46:04 +0000 @@ -53,6 +53,7 @@ capath(NULL), crlfile(NULL), dhfile(NULL), + eecdhcurve(NULL), sslflags(NULL), sslContextSessionId(NULL), generateHostCertificates(false), @@ -94,6 +95,7 @@ safe_free(capath); safe_free(crlfile); safe_free(dhfile); + safe_free(eecdhcurve); safe_free(sslflags); safe_free(sslContextSessionId); #endif @@ -139,6 +141,8 @@ b->crlfile = xstrdup(crlfile); if (dhfile) b->dhfile = xstrdup(dhfile); + if (eecdhcurve) + b->eecdhcurve = xstrdup(eecdhcurve); if (sslflags) b->sslflags = xstrdup(sslflags); if (sslContextSessionId) === modified file 'src/anyp/PortCfg.h' --- src/anyp/PortCfg.h 2015-01-13 07:25:36 +0000 +++ src/anyp/PortCfg.h 2015-05-19 14:46:04 +0000 @@ -78,6 +78,7 @@ char *capath; char *crlfile; char *dhfile; + char *eecdhcurve; char *sslflags; char *sslContextSessionId; ///< "session id context" for staticSslContext bool generateHostCertificates; ///< dynamically make host cert for sslBump === modified file 'src/cache_cf.cc' --- src/cache_cf.cc 2015-05-15 12:50:09 +0000 +++ src/cache_cf.cc 2015-05-19 14:46:04 +0000 @@ -3606,6 +3606,9 @@ } else if (strncmp(token, "dhparams=", 9) == 0) { safe_free(s->dhfile); s->dhfile = xstrdup(token + 9); + } else if (strncmp(token, "eecdhcurve=", 11) == 0) { + safe_free(s->eecdhcurve); + s->eecdhcurve = xstrdup(token + 11); } else if (strncmp(token, "sslflags=", 9) == 0) { safe_free(s->sslflags); s->sslflags = xstrdup(token + 9); @@ -3829,6 +3832,9 @@ if (s->dhfile) storeAppendPrintf(e, " dhparams=%s", s->dhfile); + if (s->eecdhcurve) + storeAppendPrintf(e, " eecdhcurve=%s", s->eecdhcurve); + if (s->sslflags) storeAppendPrintf(e, " sslflags=%s", s->sslflags); === modified file 'src/cf.data.pre' --- src/cf.data.pre 2015-05-15 12:50:09 +0000 +++ src/cf.data.pre 2015-05-20 12:23:53 +0000 @@ -2122,6 +2122,11 @@ Always create a new key when using temporary/ephemeral DH key exchanges + SINGLE_ECDH_USE + Enable ephemeral ECDH key exchange. + The adopted curve should be specified + using the eecdhcurve option. + SSL_OP_NO_TICKET Disable use of RFC5077 session tickets. Some servers may have problems @@ -2153,6 +2158,9 @@ dhparams= File containing DH parameters for temporary/ephemeral DH key exchanges. + eecdhcurve= Elliptic Curve used for ephemeral ECDH. Supported curves + can be listed using "openssl ecparam -list_curves". + sslflags= Various flags modifying the use of SSL: DELAYED_AUTH Don't request client certificates === modified file 'src/ssl/support.cc' --- src/ssl/support.cc 2015-05-08 11:18:30 +0000 +++ src/ssl/support.cc 2015-05-19 14:50:44 +0000 @@ -472,6 +472,11 @@ "NO_TICKET", SSL_OP_NO_TICKET }, #endif +#if SSL_OP_SINGLE_ECDH_USE + { + "SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE + }, +#endif { "", 0 }, @@ -824,11 +829,46 @@ } static bool +configureSslEECDH(SSL_CTX *sslContext, const char *curve) +{ + bool ok = true; +#if OPENSSL_VERSION_NUMBER >= 0x0090800fL +#ifndef OPENSSL_NO_ECDH + int nid = OBJ_sn2nid(curve); + if (!nid) + return false; + + EC_KEY *ecdh = EC_KEY_new_by_curve_name(nid); + if (ecdh == NULL) + return false; + + ok = SSL_CTX_set_tmp_ecdh(sslContext, ecdh) != 0; + EC_KEY_free(ecdh); +#endif +#endif + return ok; +} + +static void +ssl_info_cb(const SSL *ssl, int where, int ret) +{ + (void)ret; +#ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS + if ((where & SSL_CB_HANDSHAKE_DONE) != 0) { + // disable renegotiation (CVE-2009-3555) + ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS; + } +#endif +} + +static bool configureSslContext(SSL_CTX *sslContext, AnyP::PortCfg &port) { int ssl_error; SSL_CTX_set_options(sslContext, port.sslOptions); + SSL_CTX_set_info_callback(sslContext, ssl_info_cb); + if (port.sslContextSessionId) SSL_CTX_set_session_id_context(sslContext, (const unsigned char *)port.sslContextSessionId, strlen(port.sslContextSessionId)); @@ -855,6 +895,15 @@ debugs(83, 9, "Setting RSA key generation callback."); SSL_CTX_set_tmp_rsa_callback(sslContext, ssl_temp_rsa_cb); + if (port.eecdhcurve) { + debugs(83, 9, "Setting Ephemeral ECDH curve to " << port.eecdhcurve << "."); + + if (!configureSslEECDH(sslContext, port.eecdhcurve)) { + ssl_error = ERR_get_error(); + debugs(83, DBG_IMPORTANT, "WARNING: Unable to configure Ephemeral ECDH: " << ERR_error_string(ssl_error, NULL)); + } + } + debugs(83, 9, "Setting CA certificate locations."); const char *cafile = port.cafile ? port.cafile : port.clientca; @@ -1155,6 +1204,8 @@ SSL_CTX_set_options(sslContext, Ssl::parse_options(options)); + SSL_CTX_set_info_callback(sslContext, ssl_info_cb); + if (*cipher) { debugs(83, 5, "Using chiper suite " << cipher << "."); _______________________________________________ squid-users mailing list squid-users@xxxxxxxxxxxxxxxxxxxxx http://lists.squid-cache.org/listinfo/squid-users