]> git.kaiwu.me - nginx.git/commitdiff
ECDHE support
authorIgor Sysoev <igor@sysoev.ru>
Wed, 20 Jul 2011 15:42:40 +0000 (15:42 +0000)
committerIgor Sysoev <igor@sysoev.ru>
Wed, 20 Jul 2011 15:42:40 +0000 (15:42 +0000)
patch by Adrian Kotelba

src/event/ngx_event_openssl.c
src/event/ngx_event_openssl.h
src/http/modules/ngx_http_ssl_module.c
src/http/modules/ngx_http_ssl_module.h
src/mail/ngx_mail_ssl_module.c
src/mail/ngx_mail_ssl_module.h

index a12672583279345ddaf76da528f870483dec49fb..a833640272552d2234be8bbe202cba296deab718 100644 (file)
@@ -468,6 +468,45 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
     return NGX_OK;
 }
 
+ngx_int_t
+ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
+#ifndef OPENSSL_NO_ECDH
+    int      nid;
+    EC_KEY  *ecdh;
+
+    /*
+     * 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);
+
+    SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE);
+
+    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)
index d564e5d9b932edddd7dcbc6450fcdbe1afa594b5..204d5f08ed45c4fb42e324b2b465931a1896d5d5 100644 (file)
@@ -101,6 +101,7 @@ ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
 ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl);
 RSA *ngx_ssl_rsa512_key_callback(SSL *ssl, int is_export, int key_length);
 ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
+ngx_int_t ngx_ssl_ecdh_curve(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,
index 52c9196ce40c2ab43b4a6cb89aba95efaee71048..120a858dfc50a773fdd5e98fbbe15ded1026a940 100644 (file)
@@ -13,7 +13,8 @@ typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
     ngx_pool_t *pool, ngx_str_t *s);
 
 
-#define NGX_DEFAULT_CIPHERS  "HIGH:!aNULL:!MD5"
+#define NGX_DEFAULT_CIPHERS     "HIGH:!aNULL:!MD5"
+#define NGX_DEFAULT_ECDH_CURVE  "prime256v1"
 
 
 static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
@@ -78,6 +79,13 @@ static ngx_command_t  ngx_http_ssl_commands[] = {
       offsetof(ngx_http_ssl_srv_conf_t, dhparam),
       NULL },
 
+    { ngx_string("ssl_ecdh_curve"),
+      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, ecdh_curve),
+      NULL },
+
     { ngx_string("ssl_protocols"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
       ngx_conf_set_bitmask_slot,
@@ -312,6 +320,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
      *     sscf->certificate = { 0, NULL };
      *     sscf->certificate_key = { 0, NULL };
      *     sscf->dhparam = { 0, NULL };
+     *     sscf->ecdh_curve = { 0, NULL };
      *     sscf->client_certificate = { 0, NULL };
      *     sscf->crl = { 0, NULL };
      *     sscf->ciphers = { 0, NULL };
@@ -360,6 +369,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
                          "");
     ngx_conf_merge_str_value(conf->crl, prev->crl, "");
 
+    ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
+                         NGX_DEFAULT_ECDH_CURVE);
+
     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
 
 
@@ -471,6 +483,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
         return NGX_CONF_ERROR;
     }
 
+    if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
     ngx_conf_merge_value(conf->builtin_session_cache,
                          prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);
 
index 29eedc8aeb8c869cc76da41a31fcc295835b4ba2..0a5dd1d8d3526dca15bbf8974b0f36e7bda958f7 100644 (file)
@@ -32,6 +32,7 @@ typedef struct {
     ngx_str_t                       certificate;
     ngx_str_t                       certificate_key;
     ngx_str_t                       dhparam;
+    ngx_str_t                       ecdh_curve;
     ngx_str_t                       client_certificate;
     ngx_str_t                       crl;
 
index da91d37ce8df2306061cce365cfacc4b02bb865d..5767a2fd4103bc62335b81c9295a65d0fda4b7d3 100644 (file)
@@ -9,7 +9,8 @@
 #include <ngx_mail.h>
 
 
-#define NGX_DEFAULT_CIPHERS  "HIGH:!aNULL:!MD5"
+#define NGX_DEFAULT_CIPHERS     "HIGH:!aNULL:!MD5"
+#define NGX_DEFAULT_ECDH_CURVE  "prime256v1"
 
 
 static void *ngx_mail_ssl_create_conf(ngx_conf_t *cf);
@@ -77,6 +78,13 @@ static ngx_command_t  ngx_mail_ssl_commands[] = {
       offsetof(ngx_mail_ssl_conf_t, dhparam),
       NULL },
 
+    { ngx_string("ssl_ecdh_curve"),
+      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, ecdh_curve),
+      NULL },
+
     { ngx_string("ssl_protocols"),
       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
       ngx_conf_set_bitmask_slot,
@@ -163,6 +171,7 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf)
      *     scf->certificate = { 0, NULL };
      *     scf->certificate_key = { 0, NULL };
      *     scf->dhparam = { 0, NULL };
+     *     scf->ecdh_curve = { 0, NULL };
      *     scf->ciphers = { 0, NULL };
      *     scf->shm_zone = NULL;
      */
@@ -204,6 +213,9 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
 
     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
 
+    ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
+                         NGX_DEFAULT_ECDH_CURVE);
+
     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
 
 
index b27da41d976c5f8640039ec0a0c15509336457a7..61a275b36f54f5ec9874e2a083fb92e2249cc0fa 100644 (file)
@@ -34,6 +34,7 @@ typedef struct {
     ngx_str_t        certificate;
     ngx_str_t        certificate_key;
     ngx_str_t        dhparam;
+    ngx_str_t        ecdh_curve;
 
     ngx_str_t        ciphers;