INN commit: trunk (8 files)
INN Commit
rra at isc.org
Mon Dec 1 20:22:57 UTC 2014
Date: Monday, December 1, 2014 @ 12:22:57
Author: iulius
Revision: 9752
Add support for choosing the elliptic curve to use with TLS support
The new tlseccurve parameter in inn.conf takes the name of a curve
OpenSSL knows about, to use for ephemeral key exchanges.
Thanks to Christian Mock for the patch.
Modified:
trunk/doc/pod/inn.conf.pod
trunk/doc/pod/news.pod
trunk/doc/pod/nnrpd.pod
trunk/include/inn/innconf.h
trunk/lib/innconf.c
trunk/nnrpd/tls.c
trunk/nnrpd/tls.h
trunk/samples/inn.conf.in
-----------------------+
doc/pod/inn.conf.pod | 13 +++++++-
doc/pod/news.pod | 6 +--
doc/pod/nnrpd.pod | 7 ++--
include/inn/innconf.h | 1
lib/innconf.c | 1
nnrpd/tls.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++--
nnrpd/tls.h | 9 +++++
samples/inn.conf.in | 1
8 files changed, 101 insertions(+), 10 deletions(-)
Modified: doc/pod/inn.conf.pod
===================================================================
--- doc/pod/inn.conf.pod 2014-11-23 21:47:38 UTC (rev 9751)
+++ doc/pod/inn.conf.pod 2014-12-01 20:22:57 UTC (rev 9752)
@@ -1088,6 +1088,17 @@
Whether to enable or disable SSL/TLS compression support. This is a
boolean and the default is false, that is to say compression is disabled.
+=item I<tlseccurve>
+
+The name of the elliptic curve to use for ephemeral key exchanges.
+To see the list of curves supported by OpenSSL, use C<openssl ecparam
+-list_curves>.
+
+The default is unset, which means an appropriate curve is auto-selected
+(if your OpenSSL version supports it) or the NIST P-256 curve is used.
+
+This option is only effective if your OpenSSL version has ECDH support.
+
=item I<tlspreferserverciphers>
Whether to let the client or the server decide the preferred cipher.
@@ -1267,7 +1278,7 @@
=item I<status>
How frequently (in seconds) innd(8) should write out a status report. The
-report is written to I<pathhttp>/inn_status.html or I<pathlog>/inn.status
+report is written to I<pathhttp>/inn_status.html or I<pathlog>/inn.status
depending on the value of I<htmlstatus>. If this is set to C<0> or
C<false>, status reporting is disabled. The default value is C<0>.
Modified: doc/pod/news.pod
===================================================================
--- doc/pod/news.pod 2014-11-23 21:47:38 UTC (rev 9751)
+++ doc/pod/news.pod 2014-12-01 20:22:57 UTC (rev 9752)
@@ -204,9 +204,9 @@
New F<inn.conf> parameters used by B<nnrpd> to fine-tune the SSL/TLS
configuration have been added: I<tlsciphers>, I<tlscompression>,
-I<tlspreferserverciphers>, and I<tlsprotocols>. Many thanks to Christian
-Mock for his contribution that permits to tighten the level of security
-provided by TLS/SSL.
+I<tlseccurve>, I<tlspreferserverciphers>, and I<tlsprotocols>.
+Many thanks to Christian Mock for his contribution that permits to
+tighten the level of security provided by TLS/SSL.
=item *
Modified: doc/pod/nnrpd.pod
===================================================================
--- doc/pod/nnrpd.pod 2014-11-23 21:47:38 UTC (rev 9751)
+++ doc/pod/nnrpd.pod 2014-12-01 20:22:57 UTC (rev 9752)
@@ -227,9 +227,10 @@
defined in F</etc/services> on your system.
Optionally, you may set the I<tlsciphers>, I<tlscompression>,
-I<tlspreferserverciphers>, and I<tlsprotocols> parameters in F<inn.conf>
-to fine-tune the behaviour of the SSL/TLS negotiation whenever a new
-attack on the TLS protocol or some supported cipher suite is discovered.
+I<tlseccurve>, I<tlspreferserverciphers>, and I<tlsprotocols> parameters
+in F<inn.conf> to fine-tune the behaviour of the SSL/TLS negotiation
+whenever a new attack on the TLS protocol or some supported cipher
+suite is discovered.
=head1 PROTOCOL DIFFERENCES
Modified: include/inn/innconf.h
===================================================================
--- include/inn/innconf.h 2014-11-23 21:47:38 UTC (rev 9751)
+++ include/inn/innconf.h 2014-12-01 20:22:57 UTC (rev 9752)
@@ -133,6 +133,7 @@
char *tlskeyfile; /* Path to the key for the certificate */
char *tlsciphers; /* OpenSSL-style cipher string */
bool tlscompression; /* Turn TLS compression on/off */
+ char *tlseccurve; /* ECDH curve name */
bool tlspreferserverciphers; /* Make server select the cipher */
struct vector *tlsprotocols; /* List of supported TLS versions */
Modified: lib/innconf.c
===================================================================
--- lib/innconf.c 2014-11-23 21:47:38 UTC (rev 9751)
+++ lib/innconf.c 2014-12-01 20:22:57 UTC (rev 9752)
@@ -234,6 +234,7 @@
{ K(tlskeyfile), STRING (NULL) },
{ K(tlsciphers), STRING (NULL) },
{ K(tlscompression), BOOL (false) },
+ { K(tlseccurve), STRING (NULL) },
{ K(tlspreferserverciphers), BOOL (true) },
{ K(tlsprotocols), LIST (NULL) },
#endif /* HAVE_OPENSSL */
Modified: nnrpd/tls.c
===================================================================
--- nnrpd/tls.c 2014-11-23 21:47:38 UTC (rev 9751)
+++ nnrpd/tls.c 2014-12-01 20:22:57 UTC (rev 9752)
@@ -413,7 +413,53 @@
}
+#ifdef HAVE_OPENSSL_ECC
/*
+** Provide an ECKEY from a curve name.
+** Accepts a NULL pointer as the name.
+**
+** Returns the key, or NULL on error.
+*/
+static EC_KEY *
+eckey_from_name(char *name)
+{
+ EC_KEY *eckey;
+ size_t ncurves, nitems, i;
+ EC_builtin_curve *builtin_curves;
+ const char *sname;
+
+ if (name == NULL) {
+ return (NULL);
+ }
+
+ /* See EC_GROUP_new(3) for the details of this expressive dance. */
+ ncurves = EC_get_builtin_curves(NULL, 0); /* Number of curves. */
+
+ builtin_curves = xmalloc(ncurves * sizeof(EC_builtin_curve));
+ nitems = EC_get_builtin_curves(builtin_curves, ncurves);
+ if (nitems != ncurves) {
+ syslog(L_ERROR, "got %lu curves from EC_get_builtin_curves, "
+ "expected %lu", nitems, ncurves);
+ }
+ for (i = 0; i < nitems; i++) {
+ sname = OBJ_nid2sn(builtin_curves[i].nid);
+ if (strcmp(sname, name) == 0) {
+ break;
+ }
+ }
+ if (i == nitems) {
+ syslog(L_ERROR, "tlseccurve '%s' not found", name);
+ free(builtin_curves);
+ return (NULL);
+ }
+
+ eckey = EC_KEY_new_by_curve_name(builtin_curves[i].nid);
+ free(builtin_curves);
+ return (eckey);
+}
+#endif /* HAVE_OPENSSL_ECC */
+
+/*
** This is the setup routine for the SSL server. As nnrpd might be called
** more than once, we only want to do the initialization one time.
**
@@ -427,7 +473,7 @@
char *tls_CAfile, char *tls_CApath, char *tls_cert_file,
char *tls_key_file, bool prefer_server_ciphers,
bool tls_compression, struct vector *tls_proto_vect,
- char *tls_ciphers)
+ char *tls_ciphers, char *tls_ec_curve UNUSED)
{
int off = 0;
int verify_flags = SSL_VERIFY_NONE;
@@ -438,6 +484,9 @@
struct stat buf;
size_t tls_protos = 0;
size_t i;
+#ifdef HAVE_OPENSSL_ECC
+ EC_KEY *eckey;
+#endif
if (tls_serverengine)
return (0); /* Already running. */
@@ -497,6 +546,25 @@
SSL_CTX_set_tmp_dh_callback(CTX, tmp_dh_cb);
SSL_CTX_set_options(CTX, SSL_OP_SINGLE_DH_USE);
+#ifdef HAVE_OPENSSL_ECC
+ SSL_CTX_set_options(CTX, SSL_OP_SINGLE_ECDH_USE);
+
+ /* We set a curve here by name if provided
+ * or we use OpenSSL (>= 1.0.2) auto-selection
+ * or we default to NIST P-256. */
+ eckey = eckey_from_name(tls_ec_curve);
+ if (eckey != NULL) {
+ SSL_CTX_set_tmp_ecdh(CTX, eckey);
+ } else {
+# ifdef SSL_CTX_set_ecdh_auto
+ SSL_CTX_set_ecdh_auto(CTX, 1);
+# else
+ SSL_CTX_set_tmp_ecdh(CTX,
+ EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+# endif /* SSL_CTX_set_ecdh_auto */
+ }
+#endif /* HAVE_OPENSSL_ECC */
+
if (prefer_server_ciphers) {
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
SSL_CTX_set_options(CTX, SSL_OP_CIPHER_SERVER_PREFERENCE);
@@ -604,7 +672,8 @@
innconf->tlspreferserverciphers,
innconf->tlscompression,
innconf->tlsprotocols,
- innconf->tlsciphers);
+ innconf->tlsciphers,
+ innconf->tlseccurve);
if (ssl_result == -1) {
Reply("%d Error initializing TLS\r\n",
Modified: nnrpd/tls.h
===================================================================
--- nnrpd/tls.h 2014-11-23 21:47:38 UTC (rev 9751)
+++ nnrpd/tls.h 2014-12-01 20:22:57 UTC (rev 9752)
@@ -27,6 +27,12 @@
#include <openssl/x509.h>
#include <openssl/ssl.h>
+#if !defined(OPENSSL_NO_EC) && defined(TLSEXT_ECPOINTFORMAT_uncompressed)
+# include <openssl/ec.h>
+# include <openssl/objects.h>
+# define HAVE_OPENSSL_ECC
+#endif
+
/* Protocol support. */
#define INN_TLS_SSLv2 1
#define INN_TLS_SSLv3 2
@@ -45,7 +51,8 @@
bool prefer_server_ciphers,
bool tls_compression,
struct vector *tls_protocols,
- char *tls_ciphers);
+ char *tls_ciphers,
+ char *tls_ec_curve);
/* Init TLS. */
int tls_init(void);
Modified: samples/inn.conf.in
===================================================================
--- samples/inn.conf.in 2014-11-23 21:47:38 UTC (rev 9751)
+++ samples/inn.conf.in 2014-12-01 20:22:57 UTC (rev 9752)
@@ -141,6 +141,7 @@
#tlskeyfile: @sysconfdir@/key.pem
#tlsciphers:
#tlscompression: false
+#tlseccurve:
#tlspreferserverciphers: true
#tlsprotocols: [ TLSv1 TLSv1.1 TLSv1.2 ]
More information about the inn-committers
mailing list