summaryrefslogtreecommitdiffhomepage
path: root/src/event/ngx_event_openssl.c
diff options
context:
space:
mode:
authorSergey Kandaurov <pluknet@nginx.com>2018-07-17 12:53:23 +0300
committerSergey Kandaurov <pluknet@nginx.com>2018-07-17 12:53:23 +0300
commitd5a27006e03174aa518f6c849d377a130a7c705c (patch)
treeea8b041547925ace0f5876b28102942ce34246eb /src/event/ngx_event_openssl.c
parente1bebd05cb75fa6e8be5f4f942028501c9b22821 (diff)
downloadnginx-d5a27006e03174aa518f6c849d377a130a7c705c.tar.gz
nginx-d5a27006e03174aa518f6c849d377a130a7c705c.tar.bz2
SSL: save sessions for upstream peers using a callback function.
In TLSv1.3, NewSessionTicket messages arrive after the handshake and can come at any time. Therefore we use a callback to save the session when we know about it. This approach works for < TLSv1.3 as well. The callback function is set once per location on merge phase. Since SSL_get_session() in BoringSSL returns an unresumable session for TLSv1.3, peer save_session() methods have been updated as well to use a session supplied within the callback. To preserve API, the session is cached in c->ssl->session. It is preferably accessed in save_session() methods by ngx_ssl_get_session() and ngx_ssl_get0_session() wrappers.
Diffstat (limited to 'src/event/ngx_event_openssl.c')
-rw-r--r--src/event/ngx_event_openssl.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 04b092305..96ee10543 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -24,6 +24,8 @@ static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where,
int ret);
static void ngx_ssl_passwords_cleanup(void *data);
+static int ngx_ssl_new_client_session(ngx_ssl_conn_t *ssl_conn,
+ ngx_ssl_session_t *sess);
static void ngx_ssl_handshake_handler(ngx_event_t *ev);
static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n);
static void ngx_ssl_write_handler(ngx_event_t *wev);
@@ -1162,6 +1164,42 @@ ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
ngx_int_t
+ngx_ssl_client_session_cache(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_uint_t enable)
+{
+ if (!enable) {
+ return NGX_OK;
+ }
+
+ SSL_CTX_set_session_cache_mode(ssl->ctx,
+ SSL_SESS_CACHE_CLIENT
+ |SSL_SESS_CACHE_NO_INTERNAL);
+
+ SSL_CTX_sess_set_new_cb(ssl->ctx, ngx_ssl_new_client_session);
+
+ return NGX_OK;
+}
+
+
+static int
+ngx_ssl_new_client_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
+{
+ ngx_connection_t *c;
+
+ c = ngx_ssl_get_connection(ssl_conn);
+
+ if (c->ssl->save_session) {
+ c->ssl->session = sess;
+
+ c->ssl->save_session(c);
+
+ c->ssl->session = NULL;
+ }
+
+ return 0;
+}
+
+
+ngx_int_t
ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
{
ngx_ssl_connection_t *sc;
@@ -1210,6 +1248,31 @@ ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
}
+ngx_ssl_session_t *
+ngx_ssl_get_session(ngx_connection_t *c)
+{
+#ifdef TLS1_3_VERSION
+ if (c->ssl->session) {
+ SSL_SESSION_up_ref(c->ssl->session);
+ return c->ssl->session;
+ }
+#endif
+
+ return SSL_get1_session(c->ssl->connection);
+}
+
+
+ngx_ssl_session_t *
+ngx_ssl_get0_session(ngx_connection_t *c)
+{
+ if (c->ssl->session) {
+ return c->ssl->session;
+ }
+
+ return SSL_get0_session(c->ssl->connection);
+}
+
+
ngx_int_t
ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session)
{