changeset 8586:7621ffaa79b3 quic

SSL: added the "ssl_keys_file" directive.
author Vladimir Homutov <vl@nginx.com>
date Tue, 15 Sep 2020 22:44:46 +0300
parents 02ee77f8d53d
children 61f1c6ac8967
files 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
diffstat 4 files changed, 72 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -255,6 +255,50 @@ ngx_ssl_init(ngx_log_t *log)
 }
 
 
+void
+ngx_ssl_keylogger(const ngx_ssl_conn_t *ssl_conn, const char *line)
+{
+    u_char                *p;
+    size_t                 len;
+    ssize_t                n;
+    ngx_connection_t      *c;
+    ngx_ssl_connection_t  *sc;
+
+    if (line == NULL) {
+        return;
+    }
+
+    len = ngx_strlen(line);
+
+    if (len == 0) {
+        return;
+    }
+
+    c = ngx_ssl_get_connection(ssl_conn);
+    sc = c->ssl;
+
+    p = ngx_alloc(len + 1, c->log);
+    if (p == NULL) {
+        return;
+    }
+
+    ngx_memcpy(p, line, len);
+    p[len] = '\n';
+
+    n = ngx_write_fd(sc->keylog->fd, p, len + 1);
+    if (n == -1) {
+        ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
+                      ngx_write_fd_n " to \"%s\" failed",
+                      sc->keylog->name.data);
+
+    } else if ((size_t) n != len + 1) {
+        ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                      ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
+                      sc->keylog->name.data, n, len + 1);
+    }
+}
+
+
 ngx_int_t
 ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
 {
@@ -1516,6 +1560,8 @@ ngx_ssl_create_connection(ngx_ssl_t *ssl
         return NGX_ERROR;
     }
 
+    sc->keylog = ssl->keylog;
+
     sc->buffer = ((flags & NGX_SSL_BUFFER) != 0);
     sc->buffer_size = ssl->buffer_size;
 
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -78,6 +78,7 @@ struct ngx_ssl_s {
     SSL_CTX                    *ctx;
     ngx_log_t                  *log;
     size_t                      buffer_size;
+    ngx_open_file_t            *keylog;
 };
 
 
@@ -100,6 +101,7 @@ struct ngx_ssl_connection_s {
     ngx_ssl_ocsp_t             *ocsp;
 
     u_char                      early_buf;
+    ngx_open_file_t            *keylog;
 
     unsigned                    handshaked:1;
     unsigned                    renegotiation:1;
@@ -296,6 +298,7 @@ ngx_int_t ngx_ssl_shutdown(ngx_connectio
 void ngx_cdecl ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
     char *fmt, ...);
 void ngx_ssl_cleanup_ctx(void *data);
+void ngx_ssl_keylogger(const ngx_ssl_conn_t *ssl, const char *line);
 
 
 extern int  ngx_ssl_connection_index;
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -119,6 +119,13 @@ static ngx_command_t  ngx_http_ssl_comma
       0,
       NULL },
 
+    { ngx_string("ssl_keys_file"),
+      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, keys_file),
+      NULL },
+
     { ngx_string("ssl_dhparam"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_str_slot,
@@ -605,6 +612,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t 
      *     sscf->trusted_certificate = { 0, NULL };
      *     sscf->crl = { 0, NULL };
      *     sscf->ciphers = { 0, NULL };
+     *     sscf->keys_file = { 0, NULL };
      *     sscf->shm_zone = NULL;
      *     sscf->ocsp_responder = { 0, NULL };
      *     sscf->stapling_file = { 0, NULL };
@@ -676,6 +684,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *
 
     ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);
 
+    ngx_conf_merge_str_value(conf->keys_file, prev->keys_file, "");
+
     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
 
     ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
@@ -912,6 +922,17 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *
         return NGX_CONF_ERROR;
     }
 
+    if (conf->keys_file.len) {
+
+        conf->ssl.keylog = ngx_conf_open_file(cf->cycle, &conf->keys_file);
+
+        if (conf->ssl.keylog == NULL) {
+            return NGX_CONF_ERROR;
+        }
+
+        SSL_CTX_set_keylog_callback(conf->ssl.ctx, ngx_ssl_keylogger);
+    }
+
     if (conf->stapling) {
 
         if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
--- a/src/http/modules/ngx_http_ssl_module.h
+++ b/src/http/modules/ngx_http_ssl_module.h
@@ -36,6 +36,8 @@ typedef struct {
     ngx_array_t                    *certificates;
     ngx_array_t                    *certificate_keys;
 
+    ngx_str_t                       keys_file;
+
     ngx_array_t                    *certificate_values;
     ngx_array_t                    *certificate_key_values;