ECDHE key exchange with TLSv1

Does Nginx support the elliptic curve cryptography ciphers like
ECDHE-ECDSA-AES256-SHA available through OpenSSL v1.0.0a ?

I have built OpenSSL v1.0.0a and placed it in a separate directory. I
then built nginx with --with-cc-opt=“-I /path_openssl/include/”
–with-ld-opt=“-L /path_openssl/lib/” and it builds fine.

Nginx.conf has the following for SSL:

 ## SSL Certs
  ssl on;
  ssl_certificate /ssl/host.com_ssl.crt;
  ssl_certificate_key /ssl/host_ssl.key;
  ssl_ciphers ECDHE-ECDSA-AES256-SHA:AES256-SHA;
 #ssl_dhparam /ssl/host_dh.pem;
  ssl_prefer_server_ciphers on;
  ssl_protocols TLSv1;
  ssl_session_cache shared:SSL:1m;
  ssl_session_timeout 5m;

The daemon starts up correctly, but clients will only negotiate their
SSL connection as AES256-SHA.

Does “ssl_dhparam” need a PEM string? Any examples?

BTW, I found another post in the archives where Maxim D. said
support was not available as of October 2009.

Build error --with-debug; ECDHE key exchange TLS problem.[nginx 0.7.62]


Calomel @ https://calomel.org
Open Source Research and Reference

I tried a few variations to get ECC keys working with Nginx. Most
likely Nginx does not yet support ECC key exchanges yet.

Firefox, Chrome, Safari and IE8 do support ECC ciphers. The
about:config in Firefox shows “security.ssl3.ecdhe_ecdsa_aes_256_sha”
for example.

For future reference,

The build environment:
Nginx v0.8.45 (built and linked against openssl v1.0.0.a)
Openssl v1.0.0.a

The ECC ciphers are available according to the cipher list:
openssl ciphers -tls1 -v ‘HIGH:!ADH:!MD5:@STRENGTH’ | grep 256 | grep
ECDH
ECDHE-RSA-AES256-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1
ECDHE-ECDSA-AES256-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1
AECDH-AES256-SHA SSLv3 Kx=ECDH Au=None Enc=AES(256) Mac=SHA1
ECDH-RSA-AES256-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(256) Mac=SHA1
ECDH-ECDSA-AES256-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256) Mac=SHA1

I am not sure if this is right format for Nginx and the ssl_dhparam
directive, but I was able to generate a ECC key using:
openssl ecparam -genkey -name secp521r1 -out eckey.pem | /
openssl ec -aes128 -out EC-newkey.pem

This is the s_client test used from another machine also using openssl
v1.0.0.a:
openssl s_client -connect hostname.com:443 -cipher
ECDHE-ECDSA-AES256-SHA

Anyone is interested in more information about ECC could start with,
Elliptical Curves suggest the most modern concepts of cryptography
http://blog.taragana.com/index.php/archive/mathematical-theory-of-elliptic-curves-may-help-strengthen-it-security/

If anyone sees a problem or has a solution to this setup please mail
me. Igor, I would be happy to do any tests.


Calomel @ https://calomel.org
Open Source Research and Reference

Hello!

On Fri, Jul 09, 2010 at 04:03:55PM -0400, Calomel Org wrote:

Does Nginx support the elliptic curve cryptography ciphers like
ECDHE-ECDSA-AES256-SHA available through OpenSSL v1.0.0a ?

No.

[…]

Does “ssl_dhparam” need a PEM string? Any examples?

It needs file name, but it’s for DH params, not ECDH.

BTW, I found another post in the archives where Maxim D. said
support was not available as of October 2009.

Build error --with-debug; ECDHE key exchange TLS problem.[nginx 0.7.62]
Build error --with-debug; ECDHE key exchange TLS problem. [nginx 0.7.62]

This message still applies.

Maxim D.

Hello!

On Tue, Jan 04, 2011 at 10:34:07AM -0500, timo2 wrote:

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).

You may want to use nginx-devel@ (cc’d) mailing list instead, and
use latest development version (0.9.3) for patches (it’s very
close, but just to be sure).

Most serious problem with the patch is it won’t compile with older
OpenSSL versions: nginx is currently expected to compile with
OpenSSL 0.9.7+.

As this patch uses OpenSSL 1.0.0+ only functions / data types - it
should be guarded with appropriate preprocessor / configure
checks.

Some minor problems are noted below.

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.

It looks like OpenSSL’s s_server as well as Apache defaults to
nistp256 aka secp256r1. Any specific reasons for secp224r1?

+ngx_int_t
+ngx_ssl_eccurve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t
*named_curve)

Using “name” instead of “named_curve” probably would be better
here.

  • EC_KEY *ecdh=NULL;

Any reason why this should be initialized to NULL?.. (1)

  • int nid;
  • if (named_curve->len) {

It’s probably good idea to reverse this check to be in line with
ngx_ssl_dhparam().

  •    nid = OBJ_sn2nid( (const char *) named_curve->data);
    

Casting to “const” isn’t needed, only to “char *”. Using space in
“( (” isn’t needed as well (style).

  •    if (nid == 0) {
    
  •        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "Unknown curve
    

name (%s)\n", named_curve->data);

No need to use “\n”. Applies to other places as well.

  •        EC_KEY_free(ecdh);
    

(1) … and this call EC_KEY_free(), while we are perfectly sure
we don’t have anything usefull in 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);
    

The same here. We know for sure ecdh is NULL.

  • 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);
    

And here.

ngx_int_t
ngx_int_t ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl);
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 },

Unrelated whitespace change.

  • { 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 },
    

Trailing spaces.

  *     sscf->ciphers = { 0, NULL };

@@ -473,6 +483,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *

  • ngx_str_t eccurve;
    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 },
    

Trailing spaces.

  */

@@ -294,6 +304,10 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf,

  • ngx_str_t eccurve;

    ngx_str_t ciphers;

Otherwise looks good, thank you for your patch. Please resubmit
with fixes to nginx-devel@.

Maxim D.

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.

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;

Posted at Nginx Forum:

Hello,

Updated patch

diff -rupN nginx-0.9.3/src/event/ngx_event_openssl.c
nginx-0.9.3p/src/event/ngx_event_openssl.c
--- nginx-0.9.3/src/event/ngx_event_openssl.c  2011-01-05
20:38:18.000000000 +0200
+++ nginx-0.9.3p/src/event/ngx_event_openssl.c  2011-01-05
20:33:55.000000000 +0200
@@ -478,6 +478,42 @@ 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 *name)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
+#ifndef OPENSSL_NO_ECDH
+    EC_KEY *ecdh;
+    int  nid;
+
+    /*
+     * Elliptic-Curve Diffie-Hellman parameters are either "named
curves"
+     * from RFC 4492 section 5.1.1, or explicitely described curves
over
+     * binary fields. OpenSSL only supports the "named curves", which
provide
+     * maximum interoperability.
+     */
+
+    nid = OBJ_sn2nid((const char *)name->data);
+    if (nid == 0) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "Unknown curve name (%s)", name->data);
+        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)", name->data);
+        return NGX_ERROR;
+    }
+
+    SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
+
+    EC_KEY_free(ecdh);
+#endif
+#endif
+    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.9.3/src/event/ngx_event_openssl.h
nginx-0.9.3p/src/event/ngx_event_openssl.h
--- nginx-0.9.3/src/event/ngx_event_openssl.h  2011-01-05
20:38:16.000000000 +0200
+++ nginx-0.9.3p/src/event/ngx_event_openssl.h  2011-01-05
20:33:53.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
*name);
 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.9.3/src/http/modules/ngx_http_ssl_module.c
nginx-0.9.3p/src/http/modules/ngx_http_ssl_module.c
--- nginx-0.9.3/src/http/modules/ngx_http_ssl_module.c  2011-01-05
20:38:28.000000000 +0200
+++ nginx-0.9.3p/src/http/modules/ngx_http_ssl_module.c  2011-01-05
21:15:29.000000000 +0200
@@ -14,7 +14,7 @@ typedef ngx_int_t (*ngx_ssl_variable_han


 #define NGX_DEFAULT_CIPHERS  "HIGH:!ADH:!MD5"
-
+#define NGX_DEFAULT_ECCURVE  "prime256v1"

 static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
@@ -78,6 +78,13 @@ static ngx_command_t  ngx_http_ssl_comma
       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 };
@@ -360,6 +368,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *
                          "");
     ngx_conf_merge_str_value(conf->crl, prev->crl, "");

+    ngx_conf_merge_str_value(conf->eccurve, prev->eccurve,
NGX_DEFAULT_ECCURVE);
+
     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers,
NGX_DEFAULT_CIPHERS);


@@ -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.9.3/src/http/modules/ngx_http_ssl_module.h
nginx-0.9.3p/src/http/modules/ngx_http_ssl_module.h
--- nginx-0.9.3/src/http/modules/ngx_http_ssl_module.h  2011-01-05
20:38:37.000000000 +0200
+++ nginx-0.9.3p/src/http/modules/ngx_http_ssl_module.h  2011-01-05
20:34:16.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.9.3/src/mail/ngx_mail_ssl_module.c
nginx-0.9.3p/src/mail/ngx_mail_ssl_module.c
--- nginx-0.9.3/src/mail/ngx_mail_ssl_module.c  2011-01-05
20:37:52.000000000 +0200
+++ nginx-0.9.3p/src/mail/ngx_mail_ssl_module.c  2011-01-05
20:33:43.000000000 +0200
@@ -10,7 +10,7 @@


 #define NGX_DEFAULT_CIPHERS  "HIGH:!ADH:!MD5"
-
+#define NGX_DEFAULT_ECCURVE  "prime256v1"

 static void *ngx_mail_ssl_create_conf(ngx_conf_t *cf);
 static char *ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void
*child);
@@ -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_DEFAULT_ECCURVE);
+
     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers,
NGX_DEFAULT_CIPHERS);


diff -rupN nginx-0.9.3/src/mail/ngx_mail_ssl_module.h
nginx-0.9.3p/src/mail/ngx_mail_ssl_module.h
--- nginx-0.9.3/src/mail/ngx_mail_ssl_module.h  2011-01-05
20:37:52.000000000 +0200
+++ nginx-0.9.3p/src/mail/ngx_mail_ssl_module.h  2011-01-05
20:33:43.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;

Topic continues in Re: ECDHE key exchange with TLSv1

Posted at Nginx Forum: