Skip to content

Commit

Permalink
feat(tls) add function disable_session_reuse for disabling TLS sess…
Browse files Browse the repository at this point in the history
…ion reuse when handshaking with client
  • Loading branch information
dndx authored May 13, 2019
1 parent 2d67721 commit be6960e
Show file tree
Hide file tree
Showing 5 changed files with 647 additions and 248 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ in later phases.
This function returns `true` when the call is successful. Otherwise it returns
`nil` and a string describing the error.

resty.kong.tls.disable\_session\_reuse
--------------------------------------
**syntax:** *succ, err = resty.kong.tls.disable\_session\_reuse()*

**context:** *ssl_certificate_by_lua**

Prevents the TLS session for the current connection from being reused by
disabling session ticket and session ID for the current TLS connection.

This function returns `true` when the call is successful. Otherwise it returns
`nil` and a string describing the error.


resty.kong.tls.get\_full\_client\_certificate\_chain
-------------------------------------------
Expand Down
23 changes: 20 additions & 3 deletions lualib/resty/kong/tls.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ base.allows_subsystem('http')


ffi.cdef([[
const char *ngx_http_lua_kong_ffi_request_client_certificate(
ngx_http_request_t *r);
const char *ngx_http_lua_kong_ffi_request_client_certificate(ngx_http_request_t *r);
int ngx_http_lua_kong_ffi_get_full_client_certificate_chain(
ngx_http_request_t *r, char *buf, size_t *buf_len);
const char *ngx_http_lua_kong_ffi_disable_session_reuse(ngx_http_request_t *r);
]])


Expand All @@ -46,7 +46,7 @@ local NGX_DONE = ngx.DONE
local NGX_DECLINED = ngx.DECLINED


function _M.request_client_certificate()
function _M.request_client_certificate(no_session_reuse)
if get_phase() ~= 'ssl_cert' then
error("API disabled in the current context")
end
Expand All @@ -63,6 +63,23 @@ function _M.request_client_certificate()
return nil, ffi_string(errmsg)
end


function _M.disable_session_reuse()
if get_phase() ~= 'ssl_cert' then
error("API disabled in the current context")
end

local r = getfenv(0).__ngx_req

local errmsg = C.ngx_http_lua_kong_ffi_disable_session_reuse(r)
if errmsg == nil then
return true
end

return nil, ffi_string(errmsg)
end


do
local ALLOWED_PHASES = {
['rewrite'] = true,
Expand Down
120 changes: 119 additions & 1 deletion src/ngx_http_lua_kong_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,19 @@


#if (NGX_SSL)
static int ngx_http_lua_kong_ssl_old_sess_new_cb_index = -1;
static int ngx_http_lua_kong_ssl_no_session_cache_flag_index = -1;


static int
ngx_http_lua_kong_verify_callback(int ok, X509_STORE_CTX *x509_store);
#endif
static ngx_int_t ngx_http_lua_kong_init(ngx_conf_t *cf);


static ngx_http_module_t ngx_http_lua_kong_module_ctx = {
NULL, /* preconfiguration */
NULL, /* postconfiguration */
ngx_http_lua_kong_init, /* postconfiguration */

NULL, /* create main configuration */
NULL, /* init main configuration */
Expand Down Expand Up @@ -57,6 +62,37 @@ ngx_module_t ngx_http_lua_kong_module = {
};


static ngx_int_t
ngx_http_lua_kong_init(ngx_conf_t *cf)
{
#if (NGX_SSL)
if (ngx_http_lua_kong_ssl_old_sess_new_cb_index == -1) {
ngx_http_lua_kong_ssl_old_sess_new_cb_index =
SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);

if (ngx_http_lua_kong_ssl_old_sess_new_cb_index == -1) {
ngx_ssl_error(NGX_LOG_ALERT, cf->log, 0,
"kong: SSL_CTX_get_ex_new_index() for ssl ctx failed");
return NGX_ERROR;
}
}

if (ngx_http_lua_kong_ssl_no_session_cache_flag_index == -1) {
ngx_http_lua_kong_ssl_no_session_cache_flag_index =
SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);

if (ngx_http_lua_kong_ssl_no_session_cache_flag_index == -1) {
ngx_ssl_error(NGX_LOG_ALERT, cf->log, 0,
"kong: SSL_get_ex_new_index() for ssl failed");
return NGX_ERROR;
}
}
#endif

return NGX_OK;
}


#if (NGX_SSL)
static int
ngx_http_lua_kong_verify_callback(int ok, X509_STORE_CTX *x509_store)
Expand All @@ -65,9 +101,90 @@ ngx_http_lua_kong_verify_callback(int ok, X509_STORE_CTX *x509_store)
* to conclude before deciding the validity of client certificate */
return 1;
}


static int
ngx_http_lua_kong_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
{
ngx_uint_t flag;

flag = (ngx_uint_t) SSL_get_ex_data(ssl_conn,
ngx_http_lua_kong_ssl_no_session_cache_flag_index);

if (flag) {
return 0;
}

return ((int (*)(SSL *ssl, SSL_SESSION *sess))
SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl_conn),
ngx_http_lua_kong_ssl_old_sess_new_cb_index))(ssl_conn,
sess);
}
#endif


/*
* disables session reuse for the current TLS connection, must be called
* in ssl_certby_lua* phase
*/

const char *
ngx_http_lua_kong_ffi_disable_session_reuse(ngx_http_request_t *r)
{
#if (NGX_SSL)
ngx_uint_t flag;
ngx_connection_t *c = r->connection;
ngx_ssl_conn_t *sc;
SSL_CTX *ctx;

if (c->ssl == NULL) {
return "server does not have TLS enabled";
}

sc = c->ssl->connection;

/* the following disables session ticket for the current connection */
SSL_set_options(sc, SSL_OP_NO_TICKET);

/* the following disables session cache for the current connection
* note that we are using the pointer storage to store a flag value to
* avoid having to do memory allocations. since the pointer is never
* dereferenced this is completely safe to do */
flag = 1;

if (SSL_set_ex_data(sc,
ngx_http_lua_kong_ssl_no_session_cache_flag_index,
(void *) flag) == 0)
{
return "unable to disable session cache for current connection";
}

ctx = c->ssl->session_ctx;

/* hook session_new_cb if not already done so */
if (SSL_CTX_sess_get_new_cb(ctx) !=
ngx_http_lua_kong_new_session)
{
/* save old callback */
if (SSL_CTX_set_ex_data(ctx,
ngx_http_lua_kong_ssl_old_sess_new_cb_index,
SSL_CTX_sess_get_new_cb(ctx)) == 0)
{
return "unable to install new session hook";
}

/* install hook */
SSL_CTX_sess_set_new_cb(ctx, ngx_http_lua_kong_new_session);
}

return NULL;

#else
return "TLS support is not enabled in Nginx build"
#endif
}


/*
* request downstream to present a client certificate during TLS handshake,
* but does not validate it
Expand All @@ -84,6 +201,7 @@ ngx_http_lua_kong_ffi_request_client_certificate(ngx_http_request_t *r)
#if (NGX_SSL)
ngx_connection_t *c = r->connection;
ngx_ssl_conn_t *sc;
SSL_CTX *ctx;

if (c->ssl == NULL) {
return "server does not have TLS enabled";
Expand Down
Loading

0 comments on commit be6960e

Please sign in to comment.