From 7fc0fac774ed7d6d45ba522026d32d2d79726baa Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Fri, 28 Jul 2017 13:11:49 +0300 Subject: [PATCH 01/30] feature: TLS-PSK handshake control. * implemented the ssl_psk_by_lua_block and ssl_psk_by_lua_file directives for controlling the NGINX downstream TLS-PSK handshake dynamically with Lua. * added pure C API for Lua library ngx.ssl in the lua-resty-core library for getting TLS-PSK client identity and setting TLS-PSK key. * added ssl_psk_identity_hint directive for setting TLS-PSK identity hint for the NGINX downstream TLS-PSK handshake. * added lua_ssl_psk_identity and lua_ssl_psk_key directives for setting the NGINX upstream TLS-PSK identity and key. --- config | 2 + src/ngx_http_lua_common.h | 8 + src/ngx_http_lua_control.c | 18 +- src/ngx_http_lua_module.c | 136 +++++++ src/ngx_http_lua_phase.c | 4 + src/ngx_http_lua_socket_tcp.c | 43 +++ src/ngx_http_lua_socket_tcp.h | 1 + src/ngx_http_lua_ssl.h | 3 + src/ngx_http_lua_ssl_pskby.c | 706 ++++++++++++++++++++++++++++++++++ src/ngx_http_lua_ssl_pskby.h | 41 ++ src/ngx_http_lua_util.h | 1 + 11 files changed, 957 insertions(+), 6 deletions(-) create mode 100644 src/ngx_http_lua_ssl_pskby.c create mode 100644 src/ngx_http_lua_ssl_pskby.h diff --git a/config b/config index 044deb974e..50271159b6 100644 --- a/config +++ b/config @@ -359,6 +359,7 @@ HTTP_LUA_SRCS=" \ $ngx_addon_dir/src/ngx_http_lua_balancer.c \ $ngx_addon_dir/src/ngx_http_lua_ssl_session_storeby.c \ $ngx_addon_dir/src/ngx_http_lua_ssl_session_fetchby.c \ + $ngx_addon_dir/src/ngx_http_lua_ssl_pskby.c \ $ngx_addon_dir/src/ngx_http_lua_ssl.c \ $ngx_addon_dir/src/ngx_http_lua_log_ringbuf.c \ " @@ -420,6 +421,7 @@ HTTP_LUA_DEPS=" \ $ngx_addon_dir/src/ngx_http_lua_balancer.h \ $ngx_addon_dir/src/ngx_http_lua_ssl_session_storeby.h \ $ngx_addon_dir/src/ngx_http_lua_ssl_session_fetchby.h \ + $ngx_addon_dir/src/ngx_http_lua_ssl_pskby.c \ $ngx_addon_dir/src/ngx_http_lua_ssl.h \ $ngx_addon_dir/src/ngx_http_lua_log_ringbuf.h \ " diff --git a/src/ngx_http_lua_common.h b/src/ngx_http_lua_common.h index e38978389c..0845959f50 100644 --- a/src/ngx_http_lua_common.h +++ b/src/ngx_http_lua_common.h @@ -129,6 +129,7 @@ typedef struct { #define NGX_HTTP_LUA_CONTEXT_SSL_CERT 0x0400 #define NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE 0x0800 #define NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH 0x1000 +#define NGX_HTTP_LUA_CONTEXT_SSL_PSK 0x2000 #ifndef NGX_LUA_NO_FFI_API @@ -248,6 +249,11 @@ union ngx_http_lua_srv_conf_u { ngx_http_lua_srv_conf_handler_pt ssl_sess_fetch_handler; ngx_str_t ssl_sess_fetch_src; u_char *ssl_sess_fetch_src_key; + + ngx_http_lua_srv_conf_handler_pt ssl_psk_handler; + ngx_str_t ssl_psk_src; + u_char *ssl_psk_src_key; + ngx_str_t ssl_psk_identity_hint; } srv; #endif @@ -268,6 +274,8 @@ typedef struct { ngx_uint_t ssl_verify_depth; ngx_str_t ssl_trusted_certificate; ngx_str_t ssl_crl; + ngx_str_t ssl_psk_identity; + ngx_str_t ssl_psk_key; #endif ngx_flag_t force_read_body; /* whether force request body to diff --git a/src/ngx_http_lua_control.c b/src/ngx_http_lua_control.c index ae36505f9d..62fce7c8ae 100644 --- a/src/ngx_http_lua_control.c +++ b/src/ngx_http_lua_control.c @@ -322,13 +322,15 @@ ngx_http_lua_ngx_exit(lua_State *L) | NGX_HTTP_LUA_CONTEXT_BALANCER | NGX_HTTP_LUA_CONTEXT_SSL_CERT | NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE - | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH); + | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH + | NGX_HTTP_LUA_CONTEXT_SSL_PSK); rc = (ngx_int_t) luaL_checkinteger(L, 1); if (ctx->context & (NGX_HTTP_LUA_CONTEXT_SSL_CERT | NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE - | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH)) + | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH + | NGX_HTTP_LUA_CONTEXT_SSL_PSK)) { #if (NGX_HTTP_SSL) @@ -339,7 +341,8 @@ ngx_http_lua_ngx_exit(lua_State *L) ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua exit with code %i", rc); - if (ctx->context == NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE) { + if (ctx->context == NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE + || ctx->context == NGX_HTTP_LUA_CONTEXT_SSL_PSK) { return 0; } @@ -473,7 +476,8 @@ ngx_http_lua_ffi_exit(ngx_http_request_t *r, int status, u_char *err, | NGX_HTTP_LUA_CONTEXT_BALANCER | NGX_HTTP_LUA_CONTEXT_SSL_CERT | NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE - | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH, + | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH + | NGX_HTTP_LUA_CONTEXT_SSL_PSK, err, errlen) != NGX_OK) { @@ -482,7 +486,8 @@ ngx_http_lua_ffi_exit(ngx_http_request_t *r, int status, u_char *err, if (ctx->context & (NGX_HTTP_LUA_CONTEXT_SSL_CERT | NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE - | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH)) + | NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH + | NGX_HTTP_LUA_CONTEXT_SSL_PSK)) { #if (NGX_HTTP_SSL) @@ -493,7 +498,8 @@ ngx_http_lua_ffi_exit(ngx_http_request_t *r, int status, u_char *err, ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua exit with code %d", status); - if (ctx->context == NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE) { + if (ctx->context == NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE + || ctx->context == NGX_HTTP_LUA_CONTEXT_SSL_PSK) { return NGX_DONE; } diff --git a/src/ngx_http_lua_module.c b/src/ngx_http_lua_module.c index 9d914e86e8..5c0aeb2bf8 100644 --- a/src/ngx_http_lua_module.c +++ b/src/ngx_http_lua_module.c @@ -28,6 +28,7 @@ #include "ngx_http_lua_ssl_certby.h" #include "ngx_http_lua_ssl_session_storeby.h" #include "ngx_http_lua_ssl_session_fetchby.h" +#include "ngx_http_lua_ssl_pskby.h" #include "ngx_http_lua_headers.h" @@ -557,6 +558,41 @@ static ngx_command_t ngx_http_lua_cmds[] = { 0, (void *) ngx_http_lua_ssl_sess_fetch_handler_file }, + { ngx_string("ssl_psk_identity_hint"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_lua_srv_conf_t, srv.ssl_psk_identity_hint), + NULL }, + + { ngx_string("ssl_psk_by_lua_block"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, + ngx_http_lua_ssl_psk_by_lua_block, + NGX_HTTP_SRV_CONF_OFFSET, + 0, + (void *) ngx_http_lua_ssl_psk_server_handler_inline }, + + { ngx_string("ssl_psk_by_lua_file"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_http_lua_ssl_psk_by_lua, + NGX_HTTP_SRV_CONF_OFFSET, + 0, + (void *) ngx_http_lua_ssl_psk_server_handler_file }, + + { ngx_string("lua_ssl_psk_identity"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_lua_loc_conf_t, ssl_psk_identity), + NULL }, + + { ngx_string("lua_ssl_psk_key"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_lua_loc_conf_t, ssl_psk_key), + NULL }, + { ngx_string("lua_ssl_verify_depth"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, @@ -922,6 +958,11 @@ ngx_http_lua_create_srv_conf(ngx_conf_t *cf) * lscf->srv.ssl_session_fetch_src = { 0, NULL }; * lscf->srv.ssl_session_fetch_src_key = NULL; * + * lscf->srv.ssl_psk_handler = NULL; + * lscf->srv.ssl_psk_src = { 0, NULL }; + * lscf->srv.ssl_psk_src_key = NULL; + * lscf->srv.ssl_psk_identity_hint = { 0, NULL }; + * * lscf->balancer.handler = NULL; * lscf->balancer.src = { 0, NULL }; * lscf->balancer.src_key = NULL; @@ -1024,6 +1065,77 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) } } + if (conf->srv.ssl_psk_identity_hint.len == 0) { + conf->srv.ssl_psk_identity_hint = prev->srv.ssl_psk_identity_hint; + } + + if (conf->srv.ssl_psk_identity_hint.len) { + dd("ssl psk identity hint: %.*s", (int) conf->srv.ssl_psk_identity_hint.len, conf->srv.ssl_psk_identity_hint.data); + + # if OPENSSL_VERSION_NUMBER >= 0x1000100fL + + sscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_ssl_module); + if (sscf == NULL || sscf->ssl.ctx == NULL) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "no ssl configured for the server"); + + return NGX_CONF_ERROR; + } + + if (SSL_CTX_use_psk_identity_hint(sscf->ssl.ctx, (const char *) conf->srv.ssl_psk_identity_hint.data) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, + "SSL_CTX_use_psk_identity_hint(\"%V\") failed", + &conf->srv.ssl_psk_identity_hint); + return NGX_CONF_ERROR; + } + + # else + + ngx_log_error(NGX_LOG_CRIT, cf->log, 0, + "OpenSSL too old to support ssl_psk_identity_hint"); + return NGX_CONF_ERROR; + + # endif + } + + if (conf->srv.ssl_psk_src.len == 0) { + conf->srv.ssl_psk_src = prev->srv.ssl_psk_src; + conf->srv.ssl_psk_src_key = prev->srv.ssl_psk_src_key; + conf->srv.ssl_psk_handler = prev->srv.ssl_psk_handler; + } + + if (conf->srv.ssl_psk_src.len) { + sscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_ssl_module); + if (sscf == NULL || sscf->ssl.ctx == NULL) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "no ssl configured for the server"); + + return NGX_CONF_ERROR; + } + +#ifdef LIBRESSL_VERSION_NUMBER + + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "LibreSSL does not support ssl_psk_by_lua*"); + return NGX_CONF_ERROR; + +#else + +# if OPENSSL_VERSION_NUMBER >= 0x1000100fL + + SSL_CTX_set_psk_server_callback(sscf->ssl.ctx, ngx_http_lua_ssl_psk_server_handler); + +# else + + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "OpenSSL too old to support ssl_psk_by_lua*"); + return NGX_CONF_ERROR; + +# endif + +#endif + } + #endif /* NGX_HTTP_SSL */ return NGX_CONF_OK; } @@ -1067,6 +1179,8 @@ ngx_http_lua_create_loc_conf(ngx_conf_t *cf) * conf->ssl_ciphers = { 0, NULL }; * conf->ssl_trusted_certificate = { 0, NULL }; * conf->ssl_crl = { 0, NULL }; + * conf->ssl_psk_identity = { 0, NULL }; + * conf->ssl_psk_key = {0, NULL }; */ conf->force_read_body = NGX_CONF_UNSET; @@ -1160,6 +1274,11 @@ ngx_http_lua_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) prev->ssl_trusted_certificate, ""); ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); + ngx_conf_merge_str_value(conf->ssl_psk_identity, + prev->ssl_psk_identity, ""); + ngx_conf_merge_str_value(conf->ssl_psk_key, + prev->ssl_psk_key, ""); + if (ngx_http_lua_set_ssl(cf, conf) != NGX_OK) { return NGX_CONF_ERROR; } @@ -1266,6 +1385,23 @@ ngx_http_lua_set_ssl(ngx_conf_t *cf, ngx_http_lua_loc_conf_t *llcf) return NGX_ERROR; } + if (llcf->ssl_psk_identity.len && llcf->ssl_psk_key.len) { + dd("ssl psk identity: %.*s", (int) llcf->ssl_psk_identity.len, llcf->ssl_psk_identity.data); + dd("ssl psk key: %.*s", (int) llcf->ssl_psk_key.len, llcf->ssl_psk_key.data); + +# if OPENSSL_VERSION_NUMBER >= 0x1000100fL + + SSL_CTX_set_psk_client_callback(llcf->ssl->ctx, ngx_http_lua_ssl_psk_client_handler); + +# else + + ngx_log_error(NGX_LOG_CRIT, cf->log, 0, + "OpenSSL too old to support ssl_psk_identity"); + return NGX_ERROR; + +# endif + } + return NGX_OK; } diff --git a/src/ngx_http_lua_phase.c b/src/ngx_http_lua_phase.c index 50c53110b8..7ed0ad105d 100644 --- a/src/ngx_http_lua_phase.c +++ b/src/ngx_http_lua_phase.c @@ -80,6 +80,10 @@ ngx_http_lua_ngx_get_phase(lua_State *L) lua_pushliteral(L, "balancer"); break; + case NGX_HTTP_LUA_CONTEXT_SSL_PSK: + lua_pushliteral(L, "ssl_psk"); + break; + case NGX_HTTP_LUA_CONTEXT_SSL_CERT: lua_pushliteral(L, "ssl_cert"); break; diff --git a/src/ngx_http_lua_socket_tcp.c b/src/ngx_http_lua_socket_tcp.c index 85f9f6a04a..06838ccfd2 100644 --- a/src/ngx_http_lua_socket_tcp.c +++ b/src/ngx_http_lua_socket_tcp.c @@ -22,6 +22,7 @@ static int ngx_http_lua_socket_tcp(lua_State *L); static int ngx_http_lua_socket_tcp_connect(lua_State *L); #if (NGX_HTTP_SSL) static int ngx_http_lua_socket_tcp_sslhandshake(lua_State *L); +static int ngx_http_lua_socket_tcp_sslgetpskidhint(lua_State *L); #endif static int ngx_http_lua_socket_tcp_receive(lua_State *L); static int ngx_http_lua_socket_tcp_send(lua_State *L); @@ -283,6 +284,9 @@ ngx_http_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L) lua_pushcfunction(L, ngx_http_lua_socket_tcp_sslhandshake); lua_setfield(L, -2, "sslhandshake"); + lua_pushcfunction(L, ngx_http_lua_socket_tcp_sslgetpskidhint); + lua_setfield(L, -2, "sslgetpskidhint"); + #endif lua_pushcfunction(L, ngx_http_lua_socket_tcp_receive); @@ -1599,6 +1603,40 @@ ngx_http_lua_ssl_handshake_retval_handler(ngx_http_request_t *r, return 1; } + +static int +ngx_http_lua_socket_tcp_sslgetpskidhint(lua_State *L) +{ + ngx_http_lua_socket_tcp_upstream_t *u; + + if (lua_gettop(L) != 1) { + return luaL_error(L, "expecting 1 argument " + "(including the object), but got %d", lua_gettop(L)); + } + + luaL_checktype(L, 1, LUA_TTABLE); + + lua_rawgeti(L, 1, SOCKET_CTX_INDEX); + u = lua_touserdata(L, -1); + + if (u == NULL + || u->peer.connection == NULL + || (u->read_closed && u->write_closed)) + { + lua_pushnil(L); + lua_pushliteral(L, "closed"); + return 2; + } + + if (u->ssl_psk_identity_hint.len == 0) { + lua_pushliteral(L, ""); + return 1; + } + + lua_pushlstring(L, (char *) u->ssl_psk_identity_hint.data, u->ssl_psk_identity_hint.len); + return 1; +} + #endif /* NGX_HTTP_SSL */ @@ -3493,6 +3531,11 @@ ngx_http_lua_socket_tcp_finalize(ngx_http_request_t *r, u->ssl_name.data = NULL; u->ssl_name.len = 0; } + if (u->ssl_psk_identity_hint.data) { + ngx_free(u->ssl_psk_identity_hint.data); + u->ssl_psk_identity_hint.data = NULL; + u->ssl_psk_identity_hint.len = 0; + } #endif c = u->peer.connection; diff --git a/src/ngx_http_lua_socket_tcp.h b/src/ngx_http_lua_socket_tcp.h index dbdee41c6e..51f93ab921 100644 --- a/src/ngx_http_lua_socket_tcp.h +++ b/src/ngx_http_lua_socket_tcp.h @@ -92,6 +92,7 @@ struct ngx_http_lua_socket_tcp_upstream_s { #if (NGX_HTTP_SSL) ngx_str_t ssl_name; + ngx_str_t ssl_psk_identity_hint; #endif unsigned ft_type:16; diff --git a/src/ngx_http_lua_ssl.h b/src/ngx_http_lua_ssl.h index acb8c4b16c..6f9f4baad8 100644 --- a/src/ngx_http_lua_ssl.h +++ b/src/ngx_http_lua_ssl.h @@ -24,6 +24,9 @@ typedef struct { ngx_str_t session_id; + ngx_str_t psk_identity; + ngx_str_t psk_key; + int exit_code; /* exit code for openssl's set_cert_cb callback */ diff --git a/src/ngx_http_lua_ssl_pskby.c b/src/ngx_http_lua_ssl_pskby.c new file mode 100644 index 0000000000..515977e2de --- /dev/null +++ b/src/ngx_http_lua_ssl_pskby.c @@ -0,0 +1,706 @@ + +/* + * Based on ngx_http_lua_ssl_certby.c and ngx_http_lua_ssl_session_storeby.c + * by Yichun Zhang (agentzh) + * + * Author: Tuure Vartiainen (vartiait) + */ + + +#ifndef DDEBUG +#define DDEBUG 0 +#endif +#include "ddebug.h" + + +#if (NGX_HTTP_SSL) + +#include "ngx_http_lua_cache.h" +#include "ngx_http_lua_initworkerby.h" +#include "ngx_http_lua_util.h" +#include "ngx_http_ssl_module.h" +#include "ngx_http_lua_contentby.h" +#include "ngx_http_lua_ssl_pskby.h" +#include "ngx_http_lua_directive.h" +#include "ngx_http_lua_ssl.h" +#include "ngx_http_lua_socket_tcp.h" + + +static u_char *ngx_http_lua_log_ssl_psk_error(ngx_log_t *log, u_char *buf, + size_t len); +static ngx_int_t ngx_http_lua_ssl_psk_by_chunk(lua_State *L, + ngx_http_request_t *r); + + +ngx_int_t +ngx_http_lua_ssl_psk_server_handler_file(ngx_http_request_t *r, + ngx_http_lua_srv_conf_t *lscf, lua_State *L) +{ + ngx_int_t rc; + + rc = ngx_http_lua_cache_loadfile(r->connection->log, L, + lscf->srv.ssl_psk_src.data, + lscf->srv.ssl_psk_src_key); + if (rc != NGX_OK) { + return rc; + } + + /* make sure we have a valid code chunk */ + ngx_http_lua_assert(lua_isfunction(L, -1)); + + return ngx_http_lua_ssl_psk_by_chunk(L, r); +} + + +ngx_int_t +ngx_http_lua_ssl_psk_server_handler_inline(ngx_http_request_t *r, + ngx_http_lua_srv_conf_t *lscf, lua_State *L) +{ + ngx_int_t rc; + + rc = ngx_http_lua_cache_loadbuffer(r->connection->log, L, + lscf->srv.ssl_psk_src.data, + lscf->srv.ssl_psk_src.len, + lscf->srv.ssl_psk_src_key, + "=ssl_psk_by_lua"); + if (rc != NGX_OK) { + return rc; + } + + /* make sure we have a valid code chunk */ + ngx_http_lua_assert(lua_isfunction(L, -1)); + + return ngx_http_lua_ssl_psk_by_chunk(L, r); +} + + +char * +ngx_http_lua_ssl_psk_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf) +{ + char *rv; + ngx_conf_t save; + + save = *cf; + cf->handler = ngx_http_lua_ssl_psk_by_lua; + cf->handler_conf = conf; + + rv = ngx_http_lua_conf_lua_block_parse(cf, cmd); + + *cf = save; + + return rv; +} + + +char * +ngx_http_lua_ssl_psk_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf) +{ +#if OPENSSL_VERSION_NUMBER < 0x1000100fL + + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "at least OpenSSL 1.0.1 required but found " + OPENSSL_VERSION_TEXT); + + return NGX_CONF_ERROR; + +#else + + u_char *p; + u_char *name; + ngx_str_t *value; + ngx_http_lua_srv_conf_t *lscf = conf; + + /* must specify a concrete handler */ + if (cmd->post == NULL) { + return NGX_CONF_ERROR; + } + + if (lscf->srv.ssl_psk_handler) { + return "is duplicate"; + } + + if (ngx_http_lua_ssl_init(cf->log) != NGX_OK) { + return NGX_CONF_ERROR; + } + + value = cf->args->elts; + + lscf->srv.ssl_psk_handler = (ngx_http_lua_srv_conf_handler_pt) cmd->post; + + if (cmd->post == ngx_http_lua_ssl_psk_server_handler_file) { + /* Lua code in an external file */ + + name = ngx_http_lua_rebase_path(cf->pool, value[1].data, + value[1].len); + if (name == NULL) { + return NGX_CONF_ERROR; + } + + lscf->srv.ssl_psk_src.data = name; + lscf->srv.ssl_psk_src.len = ngx_strlen(name); + + p = ngx_palloc(cf->pool, NGX_HTTP_LUA_FILE_KEY_LEN + 1); + if (p == NULL) { + return NGX_CONF_ERROR; + } + + lscf->srv.ssl_psk_src_key = p; + + p = ngx_copy(p, NGX_HTTP_LUA_FILE_TAG, NGX_HTTP_LUA_FILE_TAG_LEN); + p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len); + *p = '\0'; + + } else { + /* inlined Lua code */ + + lscf->srv.ssl_psk_src = value[1]; + + p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1); + if (p == NULL) { + return NGX_CONF_ERROR; + } + + lscf->srv.ssl_psk_src_key = p; + + p = ngx_copy(p, NGX_HTTP_LUA_INLINE_TAG, NGX_HTTP_LUA_INLINE_TAG_LEN); + p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len); + *p = '\0'; + } + + return NGX_CONF_OK; + +#endif /* OPENSSL_VERSION_NUMBER < 0x1000205fL */ +} + + +unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, const char *identity, unsigned char *psk, unsigned int max_psk_len) +{ + lua_State *L; + ngx_int_t rc; + ngx_connection_t *c, *fc; + ngx_http_request_t *r = NULL; + ngx_http_connection_t *hc; + ngx_http_lua_srv_conf_t *lscf; + ngx_http_core_loc_conf_t *clcf; + ngx_http_lua_ssl_ctx_t *cctx; + + c = ngx_ssl_get_connection(ssl_conn); + + dd("c = %p", c); + + cctx = ngx_http_lua_ssl_get_ctx(c->ssl->connection); + + dd("ssl server psk handler, psk-ctx=%p", cctx); + + hc = c->data; + + fc = ngx_http_lua_create_fake_connection(NULL); + if (fc == NULL) { + goto failed; + } + + fc->log->handler = ngx_http_lua_log_ssl_psk_error; + fc->log->data = fc; + + fc->addr_text = c->addr_text; + fc->listening = c->listening; + + r = ngx_http_lua_create_fake_request(fc); + if (r == NULL) { + goto failed; + } + + r->main_conf = hc->conf_ctx->main_conf; + r->srv_conf = hc->conf_ctx->srv_conf; + r->loc_conf = hc->conf_ctx->loc_conf; + + fc->log->file = c->log->file; + fc->log->log_level = c->log->log_level; + fc->ssl = c->ssl; + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + +#if defined(nginx_version) && nginx_version >= 1003014 + +# if nginx_version >= 1009000 + + ngx_set_connection_log(fc, clcf->error_log); + +# else + + ngx_http_set_connection_log(fc, clcf->error_log); + +# endif + +#else + + fc->log->file = clcf->error_log->file; + + if (!(fc->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { + fc->log->log_level = clcf->error_log->log_level; + } + +#endif + + if (cctx == NULL) { + cctx = ngx_pcalloc(c->pool, sizeof(ngx_http_lua_ssl_ctx_t)); + if (cctx == NULL) { + goto failed; /* error */ + } + } + + if (identity == NULL) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "client did not send TLS-PSK identity"); + goto failed; + } + + cctx->exit_code = 0; /* unsuccessful by default */ + cctx->connection = c; + cctx->request = r; + cctx->psk_identity.data = (u_char *) identity; + cctx->psk_identity.len = ngx_strlen(identity); + cctx->done = 0; + + dd("setting cctx = %p", cctx); + + if (SSL_set_ex_data(c->ssl->connection, ngx_http_lua_ssl_ctx_index, cctx) + == 0) + { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_ex_data() failed"); + goto failed; + } + + lscf = ngx_http_get_module_srv_conf(r, ngx_http_lua_module); + + /* TODO honor lua_code_cache off */ + L = ngx_http_lua_get_lua_vm(r, NULL); + + c->log->action = "setting SSL PSK by lua"; + + rc = lscf->srv.ssl_psk_handler(r, lscf, L); + + if (rc >= NGX_OK || rc == NGX_ERROR) { + cctx->done = 1; + + if (cctx->cleanup) { + *cctx->cleanup = NULL; + } + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, + "lua_psk_by_lua: handler return value: %i, " + "psk server cb exit code: %d", rc, cctx->exit_code); + + c->log->action = "SSL handshaking"; + + if (rc == NGX_ERROR) { + /* 0 == unknown_psk_identity */ + return cctx->exit_code; + } + + if (cctx->psk_key.data == NULL) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "psk_key.data == NULL"); + + return cctx->exit_code; + } + + if (cctx->psk_key.len == 0) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "psk_key.len == 0"); + + return cctx->exit_code; + } + + if (cctx->psk_key.len > (size_t) max_psk_len) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "psk_key.len: %i > max_psk_len: %i", cctx->psk_key.len, max_psk_len); + + return cctx->exit_code; + } + + ngx_memcpy(psk, cctx->psk_key.data, cctx->psk_key.len); + cctx->exit_code = cctx->psk_key.len; + + /* return length of psk key */ + return cctx->exit_code; + } + + /* impossible to reach here */ + ngx_http_lua_assert(0); + +failed: + + if (r && r->pool) { + ngx_http_lua_free_fake_request(r); + } + + if (fc) { + ngx_http_lua_close_fake_connection(fc); + } + + return 0; +} + + +unsigned int ngx_http_lua_ssl_psk_client_handler(ngx_ssl_conn_t *ssl_conn, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len) +{ + ngx_connection_t *c; + ngx_connection_t *dc; /* downstream connection */ + ngx_http_request_t *r = NULL; + ngx_http_lua_loc_conf_t *llcf; + + ngx_http_lua_socket_tcp_upstream_t *u; + + c = ngx_ssl_get_connection(ssl_conn); + + if (c == NULL) { + goto failed; + } + + dd("ssl psk client handler, c = %p", c); + + u = c->data; + + if (u == NULL) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "no upstream socket found"); + goto failed; + } + + r = u->request; + + if (r == NULL) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "no http request found"); + goto failed; + } + + dc = r->connection; + + if (dc == NULL) { + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "no downstream socket found"); + goto failed; + } + + llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); + + if (llcf == NULL) { + ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, "getting module loc conf failed"); + goto failed; + } + + if (hint == NULL) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, + "sslhandshake: psk server hint was null"); + } + else { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, + "sslhandshake: psk server hint: %s", hint); + + size_t hint_len = ngx_strlen(hint); + if (u->ssl_psk_identity_hint.data) { + /* buffer already allocated */ + + if (u->ssl_psk_identity_hint.len > hint_len) { + /* reuse it */ + ngx_memcpy(u->ssl_psk_identity_hint.data, hint, hint_len); + u->ssl_psk_identity_hint.len = hint_len; + } else { + ngx_free(u->ssl_psk_identity_hint.data); + goto new_ssl_psk_identity_hint; + } + } + else { + +new_ssl_psk_identity_hint: + + u->ssl_psk_identity_hint.data = ngx_alloc(hint_len + 1, ngx_cycle->log); + if (u->ssl_psk_identity_hint.data == NULL) { + u->ssl_psk_identity_hint.len = 0; + + ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, "could not allocate memory for ssl_psk_identity_hint"); + goto failed; + } + + ngx_memcpy(u->ssl_psk_identity_hint.data, hint, hint_len); + u->ssl_psk_identity_hint.len = hint_len; + } + } + + if (llcf->ssl_psk_identity.len) { + if (llcf->ssl_psk_identity.len <= max_identity_len) { + ngx_snprintf((u_char *) identity, max_identity_len, "%V", &llcf->ssl_psk_identity); + } + else { + ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, "ssl_psk_identity.len: %i > max_identity_len: %i", llcf->ssl_psk_identity.len, max_identity_len); + goto failed; + } + } + else { + ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, "no ssl_psk_identity defined"); + goto failed; + } + + if (llcf->ssl_psk_key.len) { + if (llcf->ssl_psk_key.len <= max_psk_len) { + ngx_memcpy(psk, llcf->ssl_psk_key.data, llcf->ssl_psk_key.len); + return llcf->ssl_psk_key.len; + } + else { + ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, "ssl_psk_key.len: %i > max_psk_len: %i", llcf->ssl_psk_key.len, max_psk_len); + goto failed; + } + } + else { + ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, "no ssl_psk_key defined"); + goto failed; + } + + /* impossible to reach here */ + ngx_http_lua_assert(0); + +failed: + + return 0; +} + +static u_char * +ngx_http_lua_log_ssl_psk_error(ngx_log_t *log, u_char *buf, size_t len) +{ + u_char *p; + ngx_connection_t *c; + + if (log->action) { + p = ngx_snprintf(buf, len, " while %s", log->action); + len -= p - buf; + buf = p; + } + + p = ngx_snprintf(buf, len, ", context: ssl_psk_by_lua*"); + len -= p - buf; + buf = p; + + c = log->data; + + if (c->addr_text.len) { + p = ngx_snprintf(buf, len, ", client: %V", &c->addr_text); + len -= p - buf; + buf = p; + } + + if (c && c->listening && c->listening->addr_text.len) { + p = ngx_snprintf(buf, len, ", server: %V", &c->listening->addr_text); + /* len -= p - buf; */ + buf = p; + } + + return buf; +} + + +static ngx_int_t +ngx_http_lua_ssl_psk_by_chunk(lua_State *L, ngx_http_request_t *r) +{ + size_t len; + u_char *err_msg; + ngx_int_t rc; + ngx_http_lua_ctx_t *ctx; + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + + if (ctx == NULL) { + ctx = ngx_http_lua_create_ctx(r); + if (ctx == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + } else { + dd("reset ctx"); + ngx_http_lua_reset_ctx(r, L, ctx); + } + + ctx->entered_content_phase = 1; + ctx->context = NGX_HTTP_LUA_CONTEXT_SSL_PSK; + + /* init nginx context in Lua VM */ + ngx_http_lua_set_req(L, r); + ngx_http_lua_create_new_globals_table(L, 0 /* narr */, 1 /* nrec */); + + /* {{{ make new env inheriting main thread's globals table */ + lua_createtable(L, 0, 1 /* nrec */); /* the metatable for the new env */ + ngx_http_lua_get_globals_table(L); + lua_setfield(L, -2, "__index"); + lua_setmetatable(L, -2); /* setmetatable({}, {__index = _G}) */ + /* }}} */ + + lua_setfenv(L, -2); /* set new running env for the code closure */ + + lua_pushcfunction(L, ngx_http_lua_traceback); + lua_insert(L, 1); /* put it under chunk and args */ + + /* protected call user code */ + rc = lua_pcall(L, 0, 1, 1); + + lua_remove(L, 1); /* remove traceback function */ + + dd("rc == %d", (int) rc); + + if (rc != 0) { + /* error occured when running loaded code */ + err_msg = (u_char *) lua_tolstring(L, -1, &len); + + if (err_msg == NULL) { + err_msg = (u_char *) "unknown reason"; + len = sizeof("unknown reason") - 1; + } + + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "failed to run ssl_psk_by_lua*: %*s", len, err_msg); + + lua_settop(L, 0); /* clear remaining elems on stack */ + ngx_http_lua_finalize_request(r, rc); + + return NGX_ERROR; + } + + lua_settop(L, 0); /* clear remaining elems on stack */ + ngx_http_lua_finalize_request(r, rc); + return rc; +} + + +#ifndef NGX_LUA_NO_FFI_API + +/* set psk key from key to lua context. */ +int +ngx_http_lua_ffi_ssl_set_psk_key(ngx_http_request_t *r, + const char *key, size_t len, char **err) +{ + u_char *buf; + ngx_connection_t *c; + ngx_ssl_conn_t *ssl_conn; + ngx_http_lua_ssl_ctx_t *cctx; + + c = r->connection; + + if (c == NULL || c->ssl == NULL) { + *err = "bad request"; + return NGX_ERROR; + } + + ssl_conn = c->ssl->connection; + if (ssl_conn == NULL) { + *err = "bad ssl conn"; + return NGX_ERROR; + } + + dd("set cctx psk key"); + cctx = ngx_http_lua_ssl_get_ctx(ssl_conn); + if (cctx == NULL) { + *err = "bad lua context"; + return NGX_ERROR; + } + + buf = ngx_palloc(r->pool, len); + if (buf == NULL) { + *err = "unable to alloc memory for buffer"; + return NGX_ERROR; + } + ngx_memcpy(buf, key, len); + + cctx->psk_key.data = buf; + cctx->psk_key.len = len; + + return NGX_OK; +} + + +/* get psk identity from lua context into buf. + * the memory allocation of buf should be handled externally. */ +int +ngx_http_lua_ffi_ssl_get_psk_identity(ngx_http_request_t *r, + char *buf, char **err) +{ + int id_len; + u_char *id; + ngx_connection_t *c; + ngx_ssl_conn_t *ssl_conn; + ngx_http_lua_ssl_ctx_t *cctx; + + c = r->connection; + + if (c == NULL || c->ssl == NULL) { + *err = "bad request"; + return NGX_ERROR; + } + + ssl_conn = c->ssl->connection; + if (ssl_conn == NULL) { + *err = "bad ssl conn"; + return NGX_ERROR; + } + + dd("get cctx psk identity"); + cctx = ngx_http_lua_ssl_get_ctx(ssl_conn); + if (cctx == NULL) { + *err = "bad lua context"; + return NGX_ERROR; + } + + id = cctx->psk_identity.data; + if (id == NULL) { + *err = "uninitialized psk identity in lua context"; + return NGX_ERROR; + } + + id_len = cctx->psk_identity.len; + if (id_len == 0) { + *err = "uninitialized psk identity len in lua context"; + return NGX_ERROR; + } + + ngx_memcpy(buf, id, id_len); + + return NGX_OK; +} + + +/* return the size of psk identity. */ +int +ngx_http_lua_ffi_ssl_get_psk_identity_size(ngx_http_request_t *r, + char **err) +{ + ngx_connection_t *c; + ngx_ssl_conn_t *ssl_conn; + ngx_http_lua_ssl_ctx_t *cctx; + + c = r->connection; + + if (c == NULL || c->ssl == NULL) { + *err = "bad request"; + return NGX_ERROR; + } + + ssl_conn = c->ssl->connection; + if (ssl_conn == NULL) { + *err = "bad ssl conn"; + return NGX_ERROR; + } + + dd("get cctx psk identity"); + cctx = ngx_http_lua_ssl_get_ctx(ssl_conn); + if (cctx == NULL) { + *err = "bad lua context"; + return NGX_ERROR; + } + + if (cctx->psk_identity.len == 0) { + *err = "uninitialized psk identity len in lua context"; + return NGX_ERROR; + } + + return cctx->psk_identity.len; +} + + +#endif /* NGX_LUA_NO_FFI_API */ + + +#endif /* NGX_HTTP_SSL */ diff --git a/src/ngx_http_lua_ssl_pskby.h b/src/ngx_http_lua_ssl_pskby.h new file mode 100644 index 0000000000..3cbe9c64c6 --- /dev/null +++ b/src/ngx_http_lua_ssl_pskby.h @@ -0,0 +1,41 @@ + +/* + * Based on ngx_http_lua_ssl_certby.h and ngx_http_lua_ssl_session_storeby.h + * by Yichun Zhang (agentzh) + * + * Author: Tuure Vartiainen (vartiait) + */ + + +#ifndef _NGX_HTTP_LUA_SSL_PSKBY_H_INCLUDED_ +#define _NGX_HTTP_LUA_SSL_PSKBY_H_INCLUDED_ + + +#include "ngx_http_lua_common.h" + + +#if (NGX_HTTP_SSL) + + +ngx_int_t ngx_http_lua_ssl_psk_server_handler_inline(ngx_http_request_t *r, + ngx_http_lua_srv_conf_t *lscf, lua_State *L); + +ngx_int_t ngx_http_lua_ssl_psk_server_handler_file(ngx_http_request_t *r, + ngx_http_lua_srv_conf_t *lscf, lua_State *L); + +char *ngx_http_lua_ssl_psk_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); + +char *ngx_http_lua_ssl_psk_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); + +unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, const char *identity, unsigned char *psk, unsigned int max_psk_len); + +unsigned int ngx_http_lua_ssl_psk_client_handler(ngx_ssl_conn_t *ssl_conn, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len); + +#endif /* NGX_HTTP_SSL */ + + +#endif /* _NGX_HTTP_LUA_SSL_PSKBY_H_INCLUDED_ */ + +/* vi:set ft=c ts=4 sw=4 et fdm=marker: */ diff --git a/src/ngx_http_lua_util.h b/src/ngx_http_lua_util.h index 2f995e0455..9b731cfd9a 100644 --- a/src/ngx_http_lua_util.h +++ b/src/ngx_http_lua_util.h @@ -91,6 +91,7 @@ extern char ngx_http_lua_headers_metatable_key; "ssl_session_store_by_lua*" \ : (c) == NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH ? \ "ssl_session_fetch_by_lua*" \ + : (c) == NGX_HTTP_LUA_CONTEXT_SSL_PSK ? "ssl_psk_by_lua*" \ : "(unknown)") From 26bd22854bfd5e12f5173ddebd3928049f810f19 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Mon, 31 Jul 2017 14:52:38 +0300 Subject: [PATCH 02/30] tests: added a test case for TLS-PSK upstream and downstream. --- t/140-ssl-c-api.t | 156 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/t/140-ssl-c-api.t b/t/140-ssl-c-api.t index 8734d1477d..d7dc91872c 100644 --- a/t/140-ssl-c-api.t +++ b/t/140-ssl-c-api.t @@ -62,6 +62,15 @@ ffi.cdef[[ void ngx_http_lua_ffi_free_priv_key(void *cdata); int ngx_http_lua_ffi_ssl_clear_certs(void *r, char **err); + + int ngx_http_lua_ffi_ssl_set_psk_key(void *r, + const char *key, size_t len, char **err); + + int ngx_http_lua_ffi_ssl_get_psk_identity(void *r, + char *buf, char **err); + + int ngx_http_lua_ffi_ssl_get_psk_identity_size(void *r, + char **err); ]] _EOC_ } @@ -811,3 +820,150 @@ lua ssl server name: "test.com" --- no_error_log [error] [alert] + + + +=== TEST 6: TLS-PSK +--- http_config + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name test.com; + + ssl_psk_by_lua_block { + collectgarbage() + + local ffi = require "ffi" + require "defines" + + local errmsg = ffi.new("char *[1]") + + local r = getfenv(0).__ngx_req + if not r then + ngx.log(ngx.ERR, "no request found") + return + end + + local len = ffi.C.ngx_http_lua_ffi_ssl_get_psk_identity_size(r, errmsg) + + if len < 0 then + ngx.log(ngx.ERR, "failed to get psk identity size: ", ffi.string(errmsg[0])) + return + end + + if len > 4096 then + ngx.log(ngx.ERR, "psk identity size too long") + return + end + + local buf = ffi.new("char[?]", 4096) + + local rc = ffi.C.ngx_http_lua_ffi_ssl_get_psk_identity(r, buf, errmsg) + if rc ~= 0 then + ngx.log(ngx.ERR, "failed to get psk identity: ", ffi.string(errmsg[0])) + return + end + + local psk_identity = ffi.string(buf, len) + if not psk_identity then + ngx.log(ngx.ERR, "psk_identity is undefined") + return + end + + local psk_key = "psk_test_key" + + local rc = ffi.C.ngx_http_lua_ffi_ssl_set_psk_key(r, psk_key, #psk_key, errmsg) + if rc ~= 0 then + ngx.log(ngx.ERR, "failed to set psk key: ", ffi.string(errmsg[0])) + return + end + } + + ssl_certificate ../../cert/test.crt; + ssl_certificate_key ../../cert/test.key; + + lua_ssl_psk_identity psk_test_identity_hint; + + server_tokens off; + location /foo { + default_type 'text/plain'; + content_by_lua_block { ngx.status = 201 ngx.say("foo") ngx.exit(201) } + more_clear_headers Date; + } + } +--- config + server_tokens off; + + location /t { + lua_ssl_ciphers PSK-AES256-CBC-SHA; + lua_ssl_psk_identity psk_test_identity; + lua_ssl_psk_key psk_test_key; + + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(2000) + + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local sess, err = sock:sslhandshake(nil, "test.com", false) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + + ngx.say("ssl handshake: ", type(sess)) + + local req = "GET /foo HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n" + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send http request: ", err) + return + end + + ngx.say("sent http request: ", bytes, " bytes.") + + while true do + local line, err = sock:receive() + if not line then + -- ngx.say("failed to recieve response status line: ", err) + break + end + + ngx.say("received: ", line) + end + + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + -- collectgarbage() + } + } + +--- request +GET /t +--- response_body +connected: 1 +ssl handshake: userdata +sent http request: 56 bytes. +received: HTTP/1.1 201 Created +received: Server: nginx +received: Content-Type: text/plain +received: Content-Length: 4 +received: Connection: close +received: +received: foo +close: 1 nil + +--- error_log +lua ssl server name: "test.com" + +--- no_error_log +[error] +[alert] From 7f5808a7ec3cc3b5e8129edc2583b892856814c5 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Mon, 31 Jul 2017 14:56:30 +0300 Subject: [PATCH 03/30] travis-ci: use ssl-psk branch of lua-resty-core. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7448f65ac2..86581be635 100644 --- a/.travis.yml +++ b/.travis.yml @@ -84,7 +84,7 @@ install: - git clone https://github.com/openresty/rds-json-nginx-module.git ../rds-json-nginx-module - git clone https://github.com/openresty/srcache-nginx-module.git ../srcache-nginx-module - git clone https://github.com/openresty/redis2-nginx-module.git ../redis2-nginx-module - - git clone https://github.com/openresty/lua-resty-core.git ../lua-resty-core + - git clone -b ssl-psk https://github.com/vartiait/lua-resty-core.git ../lua-resty-core - git clone https://github.com/openresty/lua-resty-lrucache.git ../lua-resty-lrucache - git clone https://github.com/openresty/lua-resty-mysql.git ../lua-resty-mysql - git clone -b v2.1-agentzh https://github.com/openresty/luajit2.git From 78e1aed29bccac2eabd6227f01e416ba35faa529 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Mon, 31 Jul 2017 15:13:50 +0300 Subject: [PATCH 04/30] config: fixed a typo, include ngx_http_lua_ssl_pskby.h in HTTP_LUA_DEPS. --- config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config b/config index 50271159b6..143ad92d12 100644 --- a/config +++ b/config @@ -421,7 +421,7 @@ HTTP_LUA_DEPS=" \ $ngx_addon_dir/src/ngx_http_lua_balancer.h \ $ngx_addon_dir/src/ngx_http_lua_ssl_session_storeby.h \ $ngx_addon_dir/src/ngx_http_lua_ssl_session_fetchby.h \ - $ngx_addon_dir/src/ngx_http_lua_ssl_pskby.c \ + $ngx_addon_dir/src/ngx_http_lua_ssl_pskby.h \ $ngx_addon_dir/src/ngx_http_lua_ssl.h \ $ngx_addon_dir/src/ngx_http_lua_log_ringbuf.h \ " From a22ed551e61b386ae56fe1ec0c234623d980c8d9 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 00:32:46 +0300 Subject: [PATCH 05/30] bugfix: TLS-PSK requires at least OpenSSL 1.0.0, not OpenSSL 1.0.1. --- src/ngx_http_lua_module.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ngx_http_lua_module.c b/src/ngx_http_lua_module.c index 5c0aeb2bf8..9ffe91a827 100644 --- a/src/ngx_http_lua_module.c +++ b/src/ngx_http_lua_module.c @@ -1072,7 +1072,7 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) if (conf->srv.ssl_psk_identity_hint.len) { dd("ssl psk identity hint: %.*s", (int) conf->srv.ssl_psk_identity_hint.len, conf->srv.ssl_psk_identity_hint.data); - # if OPENSSL_VERSION_NUMBER >= 0x1000100fL + # if OPENSSL_VERSION_NUMBER >= 0x1000000fL sscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_ssl_module); if (sscf == NULL || sscf->ssl.ctx == NULL) { @@ -1121,7 +1121,7 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) #else -# if OPENSSL_VERSION_NUMBER >= 0x1000100fL +# if OPENSSL_VERSION_NUMBER >= 0x1000000fL SSL_CTX_set_psk_server_callback(sscf->ssl.ctx, ngx_http_lua_ssl_psk_server_handler); @@ -1389,7 +1389,7 @@ ngx_http_lua_set_ssl(ngx_conf_t *cf, ngx_http_lua_loc_conf_t *llcf) dd("ssl psk identity: %.*s", (int) llcf->ssl_psk_identity.len, llcf->ssl_psk_identity.data); dd("ssl psk key: %.*s", (int) llcf->ssl_psk_key.len, llcf->ssl_psk_key.data); -# if OPENSSL_VERSION_NUMBER >= 0x1000100fL +# if OPENSSL_VERSION_NUMBER >= 0x1000000fL SSL_CTX_set_psk_client_callback(llcf->ssl->ctx, ngx_http_lua_ssl_psk_client_handler); From a25045598bd4bd7e8bbc1bd9854c67204da22d17 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 00:33:20 +0300 Subject: [PATCH 06/30] tests: fixed a typo in TLS-PSK test case. --- t/140-ssl-c-api.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/140-ssl-c-api.t b/t/140-ssl-c-api.t index d7dc91872c..bed73d62cb 100644 --- a/t/140-ssl-c-api.t +++ b/t/140-ssl-c-api.t @@ -881,7 +881,7 @@ lua ssl server name: "test.com" ssl_certificate ../../cert/test.crt; ssl_certificate_key ../../cert/test.key; - lua_ssl_psk_identity psk_test_identity_hint; + ssl_psk_identity_hint psk_test_identity_hint; server_tokens off; location /foo { From 88737ed1b51590d680a2109e4e4adb05db362498 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 00:33:47 +0300 Subject: [PATCH 07/30] doc: documented ssl_psk_by_lua_block, ssl_psk_by_lua_file, ssl_psk_identity_hint, lua_ssl_psk_identity and lua_ssl_psk_key directives. --- doc/HttpLuaModule.wiki | 116 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/doc/HttpLuaModule.wiki b/doc/HttpLuaModule.wiki index 8ad2b2d4a9..8042e903cd 100644 --- a/doc/HttpLuaModule.wiki +++ b/doc/HttpLuaModule.wiki @@ -2159,6 +2159,98 @@ When a relative path like foo/bar.lua is given, they will be turned This directive was first introduced in the v0.10.0 release. +== ssl_psk_by_lua_block == + +'''syntax:''' ''ssl_psk_by_lua_block { lua-script }'' + +'''context:''' ''server'' + +'''phase:''' ''right-before-SSL-handshake'' + +This directive runs user Lua code when NGINX is about to start the SSL handshake for the downstream +SSL (https) connections using TLS-PSK and is meant for setting the TLS pre-shared key on a per-request basis. + +The [https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md ngx.ssl] + Lua module provided by the [https://github.com/openresty/lua-resty-core/#readme lua-resty-core] +library is particularly useful in this context. You can use the Lua API offered by this Lua module +to set the TLS pre-shared key for the current SSL connection being initiated. + +This Lua handler does not run at all, however, when NGINX/OpenSSL successfully resumes +the SSL session via SSL session IDs or TLS session tickets for the current SSL connection. In +other words, this Lua handler only runs when NGINX has to initiate a full SSL handshake. + +Below is a trivial example using the +[https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md ngx.ssl] module +at the same time: + + + server { + listen 443 ssl; + server_name test.com; + + ssl_psk_identity_hint Test_TLS-PSK_Identity_Hint; + + ssl_psk_by_lua_block { + print("About to initiate a new TLS-PSK handshake!") + } + + location / { + root html; + } + } + + +See more complicated examples in the [https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md ngx.ssl] +Lua module's official documentation. + +Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does the +[[#ngx.exit|ngx.exit]] call with an error code like ngx.ERROR. + +This Lua code execution context *does not* support yielding, so Lua APIs that may yield +(like cosockets, sleeping, and "light threads") +are disabled in this context. + +Note, however, you still need to configure the [http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate ssl_certificate] and +[http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key ssl_certificate_key] +directives even though you will not use this static certificate and private key at all. This is +because the NGINX core requires their appearance otherwise you are seeing the following error +while starting NGINX: + + + nginx: [emerg] no ssl configured for the server + + +Furthermore, one needs at least OpenSSL 1.0.0 for this directive to work. + +This directive was first introduced in the v0.XX.YY release. + +== ssl_psk_by_lua_file == + +'''syntax:''' ''ssl_psk_by_lua_file '' + +'''context:''' ''server'' + +'''phase:''' ''right-before-SSL-handshake'' + +Equivalent to [[#ssl_psk_by_lua_block|ssl_psk_by_lua_block]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#Lua/LuaJIT bytecode support|Lua/LuaJIT bytecode]] to be executed. + +When a relative path like foo/bar.lua is given, they will be turned into the absolute path relative to the server prefix path determined by the -p PATH command-line option while starting the Nginx server. + +This directive was first introduced in the v0.XX.YY release. + +== ssl_psk_identity_hint == + +'''syntax:''' ''ssl_psk_identity_hint '' + +'''default:''' ''no'' + +'''context:''' ''http, server'' + +Specifies the TLS-PSK identity hint string which NGINX will send to a client during +the SSL handshake for the downstream SSL (https) connections. + +This directive was first introduced in the v0.XX.YY release. + == ssl_session_fetch_by_lua_block == '''syntax:''' ''ssl_session_fetch_by_lua_block { lua-script }'' @@ -2498,6 +2590,30 @@ This directive was first introduced in the v0.9.11 release. See also [[#lua_ssl_trusted_certificate|lua_ssl_trusted_certificate]]. +== lua_ssl_psk_identity == + +'''syntax:''' ''lua_ssl_psk_identity '' + +'''default:''' ''no'' + +'''context:''' ''http, server, location'' + +Specifies the TLS-PSK identity string which NGINX will send to a SSL/TLS server in the [[#tcpsock:sslhandshake|tcpsock:sslhandshake]] method. + +This directive was first introduced in the v0.XX.YY release. + +== lua_ssl_psk_key == + +'''syntax:''' ''lua_ssl_psk_key '' + +'''default:''' ''no'' + +'''context:''' ''http, server, location'' + +Specifies the TLS-PSK key string which NGINX will try use with a SSL/TLS server in the [[#tcpsock:sslhandshake|tcpsock:sslhandshake]] method. + +This directive was first introduced in the v0.XX.YY release. + == lua_http10_buffering == '''syntax:''' ''lua_http10_buffering on|off'' From 8b308df1c53e2edc08b17e2c6bd742476bc57b2e Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 01:53:17 +0300 Subject: [PATCH 08/30] style: fixed oversized lines. --- src/ngx_http_lua_module.c | 16 ++++++++++----- src/ngx_http_lua_socket_tcp.c | 3 ++- src/ngx_http_lua_ssl_pskby.c | 37 ++++++++++++++++++++++++----------- src/ngx_http_lua_ssl_pskby.h | 7 +++++-- 4 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/ngx_http_lua_module.c b/src/ngx_http_lua_module.c index 9ffe91a827..975c536624 100644 --- a/src/ngx_http_lua_module.c +++ b/src/ngx_http_lua_module.c @@ -1070,7 +1070,9 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) } if (conf->srv.ssl_psk_identity_hint.len) { - dd("ssl psk identity hint: %.*s", (int) conf->srv.ssl_psk_identity_hint.len, conf->srv.ssl_psk_identity_hint.data); + dd("ssl psk identity hint: %.*s", + (int) conf->srv.ssl_psk_identity_hint.len, + conf->srv.ssl_psk_identity_hint.data); # if OPENSSL_VERSION_NUMBER >= 0x1000000fL @@ -1082,7 +1084,8 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) return NGX_CONF_ERROR; } - if (SSL_CTX_use_psk_identity_hint(sscf->ssl.ctx, (const char *) conf->srv.ssl_psk_identity_hint.data) == 0) { + if (SSL_CTX_use_psk_identity_hint(sscf->ssl.ctx, + (const char *) conf->srv.ssl_psk_identity_hint.data) == 0) { ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, "SSL_CTX_use_psk_identity_hint(\"%V\") failed", &conf->srv.ssl_psk_identity_hint); @@ -1123,7 +1126,8 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) # if OPENSSL_VERSION_NUMBER >= 0x1000000fL - SSL_CTX_set_psk_server_callback(sscf->ssl.ctx, ngx_http_lua_ssl_psk_server_handler); + SSL_CTX_set_psk_server_callback(sscf->ssl.ctx, + ngx_http_lua_ssl_psk_server_handler); # else @@ -1387,11 +1391,13 @@ ngx_http_lua_set_ssl(ngx_conf_t *cf, ngx_http_lua_loc_conf_t *llcf) if (llcf->ssl_psk_identity.len && llcf->ssl_psk_key.len) { dd("ssl psk identity: %.*s", (int) llcf->ssl_psk_identity.len, llcf->ssl_psk_identity.data); - dd("ssl psk key: %.*s", (int) llcf->ssl_psk_key.len, llcf->ssl_psk_key.data); + dd("ssl psk key: %.*s", (int) llcf->ssl_psk_key.len, + llcf->ssl_psk_key.data); # if OPENSSL_VERSION_NUMBER >= 0x1000000fL - SSL_CTX_set_psk_client_callback(llcf->ssl->ctx, ngx_http_lua_ssl_psk_client_handler); + SSL_CTX_set_psk_client_callback(llcf->ssl->ctx, + ngx_http_lua_ssl_psk_client_handler); # else diff --git a/src/ngx_http_lua_socket_tcp.c b/src/ngx_http_lua_socket_tcp.c index 06838ccfd2..826cba11b5 100644 --- a/src/ngx_http_lua_socket_tcp.c +++ b/src/ngx_http_lua_socket_tcp.c @@ -1633,7 +1633,8 @@ ngx_http_lua_socket_tcp_sslgetpskidhint(lua_State *L) return 1; } - lua_pushlstring(L, (char *) u->ssl_psk_identity_hint.data, u->ssl_psk_identity_hint.len); + lua_pushlstring(L, (char *) u->ssl_psk_identity_hint.data, + u->ssl_psk_identity_hint.len); return 1; } diff --git a/src/ngx_http_lua_ssl_pskby.c b/src/ngx_http_lua_ssl_pskby.c index 515977e2de..091ac493ac 100644 --- a/src/ngx_http_lua_ssl_pskby.c +++ b/src/ngx_http_lua_ssl_pskby.c @@ -175,7 +175,8 @@ ngx_http_lua_ssl_psk_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, } -unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, const char *identity, unsigned char *psk, unsigned int max_psk_len) +unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, + const char *identity, unsigned char *psk, unsigned int max_psk_len) { lua_State *L; ngx_int_t rc; @@ -252,7 +253,8 @@ unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, const } if (identity == NULL) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "client did not send TLS-PSK identity"); + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, + "client did not send TLS-PSK identity"); goto failed; } @@ -312,7 +314,9 @@ unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, const } if (cctx->psk_key.len > (size_t) max_psk_len) { - ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "psk_key.len: %i > max_psk_len: %i", cctx->psk_key.len, max_psk_len); + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, + "psk_key.len: %i > max_psk_len: %i", + cctx->psk_key.len, max_psk_len); return cctx->exit_code; } @@ -341,7 +345,9 @@ unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, const } -unsigned int ngx_http_lua_ssl_psk_client_handler(ngx_ssl_conn_t *ssl_conn, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len) +unsigned int ngx_http_lua_ssl_psk_client_handler(ngx_ssl_conn_t *ssl_conn, + const char *hint, char *identity, unsigned int max_identity_len, + unsigned char *psk, unsigned int max_psk_len) { ngx_connection_t *c; ngx_connection_t *dc; /* downstream connection */ @@ -382,7 +388,8 @@ unsigned int ngx_http_lua_ssl_psk_client_handler(ngx_ssl_conn_t *ssl_conn, const llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); if (llcf == NULL) { - ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, "getting module loc conf failed"); + ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, + "getting module loc conf failed"); goto failed; } @@ -411,11 +418,13 @@ unsigned int ngx_http_lua_ssl_psk_client_handler(ngx_ssl_conn_t *ssl_conn, const new_ssl_psk_identity_hint: - u->ssl_psk_identity_hint.data = ngx_alloc(hint_len + 1, ngx_cycle->log); + u->ssl_psk_identity_hint.data = ngx_alloc(hint_len + 1, + ngx_cycle->log); if (u->ssl_psk_identity_hint.data == NULL) { u->ssl_psk_identity_hint.len = 0; - ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, "could not allocate memory for ssl_psk_identity_hint"); + ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, + "could not allocate memory for ssl_psk_identity_hint"); goto failed; } @@ -426,15 +435,19 @@ unsigned int ngx_http_lua_ssl_psk_client_handler(ngx_ssl_conn_t *ssl_conn, const if (llcf->ssl_psk_identity.len) { if (llcf->ssl_psk_identity.len <= max_identity_len) { - ngx_snprintf((u_char *) identity, max_identity_len, "%V", &llcf->ssl_psk_identity); + ngx_snprintf((u_char *) identity, max_identity_len, "%V", + &llcf->ssl_psk_identity); } else { - ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, "ssl_psk_identity.len: %i > max_identity_len: %i", llcf->ssl_psk_identity.len, max_identity_len); + ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, + "ssl_psk_identity.len: %i > max_identity_len: %i", + llcf->ssl_psk_identity.len, max_identity_len); goto failed; } } else { - ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, "no ssl_psk_identity defined"); + ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, + "no ssl_psk_identity defined"); goto failed; } @@ -444,7 +457,9 @@ unsigned int ngx_http_lua_ssl_psk_client_handler(ngx_ssl_conn_t *ssl_conn, const return llcf->ssl_psk_key.len; } else { - ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, "ssl_psk_key.len: %i > max_psk_len: %i", llcf->ssl_psk_key.len, max_psk_len); + ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, + "ssl_psk_key.len: %i > max_psk_len: %i", + llcf->ssl_psk_key.len, max_psk_len); goto failed; } } diff --git a/src/ngx_http_lua_ssl_pskby.h b/src/ngx_http_lua_ssl_pskby.h index 3cbe9c64c6..2289048834 100644 --- a/src/ngx_http_lua_ssl_pskby.h +++ b/src/ngx_http_lua_ssl_pskby.h @@ -29,9 +29,12 @@ char *ngx_http_lua_ssl_psk_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd, char *ngx_http_lua_ssl_psk_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, const char *identity, unsigned char *psk, unsigned int max_psk_len); +unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, + const char *identity, unsigned char *psk, unsigned int max_psk_len); -unsigned int ngx_http_lua_ssl_psk_client_handler(ngx_ssl_conn_t *ssl_conn, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len); +unsigned int ngx_http_lua_ssl_psk_client_handler(ngx_ssl_conn_t *ssl_conn, + const char *hint, char *identity, unsigned int max_identity_len, + unsigned char *psk, unsigned int max_psk_len); #endif /* NGX_HTTP_SSL */ From 1b9827f25362e3afc7ef3e309794c956ec77150d Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 01:58:58 +0300 Subject: [PATCH 09/30] style: fixed one oversized line. --- src/ngx_http_lua_module.c | 3 ++- src/ngx_http_lua_ssl_pskby.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ngx_http_lua_module.c b/src/ngx_http_lua_module.c index 975c536624..27208bc2f8 100644 --- a/src/ngx_http_lua_module.c +++ b/src/ngx_http_lua_module.c @@ -1390,7 +1390,8 @@ ngx_http_lua_set_ssl(ngx_conf_t *cf, ngx_http_lua_loc_conf_t *llcf) } if (llcf->ssl_psk_identity.len && llcf->ssl_psk_key.len) { - dd("ssl psk identity: %.*s", (int) llcf->ssl_psk_identity.len, llcf->ssl_psk_identity.data); + dd("ssl psk identity: %.*s", (int) llcf->ssl_psk_identity.len, + llcf->ssl_psk_identity.data); dd("ssl psk key: %.*s", (int) llcf->ssl_psk_key.len, llcf->ssl_psk_key.data); diff --git a/src/ngx_http_lua_ssl_pskby.c b/src/ngx_http_lua_ssl_pskby.c index 091ac493ac..af087a2730 100644 --- a/src/ngx_http_lua_ssl_pskby.c +++ b/src/ngx_http_lua_ssl_pskby.c @@ -435,11 +435,11 @@ unsigned int ngx_http_lua_ssl_psk_client_handler(ngx_ssl_conn_t *ssl_conn, if (llcf->ssl_psk_identity.len) { if (llcf->ssl_psk_identity.len <= max_identity_len) { - ngx_snprintf((u_char *) identity, max_identity_len, "%V", + ngx_snprintf((u_char *) identity, max_identity_len, "%V", &llcf->ssl_psk_identity); } else { - ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, + ngx_ssl_error(NGX_LOG_ALERT, dc->log, 0, "ssl_psk_identity.len: %i > max_identity_len: %i", llcf->ssl_psk_identity.len, max_identity_len); goto failed; From e2c532ebbd2fbc5afbe3a2a924da1464719b11c7 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 02:30:33 +0300 Subject: [PATCH 10/30] tests: Use TLSv1 in TLS-PSK test case. --- t/140-ssl-c-api.t | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/t/140-ssl-c-api.t b/t/140-ssl-c-api.t index bed73d62cb..7b5f784a6c 100644 --- a/t/140-ssl-c-api.t +++ b/t/140-ssl-c-api.t @@ -894,7 +894,8 @@ lua ssl server name: "test.com" server_tokens off; location /t { - lua_ssl_ciphers PSK-AES256-CBC-SHA; + ssl_protocols TLSv1; + lua_ssl_ciphers PSK; lua_ssl_psk_identity psk_test_identity; lua_ssl_psk_key psk_test_key; From 121534b4bc4bb19054cb382b004e76fd9018cd12 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 02:34:15 +0300 Subject: [PATCH 11/30] tests: Fixed a typo, use TLSv1 in TLS-PSK test case. --- t/140-ssl-c-api.t | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/t/140-ssl-c-api.t b/t/140-ssl-c-api.t index 7b5f784a6c..57b930fef7 100644 --- a/t/140-ssl-c-api.t +++ b/t/140-ssl-c-api.t @@ -829,6 +829,9 @@ lua ssl server name: "test.com" listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; + ssl_protocols TLSv1; + ssl_ciphers PSK; + ssl_psk_by_lua_block { collectgarbage() @@ -894,7 +897,6 @@ lua ssl server name: "test.com" server_tokens off; location /t { - ssl_protocols TLSv1; lua_ssl_ciphers PSK; lua_ssl_psk_identity psk_test_identity; lua_ssl_psk_key psk_test_key; From 92ebec5aedab5eee4ad59c9ed6b02a4ab3a8a3aa Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 15:22:12 +0300 Subject: [PATCH 12/30] bugfix: use correct memory pool for ngx_palloc in ngx_http_lua_ffi_ssl_set_psk_key --- src/ngx_http_lua_ssl_pskby.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ngx_http_lua_ssl_pskby.c b/src/ngx_http_lua_ssl_pskby.c index af087a2730..c84ef8bff3 100644 --- a/src/ngx_http_lua_ssl_pskby.c +++ b/src/ngx_http_lua_ssl_pskby.c @@ -613,7 +613,7 @@ ngx_http_lua_ffi_ssl_set_psk_key(ngx_http_request_t *r, return NGX_ERROR; } - buf = ngx_palloc(r->pool, len); + buf = ngx_palloc(cctx->connection->pool, len); if (buf == NULL) { *err = "unable to alloc memory for buffer"; return NGX_ERROR; From a28db8bdb53fbde36fa27294c89c042c99bc202c Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 16:20:30 +0300 Subject: [PATCH 13/30] tests: trigger travis-ci run again --- t/140-ssl-c-api.t | 2 ++ 1 file changed, 2 insertions(+) diff --git a/t/140-ssl-c-api.t b/t/140-ssl-c-api.t index 57b930fef7..96ecb92343 100644 --- a/t/140-ssl-c-api.t +++ b/t/140-ssl-c-api.t @@ -879,6 +879,8 @@ lua ssl server name: "test.com" ngx.log(ngx.ERR, "failed to set psk key: ", ffi.string(errmsg[0])) return end + + return ngx.OK } ssl_certificate ../../cert/test.crt; From 1a03ba26ff3a2014bf54d3f66da5be74a464bddc Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 17:25:52 +0300 Subject: [PATCH 14/30] bugfix: get return value of ssl_psk_by_lua_* pcall. --- src/ngx_http_lua_ssl_pskby.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ngx_http_lua_ssl_pskby.c b/src/ngx_http_lua_ssl_pskby.c index c84ef8bff3..92e64dbf80 100644 --- a/src/ngx_http_lua_ssl_pskby.c +++ b/src/ngx_http_lua_ssl_pskby.c @@ -575,6 +575,14 @@ ngx_http_lua_ssl_psk_by_chunk(lua_State *L, ngx_http_request_t *r) return NGX_ERROR; } + /* rc == 0 */ + rc = (ngx_int_t) lua_tointeger(L, -1); + dd("got return value: %d", (int) rc); + + if (rc != NGX_OK) { + rc = NGX_ERROR; + } + lua_settop(L, 0); /* clear remaining elems on stack */ ngx_http_lua_finalize_request(r, rc); return rc; From aaeee5891e9798fc59bfbb669cf12a523b0eaffa Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 17:47:25 +0300 Subject: [PATCH 15/30] tests: trigger travis-ci run again. --- t/140-ssl-c-api.t | 1 + 1 file changed, 1 insertion(+) diff --git a/t/140-ssl-c-api.t b/t/140-ssl-c-api.t index 96ecb92343..e9e86c3aa4 100644 --- a/t/140-ssl-c-api.t +++ b/t/140-ssl-c-api.t @@ -880,6 +880,7 @@ lua ssl server name: "test.com" return end + return ngx.OK } From 77663774b5ebb43419fddb14b46f61ca33eda0a1 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 18:08:54 +0300 Subject: [PATCH 16/30] tests: trigger travis-ci run again. --- t/140-ssl-c-api.t | 1 - 1 file changed, 1 deletion(-) diff --git a/t/140-ssl-c-api.t b/t/140-ssl-c-api.t index e9e86c3aa4..96ecb92343 100644 --- a/t/140-ssl-c-api.t +++ b/t/140-ssl-c-api.t @@ -880,7 +880,6 @@ lua ssl server name: "test.com" return end - return ngx.OK } From 2e2c5d9c329f0ad1c1e57e25a3ce30bc94d24567 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 20:36:51 +0300 Subject: [PATCH 17/30] doc: generated a new markdown version. --- README.markdown | 137 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/README.markdown b/README.markdown index 28ba6e68c0..1e48899527 100644 --- a/README.markdown +++ b/README.markdown @@ -1076,6 +1076,9 @@ Directives * [lua_need_request_body](#lua_need_request_body) * [ssl_certificate_by_lua_block](#ssl_certificate_by_lua_block) * [ssl_certificate_by_lua_file](#ssl_certificate_by_lua_file) +* [ssl_psk_by_lua_block](#ssl_psk_by_lua_block) +* [ssl_psk_by_lua_file](#ssl_psk_by_lua_file) +* [ssl_psk_identity_hint](#ssl_psk_identity_hint) * [ssl_session_fetch_by_lua_block](#ssl_session_fetch_by_lua_block) * [ssl_session_fetch_by_lua_file](#ssl_session_fetch_by_lua_file) * [ssl_session_store_by_lua_block](#ssl_session_store_by_lua_block) @@ -1094,6 +1097,8 @@ Directives * [lua_ssl_protocols](#lua_ssl_protocols) * [lua_ssl_trusted_certificate](#lua_ssl_trusted_certificate) * [lua_ssl_verify_depth](#lua_ssl_verify_depth) +* [lua_ssl_psk_identity](#lua_ssl_psk_identity) +* [lua_ssl_psk_key](#lua_ssl_psk_key) * [lua_http10_buffering](#lua_http10_buffering) * [rewrite_by_lua_no_postpone](#rewrite_by_lua_no_postpone) * [access_by_lua_no_postpone](#access_by_lua_no_postpone) @@ -2564,6 +2569,108 @@ This directive was first introduced in the `v0.10.0` release. [Back to TOC](#directives) +ssl_psk_by_lua_block +-------------------- + +**syntax:** *ssl_psk_by_lua_block { lua-script }* + +**context:** *server* + +**phase:** *right-before-SSL-handshake* + +This directive runs user Lua code when NGINX is about to start the SSL handshake for the downstream +SSL (https) connections using TLS-PSK and is meant for setting the TLS pre-shared key on a per-request basis. + +The [ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md) + Lua module provided by the [lua-resty-core](https://github.com/openresty/lua-resty-core/#readme) +library is particularly useful in this context. You can use the Lua API offered by this Lua module +to set the TLS pre-shared key for the current SSL connection being initiated. + +This Lua handler does not run at all, however, when NGINX/OpenSSL successfully resumes +the SSL session via SSL session IDs or TLS session tickets for the current SSL connection. In +other words, this Lua handler only runs when NGINX has to initiate a full SSL handshake. + +Below is a trivial example using the +[ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md) module +at the same time: + +```nginx + + server { + listen 443 ssl; + server_name test.com; + + ssl_psk_identity_hint Test_TLS-PSK_Identity_Hint; + + ssl_psk_by_lua_block { + print("About to initiate a new TLS-PSK handshake!") + } + + location / { + root html; + } + } +``` + +See more complicated examples in the [ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md) +Lua module's official documentation. + +Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does the +[ngx.exit](#ngxexit) call with an error code like `ngx.ERROR`. + +This Lua code execution context *does not* support yielding, so Lua APIs that may yield +(like cosockets, sleeping, and "light threads") +are disabled in this context. + +Note, however, you still need to configure the [ssl_certificate](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate) and +[ssl_certificate_key](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key) +directives even though you will not use this static certificate and private key at all. This is +because the NGINX core requires their appearance otherwise you are seeing the following error +while starting NGINX: + + + nginx: [emerg] no ssl configured for the server + + +Furthermore, one needs at least OpenSSL 1.0.0 for this directive to work. + +This directive was first introduced in the `v0.XX.YY` release. + +[Back to TOC](#directives) + +ssl_psk_by_lua_file +------------------- + +**syntax:** *ssl_psk_by_lua_file <path-to-lua-script-file>* + +**context:** *server* + +**phase:** *right-before-SSL-handshake* + +Equivalent to [ssl_psk_by_lua_block](#ssl_psk_by_lua_block), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [Lua/LuaJIT bytecode](#lualuajit-bytecode-support) to be executed. + +When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server. + +This directive was first introduced in the `v0.XX.YY` release. + +[Back to TOC](#directives) + +ssl_psk_identity_hint +--------------------- + +**syntax:** *ssl_psk_identity_hint <tls_psk_identity_hint>* + +**default:** *no* + +**context:** *http, server* + +Specifies the TLS-PSK identity hint string which NGINX will send to a client during +the SSL handshake for the downstream SSL (https) connections. + +This directive was first introduced in the `v0.XX.YY` release. + +[Back to TOC](#directives) + ssl_session_fetch_by_lua_block ------------------------------ @@ -2958,6 +3065,36 @@ See also [lua_ssl_trusted_certificate](#lua_ssl_trusted_certificate). [Back to TOC](#directives) +lua_ssl_psk_identity +-------------------- + +**syntax:** *lua_ssl_psk_identity <tls_psk_identity>* + +**default:** *no* + +**context:** *http, server, location* + +Specifies the TLS-PSK identity string which NGINX will send to a SSL/TLS server in the [tcpsock:sslhandshake](#tcpsocksslhandshake) method. + +This directive was first introduced in the `v0.XX.YY` release. + +[Back to TOC](#directives) + +lua_ssl_psk_key +--------------- + +**syntax:** *lua_ssl_psk_key <tls_psk_key>* + +**default:** *no* + +**context:** *http, server, location* + +Specifies the TLS-PSK key string which NGINX will try use with a SSL/TLS server in the [tcpsock:sslhandshake](#tcpsocksslhandshake) method. + +This directive was first introduced in the `v0.XX.YY` release. + +[Back to TOC](#directives) + lua_http10_buffering -------------------- From 375a933200e9c4caeb3c1d9624c1db3f506bb35b Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 20:51:05 +0300 Subject: [PATCH 18/30] doc: updated the documentation to point to a related branch of lua-resty-core containing TLS-PSK functions. --- README.markdown | 5 ++--- doc/HttpLuaModule.wiki | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/README.markdown b/README.markdown index 1e48899527..b0b1382d93 100644 --- a/README.markdown +++ b/README.markdown @@ -2591,7 +2591,7 @@ the SSL session via SSL session IDs or TLS session tickets for the current SSL c other words, this Lua handler only runs when NGINX has to initiate a full SSL handshake. Below is a trivial example using the -[ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md) module +[ngx.ssl](https://github.com/vartiait/lua-resty-core/blob/ssl-psk/lib/ngx/ssl.md) module at the same time: ```nginx @@ -2615,8 +2615,7 @@ at the same time: See more complicated examples in the [ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md) Lua module's official documentation. -Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does the -[ngx.exit](#ngxexit) call with an error code like `ngx.ERROR`. +Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does return call with an error code like `ngx.ERROR`. This Lua code execution context *does not* support yielding, so Lua APIs that may yield (like cosockets, sleeping, and "light threads") diff --git a/doc/HttpLuaModule.wiki b/doc/HttpLuaModule.wiki index 8042e903cd..f3e444f01d 100644 --- a/doc/HttpLuaModule.wiki +++ b/doc/HttpLuaModule.wiki @@ -2180,7 +2180,7 @@ the SSL session via SSL session IDs or TLS session tickets for the current SSL c other words, this Lua handler only runs when NGINX has to initiate a full SSL handshake. Below is a trivial example using the -[https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md ngx.ssl] module +[https://github.com/vartiait/lua-resty-core/blob/ssl-psk/lib/ngx/ssl.md ngx.ssl] module at the same time: @@ -2203,8 +2203,7 @@ at the same time: See more complicated examples in the [https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md ngx.ssl] Lua module's official documentation. -Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does the -[[#ngx.exit|ngx.exit]] call with an error code like ngx.ERROR. +Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does return call with an error code like ngx.ERROR. This Lua code execution context *does not* support yielding, so Lua APIs that may yield (like cosockets, sleeping, and "light threads") From 7d319c94139e9215c3d109a1621c5ad1d4396444 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 20:56:24 +0300 Subject: [PATCH 19/30] doc: updated the documentation to point to a related branch of lua-resty-core containing TLS-PSK functions. --- README.markdown | 2 +- doc/HttpLuaModule.wiki | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index b0b1382d93..aaab4080c3 100644 --- a/README.markdown +++ b/README.markdown @@ -2612,7 +2612,7 @@ at the same time: } ``` -See more complicated examples in the [ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md) +See more complicated examples in the [ngx.ssl](https://github.com/vartiait/lua-resty-core/blob/ssl-psk/lib/ngx/ssl.md) Lua module's official documentation. Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does return call with an error code like `ngx.ERROR`. diff --git a/doc/HttpLuaModule.wiki b/doc/HttpLuaModule.wiki index f3e444f01d..2a09abb104 100644 --- a/doc/HttpLuaModule.wiki +++ b/doc/HttpLuaModule.wiki @@ -2200,7 +2200,7 @@ at the same time: } -See more complicated examples in the [https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md ngx.ssl] +See more complicated examples in the [https://github.com/vartiait/lua-resty-core/blob/ssl-psk/lib/ngx/ssl.md ngx.ssl] Lua module's official documentation. Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does return call with an error code like ngx.ERROR. From b2344644661cb031f916dd464589c9b377b11972 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Thu, 5 Oct 2017 21:04:17 +0300 Subject: [PATCH 20/30] doc: updated the documentation to contain a better example of using ssl_psk_by_lua_block. --- README.markdown | 22 ++++++++++++++++++++-- doc/HttpLuaModule.wiki | 22 ++++++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/README.markdown b/README.markdown index aaab4080c3..0256b901bd 100644 --- a/README.markdown +++ b/README.markdown @@ -2581,7 +2581,7 @@ ssl_psk_by_lua_block This directive runs user Lua code when NGINX is about to start the SSL handshake for the downstream SSL (https) connections using TLS-PSK and is meant for setting the TLS pre-shared key on a per-request basis. -The [ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md) +The [ngx.ssl](https://github.com/vartiait/lua-resty-core/blob/ssl-psk/lib/ngx/ssl.md) Lua module provided by the [lua-resty-core](https://github.com/openresty/lua-resty-core/#readme) library is particularly useful in this context. You can use the Lua API offered by this Lua module to set the TLS pre-shared key for the current SSL connection being initiated. @@ -2603,7 +2603,25 @@ at the same time: ssl_psk_identity_hint Test_TLS-PSK_Identity_Hint; ssl_psk_by_lua_block { - print("About to initiate a new TLS-PSK handshake!") + local ssl = require "ngx.ssl" + + local psk_identity, err = ssl.get_psk_identity() + if not psk_identity then + ngx.log(ngx.ERR, "Failed to get TLS-PSK Identity: ", err) + return ngx.ERROR + end + + print("Client TLS-PSK Identity: ", psk_identity) + + local psk_key = "psk_test_key" + + local ok, err = ssl.set_psk_key(psk_key) + if not ok then + ngx.log(ngx.ERR, "Failed to set TLS-PSK key: ", err) + return ngx.ERROR + end + + return ngx.OK } location / { diff --git a/doc/HttpLuaModule.wiki b/doc/HttpLuaModule.wiki index 2a09abb104..73d7578dd6 100644 --- a/doc/HttpLuaModule.wiki +++ b/doc/HttpLuaModule.wiki @@ -2170,7 +2170,7 @@ This directive was first introduced in the v0.10.0 release. This directive runs user Lua code when NGINX is about to start the SSL handshake for the downstream SSL (https) connections using TLS-PSK and is meant for setting the TLS pre-shared key on a per-request basis. -The [https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md ngx.ssl] +The [https://github.com/vartiait/lua-resty-core/blob/ssl-psk/lib/ngx/ssl.md ngx.ssl] Lua module provided by the [https://github.com/openresty/lua-resty-core/#readme lua-resty-core] library is particularly useful in this context. You can use the Lua API offered by this Lua module to set the TLS pre-shared key for the current SSL connection being initiated. @@ -2191,7 +2191,25 @@ at the same time: ssl_psk_identity_hint Test_TLS-PSK_Identity_Hint; ssl_psk_by_lua_block { - print("About to initiate a new TLS-PSK handshake!") + local ssl = require "ngx.ssl" + + local psk_identity, err = ssl.get_psk_identity() + if not psk_identity then + ngx.log(ngx.ERR, "Failed to get TLS-PSK Identity: ", err) + return ngx.ERROR + end + + print("Client TLS-PSK Identity: ", psk_identity) + + local psk_key = "psk_test_key" + + local ok, err = ssl.set_psk_key(psk_key) + if not ok then + ngx.log(ngx.ERR, "Failed to set TLS-PSK key: ", err) + return ngx.ERROR + end + + return ngx.OK } location / { From 81a1273814c7e6bae4e100b0c4313872451fcf73 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Fri, 6 Oct 2017 10:52:59 +0300 Subject: [PATCH 21/30] bugfix: return NGX_OK in ngx_http_lua_ffi_exit when in NGX_HTTP_LUA_CONTEXT_SSL_PSK. --- src/ngx_http_lua_control.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ngx_http_lua_control.c b/src/ngx_http_lua_control.c index 62fce7c8ae..45c31262d9 100644 --- a/src/ngx_http_lua_control.c +++ b/src/ngx_http_lua_control.c @@ -498,8 +498,7 @@ ngx_http_lua_ffi_exit(ngx_http_request_t *r, int status, u_char *err, ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua exit with code %d", status); - if (ctx->context == NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE - || ctx->context == NGX_HTTP_LUA_CONTEXT_SSL_PSK) { + if (ctx->context == NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE) { return NGX_DONE; } From dda90bcc06bb2b99ed65292fbfdec4d38b6e7372 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Sat, 7 Oct 2017 11:05:38 +0300 Subject: [PATCH 22/30] Removed trailing white spaces. --- src/ngx_http_lua_module.c | 4 ++-- src/ngx_http_lua_ssl_pskby.c | 4 ++-- src/ngx_http_lua_ssl_pskby.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ngx_http_lua_module.c b/src/ngx_http_lua_module.c index 27208bc2f8..0848dec3b4 100644 --- a/src/ngx_http_lua_module.c +++ b/src/ngx_http_lua_module.c @@ -1070,7 +1070,7 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) } if (conf->srv.ssl_psk_identity_hint.len) { - dd("ssl psk identity hint: %.*s", + dd("ssl psk identity hint: %.*s", (int) conf->srv.ssl_psk_identity_hint.len, conf->srv.ssl_psk_identity_hint.data); @@ -1126,7 +1126,7 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) # if OPENSSL_VERSION_NUMBER >= 0x1000000fL - SSL_CTX_set_psk_server_callback(sscf->ssl.ctx, + SSL_CTX_set_psk_server_callback(sscf->ssl.ctx, ngx_http_lua_ssl_psk_server_handler); # else diff --git a/src/ngx_http_lua_ssl_pskby.c b/src/ngx_http_lua_ssl_pskby.c index 92e64dbf80..101198be0e 100644 --- a/src/ngx_http_lua_ssl_pskby.c +++ b/src/ngx_http_lua_ssl_pskby.c @@ -2,7 +2,7 @@ /* * Based on ngx_http_lua_ssl_certby.c and ngx_http_lua_ssl_session_storeby.c * by Yichun Zhang (agentzh) - * + * * Author: Tuure Vartiainen (vartiait) */ @@ -593,7 +593,7 @@ ngx_http_lua_ssl_psk_by_chunk(lua_State *L, ngx_http_request_t *r) /* set psk key from key to lua context. */ int -ngx_http_lua_ffi_ssl_set_psk_key(ngx_http_request_t *r, +ngx_http_lua_ffi_ssl_set_psk_key(ngx_http_request_t *r, const char *key, size_t len, char **err) { u_char *buf; diff --git a/src/ngx_http_lua_ssl_pskby.h b/src/ngx_http_lua_ssl_pskby.h index 2289048834..394348f088 100644 --- a/src/ngx_http_lua_ssl_pskby.h +++ b/src/ngx_http_lua_ssl_pskby.h @@ -2,7 +2,7 @@ /* * Based on ngx_http_lua_ssl_certby.h and ngx_http_lua_ssl_session_storeby.h * by Yichun Zhang (agentzh) - * + * * Author: Tuure Vartiainen (vartiait) */ From c1f255b2ca97d9643da4b419901b4cfb69dc14c9 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Sun, 8 Oct 2017 22:54:51 +0300 Subject: [PATCH 23/30] Changed ngx_http_lua_ssl_psk_server_handler to use ssl_certificate_by_lua* instead of separate ssl_psk_by_lua*. --- src/ngx_http_lua_module.c | 2 ++ src/ngx_http_lua_ssl.h | 1 + src/ngx_http_lua_ssl_certby.c | 10 +++++++++- src/ngx_http_lua_ssl_pskby.c | 18 +++++++++--------- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/ngx_http_lua_module.c b/src/ngx_http_lua_module.c index 0848dec3b4..c7a85767f0 100644 --- a/src/ngx_http_lua_module.c +++ b/src/ngx_http_lua_module.c @@ -1010,6 +1010,8 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) SSL_CTX_set_cert_cb(sscf->ssl.ctx, ngx_http_lua_ssl_cert_handler, NULL); + SSL_CTX_set_psk_server_callback(sscf->ssl.ctx, + ngx_http_lua_ssl_psk_server_handler); # else ngx_log_error(NGX_LOG_EMERG, cf->log, 0, diff --git a/src/ngx_http_lua_ssl.h b/src/ngx_http_lua_ssl.h index 6f9f4baad8..a612316d93 100644 --- a/src/ngx_http_lua_ssl.h +++ b/src/ngx_http_lua_ssl.h @@ -35,6 +35,7 @@ typedef struct { unsigned entered_cert_handler:1; unsigned entered_sess_fetch_handler:1; + unsigned entered_psk_handler:1; } ngx_http_lua_ssl_ctx_t; diff --git a/src/ngx_http_lua_ssl_certby.c b/src/ngx_http_lua_ssl_certby.c index 95be47f6b5..2731ee6197 100644 --- a/src/ngx_http_lua_ssl_certby.c +++ b/src/ngx_http_lua_ssl_certby.c @@ -461,6 +461,7 @@ ngx_http_lua_ssl_cert_by_chunk(lua_State *L, ngx_http_request_t *r) lua_State *co; ngx_http_lua_ctx_t *ctx; ngx_http_cleanup_t *cln; + ngx_http_lua_ssl_ctx_t *cctx; ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); @@ -522,7 +523,14 @@ ngx_http_lua_ssl_cert_by_chunk(lua_State *L, ngx_http_request_t *r) ctx->cleanup = &cln->handler; } - ctx->context = NGX_HTTP_LUA_CONTEXT_SSL_CERT; + cctx = ngx_http_lua_ssl_get_ctx(r->connection->ssl->connection); + + if (cctx != NULL && cctx->entered_psk_handler) { + ctx->context = NGX_HTTP_LUA_CONTEXT_SSL_PSK; + } + else { + ctx->context = NGX_HTTP_LUA_CONTEXT_SSL_CERT; + } rc = ngx_http_lua_run_thread(L, r, ctx, 0); diff --git a/src/ngx_http_lua_ssl_pskby.c b/src/ngx_http_lua_ssl_pskby.c index 101198be0e..b958ea5743 100644 --- a/src/ngx_http_lua_ssl_pskby.c +++ b/src/ngx_http_lua_ssl_pskby.c @@ -263,6 +263,7 @@ unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, cctx->request = r; cctx->psk_identity.data = (u_char *) identity; cctx->psk_identity.len = ngx_strlen(identity); + cctx->entered_psk_handler = 1; cctx->done = 0; dd("setting cctx = %p", cctx); @@ -281,7 +282,7 @@ unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, c->log->action = "setting SSL PSK by lua"; - rc = lscf->srv.ssl_psk_handler(r, lscf, L); + rc = lscf->srv.ssl_cert_handler(r, lscf, L); if (rc >= NGX_OK || rc == NGX_ERROR) { cctx->done = 1; @@ -291,26 +292,26 @@ unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, - "lua_psk_by_lua: handler return value: %i, " + "lua_certificate_by_lua: handler return value: %i, " "psk server cb exit code: %d", rc, cctx->exit_code); c->log->action = "SSL handshaking"; - if (rc == NGX_ERROR) { + if (rc == NGX_ERROR || cctx->exit_code != NGX_OK) { /* 0 == unknown_psk_identity */ - return cctx->exit_code; + return 0; } if (cctx->psk_key.data == NULL) { ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "psk_key.data == NULL"); - return cctx->exit_code; + return 0; } if (cctx->psk_key.len == 0) { ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "psk_key.len == 0"); - return cctx->exit_code; + return 0; } if (cctx->psk_key.len > (size_t) max_psk_len) { @@ -318,14 +319,13 @@ unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, "psk_key.len: %i > max_psk_len: %i", cctx->psk_key.len, max_psk_len); - return cctx->exit_code; + return 0; } ngx_memcpy(psk, cctx->psk_key.data, cctx->psk_key.len); - cctx->exit_code = cctx->psk_key.len; /* return length of psk key */ - return cctx->exit_code; + return cctx->psk_key.len; } /* impossible to reach here */ From 2d2e9a4a36e7868e5cc189e4f398e8169f5aed92 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Mon, 9 Oct 2017 17:22:18 +0300 Subject: [PATCH 24/30] Removed references to ssl_psk_by_lua*. --- src/ngx_http_lua_common.h | 3 - src/ngx_http_lua_module.c | 56 --------- src/ngx_http_lua_ssl_pskby.c | 234 ++--------------------------------- src/ngx_http_lua_ssl_pskby.h | 12 -- 4 files changed, 10 insertions(+), 295 deletions(-) diff --git a/src/ngx_http_lua_common.h b/src/ngx_http_lua_common.h index 0845959f50..2ed06b96ff 100644 --- a/src/ngx_http_lua_common.h +++ b/src/ngx_http_lua_common.h @@ -250,9 +250,6 @@ union ngx_http_lua_srv_conf_u { ngx_str_t ssl_sess_fetch_src; u_char *ssl_sess_fetch_src_key; - ngx_http_lua_srv_conf_handler_pt ssl_psk_handler; - ngx_str_t ssl_psk_src; - u_char *ssl_psk_src_key; ngx_str_t ssl_psk_identity_hint; } srv; #endif diff --git a/src/ngx_http_lua_module.c b/src/ngx_http_lua_module.c index c7a85767f0..c3e67acedc 100644 --- a/src/ngx_http_lua_module.c +++ b/src/ngx_http_lua_module.c @@ -565,20 +565,6 @@ static ngx_command_t ngx_http_lua_cmds[] = { offsetof(ngx_http_lua_srv_conf_t, srv.ssl_psk_identity_hint), NULL }, - { ngx_string("ssl_psk_by_lua_block"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_http_lua_ssl_psk_by_lua_block, - NGX_HTTP_SRV_CONF_OFFSET, - 0, - (void *) ngx_http_lua_ssl_psk_server_handler_inline }, - - { ngx_string("ssl_psk_by_lua_file"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, - ngx_http_lua_ssl_psk_by_lua, - NGX_HTTP_SRV_CONF_OFFSET, - 0, - (void *) ngx_http_lua_ssl_psk_server_handler_file }, - { ngx_string("lua_ssl_psk_identity"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -958,9 +944,6 @@ ngx_http_lua_create_srv_conf(ngx_conf_t *cf) * lscf->srv.ssl_session_fetch_src = { 0, NULL }; * lscf->srv.ssl_session_fetch_src_key = NULL; * - * lscf->srv.ssl_psk_handler = NULL; - * lscf->srv.ssl_psk_src = { 0, NULL }; - * lscf->srv.ssl_psk_src_key = NULL; * lscf->srv.ssl_psk_identity_hint = { 0, NULL }; * * lscf->balancer.handler = NULL; @@ -1103,45 +1086,6 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) # endif } - if (conf->srv.ssl_psk_src.len == 0) { - conf->srv.ssl_psk_src = prev->srv.ssl_psk_src; - conf->srv.ssl_psk_src_key = prev->srv.ssl_psk_src_key; - conf->srv.ssl_psk_handler = prev->srv.ssl_psk_handler; - } - - if (conf->srv.ssl_psk_src.len) { - sscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_ssl_module); - if (sscf == NULL || sscf->ssl.ctx == NULL) { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "no ssl configured for the server"); - - return NGX_CONF_ERROR; - } - -#ifdef LIBRESSL_VERSION_NUMBER - - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "LibreSSL does not support ssl_psk_by_lua*"); - return NGX_CONF_ERROR; - -#else - -# if OPENSSL_VERSION_NUMBER >= 0x1000000fL - - SSL_CTX_set_psk_server_callback(sscf->ssl.ctx, - ngx_http_lua_ssl_psk_server_handler); - -# else - - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "OpenSSL too old to support ssl_psk_by_lua*"); - return NGX_CONF_ERROR; - -# endif - -#endif - } - #endif /* NGX_HTTP_SSL */ return NGX_CONF_OK; } diff --git a/src/ngx_http_lua_ssl_pskby.c b/src/ngx_http_lua_ssl_pskby.c index b958ea5743..e075a7b950 100644 --- a/src/ngx_http_lua_ssl_pskby.c +++ b/src/ngx_http_lua_ssl_pskby.c @@ -28,151 +28,6 @@ static u_char *ngx_http_lua_log_ssl_psk_error(ngx_log_t *log, u_char *buf, size_t len); -static ngx_int_t ngx_http_lua_ssl_psk_by_chunk(lua_State *L, - ngx_http_request_t *r); - - -ngx_int_t -ngx_http_lua_ssl_psk_server_handler_file(ngx_http_request_t *r, - ngx_http_lua_srv_conf_t *lscf, lua_State *L) -{ - ngx_int_t rc; - - rc = ngx_http_lua_cache_loadfile(r->connection->log, L, - lscf->srv.ssl_psk_src.data, - lscf->srv.ssl_psk_src_key); - if (rc != NGX_OK) { - return rc; - } - - /* make sure we have a valid code chunk */ - ngx_http_lua_assert(lua_isfunction(L, -1)); - - return ngx_http_lua_ssl_psk_by_chunk(L, r); -} - - -ngx_int_t -ngx_http_lua_ssl_psk_server_handler_inline(ngx_http_request_t *r, - ngx_http_lua_srv_conf_t *lscf, lua_State *L) -{ - ngx_int_t rc; - - rc = ngx_http_lua_cache_loadbuffer(r->connection->log, L, - lscf->srv.ssl_psk_src.data, - lscf->srv.ssl_psk_src.len, - lscf->srv.ssl_psk_src_key, - "=ssl_psk_by_lua"); - if (rc != NGX_OK) { - return rc; - } - - /* make sure we have a valid code chunk */ - ngx_http_lua_assert(lua_isfunction(L, -1)); - - return ngx_http_lua_ssl_psk_by_chunk(L, r); -} - - -char * -ngx_http_lua_ssl_psk_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf) -{ - char *rv; - ngx_conf_t save; - - save = *cf; - cf->handler = ngx_http_lua_ssl_psk_by_lua; - cf->handler_conf = conf; - - rv = ngx_http_lua_conf_lua_block_parse(cf, cmd); - - *cf = save; - - return rv; -} - - -char * -ngx_http_lua_ssl_psk_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf) -{ -#if OPENSSL_VERSION_NUMBER < 0x1000100fL - - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "at least OpenSSL 1.0.1 required but found " - OPENSSL_VERSION_TEXT); - - return NGX_CONF_ERROR; - -#else - - u_char *p; - u_char *name; - ngx_str_t *value; - ngx_http_lua_srv_conf_t *lscf = conf; - - /* must specify a concrete handler */ - if (cmd->post == NULL) { - return NGX_CONF_ERROR; - } - - if (lscf->srv.ssl_psk_handler) { - return "is duplicate"; - } - - if (ngx_http_lua_ssl_init(cf->log) != NGX_OK) { - return NGX_CONF_ERROR; - } - - value = cf->args->elts; - - lscf->srv.ssl_psk_handler = (ngx_http_lua_srv_conf_handler_pt) cmd->post; - - if (cmd->post == ngx_http_lua_ssl_psk_server_handler_file) { - /* Lua code in an external file */ - - name = ngx_http_lua_rebase_path(cf->pool, value[1].data, - value[1].len); - if (name == NULL) { - return NGX_CONF_ERROR; - } - - lscf->srv.ssl_psk_src.data = name; - lscf->srv.ssl_psk_src.len = ngx_strlen(name); - - p = ngx_palloc(cf->pool, NGX_HTTP_LUA_FILE_KEY_LEN + 1); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - lscf->srv.ssl_psk_src_key = p; - - p = ngx_copy(p, NGX_HTTP_LUA_FILE_TAG, NGX_HTTP_LUA_FILE_TAG_LEN); - p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len); - *p = '\0'; - - } else { - /* inlined Lua code */ - - lscf->srv.ssl_psk_src = value[1]; - - p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - lscf->srv.ssl_psk_src_key = p; - - p = ngx_copy(p, NGX_HTTP_LUA_INLINE_TAG, NGX_HTTP_LUA_INLINE_TAG_LEN); - p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len); - *p = '\0'; - } - - return NGX_CONF_OK; - -#endif /* OPENSSL_VERSION_NUMBER < 0x1000205fL */ -} unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, @@ -510,85 +365,6 @@ ngx_http_lua_log_ssl_psk_error(ngx_log_t *log, u_char *buf, size_t len) } -static ngx_int_t -ngx_http_lua_ssl_psk_by_chunk(lua_State *L, ngx_http_request_t *r) -{ - size_t len; - u_char *err_msg; - ngx_int_t rc; - ngx_http_lua_ctx_t *ctx; - - ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); - - if (ctx == NULL) { - ctx = ngx_http_lua_create_ctx(r); - if (ctx == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - } else { - dd("reset ctx"); - ngx_http_lua_reset_ctx(r, L, ctx); - } - - ctx->entered_content_phase = 1; - ctx->context = NGX_HTTP_LUA_CONTEXT_SSL_PSK; - - /* init nginx context in Lua VM */ - ngx_http_lua_set_req(L, r); - ngx_http_lua_create_new_globals_table(L, 0 /* narr */, 1 /* nrec */); - - /* {{{ make new env inheriting main thread's globals table */ - lua_createtable(L, 0, 1 /* nrec */); /* the metatable for the new env */ - ngx_http_lua_get_globals_table(L); - lua_setfield(L, -2, "__index"); - lua_setmetatable(L, -2); /* setmetatable({}, {__index = _G}) */ - /* }}} */ - - lua_setfenv(L, -2); /* set new running env for the code closure */ - - lua_pushcfunction(L, ngx_http_lua_traceback); - lua_insert(L, 1); /* put it under chunk and args */ - - /* protected call user code */ - rc = lua_pcall(L, 0, 1, 1); - - lua_remove(L, 1); /* remove traceback function */ - - dd("rc == %d", (int) rc); - - if (rc != 0) { - /* error occured when running loaded code */ - err_msg = (u_char *) lua_tolstring(L, -1, &len); - - if (err_msg == NULL) { - err_msg = (u_char *) "unknown reason"; - len = sizeof("unknown reason") - 1; - } - - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "failed to run ssl_psk_by_lua*: %*s", len, err_msg); - - lua_settop(L, 0); /* clear remaining elems on stack */ - ngx_http_lua_finalize_request(r, rc); - - return NGX_ERROR; - } - - /* rc == 0 */ - rc = (ngx_int_t) lua_tointeger(L, -1); - dd("got return value: %d", (int) rc); - - if (rc != NGX_OK) { - rc = NGX_ERROR; - } - - lua_settop(L, 0); /* clear remaining elems on stack */ - ngx_http_lua_finalize_request(r, rc); - return rc; -} - - #ifndef NGX_LUA_NO_FFI_API /* set psk key from key to lua context. */ @@ -667,6 +443,11 @@ ngx_http_lua_ffi_ssl_get_psk_identity(ngx_http_request_t *r, return NGX_ERROR; } + if(!cctx->entered_psk_handler) { + *err = "not in psk context"; + return NGX_ERROR; + } + id = cctx->psk_identity.data; if (id == NULL) { *err = "uninitialized psk identity in lua context"; @@ -714,6 +495,11 @@ ngx_http_lua_ffi_ssl_get_psk_identity_size(ngx_http_request_t *r, return NGX_ERROR; } + if(!cctx->entered_psk_handler) { + *err = "not in psk context"; + return NGX_ERROR; + } + if (cctx->psk_identity.len == 0) { *err = "uninitialized psk identity len in lua context"; return NGX_ERROR; diff --git a/src/ngx_http_lua_ssl_pskby.h b/src/ngx_http_lua_ssl_pskby.h index 394348f088..fcda5bee3b 100644 --- a/src/ngx_http_lua_ssl_pskby.h +++ b/src/ngx_http_lua_ssl_pskby.h @@ -17,18 +17,6 @@ #if (NGX_HTTP_SSL) -ngx_int_t ngx_http_lua_ssl_psk_server_handler_inline(ngx_http_request_t *r, - ngx_http_lua_srv_conf_t *lscf, lua_State *L); - -ngx_int_t ngx_http_lua_ssl_psk_server_handler_file(ngx_http_request_t *r, - ngx_http_lua_srv_conf_t *lscf, lua_State *L); - -char *ngx_http_lua_ssl_psk_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); - -char *ngx_http_lua_ssl_psk_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); - unsigned int ngx_http_lua_ssl_psk_server_handler(ngx_ssl_conn_t *ssl_conn, const char *identity, unsigned char *psk, unsigned int max_psk_len); From 8fbbe24c9de5809dcfd42a58e0d2fc938722ea72 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Mon, 9 Oct 2017 17:24:27 +0300 Subject: [PATCH 25/30] tests: Changed t/140-ssl-c-api.t TLS-PSK test to use ssl_certificate_by_lua_block instead of ssl_psk_by_lua_block. --- t/140-ssl-c-api.t | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/t/140-ssl-c-api.t b/t/140-ssl-c-api.t index 96ecb92343..d2ffee97cc 100644 --- a/t/140-ssl-c-api.t +++ b/t/140-ssl-c-api.t @@ -832,7 +832,7 @@ lua ssl server name: "test.com" ssl_protocols TLSv1; ssl_ciphers PSK; - ssl_psk_by_lua_block { + ssl_certificate_by_lua_block { collectgarbage() local ffi = require "ffi" @@ -849,7 +849,12 @@ lua ssl server name: "test.com" local len = ffi.C.ngx_http_lua_ffi_ssl_get_psk_identity_size(r, errmsg) if len < 0 then - ngx.log(ngx.ERR, "failed to get psk identity size: ", ffi.string(errmsg[0])) + local error_msg = ffi.string(errmsg[0]) + if error_msg and error_msg == "not in psk context" then + -- handler was not called by TLS-PSK callback + return + end + ngx.log(ngx.ERR, "failed to get psk identity size: ", error_msg) return end From 7fd69c34cc64dc263e083342be0c0780b2c482a4 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Mon, 9 Oct 2017 17:25:32 +0300 Subject: [PATCH 26/30] doc: Removed references to ssl_psk_by_lua*. --- README.markdown | 105 ----------------------------------------- doc/HttpLuaModule.wiki | 96 ------------------------------------- 2 files changed, 201 deletions(-) diff --git a/README.markdown b/README.markdown index 0256b901bd..8562a227c0 100644 --- a/README.markdown +++ b/README.markdown @@ -1076,8 +1076,6 @@ Directives * [lua_need_request_body](#lua_need_request_body) * [ssl_certificate_by_lua_block](#ssl_certificate_by_lua_block) * [ssl_certificate_by_lua_file](#ssl_certificate_by_lua_file) -* [ssl_psk_by_lua_block](#ssl_psk_by_lua_block) -* [ssl_psk_by_lua_file](#ssl_psk_by_lua_file) * [ssl_psk_identity_hint](#ssl_psk_identity_hint) * [ssl_session_fetch_by_lua_block](#ssl_session_fetch_by_lua_block) * [ssl_session_fetch_by_lua_file](#ssl_session_fetch_by_lua_file) @@ -2569,109 +2567,6 @@ This directive was first introduced in the `v0.10.0` release. [Back to TOC](#directives) -ssl_psk_by_lua_block --------------------- - -**syntax:** *ssl_psk_by_lua_block { lua-script }* - -**context:** *server* - -**phase:** *right-before-SSL-handshake* - -This directive runs user Lua code when NGINX is about to start the SSL handshake for the downstream -SSL (https) connections using TLS-PSK and is meant for setting the TLS pre-shared key on a per-request basis. - -The [ngx.ssl](https://github.com/vartiait/lua-resty-core/blob/ssl-psk/lib/ngx/ssl.md) - Lua module provided by the [lua-resty-core](https://github.com/openresty/lua-resty-core/#readme) -library is particularly useful in this context. You can use the Lua API offered by this Lua module -to set the TLS pre-shared key for the current SSL connection being initiated. - -This Lua handler does not run at all, however, when NGINX/OpenSSL successfully resumes -the SSL session via SSL session IDs or TLS session tickets for the current SSL connection. In -other words, this Lua handler only runs when NGINX has to initiate a full SSL handshake. - -Below is a trivial example using the -[ngx.ssl](https://github.com/vartiait/lua-resty-core/blob/ssl-psk/lib/ngx/ssl.md) module -at the same time: - -```nginx - - server { - listen 443 ssl; - server_name test.com; - - ssl_psk_identity_hint Test_TLS-PSK_Identity_Hint; - - ssl_psk_by_lua_block { - local ssl = require "ngx.ssl" - - local psk_identity, err = ssl.get_psk_identity() - if not psk_identity then - ngx.log(ngx.ERR, "Failed to get TLS-PSK Identity: ", err) - return ngx.ERROR - end - - print("Client TLS-PSK Identity: ", psk_identity) - - local psk_key = "psk_test_key" - - local ok, err = ssl.set_psk_key(psk_key) - if not ok then - ngx.log(ngx.ERR, "Failed to set TLS-PSK key: ", err) - return ngx.ERROR - end - - return ngx.OK - } - - location / { - root html; - } - } -``` - -See more complicated examples in the [ngx.ssl](https://github.com/vartiait/lua-resty-core/blob/ssl-psk/lib/ngx/ssl.md) -Lua module's official documentation. - -Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does return call with an error code like `ngx.ERROR`. - -This Lua code execution context *does not* support yielding, so Lua APIs that may yield -(like cosockets, sleeping, and "light threads") -are disabled in this context. - -Note, however, you still need to configure the [ssl_certificate](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate) and -[ssl_certificate_key](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key) -directives even though you will not use this static certificate and private key at all. This is -because the NGINX core requires their appearance otherwise you are seeing the following error -while starting NGINX: - - - nginx: [emerg] no ssl configured for the server - - -Furthermore, one needs at least OpenSSL 1.0.0 for this directive to work. - -This directive was first introduced in the `v0.XX.YY` release. - -[Back to TOC](#directives) - -ssl_psk_by_lua_file -------------------- - -**syntax:** *ssl_psk_by_lua_file <path-to-lua-script-file>* - -**context:** *server* - -**phase:** *right-before-SSL-handshake* - -Equivalent to [ssl_psk_by_lua_block](#ssl_psk_by_lua_block), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [Lua/LuaJIT bytecode](#lualuajit-bytecode-support) to be executed. - -When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server. - -This directive was first introduced in the `v0.XX.YY` release. - -[Back to TOC](#directives) - ssl_psk_identity_hint --------------------- diff --git a/doc/HttpLuaModule.wiki b/doc/HttpLuaModule.wiki index 73d7578dd6..23aba0d30e 100644 --- a/doc/HttpLuaModule.wiki +++ b/doc/HttpLuaModule.wiki @@ -2159,102 +2159,6 @@ When a relative path like foo/bar.lua is given, they will be turned This directive was first introduced in the v0.10.0 release. -== ssl_psk_by_lua_block == - -'''syntax:''' ''ssl_psk_by_lua_block { lua-script }'' - -'''context:''' ''server'' - -'''phase:''' ''right-before-SSL-handshake'' - -This directive runs user Lua code when NGINX is about to start the SSL handshake for the downstream -SSL (https) connections using TLS-PSK and is meant for setting the TLS pre-shared key on a per-request basis. - -The [https://github.com/vartiait/lua-resty-core/blob/ssl-psk/lib/ngx/ssl.md ngx.ssl] - Lua module provided by the [https://github.com/openresty/lua-resty-core/#readme lua-resty-core] -library is particularly useful in this context. You can use the Lua API offered by this Lua module -to set the TLS pre-shared key for the current SSL connection being initiated. - -This Lua handler does not run at all, however, when NGINX/OpenSSL successfully resumes -the SSL session via SSL session IDs or TLS session tickets for the current SSL connection. In -other words, this Lua handler only runs when NGINX has to initiate a full SSL handshake. - -Below is a trivial example using the -[https://github.com/vartiait/lua-resty-core/blob/ssl-psk/lib/ngx/ssl.md ngx.ssl] module -at the same time: - - - server { - listen 443 ssl; - server_name test.com; - - ssl_psk_identity_hint Test_TLS-PSK_Identity_Hint; - - ssl_psk_by_lua_block { - local ssl = require "ngx.ssl" - - local psk_identity, err = ssl.get_psk_identity() - if not psk_identity then - ngx.log(ngx.ERR, "Failed to get TLS-PSK Identity: ", err) - return ngx.ERROR - end - - print("Client TLS-PSK Identity: ", psk_identity) - - local psk_key = "psk_test_key" - - local ok, err = ssl.set_psk_key(psk_key) - if not ok then - ngx.log(ngx.ERR, "Failed to set TLS-PSK key: ", err) - return ngx.ERROR - end - - return ngx.OK - } - - location / { - root html; - } - } - - -See more complicated examples in the [https://github.com/vartiait/lua-resty-core/blob/ssl-psk/lib/ngx/ssl.md ngx.ssl] -Lua module's official documentation. - -Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does return call with an error code like ngx.ERROR. - -This Lua code execution context *does not* support yielding, so Lua APIs that may yield -(like cosockets, sleeping, and "light threads") -are disabled in this context. - -Note, however, you still need to configure the [http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate ssl_certificate] and -[http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key ssl_certificate_key] -directives even though you will not use this static certificate and private key at all. This is -because the NGINX core requires their appearance otherwise you are seeing the following error -while starting NGINX: - - - nginx: [emerg] no ssl configured for the server - - -Furthermore, one needs at least OpenSSL 1.0.0 for this directive to work. - -This directive was first introduced in the v0.XX.YY release. - -== ssl_psk_by_lua_file == - -'''syntax:''' ''ssl_psk_by_lua_file '' - -'''context:''' ''server'' - -'''phase:''' ''right-before-SSL-handshake'' - -Equivalent to [[#ssl_psk_by_lua_block|ssl_psk_by_lua_block]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#Lua/LuaJIT bytecode support|Lua/LuaJIT bytecode]] to be executed. - -When a relative path like foo/bar.lua is given, they will be turned into the absolute path relative to the server prefix path determined by the -p PATH command-line option while starting the Nginx server. - -This directive was first introduced in the v0.XX.YY release. - == ssl_psk_identity_hint == '''syntax:''' ''ssl_psk_identity_hint '' From 2ca05ce71f975651359518c2d06db20b62f49c8d Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Mon, 9 Oct 2017 17:26:34 +0300 Subject: [PATCH 27/30] bugfix: copy ctx->exit_code to cctx->exit_code in ngx_http_lua_ssl_cert_by_chunk. --- src/ngx_http_lua_ssl_certby.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ngx_http_lua_ssl_certby.c b/src/ngx_http_lua_ssl_certby.c index 2731ee6197..178db81ded 100644 --- a/src/ngx_http_lua_ssl_certby.c +++ b/src/ngx_http_lua_ssl_certby.c @@ -535,8 +535,10 @@ ngx_http_lua_ssl_cert_by_chunk(lua_State *L, ngx_http_request_t *r) rc = ngx_http_lua_run_thread(L, r, ctx, 0); if (rc == NGX_ERROR || rc >= NGX_OK) { - /* do nothing */ - + /* copy ctx->exit_code to cctx->exit_code */ + if (ctx->exited) { + cctx->exit_code = ctx->exit_code; + } } else if (rc == NGX_AGAIN) { rc = ngx_http_lua_content_run_posted_threads(L, r, ctx, 0); From 7fff2b20f40ad6c0b9da1516dea13b64c3a86241 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Mon, 9 Oct 2017 18:14:38 +0300 Subject: [PATCH 28/30] This reverts commit 01055ca82044dd452b2a10b46f67850f0526473b --- src/ngx_http_lua_ssl_certby.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ngx_http_lua_ssl_certby.c b/src/ngx_http_lua_ssl_certby.c index 178db81ded..708756b77e 100644 --- a/src/ngx_http_lua_ssl_certby.c +++ b/src/ngx_http_lua_ssl_certby.c @@ -535,10 +535,7 @@ ngx_http_lua_ssl_cert_by_chunk(lua_State *L, ngx_http_request_t *r) rc = ngx_http_lua_run_thread(L, r, ctx, 0); if (rc == NGX_ERROR || rc >= NGX_OK) { - /* copy ctx->exit_code to cctx->exit_code */ - if (ctx->exited) { - cctx->exit_code = ctx->exit_code; - } + /* do nothing */ } else if (rc == NGX_AGAIN) { rc = ngx_http_lua_content_run_posted_threads(L, r, ctx, 0); From 3353c6da86a16324a38f36b07642d4f939ec0224 Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Sat, 14 Oct 2017 14:03:08 +0300 Subject: [PATCH 29/30] tests: Updated expected ciphers to match ones used by openresty.org in t/129-ssl-socket.t --- t/129-ssl-socket.t | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/t/129-ssl-socket.t b/t/129-ssl-socket.t index e7447a7ced..38b21a6a1f 100644 --- a/t/129-ssl-socket.t +++ b/t/129-ssl-socket.t @@ -1181,7 +1181,7 @@ lua ssl free session: ([0-9A-F]+):1 $/ --- error_log lua ssl server name: "openresty.org" -SSL: TLSv1.2, cipher: "ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 +SSL: TLSv1.2, cipher: "ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 --- no_error_log SSL reused session [error] @@ -1341,7 +1341,7 @@ lua ssl free session: ([0-9A-F]+):1 $/ --- error_log lua ssl server name: "openresty.org" -SSL: TLSv1, cipher: "ECDHE-RSA-AES128-SHA SSLv3 +SSL: TLSv1, cipher: "ECDHE-RSA-AES256-SHA SSLv3 --- no_error_log SSL reused session [error] From f1844c88dd0996f0881a26e072f1ef2711e491cd Mon Sep 17 00:00:00 2001 From: Tuure Vartiainen Date: Sat, 14 Oct 2017 14:27:31 +0300 Subject: [PATCH 30/30] tests: increased a timeout value of test 25 by one second in t/129-ssl-socket.t --- t/129-ssl-socket.t | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/t/129-ssl-socket.t b/t/129-ssl-socket.t index 38b21a6a1f..8d7d97b789 100644 --- a/t/129-ssl-socket.t +++ b/t/129-ssl-socket.t @@ -2034,7 +2034,7 @@ SSL reused session content_by_lua ' local sock = ngx.socket.tcp() - sock:settimeout(2000) + sock:settimeout(3000) do local ok, err = sock:connect("openresty.org", 443) @@ -2103,7 +2103,7 @@ lua ssl server name: "openresty.org" SSL reused session [error] [alert] ---- timeout: 5 +--- timeout: 6