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