ECDHE key exchange with TLSv1

timo2 nginx-forum at nginx.us
Tue Jan 4 18:34:07 MSK 2011


Hi,

I was able to add support for elliptic curve cryptography. Nginx has to
be compiled with Openssl 1.0.0 libraries, though. The patch against
nginx-0.8.54 is here (sorry I do not know how to add attachment).
Basicly, it ads extra configuration parameter ssl_eccurve with which one
can specify the elliptic curve. If this parameter is missing then the
default secp224r1 curve is used.
 
[code]
diff -rupN nginx-0.8.54/src/event/ngx_event_openssl.c
nginx-0.8.54p/src/event/ngx_event_openssl.c
--- nginx-0.8.54/src/event/ngx_event_openssl.c	2010-07-29
12:30:15.000000000 +0300
+++ nginx-0.8.54p/src/event/ngx_event_openssl.c	2011-01-04
17:11:08.000000000 +0200
@@ -479,6 +479,60 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_
     return NGX_OK;
 }
 
+ngx_int_t
+ngx_ssl_eccurve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t
*named_curve)
+{
+    /*
+     * Elliptic-Curve Diffie-Hellman parameters are either "named
curves"
+     * from RFC 4492 section 5.1.1, or explicitly described curves
over
+     * binary fields. OpenSSL only supports the "named curves", which
provide
+     * maximum interoperability.
+     */
+
+    EC_KEY *ecdh=NULL;
+    int nid;
+
+    if (named_curve->len) {
+        nid = OBJ_sn2nid( (const char *) named_curve->data);
+
+        if (nid == 0) {
+            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "Unknown curve
name (%s)\n", named_curve->data);
+
+            EC_KEY_free(ecdh);
+            return NGX_ERROR;
+        }
+
+        ecdh = EC_KEY_new_by_curve_name(nid);
+
+        if (ecdh == NULL) {
+            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "Unable to create
curve (%s)\n", named_curve->data);
+
+            EC_KEY_free(ecdh);
+            return NGX_ERROR;
+        }
+
+        SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
+
+        EC_KEY_free(ecdh);
+
+        return NGX_OK;
+    }
+
+    ecdh = EC_KEY_new_by_curve_name(NID_secp224r1);
+
+    if (ecdh == NULL) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "Unable to create
curve (%s)\n", named_curve->data);
+
+        EC_KEY_free(ecdh);
+        return NGX_ERROR;
+    }
+
+    SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
+
+    EC_KEY_free(ecdh);
+
+    return NGX_OK;
+}
 
 ngx_int_t
 ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c,
ngx_uint_t flags)
diff -rupN nginx-0.8.54/src/event/ngx_event_openssl.h
nginx-0.8.54p/src/event/ngx_event_openssl.h
--- nginx-0.8.54/src/event/ngx_event_openssl.h	2010-03-03
18:23:14.000000000 +0200
+++ nginx-0.8.54p/src/event/ngx_event_openssl.h	2011-01-04
14:57:00.000000000 +0200
@@ -101,6 +101,7 @@ ngx_int_t ngx_ssl_client_certificate(ngx
 ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl);
 ngx_int_t ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl);
 ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t
*file);
+ngx_int_t ngx_ssl_eccurve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t
*named_curve);
 ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
     ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t
timeout);
 ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t
*c,
diff -rupN nginx-0.8.54/src/http/modules/ngx_http_ssl_module.c
nginx-0.8.54p/src/http/modules/ngx_http_ssl_module.c
--- nginx-0.8.54/src/http/modules/ngx_http_ssl_module.c	2010-05-14
12:56:37.000000000 +0300
+++ nginx-0.8.54p/src/http/modules/ngx_http_ssl_module.c	2011-01-04
16:06:10.000000000 +0200
@@ -77,7 +77,14 @@ static ngx_command_t  ngx_http_ssl_comma
       NGX_HTTP_SRV_CONF_OFFSET,
       offsetof(ngx_http_ssl_srv_conf_t, dhparam),
       NULL },
-
+    
+    { ngx_string("ssl_eccurve"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_str_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_ssl_srv_conf_t, eccurve),
+      NULL },
+      
     { ngx_string("ssl_protocols"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
       ngx_conf_set_bitmask_slot,
@@ -312,6 +319,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t
      *     sscf->certificate = { 0, NULL };
      *     sscf->certificate_key = { 0, NULL };
      *     sscf->dhparam = { 0, NULL };
+     *     sscf->eccurve = { 0, NULL };
      *     sscf->client_certificate = { 0, NULL };
      *     sscf->crl = { 0, NULL };
      *     sscf->ciphers = { 0, NULL };
@@ -356,6 +364,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *
 
     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
 
+    ngx_conf_merge_str_value(conf->eccurve, prev->eccurve, "");
+
     ngx_conf_merge_str_value(conf->client_certificate,
prev->client_certificate,
                          "");
     ngx_conf_merge_str_value(conf->crl, prev->crl, "");
@@ -473,6 +483,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *
         return NGX_CONF_ERROR;
     }
 
+    if (ngx_ssl_eccurve(cf, &conf->ssl, &conf->eccurve) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+    
     ngx_conf_merge_value(conf->builtin_session_cache,
                          prev->builtin_session_cache,
NGX_SSL_NONE_SCACHE);
 
diff -rupN nginx-0.8.54/src/http/modules/ngx_http_ssl_module.h
nginx-0.8.54p/src/http/modules/ngx_http_ssl_module.h
--- nginx-0.8.54/src/http/modules/ngx_http_ssl_module.h	2009-07-23
15:21:26.000000000 +0300
+++ nginx-0.8.54p/src/http/modules/ngx_http_ssl_module.h	2011-01-04
15:41:00.000000000 +0200
@@ -32,6 +32,7 @@ typedef struct {
     ngx_str_t                       certificate;
     ngx_str_t                       certificate_key;
     ngx_str_t                       dhparam;
+    ngx_str_t                       eccurve;
     ngx_str_t                       client_certificate;
     ngx_str_t                       crl;
 
diff -rupN nginx-0.8.54/src/mail/ngx_mail_ssl_module.c
nginx-0.8.54p/src/mail/ngx_mail_ssl_module.c
--- nginx-0.8.54/src/mail/ngx_mail_ssl_module.c	2010-05-14
12:56:37.000000000 +0300
+++ nginx-0.8.54p/src/mail/ngx_mail_ssl_module.c	2011-01-04
14:55:00.000000000 +0200
@@ -77,6 +77,13 @@ static ngx_command_t  ngx_mail_ssl_comma
       offsetof(ngx_mail_ssl_conf_t, dhparam),
       NULL },
 
+    { ngx_string("ssl_eccurve"),
+      NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_str_slot,
+      NGX_MAIL_SRV_CONF_OFFSET,
+      offsetof(ngx_mail_ssl_conf_t, eccurve),
+      NULL },
+    
     { ngx_string("ssl_protocols"),
       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
       ngx_conf_set_bitmask_slot,
@@ -163,6 +170,7 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf)
      *     scf->certificate = { 0, NULL };
      *     scf->certificate_key = { 0, NULL };
      *     scf->dhparam = { 0, NULL };
+     *     scf->eccurve = { 0, NULL };
      *     scf->ciphers = { 0, NULL };
      *     scf->shm_zone = NULL;
      */
@@ -204,6 +212,8 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf,
 
     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
 
+    ngx_conf_merge_str_value(conf->eccurve, prev->eccurve, "");
+
     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers,
NGX_DEFAULT_CIPHERS);
 
 
@@ -294,6 +304,10 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf,
         return NGX_CONF_ERROR;
     }
 
+    if (ngx_ssl_eccurve(cf, &conf->ssl, &conf->eccurve) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
     ngx_conf_merge_value(conf->builtin_session_cache,
                          prev->builtin_session_cache,
NGX_SSL_NONE_SCACHE);
 
diff -rupN nginx-0.8.54/src/mail/ngx_mail_ssl_module.h
nginx-0.8.54p/src/mail/ngx_mail_ssl_module.h
--- nginx-0.8.54/src/mail/ngx_mail_ssl_module.h	2008-09-01
17:19:01.000000000 +0300
+++ nginx-0.8.54p/src/mail/ngx_mail_ssl_module.h	2011-01-04
14:49:00.000000000 +0200
@@ -34,6 +34,7 @@ typedef struct {
     ngx_str_t        certificate;
     ngx_str_t        certificate_key;
     ngx_str_t        dhparam;
+    ngx_str_t        eccurve;
 
     ngx_str_t        ciphers;
 
[/code]

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,107166,163401#msg-163401




More information about the nginx mailing list