]> git.kaiwu.me - nginx.git/commitdiff
SSL: $ssl_curves (ticket #1088).
authorMaxim Dounin <mdounin@mdounin.ru>
Mon, 5 Dec 2016 19:23:23 +0000 (22:23 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Mon, 5 Dec 2016 19:23:23 +0000 (22:23 +0300)
The variable contains a list of curves as supported by the client.
Known curves are listed by their names, unknown ones are shown
in hex, e.g., "0x001d:prime256v1:secp521r1:secp384r1".

Note that OpenSSL uses session data for SSL_get1_curves(), and
it doesn't store full list of curves supported by the client when
serializing a session.  As a result $ssl_curves is only available
for new sessions (and will be empty for reused ones).

The variable is only meaningful when using OpenSSL 1.0.2 and above.
With older versions the variable is empty.

src/event/ngx_event_openssl.c
src/event/ngx_event_openssl.h
src/http/modules/ngx_http_ssl_module.c
src/stream/ngx_stream_ssl_module.c

index b9ccf7631e4d4dfff875073309c32aa903bbcc7e..1b39f33c2f67b4722dd9b221d3de392d7feab2fd 100644 (file)
@@ -3377,6 +3377,74 @@ ngx_ssl_get_ciphers(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
 }
 
 
+ngx_int_t
+ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
+{
+#ifdef SSL_CTRL_GET_CURVES
+
+    int         *curves, n, i, nid;
+    u_char      *p;
+    size_t       len;
+
+    n = SSL_get1_curves(c->ssl->connection, NULL);
+
+    if (n <= 0) {
+        s->len = 0;
+        return NGX_OK;
+    }
+
+    curves = ngx_palloc(pool, n * sizeof(int));
+
+    n = SSL_get1_curves(c->ssl->connection, curves);
+    len = 0;
+
+    for (i = 0; i < n; i++) {
+        nid = curves[i];
+
+        if (nid & TLSEXT_nid_unknown) {
+            len += sizeof("0x0000") - 1;
+
+        } else {
+            len += ngx_strlen(OBJ_nid2sn(nid));
+        }
+
+        len += sizeof(":") - 1;
+    }
+
+    s->data = ngx_pnalloc(pool, len);
+    if (s->data == NULL) {
+        return NGX_ERROR;
+    }
+
+    p = s->data;
+
+    for (i = 0; i < n; i++) {
+        nid = curves[i];
+
+        if (nid & TLSEXT_nid_unknown) {
+            p = ngx_sprintf(p, "0x%04xd", nid & 0xffff);
+
+        } else {
+            p = ngx_sprintf(p, "%s", OBJ_nid2sn(nid));
+        }
+
+        *p++ = ':';
+    }
+
+    p--;
+
+    s->len = p - s->data;
+
+#else
+
+    s->len = 0;
+
+#endif
+
+    return NGX_OK;
+}
+
+
 ngx_int_t
 ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
 {
index e2b6f4863fb22cc46f88c64a9226d5fc925546e9..c0223070cc4585683181a7d9e4fc080a8a1ac42e 100644 (file)
@@ -193,6 +193,8 @@ ngx_int_t ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool,
     ngx_str_t *s);
 ngx_int_t ngx_ssl_get_ciphers(ngx_connection_t *c, ngx_pool_t *pool,
     ngx_str_t *s);
+ngx_int_t ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool,
+    ngx_str_t *s);
 ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool,
     ngx_str_t *s);
 ngx_int_t ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool,
index 24540a89385451ed744200142cef8f5cf03be3b5..2771ac1f68c7d2f33f50ab11aae0901deea5a8a5 100644 (file)
@@ -279,6 +279,9 @@ static ngx_http_variable_t  ngx_http_ssl_vars[] = {
     { ngx_string("ssl_ciphers"), NULL, ngx_http_ssl_variable,
       (uintptr_t) ngx_ssl_get_ciphers, NGX_HTTP_VAR_CHANGEABLE, 0 },
 
+    { ngx_string("ssl_curves"), NULL, ngx_http_ssl_variable,
+      (uintptr_t) ngx_ssl_get_curves, NGX_HTTP_VAR_CHANGEABLE, 0 },
+
     { ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable,
       (uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 },
 
index 39ecc51f347ac22a0fd07998f2ad3761498f6989..9191641d1254918e8f27a5ee9f6cb5ca31bc4cb4 100644 (file)
@@ -185,6 +185,9 @@ static ngx_stream_variable_t  ngx_stream_ssl_vars[] = {
     { ngx_string("ssl_ciphers"), NULL, ngx_stream_ssl_variable,
       (uintptr_t) ngx_ssl_get_ciphers, NGX_STREAM_VAR_CHANGEABLE, 0 },
 
+    { ngx_string("ssl_curves"), NULL, ngx_stream_ssl_variable,
+      (uintptr_t) ngx_ssl_get_curves, NGX_STREAM_VAR_CHANGEABLE, 0 },
+
     { ngx_string("ssl_session_id"), NULL, ngx_stream_ssl_variable,
       (uintptr_t) ngx_ssl_get_session_id, NGX_STREAM_VAR_CHANGEABLE, 0 },