Squashed 'src/deps/src/lua-resty-core/' changes from 812b2d3871..fa3cd7aec1

fa3cd7aec1 bumped lua-resty-core to 0.1.29.
8537c5ed16 tests: updated test plan specifically for check leak mode.
c3ccf27184 tests: valgrind.suppress: replace part of the call stack with `...`.
4154b8bd58 tests: increase timeout for valgrind mode.
caef76e0f4 travis: bumped the NGINX core to 1.27.0.
837a252dbc tests: t/pipe.t: updated plan tests number.
25e9ac84d3 tests: updated the regular expression to avoid matching other content in HUP reload mode.
aed8afb22b tests: Change TEST_NGINX_SERVER_SSL_PORT* to use random ports.
f068a8528c tests: valgrind.suppress: added SSL-related valgrind.suppress entries. (#478)
b5e1933479 tests: fixed malformed valgrind.suppress.
09fe698c13 tests: use nginx-1.25.3 instead of nginx-1.25.1.
be1e9219e4 tests: t/balancer.t: updated expected output, now respecting the maximum retry count when using balancer pool as well.
817a22031b feature: add ssl_trusted_certificate argument for ssl.verify_client().
1ea604b816 tests: fixed test cases for set_current_peer.
b024e43e61 tests: remove build duplicate param.
799d9b1905 feature: add balancer.bind_to_local_addr for stream module. Co-author: ytlm <ytlm.lv@gmail.com>
fb70407059 feature: makes outgoing connections to a proxied server originate from the specified local IP address with an optional port.
d981e1bd8d feature: implemented keepalive pooling in 'balancer_by_lua*'.
f9add68387 bugfix: might get previous nextupdate value.
3e21967485 doc: add ToC entry for 'get_supported_versions'.
64fb9c1acf optimize: localize tonumber for ngx.worker.pids.
5ada3082bd tests: fixed the repo URL.
7a6521deb7 feature: validate_ocsp_response should return nextUpdate if available.
48ee7600fa feature: add ssl.get_req_ssl_pointer.
149e64003f feature: add support for exporting key material to derive keys from the tls master secret.
59965f8a6b doc: add doc for ssl.get_client_random.
6b981dc7f4 feature: add balancer.set_upstream_tls(on).
a16f55c36c feature: add ssl.get_client_random.
dc3fdd91b1 optimize: explicit requirement to use bash.
a05338b090 doc: added installation section.
6351efec0d feature: add parse_der_cert and parse_der_priv_key functions.

git-subtree-dir: src/deps/src/lua-resty-core
git-subtree-split: fa3cd7aec1d5da30b44cb093ae6076ac6778b1e8
This commit is contained in:
Théophile Diot 2024-08-30 11:12:05 +02:00
parent 9117cd7304
commit 9d19872aff
62 changed files with 4759 additions and 90 deletions

View file

@ -49,8 +49,8 @@ env:
- TEST_NGINX_RANDOMIZE=1
- LUACHECK_VER=0.21.1
matrix:
- NGINX_VERSION=1.25.1 OPENSSL_VER=1.1.1w OPENSSL_PATCH_VER=1.1.1f USE_PCRE2=Y
- NGINX_VERSION=1.21.4 OPENSSL_VER=1.1.1w OPENSSL_PATCH_VER=1.1.1f
- NGINX_VERSION=1.27.0 OPENSSL_VER=1.1.1w OPENSSL_PATCH_VER=1.1.1f USE_PCRE2=Y
- NGINX_VERSION=1.25.3 OPENSSL_VER=1.1.1w OPENSSL_PATCH_VER=1.1.1f
services:
- memcache
@ -107,7 +107,7 @@ script:
- if [ "$OPENSSL_VER" = "1.1.0l" ] || [ "$answer" = "N" ]; then add_http3_module=""; fi
- if [ "$answer" = "N" ] || [ "$USE_PCRE2" = "Y" ]; then disable_pcre2=""; fi
- if [ "$USE_PCRE2" = "Y" ]; then PCRE_INC=$PCRE2_INC; PCRE_LIB=$PCRE2_LIB; fi
- ngx-build $NGINX_VERSION --with-ipv6 $disable_pcre2 $add_http3_module --with-http_realip_module --with-http_ssl_module --with-pcre-jit --with-cc-opt="-I$OPENSSL_INC -I$PCRE_INC" --with-ld-opt="-L$OPENSSL_LIB -Wl,-rpath,$OPENSSL_LIB -L$PCRE_LIB -Wl,-rpath,$PCRE_LIB" --add-module=../ndk-nginx-module --add-module=../echo-nginx-module --add-module=../set-misc-nginx-module --add-module=../headers-more-nginx-module --add-module=../lua-nginx-module --with-debug --with-stream_ssl_module --with-stream --with-ipv6 --add-module=../stream-lua-nginx-module > build.log 2>&1 || (cat build.log && exit 1)
- ngx-build $NGINX_VERSION $disable_pcre2 $add_http3_module --with-http_v2_module --with-http_realip_module --with-http_ssl_module --with-pcre-jit --with-cc-opt="-I$OPENSSL_INC -I$PCRE_INC" --with-ld-opt="-L$OPENSSL_LIB -Wl,-rpath,$OPENSSL_LIB -L$PCRE_LIB -Wl,-rpath,$PCRE_LIB" --add-module=../ndk-nginx-module --add-module=../echo-nginx-module --add-module=../set-misc-nginx-module --add-module=../headers-more-nginx-module --add-module=../lua-nginx-module --with-debug --with-stream_ssl_module --with-stream --with-ipv6 --add-module=../stream-lua-nginx-module > build.log 2>&1 || (cat build.log && exit 1)
- nginx -V
- ldd `which nginx`|grep -E 'luajit|ssl|pcre'
- prove -I. -Itest-nginx/lib -j$JOBS -r t

View file

@ -6,6 +6,8 @@ LUA_INCLUDE_DIR ?= $(PREFIX)/include
LUA_LIB_DIR ?= $(PREFIX)/lib/lua/$(LUA_VERSION)
INSTALL ?= install
SHELL := /bin/bash
.PHONY: all test install
all: ;
@ -18,6 +20,13 @@ install: all
$(INSTALL) lib/resty/core/*.lua $(DESTDIR)$(LUA_LIB_DIR)/resty/core/
$(INSTALL) lib/ngx/*.lua $(DESTDIR)$(LUA_LIB_DIR)/ngx/
$(INSTALL) lib/ngx/ssl/*.lua $(DESTDIR)$(LUA_LIB_DIR)/ngx/ssl/
ifeq ($(LUA_LIB_DIR),/usr/local/lib/lua/)
@echo
@echo -e "\033[33mPLEASE NOTE: \033[0m"
@echo -e "\033[33mThe necessary lua_package_path directive needs to be added to nginx.conf\033[0m"
@echo -e "\033[33min the http context, because \"/usr/local/lib/lua/\" is not in LuaJITs default search path.\033[0m"
@echo -e "\033[33mRefer to the Installation section of README.markdown.\033[0m"
endif
test: all
PATH=$(OPENRESTY_PREFIX)/nginx/sbin:$$PATH prove -I../test-nginx/lib -r t

View file

@ -11,6 +11,7 @@ Table of Contents
* [Synopsis](#synopsis)
* [Description](#description)
* [Prerequisites](#prerequisites)
* [Installation](#installation)
* [API Implemented](#api-implemented)
* [resty.core.hash](#restycorehash)
* [resty.core.base64](#restycorebase64)
@ -118,6 +119,39 @@ into serious compatibility issues.
[Back to TOC](#table-of-contents)
Installation
============
By default, LuaJIT will search Lua files in /usr/local/share/lua/5.1/.
But `make install` will install this module to /usr/local/lib/lua.
So you may find the error like this:
```text
nginx: [alert] failed to load the 'resty.core' module
```
You can install this module with the following command to resolve the above problem.
```bash
cd lua-resty-core
sudo make install LUA_LIB_DIR=/usr/local/share/lua/5.1
```
You can also change the installation directory to any other directory you like with the LUA_LIB_DIR argument.
```bash
cd lua-resty-core
sudo make install LUA_LIB_DIR=/opt/nginx/lualib
```
After that, you need to add the above directory to the LuaJIT search direcotries with `lua_package_path` nginx directive in the http context and stream context.
```
lua_package_path "/opt/nginx/lualib/?.lua;;";
```
[Back to TOC](#table-of-contents)
API Implemented
===============

View file

@ -13,21 +13,33 @@ local FFI_OK = base.FFI_OK
local FFI_ERROR = base.FFI_ERROR
local int_out = ffi.new("int[1]")
local get_request = base.get_request
local get_string_buf = base.get_string_buf
local get_size_ptr = base.get_size_ptr
local error = error
local type = type
local tonumber = tonumber
local max = math.max
local subsystem = ngx.config.subsystem
local ngx_lua_ffi_balancer_set_current_peer
local ngx_lua_ffi_balancer_enable_keepalive
local ngx_lua_ffi_balancer_set_more_tries
local ngx_lua_ffi_balancer_get_last_failure
local ngx_lua_ffi_balancer_set_timeouts -- used by both stream and http
local ngx_lua_ffi_balancer_set_upstream_tls
local ngx_lua_ffi_balancer_bind_to_local_addr
if subsystem == 'http' then
ffi.cdef[[
int ngx_http_lua_ffi_balancer_set_current_peer(ngx_http_request_t *r,
const unsigned char *addr, size_t addr_len, int port, char **err);
const unsigned char *addr, size_t addr_len, int port,
const unsigned char *host, ssize_t host_len,
char **err);
int ngx_http_lua_ffi_balancer_enable_keepalive(ngx_http_request_t *r,
unsigned long timeout, unsigned int max_requests, char **err);
int ngx_http_lua_ffi_balancer_set_more_tries(ngx_http_request_t *r,
int count, char **err);
@ -41,11 +53,21 @@ if subsystem == 'http' then
int ngx_http_lua_ffi_balancer_recreate_request(ngx_http_request_t *r,
char **err);
int ngx_http_lua_ffi_balancer_set_upstream_tls(ngx_http_request_t *r,
int on, char **err);
int ngx_http_lua_ffi_balancer_bind_to_local_addr(ngx_http_request_t *r,
const u_char *addr, size_t addr_len,
u_char *errbuf, size_t *errbuf_size);
]]
ngx_lua_ffi_balancer_set_current_peer =
C.ngx_http_lua_ffi_balancer_set_current_peer
ngx_lua_ffi_balancer_enable_keepalive =
C.ngx_http_lua_ffi_balancer_enable_keepalive
ngx_lua_ffi_balancer_set_more_tries =
C.ngx_http_lua_ffi_balancer_set_more_tries
@ -55,6 +77,12 @@ if subsystem == 'http' then
ngx_lua_ffi_balancer_set_timeouts =
C.ngx_http_lua_ffi_balancer_set_timeouts
ngx_lua_ffi_balancer_set_upstream_tls =
C.ngx_http_lua_ffi_balancer_set_upstream_tls
ngx_lua_ffi_balancer_bind_to_local_addr =
C.ngx_http_lua_ffi_balancer_bind_to_local_addr
elseif subsystem == 'stream' then
ffi.cdef[[
int ngx_stream_lua_ffi_balancer_set_current_peer(
@ -69,6 +97,10 @@ elseif subsystem == 'stream' then
int ngx_stream_lua_ffi_balancer_set_timeouts(ngx_stream_lua_request_t *r,
long connect_timeout, long timeout, char **err);
int ngx_stream_lua_ffi_balancer_bind_to_local_addr(
ngx_stream_lua_request_t *r, const char *addr, size_t addr_len,
char *errbuf, size_t *errbuf_size);
]]
ngx_lua_ffi_balancer_set_current_peer =
@ -91,10 +123,15 @@ elseif subsystem == 'stream' then
timeout, err)
end
ngx_lua_ffi_balancer_bind_to_local_addr =
C.ngx_stream_lua_ffi_balancer_bind_to_local_addr
else
error("unknown subsystem: " .. subsystem)
end
local DEFAULT_KEEPALIVE_IDLE_TIMEOUT = 60000
local DEFAULT_KEEPALIVE_MAX_REQUESTS = 100
local peer_state_names = {
[1] = "keepalive",
@ -105,28 +142,111 @@ local peer_state_names = {
local _M = { version = base.version }
if subsystem == "http" then
function _M.set_current_peer(addr, port, host)
local r = get_request()
if not r then
error("no request found")
end
function _M.set_current_peer(addr, port)
local r = get_request()
if not r then
error("no request found")
if not port then
port = 0
elseif type(port) ~= "number" then
port = tonumber(port)
end
if host ~= nil and type(host) ~= "string" then
error("bad argument #3 to 'set_current_peer' "
.. "(string expected, got " .. type(host) .. ")")
end
local rc = ngx_lua_ffi_balancer_set_current_peer(r, addr, #addr,
port,
host,
host and #host or 0,
errmsg)
if rc == FFI_OK then
return true
end
return nil, ffi_str(errmsg[0])
end
else
function _M.set_current_peer(addr, port, host)
local r = get_request()
if not r then
error("no request found")
end
if not port then
port = 0
elseif type(port) ~= "number" then
port = tonumber(port)
if not port then
port = 0
elseif type(port) ~= "number" then
port = tonumber(port)
end
if host ~= nil then
error("bad argument #3 to 'set_current_peer' ('host' not yet " ..
"implemented in " .. subsystem .. " subsystem)", 2)
end
local rc = ngx_lua_ffi_balancer_set_current_peer(r, addr, #addr,
port,
errmsg)
if rc == FFI_OK then
return true
end
return nil, ffi_str(errmsg[0])
end
local rc = ngx_lua_ffi_balancer_set_current_peer(r, addr, #addr,
port, errmsg)
if rc == FFI_OK then
return true
end
return nil, ffi_str(errmsg[0])
end
if subsystem == "http" then
function _M.enable_keepalive(idle_timeout, max_requests)
local r = get_request()
if not r then
error("no request found")
end
if not idle_timeout then
idle_timeout = DEFAULT_KEEPALIVE_IDLE_TIMEOUT
elseif type(idle_timeout) ~= "number" then
error("bad argument #1 to 'enable_keepalive' " ..
"(number expected, got " .. type(idle_timeout) .. ")", 2)
elseif idle_timeout < 0 then
error("bad argument #1 to 'enable_keepalive' (expected >= 0)", 2)
else
idle_timeout = idle_timeout * 1000
end
if not max_requests then
max_requests = DEFAULT_KEEPALIVE_MAX_REQUESTS
elseif type(max_requests) ~= "number" then
error("bad argument #2 to 'enable_keepalive' " ..
"(number expected, got " .. type(max_requests) .. ")", 2)
elseif max_requests < 0 then
error("bad argument #2 to 'enable_keepalive' (expected >= 0)", 2)
end
local rc = ngx_lua_ffi_balancer_enable_keepalive(r, idle_timeout,
max_requests, errmsg)
if rc == FFI_OK then
return true
end
return nil, ffi_str(errmsg[0])
end
else
function _M.enable_keepalive()
error("'enable_keepalive' not yet implemented in " .. subsystem ..
" subsystem", 2)
end
end
function _M.set_more_tries(count)
local r = get_request()
@ -228,6 +348,54 @@ if subsystem == 'http' then
return nil, "failed to recreate the upstream request"
end
function _M.set_upstream_tls(on)
local r = get_request()
if not r then
return error("no request found")
end
local rc
if on == 0 or on == false then
on = 0
else
on = 1
end
rc = ngx_lua_ffi_balancer_set_upstream_tls(r, on, errmsg);
if rc == FFI_OK then
return true
end
return nil, ffi_str(errmsg[0])
end
end
function _M.bind_to_local_addr(addr)
local r = get_request()
if not r then
error("no request found")
end
if type(addr) ~= "string" then
error("bad argument #1 to 'bind_to_local_addr' "
.. "(string expected, got " .. type(addr) .. ")")
end
local errbuf_size = 1024
local errbuf = get_string_buf(errbuf_size)
local sizep = get_size_ptr()
sizep[0] = errbuf_size
local rc = ngx_lua_ffi_balancer_bind_to_local_addr(r, addr, #addr,
errbuf,
sizep)
if rc == FFI_OK then
return true
end
return nil, ffi_str(errbuf, sizep[0])
end

View file

@ -13,11 +13,14 @@ Table of Contents
* [stream subsystem](#stream-subsystem)
* [Description](#description)
* [Methods](#methods)
* [set_current_peer](#set_current_peer)
* [set_more_tries](#set_more_tries)
* [get_last_failure](#get_last_failure)
* [set_timeouts](#set_timeouts)
* [recreate_request](#recreate_request)
* [set_current_peer](#set_current_peer)
* [bind_to_local_addr](#bind_to_local_addr)
* [enable_keepalive](#enable_keepalive)
* [set_more_tries](#set_more_tries)
* [set_timeouts](#set_timeouts)
* [set_upstream_tls](#set_upstream_tls)
* [Community](#community)
* [English Mailing List](#english-mailing-list)
* [Chinese Mailing List](#chinese-mailing-list)
@ -151,7 +154,7 @@ to call these methods.
set_current_peer
----------------
**syntax:** *ok, err = balancer.set_current_peer(host, port)*
**syntax:** *ok, err = balancer.set_current_peer(host, port, host?)*
**context:** *balancer_by_lua&#42;*
@ -163,6 +166,177 @@ all the domain names before entering the `balancer_by_lua*` handler (for example
you can perform DNS lookups in an earlier phase like [access_by_lua*](https://github.com/openresty/lua-nginx-module#access_by_lua)
and pass the results to the `balancer_by_lua*` handler via [ngx.ctx](https://github.com/openresty/lua-nginx-module#ngxctx).
`host` can be set to a string value or nil. If you set `host` to `nil`, this function will use the host set by directive `proxy_ssl_name`.
You should not specify `host` and `proxy_ssl_name` at the same time.
This directive should be used on the toplevel scope of your `nginx.conf`.
In case of an error, this function returns `nil` and a string describing the error.
[Back to TOC](#table-of-contents)
bind_to_local_addr
--------------
**syntax:** *ok, err = balancer.bind_to_local_addr(addr)*
**context:** *balancer_by_lua&#42;*
Makes outgoing connections to a proxied server originate from the specified local IP address with an optional port.
`addr` is a string value of the IP address with optional port. For example: 127.0.0.1, 127.0.0.1:12345.
In case of an error, this function returns `nil` and a string describing the error.
[Back to TOC](#table-of-contents)
enable_keepalive
----------------
**syntax:** `ok, err = balancer.enable_keepalive(idle_timeout?, max_requests?)`
**context:** *balancer_by_lua&#42;*
Instructs the current upstream connection to be kept-alive once the current
request succeeds. The connection will be inserted in the pool specified by the
`pool` option of the [set_current_peer](#set_current_peer) function (if
unspecified, the default pool name will be `"<host>:<port>"`).
The keepalive capabilities offered via this function are similar to that of the
[keepalive](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive)
directive of the ngx_http_upstream_module, with more dynamic capabilities
addressing a wide range of use-cases.
The first optional argument `idle_timeout` may be a number used to specify the
maximum amount of time the connection may remain unused in the pool. The value
is to be specified in seconds, with floating point numbers allowing for
millisecond precision. If omitted, the default value is `60` (60 seconds).
When the idle timeout threshold is reached and the connection hasn't been
reused, it will be closed. A value of `0` will keep the connection in the pool
indefinitely (it may still be eventually closed by the remote peer).
This argument is identical to the
[keepalive_timeout](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_timeout)
directive of the ngx_http_upstream_module, but can be set dynamically for each
upstream connection.
The second optional argument `max_requests` may be a number used to specify the
amount of upstream requests a given connection should be reused for before
being closed. If omitted, the default value is `100`.
When the connection has been reused as many times as the `max_requests` value,
it will be closed instead of being inserted back into the connection pool. A
value of `0` will allow for the connection to be reused for any number of
upstream requests.
This argument is identical to the
[keepalive_requests](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_requests)
directive of the ngx_http_upstream_module, but can be set dynamically for each
upstream connection.
This function returns `true` upon success, or `nil` and a string describing the
error otherwise.
Below is a standard example usage:
```nginx
http {
upstream backend {
server 0.0.0.1; # placeholder
balancer_by_lua_block {
local balancer = require "ngx.balancer"
local ok, err = balancer.set_current_peer("127.0.0.2", 8080)
if not ok then
ngx.log(ngx.ERR, "failed to set current peer: ", err)
return
end
-- default pool will be "host:port"
-- default pool_size will be 30
ok, err = balancer.enable_keepalive()
if not ok then
ngx.log(ngx.ERR, "failed to set keepalive: ", err)
return
end
}
}
server {
listen 80;
location / {
proxy_pass http://backend/;
}
}
}
```
A more advanced usage of this API can be made to overcome specific limitations
of NGINX's upstream keepalive pooling behavior. One of such limitations is the
lack of consideration for TLS attributes in the connection reuse logic: within
a given `upstream {}` block, NGINX's connection reuse logic only considers the
IP and port attributes of a connection, and fails to consider the SNI
extension (among others), which could result in requests being sent over the
wrong TLS connection. NGINX's official stance on this limitation is to use
different `upstream {}` blocks (e.g. one for each SNI), which would not only be
wasteful but also defeat the purpose of the dynamic capabilities offered by
OpenResty.
Below is an example of how to overcome this limitation and pool connections by
IP, port, and SNI:
```nginx
http {
upstream backend {
server 0.0.0.1; # placeholder
balancer_by_lua_block {
local balancer = require "ngx.balancer"
local host = "example.org"
local ip = "127.0.0.2"
local port = 8080
local ok, err = balancer.set_current_peer("127.0.0.2", 8080, host)
if not ok then
ngx.log(ngx.ERR, "failed to set current peer: ", err)
return
end
ok, err = balancer.enable_keepalive(60, 100)
if not ok then
ngx.log(ngx.ERR, "failed to set keepalive: ", err)
return
end
}
}
...
}
```
Should not specify nginx keepalive with balancer_by_lua at the same time.
The following configurations are not recommended:
```nginx
http {
upstream backend_ngx_keepalive {
server 0.0.0.1; # placeholder
balancer_by_lua_block {
local balancer = require "ngx.balancer"
local host = "example.org"
balancer.set_current_peer("127.0.0.2", 8080, host)
balancer.enable_keepalive(60, 100)
}
keepalive 60;
keepalive_timeout 60s;
keepalive_requests 100;
}
}
```
This function was first added to the `http` subsystem in the `v0.1.18` release
of this library. It is not yet supported in the `stream` subsystem.
[Back to TOC](#table-of-contents)
set_more_tries
@ -270,6 +444,21 @@ This function was first added in the `0.1.20` version of this library.
[Back to TOC](#table-of-contents)
set_upstream_tls
------------
**syntax:** `ok, err = balancer.set_upstream_tls(on)`
**context:** *balancer_by_lua&#42;*
Turn off the HTTPs or reenable the HTTPs for the upstream connection.
- If `on` is `true`, then the https protocol will be used to connect to the upstream server.
- If `on` is `false`, then the http protocol will be used to connect to the upstream server.
This function was first added in the `0.1.29` version of this library.
[Back to TOC](#table-of-contents)
Community
=========

View file

@ -7,6 +7,7 @@ base.allows_subsystem('http')
local ffi = require "ffi"
local C = ffi.C
local ffi_new = ffi.new
local ffi_str = ffi.string
local get_request = base.get_request
local error = error
@ -30,7 +31,7 @@ int ngx_http_lua_ffi_ssl_create_ocsp_request(const char *chain_data,
int ngx_http_lua_ffi_ssl_validate_ocsp_response(const unsigned char *resp,
size_t resp_len, const char *chain_data, size_t chain_len,
unsigned char *errbuf, size_t *errbuf_size);
unsigned char *errbuf, size_t *errbuf_size, long *valid);
int ngx_http_lua_ffi_ssl_set_ocsp_status_resp(ngx_http_request_t *r,
const unsigned char *resp, size_t resp_len, char **err);
@ -98,8 +99,9 @@ function _M.create_ocsp_request(certs, maxlen)
end
function _M.validate_ocsp_response(resp, chain, max_errmsg_len)
local next_update_p = ffi_new("long[1]")
function _M.validate_ocsp_response(resp, chain, max_errmsg_len)
local errbuf_size = max_errmsg_len
if not errbuf_size then
errbuf_size = get_string_buf_size()
@ -109,11 +111,19 @@ function _M.validate_ocsp_response(resp, chain, max_errmsg_len)
local sizep = get_size_ptr()
sizep[0] = errbuf_size
local rc = C.ngx_http_lua_ffi_ssl_validate_ocsp_response(
resp, #resp, chain, #chain, errbuf, sizep)
next_update_p[0] = 0
local rc = C.ngx_http_lua_ffi_ssl_validate_ocsp_response(resp, #resp,
chain, #chain,
errbuf, sizep,
next_update_p)
if rc == FFI_OK then
return true
local next_update = tonumber(next_update_p[0])
if next_update == 0 then
next_update = nil
end
return true, next_update
end
-- rc == FFI_ERROR

View file

@ -32,11 +32,17 @@ local ngx_lua_ffi_priv_key_pem_to_der
local ngx_lua_ffi_ssl_get_tls1_version
local ngx_lua_ffi_parse_pem_cert
local ngx_lua_ffi_parse_pem_priv_key
local ngx_lua_ffi_parse_der_cert
local ngx_lua_ffi_parse_der_priv_key
local ngx_lua_ffi_set_cert
local ngx_lua_ffi_set_priv_key
local ngx_lua_ffi_free_cert
local ngx_lua_ffi_free_priv_key
local ngx_lua_ffi_ssl_verify_client
local ngx_lua_ffi_ssl_client_random
local ngx_lua_ffi_ssl_export_keying_material
local ngx_lua_ffi_ssl_export_keying_material_early
local ngx_lua_ffi_get_req_ssl_pointer
if subsystem == 'http' then
@ -77,6 +83,14 @@ if subsystem == 'http' then
void *ngx_http_lua_ffi_parse_pem_priv_key(const unsigned char *pem,
size_t pem_len, char **err);
void *ngx_http_lua_ffi_parse_der_cert(const char *data,
size_t len, char **err);
void *ngx_http_lua_ffi_parse_der_priv_key(const char *data, size_t len,
char **err) ;
void *ngx_http_lua_ffi_get_req_ssl_pointer(void *r);
int ngx_http_lua_ffi_set_cert(void *r, void *cdata, char **err);
int ngx_http_lua_ffi_set_priv_key(void *r, void *cdata, char **err);
@ -86,7 +100,20 @@ if subsystem == 'http' then
void ngx_http_lua_ffi_free_priv_key(void *cdata);
int ngx_http_lua_ffi_ssl_verify_client(void *r,
void *cdata, int depth, char **err);
void *client_certs, void *trusted_certs, int depth, char **err);
int ngx_http_lua_ffi_ssl_client_random(ngx_http_request_t *r,
const unsigned char *out, size_t *outlen, char **err);
int ngx_http_lua_ffi_ssl_export_keying_material(void *r,
unsigned char *out, size_t out_size,
const char *label, size_t llen,
const unsigned char *ctx, size_t ctxlen, int use_ctx, char **err);
int ngx_http_lua_ffi_ssl_export_keying_material_early(void *r,
unsigned char *out, size_t out_size,
const char *label, size_t llen,
const unsigned char *ctx, size_t ctxlen, char **err);
]]
ngx_lua_ffi_ssl_set_der_certificate =
@ -103,11 +130,19 @@ if subsystem == 'http' then
ngx_lua_ffi_ssl_get_tls1_version = C.ngx_http_lua_ffi_ssl_get_tls1_version
ngx_lua_ffi_parse_pem_cert = C.ngx_http_lua_ffi_parse_pem_cert
ngx_lua_ffi_parse_pem_priv_key = C.ngx_http_lua_ffi_parse_pem_priv_key
ngx_lua_ffi_parse_der_cert = C.ngx_http_lua_ffi_parse_der_cert
ngx_lua_ffi_parse_der_priv_key = C.ngx_http_lua_ffi_parse_der_priv_key
ngx_lua_ffi_set_cert = C.ngx_http_lua_ffi_set_cert
ngx_lua_ffi_set_priv_key = C.ngx_http_lua_ffi_set_priv_key
ngx_lua_ffi_free_cert = C.ngx_http_lua_ffi_free_cert
ngx_lua_ffi_free_priv_key = C.ngx_http_lua_ffi_free_priv_key
ngx_lua_ffi_ssl_verify_client = C.ngx_http_lua_ffi_ssl_verify_client
ngx_lua_ffi_ssl_client_random = C.ngx_http_lua_ffi_ssl_client_random
ngx_lua_ffi_ssl_export_keying_material =
C.ngx_http_lua_ffi_ssl_export_keying_material
ngx_lua_ffi_ssl_export_keying_material_early =
C.ngx_http_lua_ffi_ssl_export_keying_material_early
ngx_lua_ffi_get_req_ssl_pointer = C.ngx_http_lua_ffi_get_req_ssl_pointer
elseif subsystem == 'stream' then
ffi.cdef[[
@ -145,9 +180,15 @@ elseif subsystem == 'stream' then
void *ngx_stream_lua_ffi_parse_pem_cert(const unsigned char *pem,
size_t pem_len, char **err);
void *ngx_stream_lua_ffi_parse_der_cert(const unsigned char *der,
size_t der_len, char **err);
void *ngx_stream_lua_ffi_parse_pem_priv_key(const unsigned char *pem,
size_t pem_len, char **err);
void *ngx_stream_lua_ffi_parse_der_priv_key(const unsigned char *der,
size_t der_len, char **err);
int ngx_stream_lua_ffi_set_cert(void *r, void *cdata, char **err);
int ngx_stream_lua_ffi_set_priv_key(void *r, void *cdata, char **err);
@ -157,7 +198,10 @@ elseif subsystem == 'stream' then
void ngx_stream_lua_ffi_free_priv_key(void *cdata);
int ngx_stream_lua_ffi_ssl_verify_client(void *r,
void *cdata, int depth, char **err);
void *client_certs, void *trusted_certs, int depth, char **err);
int ngx_stream_lua_ffi_ssl_client_random(ngx_stream_lua_request_t *r,
unsigned char *out, size_t *outlen, char **err);
]]
ngx_lua_ffi_ssl_set_der_certificate =
@ -171,14 +215,18 @@ elseif subsystem == 'stream' then
ngx_lua_ffi_ssl_raw_client_addr = C.ngx_stream_lua_ffi_ssl_raw_client_addr
ngx_lua_ffi_cert_pem_to_der = C.ngx_stream_lua_ffi_cert_pem_to_der
ngx_lua_ffi_priv_key_pem_to_der = C.ngx_stream_lua_ffi_priv_key_pem_to_der
ngx_lua_ffi_ssl_get_tls1_version = C.ngx_stream_lua_ffi_ssl_get_tls1_version
ngx_lua_ffi_ssl_get_tls1_version =
C.ngx_stream_lua_ffi_ssl_get_tls1_version
ngx_lua_ffi_parse_pem_cert = C.ngx_stream_lua_ffi_parse_pem_cert
ngx_lua_ffi_parse_der_cert = C.ngx_stream_lua_ffi_parse_der_cert
ngx_lua_ffi_parse_pem_priv_key = C.ngx_stream_lua_ffi_parse_pem_priv_key
ngx_lua_ffi_parse_der_priv_key = C.ngx_stream_lua_ffi_parse_der_priv_key
ngx_lua_ffi_set_cert = C.ngx_stream_lua_ffi_set_cert
ngx_lua_ffi_set_priv_key = C.ngx_stream_lua_ffi_set_priv_key
ngx_lua_ffi_free_cert = C.ngx_stream_lua_ffi_free_cert
ngx_lua_ffi_free_priv_key = C.ngx_stream_lua_ffi_free_priv_key
ngx_lua_ffi_ssl_verify_client = C.ngx_stream_lua_ffi_ssl_verify_client
ngx_lua_ffi_ssl_client_random = C.ngx_stream_lua_ffi_ssl_client_random
end
@ -219,7 +267,6 @@ function _M.set_der_cert(data)
return nil, ffi_str(errmsg[0])
end
function _M.set_der_priv_key(data)
local r = get_request()
if not r then
@ -387,6 +434,26 @@ function _M.parse_pem_priv_key(pem)
end
function _M.parse_der_cert(der)
local cert = ngx_lua_ffi_parse_der_cert(der, #der, errmsg)
if cert ~= nil then
return ffi_gc(cert, ngx_lua_ffi_free_cert)
end
return nil, ffi_str(errmsg[0])
end
function _M.parse_der_priv_key(der)
local pkey = ngx_lua_ffi_parse_der_priv_key(der, #der, errmsg)
if pkey ~= nil then
return ffi_gc(pkey, ngx_lua_ffi_free_priv_key)
end
return nil, ffi_str(errmsg[0])
end
function _M.set_cert(cert)
local r = get_request()
if not r then
@ -417,7 +484,7 @@ function _M.set_priv_key(priv_key)
end
function _M.verify_client(ca_certs, depth)
function _M.verify_client(client_certs, depth, trusted_certs)
local r = get_request()
if not r then
error("no request found")
@ -427,7 +494,8 @@ function _M.verify_client(ca_certs, depth)
depth = -1
end
local rc = ngx_lua_ffi_ssl_verify_client(r, ca_certs, depth, errmsg)
local rc = ngx_lua_ffi_ssl_verify_client(r, client_certs, trusted_certs,
depth, errmsg)
if rc == FFI_OK then
return true
end
@ -436,6 +504,68 @@ function _M.verify_client(ca_certs, depth)
end
function _M.export_keying_material(length, label, context)
local r = get_request()
if not r then
error("no request found")
end
local outbuf = get_string_buf(length)
local use_context = context and 1 or 0
local context_len = context and #context or 0
local rc = ngx_lua_ffi_ssl_export_keying_material(r, outbuf, length,
label, #label, context, context_len, use_context, errmsg)
if rc == FFI_OK then
return ffi_str(outbuf, length)
end
if rc == FFI_DECLINED then
return nil
end
return nil, ffi_str(errmsg[0])
end
function _M.export_keying_material_early(length, label, context)
local r = get_request()
if not r then
error("no request found")
end
local outbuf = get_string_buf(length)
local context_len = context and #context or 0
local rc = ngx_lua_ffi_ssl_export_keying_material_early(r, outbuf, length,
label, #label, context, context_len, errmsg)
if rc == FFI_OK then
return ffi_str(outbuf, length)
end
if rc == FFI_DECLINED then
return nil
end
return nil, ffi_str(errmsg[0])
end
function _M.get_req_ssl_pointer()
local r = get_request()
if not r then
error("no request found")
end
local ssl = ngx_lua_ffi_get_req_ssl_pointer(r)
if ssl == nil then
return nil, "no ssl object"
end
return ssl
end
do
_M.SSL3_VERSION = 0x0300
_M.TLS1_VERSION = 0x0301
@ -467,4 +597,31 @@ do
end
function _M.get_client_random(outlen)
local r = get_request()
if not r then
error("no request found")
end
if outlen == nil then
outlen = 32
end
local out = get_string_buf(outlen)
local sizep = get_size_ptr()
sizep[0] = outlen
local rc = ngx_lua_ffi_ssl_client_random(r, out, sizep, errmsg)
if rc == FFI_OK then
if outlen == 0 then
return tonumber(sizep[0])
end
return ffi_str(out, sizep[0])
end
return nil, ffi_str(errmsg[0])
end
return _M

View file

@ -19,14 +19,20 @@ Table of Contents
* [server_name](#server_name)
* [server_port](#server_port)
* [raw_server_addr](#raw_server_addr)
* [export_keying_material](#export_keying_material)
* [export_keying_material_early](#export_keying_material_early)
* [raw_client_addr](#raw_client_addr)
* [get_tls1_version](#get_tls1_version)
* [get_tls1_version_str](#get_tls1_version_str)
* [parse_pem_cert](#parse_pem_cert)
* [parse_pem_priv_key](#parse_pem_priv_key)
* [parse_der_cert](#parse_der_cert)
* [parse_der_priv_key](#parse_der_priv_key)
* [set_cert](#set_cert)
* [set_priv_key](#set_priv_key)
* [verify_client](#verify_client)
* [get_client_random](#get_client_random)
* [get_req_ssl_pointer](#get_req_ssl_pointer)
* [Community](#community)
* [English Mailing List](#english-mailing-list)
* [Chinese Mailing List](#chinese-mailing-list)
@ -321,6 +327,76 @@ This function can be called in any context where downstream https is used.
[Back to TOC](#table-of-contents)
export_keying_material
----------------------
**syntax:** *key, err = ssl.export_keying_material(length, label, context)*
context: *set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, body_filter_by_lua&#42;, log_by_lua&#42;*
Return a key derived from the SSL master secret.
As described in RFC8446 section 7.5 this function returns key material that is derived from the SSL master secret and can be used on the application level. The returned key material is of the given length. Label is mandatory and requires a special format that is described in RFC5705 section 4. Context is optional but note that in TLSv1.2 and below a zero length context is treated differently from no context at all, and will result in different keying material being returned. In TLSv1.3 a zero length context is that same as no context at all and will result in the same keying material being returned.
The following code snippet shows how to derive a new key that can be used on the application level.
```lua
local ssl = require "ngx.ssl"
local key_length = 16
local label = "EXPERIMENTAL my label"
local context = "\x00\x01\x02\x03"
local key, err = ssl.export_keying_material(key_length, label, context)
if not key then
ngx.log(ngx.ERR, "failed to derive key ", err)
return
end
-- use key...
end
```
This function can be called in any context where downstream https is used.
[Back to TOC](#table-of-contents)
export_keying_material_early
----------------------------
**syntax:** *key, err = ssl.export_keying_material_early(length, label, context)*
context: *set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, body_filter_by_lua&#42;, log_by_lua&#42;*
Returns a key derived from the SSL early exporter master secret.
As described in RFC8446 section 7.5 this function returns key material that is derived from the SSL early exporter master secret and can be used on the application level. The returned key material is of the given length. Label is mandatory and requires a special format that is described in RFC5705 section 4. This function is only usable with TLSv1.3, and derives keying material using the early_exporter_master_secret (as defined in the TLS 1.3 RFC). For the client, the early_exporter_master_secret is only available when the client attempts to send 0-RTT data. For the server, it is only available when the server accepts 0-RTT data.
The following code snippet shows how to derive a new key that can be used on the application level.
```lua
local ssl = require "ngx.ssl"
local key_length = 16
local label = "EXPERIMENTAL my label"
local context = "\x00\x01\x02\x03"
local key, err = ssl.export_keying_material_early(key_length, label, context)
if not key then
ngx.log(ngx.ERR, "failed to derive key ", err)
return
end
-- use key...
end
```
This function can be called in any context where downstream https TLS1.3 is used.
[Back to TOC](#table-of-contents)
raw_client_addr
---------------
**syntax:** *addr_data, addr_type, err = ssl.raw_client_addr()*
@ -457,6 +533,41 @@ This function was first added in version `0.1.7`.
[Back to TOC](#table-of-contents)
parse_der_cert
--------------
**syntax:** *cert_chain, err = ssl.parse_der_cert(der_cert_chain)*
**context:** *any*
Converts the DER-formated SSL certificate chain data into an opaque cdata pointer (for later uses
in the [set_cert](#set_cert)
function, for example).
In case of failures, returns `nil` and a string describing the error.
You can always use libraries like [lua-resty-lrucache](https://github.com/openresty/lua-resty-lrucache#readme)
to cache the cdata result.
This function can be called in any context.
[Back to TOC](#table-of-contents)
parse_der_priv_key
------------------
**syntax:** *priv_key, err = ssl.parse_der_priv_key(der_priv_key)*
**context:** *any*
Converts the DER-formatted SSL private key data into an opaque cdata pointer (for later uses
in the [set_priv_key](#set_priv_key)
function, for example).
In case of failures, returns `nil` and a string describing the error.
This function can be called in any context.
[Back to TOC](#table-of-contents)
set_cert
--------
**syntax:** *ok, err = ssl.set_cert(cert_chain)*
@ -464,7 +575,7 @@ set_cert
**context:** *ssl_certificate_by_lua&#42;*
Sets the SSL certificate chain opaque pointer returned by the
[parse_pem_cert](#parse_pem_cert) function for the current SSL connection.
[parse_pem_cert](#parse_pem_cert) or [parse_der_cert](#parse_der_cert)function for the current SSL connection.
Returns `true` on success, or a `nil` value and a string describing the error otherwise.
@ -483,7 +594,7 @@ set_priv_key
**context:** *ssl_certificate_by_lua&#42;*
Sets the SSL private key opaque pointer returned by the
[parse_pem_priv_key](#parse_pem_priv_key) function for the current SSL connection.
[parse_pem_priv_key](#parse_pem_priv_key) or [parse_der_priv_key](#parse_der_priv_key) function for the current SSL connection.
Returns `true` on success, or a `nil` value and a string describing the error otherwise.
@ -497,13 +608,13 @@ This function was first added in version `0.1.7`.
verify_client
-------------
**syntax:** *ok, err = ssl.verify_client(ca_certs?, depth?)*
**syntax:** *ok, err = ssl.verify_client(client_certs?, depth?, trusted_certs?)*
**context:** *ssl_certificate_by_lua&#42;*
Requires a client certificate during TLS handshake.
The `ca_certs` is the CA certificate chain opaque pointer returned by the
The `client_certs` is the CA certificate chain opaque pointer returned by the
[parse_pem_cert](#parse_pem_cert) function for the current SSL connection.
The list of certificates will be sent to clients. Also, they will be added to trusted store.
If omitted, will not send any CA certificate to clients.
@ -511,6 +622,9 @@ If omitted, will not send any CA certificate to clients.
The `depth` is the verification depth in the client certificates chain.
If omitted, will use the value specified by `ssl_verify_depth`.
The `trusted_certs` is same returned by the
[parse_pem_cert](#parse_pem_cert) function. They will be added to trusted store.
Returns `true` on success, or a `nil` value and a string describing the error otherwise.
Note that TLS is not terminated when verification fails. You need to examine Nginx variable `$ssl_client_verify`
@ -520,6 +634,40 @@ This function was first added in version `0.1.20`.
[Back to TOC](#table-of-contents)
get_client_random
-----------
**syntax:** *client_random = ssl.get_client_random(outlen?)*
**context:** *any*
Returns the random value sent from the client to the server during the initial SSL/TLS handshake.
The `outlen` parameter indicates the maximum length of the client_random value returned.
If the `outlen` is zero, this function returns the total length of the client_random value.
If omitted, will use the value 32.
This function can be called in any context where downstream https is used, but in the context of [ssl_client_hello_by_lua*](https://github.com/openresty/lua-nginx-module/#ssl_client_hello_by_lua_block), it can not return the real client_random value, just a string filled with 0.
[Back to TOC](#table-of-contents)
get_req_ssl_pointer
------------
**syntax:** *ssl_ptr, err = ssl.get_req_ssl_pointer()*
**context:** *any*
Retrieves the OpenSSL `SSL*` object for the current downstream connection.
Returns an FFI pointer on success, or a `nil` value and a string describing the error otherwise.
If you need to retain the pointer beyond the current phase then you will need to use OpenSSL's `SSL_up_ref` to increase the reference count.
If you do, ensure that your reference is released with `SSL_free`.
This function was first added in version `0.1.16`.
[Back to TOC](#table-of-contents)
Community
=========
@ -545,7 +693,7 @@ Bugs and Patches
Please report bugs or submit patches by
1. creating a ticket on the [GitHub Issue Tracker](https://github.com/openresty/lua-resty-core/issues),
1. or posting to the [OpenResty community](#community).
2. or posting to the [OpenResty community](#community).
[Back to TOC](#table-of-contents)

View file

@ -12,6 +12,7 @@ Table of Contents
* [Description](#description)
* [Methods](#methods)
* [get_client_hello_server_name](#get_client_hello_server_name)
* [get_supported_versions](#get_supported_versions)
* [get_client_hello_ext](#get_client_hello_ext)
* [set_protocols](#set_protocols)
* [Community](#community)

View file

@ -19,22 +19,22 @@ local FREE_LIST_REF = 0
if subsystem == 'http' then
if not ngx.config
or not ngx.config.ngx_lua_version
or ngx.config.ngx_lua_version ~= 10026
or ngx.config.ngx_lua_version ~= 10027
then
error("ngx_http_lua_module 0.10.26 required")
error("ngx_http_lua_module 0.10.27 required")
end
elseif subsystem == 'stream' then
if not ngx.config
or not ngx.config.ngx_lua_version
or ngx.config.ngx_lua_version ~= 14
or ngx.config.ngx_lua_version ~= 15
then
error("ngx_stream_lua_module 0.0.14 required")
error("ngx_stream_lua_module 0.0.15 required")
end
else
error("ngx_http_lua_module 0.10.26 or "
.. "ngx_stream_lua_module 0.0.14 required")
error("ngx_http_lua_module 0.10.27 or "
.. "ngx_stream_lua_module 0.0.15 required")
end
@ -141,7 +141,7 @@ local c_buf_type = ffi.typeof("char[?]")
local _M = new_tab(0, 18)
_M.version = "0.1.28"
_M.version = "0.1.29"
_M.new_tab = new_tab
_M.clear_tab = clear_tab

View file

@ -90,6 +90,7 @@ if is_not_windows then
ngx_lua_ffi_worker_pids = C.ngx_stream_lua_ffi_worker_pids
end
local tonumber = tonumber
local ngx_phase = ngx.get_phase
function ngx.worker.pids()

View file

@ -1,10 +1,17 @@
package t::TestCore;
use Test::Nginx::Socket::Lua -Base;
use Cwd qw(cwd);
use Cwd qw(cwd realpath abs_path);
use File::Basename;
use Test::Nginx::Util 'is_tcp_port_used';
$ENV{TEST_NGINX_HOTLOOP} ||= 10;
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
$ENV{TEST_NGINX_CERT_DIR} ||= dirname(realpath(abs_path(__FILE__)));
sub get_unused_port ($);
$ENV{TEST_NGINX_SERVER_SSL_PORT} ||= get_unused_port 23456;
our $pwd = cwd();
@ -38,6 +45,7 @@ our @EXPORT = qw(
$lua_package_path
$init_by_lua_block
$HttpConfig
get_unused_port
);
add_block_preprocessor(sub {
@ -46,6 +54,28 @@ add_block_preprocessor(sub {
if (!defined $block->http_config) {
$block->set_value("http_config", $HttpConfig);
}
if ($Test::Nginx::Util::UseValgrind) {
my $timeout = $block->timeout || 3;
$timeout *= 5;
$block->set_value("timeout", $timeout);
}
});
sub get_unused_port ($) {
my $port = shift;
my $i = 1000;
srand($$); # reset the random seed
while ($i-- > 0) {
my $rand_port = $port + int(rand(65535 - $port));
if (!is_tcp_port_used $rand_port) {
#warn "found unused port $rand_port, pid $$\n";
return $rand_port;
}
}
die "no unused port available";
}
1;

View file

@ -2,9 +2,12 @@ package t::TestCore::Stream;
use Test::Nginx::Socket::Lua::Stream -Base;
use Cwd qw(cwd);
use Test::Nginx::Util 'is_tcp_port_used';
$ENV{TEST_NGINX_HOTLOOP} ||= 10;
sub get_unused_port ($);
our $pwd = cwd();
our $lua_package_path = './lib/?.lua;../lua-resty-lrucache/lib/?.lua;;';
@ -37,6 +40,7 @@ our @EXPORT = qw(
$lua_package_path
$init_by_lua_block
$StreamConfig
get_unused_port
);
add_block_preprocessor(sub {
@ -47,4 +51,20 @@ add_block_preprocessor(sub {
}
});
sub get_unused_port ($) {
my $port = shift;
my $i = 1000;
srand($$); # reset the random seed
while ($i-- > 0) {
my $rand_port = $port + int(rand(65535 - $port));
if (!is_tcp_port_used $rand_port) {
#warn "found unused port $rand_port, pid $$\n";
return $rand_port;
}
}
die "no unused port available";
}
1;

View file

@ -0,0 +1,448 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use lib '.';
use t::TestCore;
my $NginxBinary = $ENV{TEST_NGINX_BINARY} || 'nginx';
my $NginxV = eval { `$NginxBinary -V 2>&1` };
if ($NginxV !~ m/built with OpenSSL/) {
plan(skip_all => "OpenSSL required");
} elsif ($NginxV !~ m/--with-debug/) {
plan(skip_all => "--with-debug required");
} else {
plan tests => repeat_each() * (blocks() * 4);
}
our $UpstreamSrvConfig = <<_EOC_;
server {
listen 127.0.0.1:$ENV{TEST_NGINX_SERVER_SSL_PORT} ssl;
listen 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT} ssl;
ssl_certificate $ENV{TEST_NGINX_CERT_DIR}/cert/test.crt;
ssl_certificate_key $ENV{TEST_NGINX_CERT_DIR}/cert/test.key;
ssl_session_tickets off;
ssl_verify_client optional_no_ca;
keepalive_requests 1000;
location = /echo_client_addr {
content_by_lua_block {
ngx.say(ngx.var.remote_addr)
}
}
location = /echo_client_addr_port {
content_by_lua_block {
ngx.say(ngx.var.remote_addr, ":", ngx.var.remote_port)
}
}
location / {
return 200;
}
}
_EOC_
our $ProxyLocConfig = <<_EOC_;
location ~ ^/proxy/(?<upstream_uri>.*) {
proxy_ssl_verify off;
proxy_ssl_server_name on;
proxy_ssl_name '\$arg_sni';
proxy_http_version 1.1;
proxy_set_header Connection '';
proxy_pass https://test_upstream/\$upstream_uri;
}
_EOC_
add_block_preprocessor(sub {
my $block = shift;
if (defined $block->http_upstream) {
$block->set_value("http_config",
$block->http_upstream . "\n" . $UpstreamSrvConfig);
}
if (defined $block->config) {
$block->set_value("config",
$block->config . "\n" . $ProxyLocConfig);
} else {
$block->set_value("config", $ProxyLocConfig);
}
if (!defined $block->request) {
$block->set_value("request", "GET /t");
}
if (!defined $block->grep_error_log) {
$block->set_value("grep_error_log", qr/lua balancer: keepalive (?!closing).*/);
}
if (!defined $block->no_error_log) {
$block->set_value("no_error_log", "[error]");
}
});
log_level('debug');
no_long_string();
run_tests();
__DATA__
=== TEST 1: get keepalive from pool
--- http_upstream
upstream test_upstream {
server 0.0.0.1;
balancer_by_lua_block {
local b = require "ngx.balancer"
local ip = ngx.var.arg_ip or "127.0.0.1"
local port = ngx.var.arg_port or $TEST_NGINX_SERVER_SSL_PORT
local ok, err = b.set_current_peer(ip, port, "test.com")
if not ok then
ngx.log(ngx.ERR, "failed to set current peer: ", err)
return
end
local ok, err = b.enable_keepalive()
if not ok then
ngx.log(ngx.ERR, "failed to set keepalive: ", err)
return
end
ok, err = b.bind_to_local_addr("127.0.0.11")
if not ok then
ngx.log(ngx.ERR, "failed to set local addr: ", err)
return
end
}
}
--- config eval
"
location = /t {
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.2';
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.2';
}
"
--- response_body
127.0.0.11
127.0.0.11
--- grep_error_log_out eval
qr/^lua balancer: keepalive no free connection, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive reusing connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
$/
=== TEST 2: get keepalive from pool twice
--- http_upstream
upstream test_upstream {
server 0.0.0.1;
balancer_by_lua_block {
local b = require "ngx.balancer"
local ip = ngx.var.arg_ip or "127.0.0.1"
local port = ngx.var.arg_port or $TEST_NGINX_SERVER_SSL_PORT
local ok, err = b.set_current_peer(ip, port, "test.com")
if not ok then
ngx.log(ngx.ERR, "failed to set current peer: ", err)
return
end
local ok, err = b.enable_keepalive()
if not ok then
ngx.log(ngx.ERR, "failed to set keepalive: ", err)
return
end
ok, err = b.bind_to_local_addr("127.0.0.11")
if not ok then
ngx.log(ngx.ERR, "failed to set local addr: ", err)
return
end
}
}
--- config eval
"
location = /t {
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.2';
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.2';
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.2';
}
"
--- response_body
127.0.0.11
127.0.0.11
127.0.0.11
--- grep_error_log_out eval
qr/^lua balancer: keepalive no free connection, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive reusing connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive reusing connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
$/
=== TEST 3: can not get idle connection from the pool
--- http_upstream
upstream test_upstream {
server 0.0.0.1;
balancer_by_lua_block {
local b = require "ngx.balancer"
local ip = ngx.var.arg_ip or "127.0.0.1"
local port = ngx.var.arg_port or $TEST_NGINX_SERVER_SSL_PORT
local ok, err = b.set_current_peer(ip, port, "test.com")
if not ok then
ngx.log(ngx.ERR, "failed to set current peer: ", err)
return
end
local ok, err = b.enable_keepalive()
if not ok then
ngx.log(ngx.ERR, "failed to set keepalive: ", err)
return
end
local src_ip = ngx.var.arg_src_ip or "127.0.0.1"
ok, err = b.bind_to_local_addr(src_ip)
if not ok then
ngx.log(ngx.ERR, "failed to set local addr: ", err)
return
end
}
}
--- config eval
"
location = /t {
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.2&src_ip=127.0.0.10';
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.2&src_ip=127.0.0.11';
}
"
--- response_body
127.0.0.10
127.0.0.11
--- grep_error_log_out eval
qr/^lua balancer: keepalive no free connection, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive no free connection, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
$/
=== TEST 4: et idle connections from the pool for different src ip
--- http_upstream
upstream test_upstream {
server 0.0.0.1;
balancer_by_lua_block {
local b = require "ngx.balancer"
local ip = ngx.var.arg_ip or "127.0.0.1"
local port = ngx.var.arg_port or $TEST_NGINX_SERVER_SSL_PORT
local ok, err = b.set_current_peer(ip, port, "test.com")
if not ok then
ngx.log(ngx.ERR, "failed to set current peer: ", err)
return
end
local ok, err = b.enable_keepalive()
if not ok then
ngx.log(ngx.ERR, "failed to set keepalive: ", err)
return
end
local src_ip = ngx.var.arg_src_ip or "127.0.0.1"
ok, err = b.bind_to_local_addr(src_ip)
if not ok then
ngx.log(ngx.ERR, "failed to set local addr: ", err)
return
end
}
}
--- config eval
"
location = /t {
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.2&src_ip=127.0.0.10';
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.2&src_ip=127.0.0.11';
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.2&src_ip=127.0.0.11';
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.2&src_ip=127.0.0.10';
}
"
--- response_body
127.0.0.10
127.0.0.11
127.0.0.11
127.0.0.10
--- grep_error_log_out eval
qr/^lua balancer: keepalive no free connection, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive no free connection, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive reusing connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive reusing connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
$/
=== TEST 5: should not use idle connection with different dest ip
--- http_upstream
upstream test_upstream {
server 0.0.0.1;
balancer_by_lua_block {
local b = require "ngx.balancer"
local ip = ngx.var.arg_ip or "127.0.0.1"
local port = ngx.var.arg_port or $TEST_NGINX_SERVER_SSL_PORT
local ok, err = b.set_current_peer(ip, port, "test.com")
if not ok then
ngx.log(ngx.ERR, "failed to set current peer: ", err)
return
end
local ok, err = b.enable_keepalive()
if not ok then
ngx.log(ngx.ERR, "failed to set keepalive: ", err)
return
end
ok, err = b.bind_to_local_addr("127.0.0.11")
if not ok then
ngx.log(ngx.ERR, "failed to set local addr: ", err)
return
end
}
}
--- config eval
"
location = /t {
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.1';
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.2';
}
"
--- response_body
127.0.0.11
127.0.0.11
--- grep_error_log_out eval
qr/^lua balancer: keepalive no free connection, host: 127.0.0.1:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.1:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive no free connection, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
$/
=== TEST 6: empty host
--- http_upstream
upstream test_upstream {
server 0.0.0.1;
balancer_by_lua_block {
local b = require "ngx.balancer"
local ip = ngx.var.arg_ip or "127.0.0.1"
local port = ngx.var.arg_port or $TEST_NGINX_SERVER_SSL_PORT
local ok, err = b.set_current_peer(ip, port, "test.com")
if not ok then
ngx.log(ngx.ERR, "failed to set current peer: ", err)
return
end
local ok, err = b.enable_keepalive()
if not ok then
ngx.log(ngx.ERR, "failed to set keepalive: ", err)
return
end
ok, err = b.bind_to_local_addr("127.0.0.11")
if not ok then
ngx.log(ngx.ERR, "failed to set local addr: ", err)
return
end
}
}
--- config eval
"
location = /t {
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.2';
echo_subrequest GET '/proxy/echo_client_addr' -q 'ip=127.0.0.2';
}
"
--- response_body
127.0.0.11
127.0.0.11
--- grep_error_log_out eval
qr/^lua balancer: keepalive no free connection, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive reusing connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
$/
=== TEST 7: bind addr with port
--- http_upstream
upstream test_upstream {
server 0.0.0.1;
balancer_by_lua_block {
local b = require "ngx.balancer"
local ip = ngx.var.arg_ip or "127.0.0.1"
local port = ngx.var.arg_port or $TEST_NGINX_SERVER_SSL_PORT
local ok, err = b.set_current_peer(ip, port, "test.com")
if not ok then
ngx.log(ngx.ERR, "failed to set current peer: ", err)
return
end
local ok, err = b.enable_keepalive()
if not ok then
ngx.log(ngx.ERR, "failed to set keepalive: ", err)
return
end
ok, err = b.bind_to_local_addr("127.0.0.11:64321")
if not ok then
ngx.log(ngx.ERR, "failed to set local addr: ", err)
return
end
}
}
--- config eval
"
location = /t {
echo_subrequest GET '/proxy/echo_client_addr_port' -q 'ip=127.0.0.2';
echo_subrequest GET '/proxy/echo_client_addr_port' -q 'ip=127.0.0.2';
}
"
--- response_body
127.0.0.11:64321
127.0.0.11:64321
--- grep_error_log_out eval
qr/^lua balancer: keepalive no free connection, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive reusing connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
lua balancer: keepalive saving connection [0-9A-F]+, host: 127.0.0.2:$ENV{TEST_NGINX_SERVER_SSL_PORT}, name: test.com
$/

1221
t/balancer-keepalive.t Normal file

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,10 @@ use t::TestCore;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 4 + 6);
my $TestPlan = $ENV{TEST_NGINX_CHECK_LEAK} ?
repeat_each() * (blocks() * 4 + 8) : repeat_each() * (blocks() * 4 + 6);
plan tests => $TestPlan;
$ENV{TEST_NGINX_LUA_PACKAGE_PATH} = "$t::TestCore::lua_package_path";
@ -700,7 +703,6 @@ github issue openresty/lua-nginx-module#693
--- grep_error_log_out
hello from balancer by lua!
hello from balancer by lua!
hello from balancer by lua!
--- error_log eval
qr/\[error] .*? upstream prematurely closed connection while reading response header from upstream/
@ -837,48 +839,148 @@ qr/log_by_lua\(nginx.conf:\d+\):\d+: ngx.var.upstream_addr is 127.0.0.3:12345, 1
=== TEST 19: recreate upstream module requests with header change
=== TEST 19: no 'server' directive
--- http_config
upstream backend {
balancer_by_lua_block {
print("hello from balancer by lua!")
}
}
--- config
location = /t {
proxy_pass http://backend;
}
--- request
GET /t
--- error_code: 500
--- ignore_response_body
--- error_log eval
[
'[lua] balancer_by_lua(nginx.conf:26):2: hello from balancer by lua! while connecting to upstream,',
qr/\[error\] .*? lua balancer: no peer set/,
]
--- no_error_log
[warn]
=== TEST 20: set current peer: no 'server' directive
--- http_config
upstream backend {
balancer_by_lua_block {
print("hello from balancer by lua!")
local b = require "ngx.balancer"
assert(b.set_current_peer("127.0.0.3", 12345))
}
}
--- config
location = /t {
proxy_pass http://backend;
}
--- request
GET /t
--- error_code: 502
--- ignore_response_body
--- error_log eval
[
'[lua] balancer_by_lua(nginx.conf:26):2: hello from balancer by lua! while connecting to upstream,',
qr{connect\(\) failed .*?, upstream: "http://127\.0\.0\.3:12345/t"},
]
--- no_error_log
[warn]
[crit]
=== TEST 21: set_upstream_tls off
--- skip_nginx: 5: < 1.7.5
--- http_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
upstream backend {
server 0.0.0.1;
balancer_by_lua_block {
print("here")
local b = require "ngx.balancer"
b.set_current_peer("127.0.0.1", tonumber(ngx.var.server_port))
b.set_upstream_tls(false)
}
keepalive 1;
}
if ngx.ctx.balancer_run then
assert(b.set_current_peer("127.0.0.1", tonumber(ngx.var.server_port)))
ngx.var.test = "second"
assert(b.recreate_request())
server {
listen $TEST_NGINX_RAND_PORT_1 ssl;
ssl_certificate ../../cert/test.crt;
ssl_certificate_key ../../cert/test.key;
else
ngx.ctx.balancer_run = true
assert(b.set_current_peer("127.0.0.3", 12345))
assert(b.set_more_tries(1))
end
server_tokens off;
location = /back {
return 200 "ok";
}
}
--- config
location = /t {
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_403 http_404;
proxy_next_upstream_tries 2;
set $test "first";
proxy_set_header X-Test $test;
proxy_pass http://backend/upstream;
location /t {
proxy_pass https://backend/back;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
location = /upstream {
return 200 "value is: $http_x_test";
location /back {
echo "Hello world!";
}
--- request
GET /t
--- response_body: value is: second
--- error_log
connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1
GET /t
--- no_error_log
[warn]
[crit]
[alert]
[error]
--- response_body
Hello world!
--- no_check_leak
=== TEST 22: set_upstream_tls on
--- skip_nginx: 5: < 1.7.5
--- http_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
upstream backend {
server 0.0.0.1;
balancer_by_lua_block {
local b = require "ngx.balancer"
b.set_current_peer("127.0.0.1", $TEST_NGINX_RAND_PORT_1)
b.set_upstream_tls(false)
b.set_upstream_tls(true)
}
keepalive 1;
}
server {
listen $TEST_NGINX_RAND_PORT_1 ssl;
ssl_certificate ../../cert/test.crt;
ssl_certificate_key ../../cert/test.key;
server_tokens off;
location = /back {
return 200 "ok";
}
}
--- config
location /t {
proxy_pass https://backend/back;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
location /back {
echo "Hello world!";
}
--- request
GET /t
--- no_error_log
[alert]
[error]
--- response_body chomp
ok
--- no_check_leak

78
t/cert/mtls_ca.crt Normal file
View file

@ -0,0 +1,78 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
32:ed:21:56:d8:4e:aa:03:89:a9:4a:a4:e2:85:2d:8a:3b:2b:89:22
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = California, O = OpenResty, CN = OpenResty Testing Root CA
Validity
Not Before: Mar 13 15:49:00 2022 GMT
Not After : Mar 8 15:49:00 2042 GMT
Subject: C = US, ST = California, O = OpenResty, CN = OpenResty Testing Root CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:e6:37:d2:c6:17:36:c7:b2:7f:7d:cf:d0:62:87:
99:d9:21:b8:de:ff:d8:e2:3a:1c:68:90:8f:ce:17:
68:22:b0:60:30:cc:29:e8:34:ee:ff:b2:25:de:6e:
1a:d4:df:10:19:11:4b:40:61:d3:a9:4d:80:ed:97:
81:4e:c5:74:e8:4d:63:e3:5f:21:bc:5a:6e:22:a0:
17:91:c1:cb:25:53:9b:9d:4e:e1:51:5b:f6:52:e7:
0a:27:f6:16:c2:31:cb:6c:47:f4:89:51:15:cc:06:
be:31:3e:1c:ea:ee:81:9b:c4:97:96:fd:e5:1c:95:
9e:c0:65:cd:a9:9a:cb:68:67:f2:62:a0:21:eb:5a:
c5:a1:92:ed:32:41:28:f9:47:34:eb:44:ae:d6:e7:
76:71:11:98:c9:2e:ce:6c:7c:10:1b:c7:4c:c3:14:
89:4e:d9:4c:d9:c7:43:e9:3c:29:ca:62:a9:91:b3:
87:e7:d7:b4:18:ab:65:f9:6b:ed:82:ca:a1:36:35:
18:05:cb:5c:24:26:13:13:f8:99:ac:99:be:9b:a6:
73:df:0d:16:95:b1:dc:be:fe:7a:c2:b6:dc:c8:93:
cf:10:e0:29:03:0e:28:78:18:84:ee:14:92:ab:be:
5a:a0:14:a2:4a:2f:d3:d0:b8:0e:00:d2:5a:cd:e4:
bd:a1
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
F0:D7:4B:14:73:E1:67:00:6B:54:B4:19:20:76:12:9F:9D:8E:C8:09
Signature Algorithm: sha256WithRSAEncryption
6d:52:21:6d:6e:8c:e5:4a:28:07:65:6d:d8:7c:23:2e:c6:c1:
d0:ec:27:b3:b0:c3:d3:e8:fa:72:b9:de:32:4e:ff:97:8d:86:
a9:6d:b3:a9:b4:2d:77:ca:28:97:6a:3d:7b:a2:15:ed:34:dc:
72:9f:6f:e7:01:0c:d3:28:6a:80:1b:50:09:fd:d7:2c:d8:92:
d5:10:c4:73:15:20:7d:99:dc:de:30:7b:3c:6e:e9:66:b2:0e:
4e:1a:c1:51:57:6e:5b:b0:a9:f6:ff:0b:8f:07:67:31:40:5b:
11:a9:06:d3:d3:76:c5:d2:56:95:9a:9e:4a:16:44:4b:32:e5:
af:dd:4b:4d:5d:57:b8:85:69:36:93:2a:c6:0c:8f:e1:42:35:
be:8e:f3:e7:35:d3:2c:3a:03:31:40:75:8e:e8:dd:57:35:20:
5e:18:a9:76:ce:85:be:7e:3a:cf:6e:08:58:5b:47:d5:e9:c4:
ec:0e:e9:8e:3c:2d:5c:7b:59:20:5b:24:92:a0:e0:1e:a3:5a:
67:d8:ff:7f:a5:82:f1:df:db:05:65:79:88:b1:3c:e6:01:d1:
5a:c7:d2:6e:9a:e6:a2:da:4a:c7:19:78:d9:14:71:6e:1f:70:
f3:41:e5:b3:78:31:d5:22:0e:7c:1a:b2:43:d9:86:ff:53:ea:
2b:ba:d2:27
-----BEGIN CERTIFICATE-----
MIIDhDCCAmygAwIBAgIUMu0hVthOqgOJqUqk4oUtijsriSIwDQYJKoZIhvcNAQEL
BQAwWjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAoT
CU9wZW5SZXN0eTEiMCAGA1UEAxMZT3BlblJlc3R5IFRlc3RpbmcgUm9vdCBDQTAe
Fw0yMjAzMTMxNTQ5MDBaFw00MjAzMDgxNTQ5MDBaMFoxCzAJBgNVBAYTAlVTMRMw
EQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQKEwlPcGVuUmVzdHkxIjAgBgNVBAMT
GU9wZW5SZXN0eSBUZXN0aW5nIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDmN9LGFzbHsn99z9Bih5nZIbje/9jiOhxokI/OF2gisGAwzCno
NO7/siXebhrU3xAZEUtAYdOpTYDtl4FOxXToTWPjXyG8Wm4ioBeRwcslU5udTuFR
W/ZS5won9hbCMctsR/SJURXMBr4xPhzq7oGbxJeW/eUclZ7AZc2pmstoZ/JioCHr
WsWhku0yQSj5RzTrRK7W53ZxEZjJLs5sfBAbx0zDFIlO2UzZx0PpPCnKYqmRs4fn
17QYq2X5a+2CyqE2NRgFy1wkJhMT+Jmsmb6bpnPfDRaVsdy+/nrCttzIk88Q4CkD
Dih4GITuFJKrvlqgFKJKL9PQuA4A0lrN5L2hAgMBAAGjQjBAMA4GA1UdDwEB/wQE
AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTw10sUc+FnAGtUtBkgdhKf
nY7ICTANBgkqhkiG9w0BAQsFAAOCAQEAbVIhbW6M5UooB2Vt2HwjLsbB0Owns7DD
0+j6crneMk7/l42GqW2zqbQtd8ool2o9e6IV7TTccp9v5wEM0yhqgBtQCf3XLNiS
1RDEcxUgfZnc3jB7PG7pZrIOThrBUVduW7Cp9v8LjwdnMUBbEakG09N2xdJWlZqe
ShZESzLlr91LTV1XuIVpNpMqxgyP4UI1vo7z5zXTLDoDMUB1jujdVzUgXhipds6F
vn46z24IWFtH1enE7A7pjjwtXHtZIFskkqDgHqNaZ9j/f6WC8d/bBWV5iLE85gHR
WsfSbprmotpKxxl42RRxbh9w80Hls3gx1SIOfBqyQ9mG/1PqK7rSJw==
-----END CERTIFICATE-----

27
t/cert/mtls_ca.key Normal file
View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA5jfSxhc2x7J/fc/QYoeZ2SG43v/Y4jocaJCPzhdoIrBgMMwp
6DTu/7Il3m4a1N8QGRFLQGHTqU2A7ZeBTsV06E1j418hvFpuIqAXkcHLJVObnU7h
UVv2UucKJ/YWwjHLbEf0iVEVzAa+MT4c6u6Bm8SXlv3lHJWewGXNqZrLaGfyYqAh
61rFoZLtMkEo+Uc060Su1ud2cRGYyS7ObHwQG8dMwxSJTtlM2cdD6TwpymKpkbOH
59e0GKtl+WvtgsqhNjUYBctcJCYTE/iZrJm+m6Zz3w0WlbHcvv56wrbcyJPPEOAp
Aw4oeBiE7hSSq75aoBSiSi/T0LgOANJazeS9oQIDAQABAoIBAQDhH9+uNE8uUv/X
MNvvLfklWpOlBf25o+fZ3NuzRjJgEafOsCee2fyI8FWVwIfeeE8OpFm5GLDZk1+r
dwdM10xuSheO5Z1gyfF/TJwfvamA09SNrPArFkm3YhUNZNl2hykMtwSLL06oWEOu
dbXjit4VS9aNIbTlEe7O5/6Ih0W3zmr1yvUua2swmAZMx3GFA4kbjZZ9vDs27sdu
K+VY3DYRbq1HkiNFT0otfke5bObFBCG7Yp8JLyhYaIkGYFoBXuZ6JNY8EuU2+YyP
6r40tJ7StR1Q6eZJh9/1leaYGZLCh5oFyKpilTuxHbRbr5A28RJKjKvPsdDgTtQn
yHGg70FRAoGBAOhC3TQlFcT2WCCZHHql9JEEHnHVBWnL3Jg7VJuL1i6pEIz7qQkW
AtBEIY/nnTcVNfJ6eXznYtutYvvRSgQTUsBNRoj3s1z9wKOo4uw4LoIUXDEmHCr+
49DiQyIO21SNMHA+dVxvGRDDjLI9Uc+Scb64QOodoX75HLRZG++24mtdAoGBAP2/
gCjga2p8Jx9UnhIcrEIIGANyxEQeBdhF56Nt9CJy/Iwi3a6qQ/GkbeoDm5FhXnXo
xcBaHyv2lwi4uO/hONY8eRnYxAWMwAKMZe6VnU1hWI2Ytkh+OcMPMh7NIGQf6X1o
JZrBtnTms060TuuDjLeIlaubDR/xDrMWTMKjKbsVAoGAVLuYAZ8J6xpIGlRhbGlA
6OrMxJCHcgpahvsWKc0BLXKmRBjHmTX7fslsSRihZWgKj1SZH7U2fpgpxV6cFxKJ
nPhUJEHhoKo+bjZ92tnANdqBq7iQjCsDJ8Bz52fuIlGD+1795+PsDA6bNKdkQkrV
zlNf80kuEqmFDFJ5+6EHx00CgYAf+jkpbZa71aeMgDpnZ+uhaqm0DYuEVhBAgBa/
9sRUbw86jc5IC7cCRcmAOzIosQ+ZZls9cV4KSUohVD4iJMzn2rkcM8AIPwOXjp/t
4DbxoHnrZjpaimW3Gjwju5AAbjEbl7tddFoNA2HHYlurvGlIW9MYzDJsOxGyKfZE
dRF2PQKBgQDUKNHgDYEjLJ99S5Fm5zN/64bKzzDtktGdqOxik5pBKcs/BvOdLM0i
eCjGz/3qrEoenFIBwF/IRz3ug90Zr8bWOu6DudReflAKI/N13dZ2gOTAfaX4ljJF
w0ohSi6xs+mu1GmtipGtNxHi/J3na2BeSnSRFSUg6Zd+oh8BZQKmNg==
-----END RSA PRIVATE KEY-----

4
t/cert/mtls_cert_gen/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
*.pem
*.csr
cfssl
cfssljson

View file

@ -0,0 +1,23 @@
#!/bin/bash
rm *.pem *.csr cfssl cfssljson
wget -O cfssl https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl_1.6.1_linux_amd64
wget -O cfssljson https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssljson_1.6.1_linux_amd64
chmod +x cfssl cfssljson
./cfssl gencert -initca -config profile.json mtls_ca.json | ./cfssljson -bare mtls_ca
./cfssl gencert -ca mtls_ca.pem -ca-key mtls_ca-key.pem -config profile.json -profile=client mtls_client.json | ./cfssljson -bare mtls_client
./cfssl gencert -ca mtls_ca.pem -ca-key mtls_ca-key.pem -config profile.json -profile=server mtls_server.json | ./cfssljson -bare mtls_server
openssl x509 -in mtls_ca.pem -text > ../mtls_ca.crt
mv mtls_ca-key.pem ../mtls_ca.key
openssl x509 -in mtls_client.pem -text > ../mtls_client.crt
mv mtls_client-key.pem ../mtls_client.key
openssl x509 -in mtls_server.pem -text > ../mtls_server.crt
mv mtls_server-key.pem ../mtls_server.key
rm *.pem *.csr cfssl cfssljson

View file

@ -0,0 +1,18 @@
{
"CA": {
"expiry": "175200h",
"pathlen": 0
},
"CN": "OpenResty Testing Root CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"O": "OpenResty",
"ST": "California"
}
]
}

View file

@ -0,0 +1,18 @@
{
"CN": "foo@example.com",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"O": "OpenResty",
"ST": "California"
}
],
"hosts": [
"foo@example.com",
"bar@example.com"
]
}

View file

@ -0,0 +1,17 @@
{
"CN": "example.com",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"O": "OpenResty",
"ST": "California"
}
],
"hosts": [
"example.com"
]
}

View file

@ -0,0 +1,27 @@
{
"signing": {
"default": {
"expiry": "175200h"
},
"profiles": {
"server": {
"usages": [
"signing",
"digital signing",
"key encipherment",
"server auth"
],
"expiry": "175199h"
},
"client": {
"usages": [
"signing",
"digital signature",
"key encipherment",
"client auth"
],
"expiry": "175199h"
}
}
}
}

87
t/cert/mtls_client.crt Normal file
View file

@ -0,0 +1,87 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
19:0a:a3:a8:9c:d4:0f:dc:c6:fa:23:7b:f8:fc:bd:f4:73:4e:7e:b1
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = California, O = OpenResty, CN = OpenResty Testing Root CA
Validity
Not Before: Mar 13 15:49:00 2022 GMT
Not After : Mar 8 14:49:00 2042 GMT
Subject: C = US, ST = California, O = OpenResty, CN = foo@example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:be:5b:09:4c:94:71:d3:82:54:4a:42:6a:76:aa:
34:5d:28:d9:45:e6:44:9a:74:9f:a6:e6:78:49:9e:
c6:20:75:32:5f:92:3b:ec:6e:4b:7b:b0:75:1c:75:
09:00:05:77:d6:59:ca:55:5b:13:b6:76:3a:c6:18:
dc:37:6a:20:93:e6:26:56:5d:0b:96:8c:01:f2:96:
38:08:08:36:a2:64:12:21:a0:8d:48:cd:9a:26:78:
92:29:b6:63:eb:14:d9:b6:e5:87:f7:d5:55:a4:cc:
53:1c:a3:7c:b8:bd:ad:7c:a4:d4:86:1f:a7:1c:43:
c5:1a:b5:f1:03:bd:fe:19:98:1d:b7:13:2b:93:a2:
2a:0e:21:7e:42:a9:bb:28:69:49:59:e7:89:0e:7d:
5a:ce:fb:d4:0c:20:6a:e1:db:b2:6a:e5:a7:55:e0:
d0:58:4a:e2:08:78:82:b9:06:0c:65:f9:24:06:e6:
8a:13:b2:9a:ef:1b:4a:b2:3a:b4:98:7f:dd:3c:0e:
85:0b:a6:c6:47:2f:63:c2:73:52:41:db:7c:06:c3:
2a:b5:2d:d1:e1:30:d5:c4:79:c9:b9:35:68:46:ad:
c4:45:57:ea:11:88:27:37:ed:ac:49:2d:c4:d6:c6:
a6:74:8d:d3:bc:e0:d9:69:25:0c:0c:b0:e3:b7:cb:
8d:99
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
22:70:5E:30:8C:4D:66:39:E7:60:C9:29:A2:ED:95:32:34:63:5C:C0
X509v3 Authority Key Identifier:
keyid:F0:D7:4B:14:73:E1:67:00:6B:54:B4:19:20:76:12:9F:9D:8E:C8:09
X509v3 Subject Alternative Name:
email:foo@example.com, email:bar@example.com
Signature Algorithm: sha256WithRSAEncryption
96:e7:2a:fc:2a:56:16:80:e2:d3:79:0c:46:db:c3:88:ab:d3:
ef:39:66:4b:a9:ab:6c:0e:30:08:07:7c:fc:03:6c:f7:dd:fb:
3e:a8:c8:68:28:ab:4e:73:97:80:27:5d:c5:9d:52:00:aa:08:
25:c8:f9:dc:df:64:73:a4:58:5b:bd:5f:1a:53:a4:33:a3:b1:
45:38:2d:be:d7:f3:a4:c4:f4:7a:07:71:44:f1:a2:65:02:e4:
71:84:01:b5:83:4b:de:83:b5:ad:ac:b9:3c:17:42:0c:9a:7d:
eb:7f:ab:26:dd:9b:3a:fd:95:37:55:cc:01:c3:3f:20:df:e5:
ed:49:51:7a:42:ea:f3:8a:3f:da:6e:c1:1a:11:b9:45:4d:6e:
c9:21:f4:e3:4f:31:72:5b:bb:01:92:b6:7f:f1:8a:9e:6c:d0:
7f:96:d7:eb:29:09:53:38:26:41:00:f2:33:04:77:bd:a9:ee:
60:9e:06:b7:7d:26:ae:1c:4f:56:bd:a5:b6:50:40:be:be:84:
2a:54:21:59:47:7d:a5:1e:63:6d:28:36:4d:a6:e4:62:69:9b:
9b:fa:2b:48:e8:64:d7:14:f4:62:a2:26:17:a5:05:58:4a:38:
d2:44:e7:33:90:b9:c1:8c:85:02:99:b8:03:1a:03:d2:cf:ac:
a5:6b:44:98
-----BEGIN CERTIFICATE-----
MIID3DCCAsSgAwIBAgIUGQqjqJzUD9zG+iN7+Py99HNOfrEwDQYJKoZIhvcNAQEL
BQAwWjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAoT
CU9wZW5SZXN0eTEiMCAGA1UEAxMZT3BlblJlc3R5IFRlc3RpbmcgUm9vdCBDQTAe
Fw0yMjAzMTMxNTQ5MDBaFw00MjAzMDgxNDQ5MDBaMFAxCzAJBgNVBAYTAlVTMRMw
EQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQKEwlPcGVuUmVzdHkxGDAWBgNVBAMM
D2Zvb0BleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AL5bCUyUcdOCVEpCanaqNF0o2UXmRJp0n6bmeEmexiB1Ml+SO+xuS3uwdRx1CQAF
d9ZZylVbE7Z2OsYY3DdqIJPmJlZdC5aMAfKWOAgINqJkEiGgjUjNmiZ4kim2Y+sU
2bblh/fVVaTMUxyjfLi9rXyk1IYfpxxDxRq18QO9/hmYHbcTK5OiKg4hfkKpuyhp
SVnniQ59Ws771AwgauHbsmrlp1Xg0FhK4gh4grkGDGX5JAbmihOymu8bSrI6tJh/
3TwOhQumxkcvY8JzUkHbfAbDKrUt0eEw1cR5ybk1aEatxEVX6hGIJzftrEktxNbG
pnSN07zg2WklDAyw47fLjZkCAwEAAaOBozCBoDAOBgNVHQ8BAf8EBAMCBaAwEwYD
VR0lBAwwCgYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUInBeMIxN
ZjnnYMkpou2VMjRjXMAwHwYDVR0jBBgwFoAU8NdLFHPhZwBrVLQZIHYSn52OyAkw
KwYDVR0RBCQwIoEPZm9vQGV4YW1wbGUuY29tgQ9iYXJAZXhhbXBsZS5jb20wDQYJ
KoZIhvcNAQELBQADggEBAJbnKvwqVhaA4tN5DEbbw4ir0+85Zkupq2wOMAgHfPwD
bPfd+z6oyGgoq05zl4AnXcWdUgCqCCXI+dzfZHOkWFu9XxpTpDOjsUU4Lb7X86TE
9HoHcUTxomUC5HGEAbWDS96Dta2suTwXQgyafet/qybdmzr9lTdVzAHDPyDf5e1J
UXpC6vOKP9puwRoRuUVNbskh9ONPMXJbuwGStn/xip5s0H+W1+spCVM4JkEA8jME
d72p7mCeBrd9Jq4cT1a9pbZQQL6+hCpUIVlHfaUeY20oNk2m5GJpm5v6K0joZNcU
9GKiJhelBVhKONJE5zOQucGMhQKZuAMaA9LPrKVrRJg=
-----END CERTIFICATE-----

27
t/cert/mtls_client.key Normal file
View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAvlsJTJRx04JUSkJqdqo0XSjZReZEmnSfpuZ4SZ7GIHUyX5I7
7G5Le7B1HHUJAAV31lnKVVsTtnY6xhjcN2ogk+YmVl0LlowB8pY4CAg2omQSIaCN
SM2aJniSKbZj6xTZtuWH99VVpMxTHKN8uL2tfKTUhh+nHEPFGrXxA73+GZgdtxMr
k6IqDiF+Qqm7KGlJWeeJDn1azvvUDCBq4duyauWnVeDQWEriCHiCuQYMZfkkBuaK
E7Ka7xtKsjq0mH/dPA6FC6bGRy9jwnNSQdt8BsMqtS3R4TDVxHnJuTVoRq3ERVfq
EYgnN+2sSS3E1samdI3TvODZaSUMDLDjt8uNmQIDAQABAoIBACqRsUKu78WdH7x7
ndNrvMoYmH5JQI5KBmoMoFnWZ/haPSmiSkRVZgwDKi1y/tBCaMpGyjjMZVwolHw4
kwbRdPeeQHSP2keQh974OQ+SxqUKPAPJI89kK1TvIcCySSYJQ6bjLcT+sGhqSSve
Y8XspR96vQxBh92KSknu5jcwBeMy/eG0mmszzP3y2R0BPztuZdE6dq/KxWQ/R4/P
JG9V1rNkIY+1JZvIICIH1Ehn4UKjiE+FJmyDbDlPKEi7W4CpRnShMLOF4cCFnQLW
RQds3Dj9GcVY+8Q/GLZF0ATjekIyEsKZEgrMAUF5ZSGRpjJQEHX7oseAiQGQxtHT
nj5b1AECgYEAwewXbbd1MqRQ6ohfsQ8j5HSMY6ahvUzs1dZUckr2jw8B98tfi/uj
a6Jq1KZe12+4dfwruRSaYdTsSVuvNiSJOxElY0C1p+lXdprFf7XfoQ6UNtg22jcH
9f8cftnlJoV5whh3YKjqnnnAWUQZ61FTNJ258/t+x0ZgpBJvqBoHwDUCgYEA+0qp
FZ5xS4FLJMc+Xf/hUeXo+04e4OD/se3atYqyuh1ghmQZfRRPOC110HG99H+rzq/x
xPMvRFahkAMyi+/3oIcBEuXvoQyqscIsAhkWD/e9t3Qc9OsWe1hlAgWKZxr6oR2U
KKR1FD7UVecOH+FKCKaL5UpEt4yEigc1NtSlTFUCgYBnV5agrIyzQSex5J0CMWxS
Od362PkGdXEc/8we4F4GnNvSnrm7Uo2jNXmy+zo9mtb1YT43sogXLK4C5e44bz4G
kTuYagqkgdBPb2lihpy3KprHo2+P2JXQfXRFEX9xiN37Fqi/hSUK8R0VNRqO8dbi
ik9nexXzwkiMBxsjvUN2JQKBgFy62FpZ9YTfWVNhEuqtGgCWzrqtwUdKwBBwrVyA
qiNz48Kz/ZPigrlATVF2J5qp4kSLOLRs6OxW65exFl39V2utZgALSbosanDeLk83
4qRRz3h7KJRYjBtIKz3rvX7+va3mtF2rEmk+Jizs7pFlGWTH0Kf0GBeDiwVEU6bA
IZ9hAoGAQTjnRGMjvyhq0aPYP+mRFiMKSkcL1nyXizYInfAnbfbL/uEODH7D+iMf
kak+UgmeD9ce5d/APmZp3/FzYH/M8ivBgG+MnaI+MLVMhmQdLZyMtbSKKaDpiim7
DdN1wCXYbur0HlO2t+wemMZPpQu7wybgEOLlIG7Yj/0OWDcal1c=
-----END RSA PRIVATE KEY-----

87
t/cert/mtls_server.crt Normal file
View file

@ -0,0 +1,87 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
2f:d5:41:13:5a:ff:c7:1c:5b:ce:28:cd:a6:f7:a5:5a:0d:c0:e2:d2
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = California, O = OpenResty, CN = OpenResty Testing Root CA
Validity
Not Before: Mar 13 15:49:00 2022 GMT
Not After : Mar 8 14:49:00 2042 GMT
Subject: C = US, ST = California, O = OpenResty, CN = example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:d7:03:80:a7:42:7d:06:5a:7b:70:d8:11:96:dd:
63:35:53:07:28:71:52:05:40:55:83:61:a7:14:ac:
cf:4b:9b:ab:b7:4e:9d:79:e9:13:3d:bc:c3:67:8f:
dd:88:d9:8b:c2:31:aa:b8:28:9e:13:70:db:76:b0:
12:1c:f8:35:c6:2e:33:9c:b9:04:e3:47:e0:f9:e4:
7f:a5:55:03:0c:2d:b2:54:17:29:12:dd:61:6e:5c:
33:9f:e5:8f:8a:2b:41:53:dc:e1:98:49:63:df:e3:
00:30:2d:1b:bb:f0:8f:cb:04:ec:c9:98:c4:09:5b:
b4:ba:a9:a0:0a:77:d2:42:76:7c:ac:64:c3:97:85:
50:5d:7d:02:61:2a:00:93:d0:69:5e:87:22:f0:c1:
1e:53:46:02:40:37:c9:55:77:99:7d:9d:3d:35:14:
74:84:e3:73:ca:e7:4a:ab:33:98:26:aa:41:4b:b5:
e6:63:7c:a4:1e:25:6a:88:f4:56:d9:2c:63:dd:89:
19:fa:25:41:44:95:87:40:a7:9b:4e:3a:91:29:32:
79:66:05:f4:2f:68:2c:06:53:df:4d:60:be:ac:09:
20:61:9c:6f:1a:a6:07:5a:e7:41:91:9d:36:77:38:
18:3a:69:7b:67:29:9f:1d:e0:c2:d2:8f:16:5b:14:
e8:e1
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
16:07:B5:C2:4C:B5:2D:4F:B8:E9:D6:FA:2F:3F:C0:1B:B6:4F:20:E6
X509v3 Authority Key Identifier:
keyid:F0:D7:4B:14:73:E1:67:00:6B:54:B4:19:20:76:12:9F:9D:8E:C8:09
X509v3 Subject Alternative Name:
DNS:example.com
Signature Algorithm: sha256WithRSAEncryption
d9:c0:c0:d6:8b:44:04:26:b3:98:24:2c:12:82:6d:15:79:92:
76:c9:77:94:c1:be:8f:8a:18:78:96:04:68:c9:0a:d1:84:c5:
de:cd:ba:b5:a2:3b:d4:0a:70:be:00:49:19:c0:6e:ca:e9:e5:
8b:b6:e3:a2:39:0d:d8:ee:55:1a:08:73:39:19:d3:07:07:33:
8c:d8:1b:0f:1b:73:0e:84:72:cf:e6:c1:a1:da:39:aa:c0:2e:
3d:b9:a6:8f:ec:98:3a:07:58:34:c2:5e:4c:1a:6b:db:ce:51:
92:25:1d:ba:78:4b:11:b6:f1:69:02:cb:ac:32:bb:80:f9:15:
91:bf:4e:6a:ab:51:51:7c:7b:1a:72:80:96:eb:0c:fa:56:0e:
f2:87:3c:16:8a:04:aa:8a:9d:0c:d9:e0:c4:2a:20:42:5a:12:
41:52:30:50:3d:85:f8:07:31:6b:af:a4:d2:44:38:69:ab:88:
05:d4:5b:68:34:02:dc:99:5a:6c:b7:ea:fc:79:76:fe:68:29:
df:94:22:58:46:f2:40:cb:e1:92:17:d8:1e:3d:fa:a2:56:4f:
ac:3c:3d:ae:f7:90:12:ac:3b:6c:1e:1f:26:48:08:87:9a:0e:
8d:9d:75:ef:86:1e:63:ac:e9:14:47:ad:3f:4f:10:57:2a:d1:
95:ec:6f:24
-----BEGIN CERTIFICATE-----
MIIDwzCCAqugAwIBAgIUL9VBE1r/xxxbzijNpvelWg3A4tIwDQYJKoZIhvcNAQEL
BQAwWjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAoT
CU9wZW5SZXN0eTEiMCAGA1UEAxMZT3BlblJlc3R5IFRlc3RpbmcgUm9vdCBDQTAe
Fw0yMjAzMTMxNTQ5MDBaFw00MjAzMDgxNDQ5MDBaMEwxCzAJBgNVBAYTAlVTMRMw
EQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQKEwlPcGVuUmVzdHkxFDASBgNVBAMT
C2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1wOA
p0J9Blp7cNgRlt1jNVMHKHFSBUBVg2GnFKzPS5urt06deekTPbzDZ4/diNmLwjGq
uCieE3DbdrASHPg1xi4znLkE40fg+eR/pVUDDC2yVBcpEt1hblwzn+WPiitBU9zh
mElj3+MAMC0bu/CPywTsyZjECVu0uqmgCnfSQnZ8rGTDl4VQXX0CYSoAk9BpXoci
8MEeU0YCQDfJVXeZfZ09NRR0hONzyudKqzOYJqpBS7XmY3ykHiVqiPRW2Sxj3YkZ
+iVBRJWHQKebTjqRKTJ5ZgX0L2gsBlPfTWC+rAkgYZxvGqYHWudBkZ02dzgYOml7
ZymfHeDC0o8WWxTo4QIDAQABo4GOMIGLMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUE
DDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQWB7XCTLUtT7jp
1vovP8Abtk8g5jAfBgNVHSMEGDAWgBTw10sUc+FnAGtUtBkgdhKfnY7ICTAWBgNV
HREEDzANggtleGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEA2cDA1otEBCaz
mCQsEoJtFXmSdsl3lMG+j4oYeJYEaMkK0YTF3s26taI71ApwvgBJGcBuyunli7bj
ojkN2O5VGghzORnTBwczjNgbDxtzDoRyz+bBodo5qsAuPbmmj+yYOgdYNMJeTBpr
285RkiUdunhLEbbxaQLLrDK7gPkVkb9OaqtRUXx7GnKAlusM+lYO8oc8FooEqoqd
DNngxCogQloSQVIwUD2F+Acxa6+k0kQ4aauIBdRbaDQC3JlabLfq/Hl2/mgp35Qi
WEbyQMvhkhfYHj36olZPrDw9rveQEqw7bB4fJkgIh5oOjZ1174YeY6zpFEetP08Q
VyrRlexvJA==
-----END CERTIFICATE-----

27
t/cert/mtls_server.key Normal file
View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA1wOAp0J9Blp7cNgRlt1jNVMHKHFSBUBVg2GnFKzPS5urt06d
eekTPbzDZ4/diNmLwjGquCieE3DbdrASHPg1xi4znLkE40fg+eR/pVUDDC2yVBcp
Et1hblwzn+WPiitBU9zhmElj3+MAMC0bu/CPywTsyZjECVu0uqmgCnfSQnZ8rGTD
l4VQXX0CYSoAk9BpXoci8MEeU0YCQDfJVXeZfZ09NRR0hONzyudKqzOYJqpBS7Xm
Y3ykHiVqiPRW2Sxj3YkZ+iVBRJWHQKebTjqRKTJ5ZgX0L2gsBlPfTWC+rAkgYZxv
GqYHWudBkZ02dzgYOml7ZymfHeDC0o8WWxTo4QIDAQABAoIBAEnmZUiXnJsbbEPr
r5f3vYptYA9xa2xsoTeHz8JWZuUouwtE1PE6v6c/grXMh6rqgpObOH8VTseFyZhw
ibk1Ql48MPcTzG9FnDinZYvwvRxpdFpcn3xhZIRm4kN5xi0KEuj9CPireM1RmxXz
2w1scC+qIKxlejNxNpvVgzE136mBqEFKJzecP+yZuH/A86MQCgwqqa3jSz5ApNg+
1aJE34cGFieDbAN+9sdqWA3OkRrHoy8EakUf4JEvwX1AwUN832mj+N/LfmcCGMeD
YhzybzlPBV2q2T1+pHIdNT99JVNPkgdTe1903EjnG5oSDGHt2i9MdnNkMsffDWNt
pJiqSHECgYEA2hL6l8Py4oa5AJ2WXriuHRJykAs90K0akftQt4i4lWCbeRhaGh7h
kPgpDS33RkE4SymVVr0c05abMCKabQBwbu4PNCqetCFtfmIQdQCTUbLbXjL8UuD2
QnF7nbHiwyGBKRMU/F74oX3z7lXLgRtIiyyo5yYgIAQqpz3oJAaXNTUCgYEA/GhE
Ziez8FXVAg3XwwrE3SexRFKv1JqipYE4mr+ouzfpn9yn8mttxbOORiAAEBl3ZPhd
ZUBzLy19fdFZ8RJ0zPsqoZxsd09/XetaBU56C/g9u0fycj1L2elh9rQAlOW0Grus
l8jBh01TGtlg0xobK0zjwdGPcbYkp1IzIqyD9n0CgYEAicBvVyrJ5FnhxwfEkrTq
FycuAtt3Arg2DnzH8geFQaayzv2Y/OMA7Yg0tkSQ7GoKW0A7O31eFjIOeYuCLNSY
MRpjtDov4e0zsx/S8XWZmYP3mjtutBOyuyngQi655TTm18FcAkcjmy9qxOShFj7b
xj5BuzGUHWVEZDxwxUD8hvkCgYBnrcyqyZQ4HImqllUSYNIMpclC71QaWIqGwVWm
+yMsBAOLDvBNu6MTmnXOiEZ+VnecmgiDFr45ms35aI0xYQtpR6JzT/Wd7KG8ynfn
xhyL3iQ9UYhdNKB7mkoLNFUo1FHuyThUALq+AR0p4jDLheWzG5pSeuoZI2Ba+oDW
tVZfYQKBgC5phtERR5LKU5Wkzm+uY2j+Nzh4kuKkdLosB9pUW8VnrwFDLZ+r1CxG
L6CxOZ0AylCMIlrFeUXMa91kLDJYch0NUPHuGBkdIBDXi2kqN7GflTdV3Z8uev20
uMjErA93yVOWHTR3Wo8WIHy5mdsNRQgGAPw1RVW7rnYIyXJW/mTs
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1,43 @@
Following steps require https://github.com/cloudflare/cfssl
Initiate CA by creating root certificate pair:
```
cfssl gencert -initca ca_csr.json | cfssljson -bare ca
```
Continue with intermediate certificate pair for signing:
```
cfssl gencert -ca ca.pem -ca-key ca-key.pem -config=cfssl_config.json -profile=intermediate intermediate_ca_csr.json | cfssljson -bare intermediate_ca
```
Also create OCSP certificate pair to sign OCSP responses:
```
cfssl gencert -ca intermediate_ca.pem -ca-key intermediate_ca-key.pem -config=cfssl_config.json -profile=ocsp ocsp_csr.json | cfssljson -bare ocsp
```
Create a leaf certificate:
```
cfssl gencert -ca intermediate_ca.pem -ca-key intermediate_ca-key.pem -config cfssl_config.json -profile server leaf_csr.json | cfssljson -bare leaf
```
Create an OCSP response for the certificate:
```
cfssl ocspsign -ca intermediate_ca.pem -responder ocsp.pem -responder-key ocsp-key.pem -cert leaf.pem -status good | cfssljson -bare ocsp-response-good
```
Bundle certificate to be installed at Nginx:
```
cat leaf.pem intermediate_ca.pem ca.pem > leaf-bundle.pem
```
Inspect OCSP response to see what is the Next Update:
```
openssl ocsp -text -no_cert_verify -respin t/cert/ocsp/cfssl/ocsp-response-good-response.der | grep "Next Update"
```

View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA4U+dsu8CAV+Tyhn+z1UFSJ6H7CUQuq7AeGH5df3D8nEyW83N
8NjImED3SJkns8vzwHLP/7/UqPPDWZLu/KlIaI2740W3Zin4Eq4b9Tfbu+HTI+Cf
Vo461WlKMnKGG7nzmElSRA04cQm/M/LhajQS7EwM0Hto+GEGGLjJSVMOPY3zvnqu
bRMWfzGn5cMON9bVclZHnVwhwNeR9EMYwCpN/mgXjFlC2O5vHPjM7etRn2c3EIXP
370YQ0iC2UkUB4ttX9d13obwqqprTyZH9Fl1X1XuyJLIMB5ahawyck7Jf9NB2dAJ
9udilGEO1uLiY6StbYF/9IxvW47QtFN5z+ukFwIDAQABAoIBAQDZ5TlJlsOFuH0g
8sruj/awKECjK6VmJSKWSYoLhgM+MCLXjc0go0Y7mHiNiTBQPWnaMC7f0xFC45uE
wQjG6J/SHWAbh4y6DNSQnDkFiaPDq72Z8N2nw506Tr0m1ILFxavDFwWsMmznRNnY
z4cYQowaYeHyrabyrkJLHknr05ruAs2hflAbRqVXICdF7NoubPmKEb+LCd0jyzPo
hITUtkIEssBW1zXacnAoMG+IWZOWJsbW8QtGsEfuABeHdKq1VX07XSe5tO/9KnYw
E2QZq0bncytKiiN6OzTCFROnzc8F4YYxxlOm5klNsRKFBNh6wm7KwEMT/eA6gcbo
WkT/EpMhAoGBAOwL3YqD6fxTOnEXhKgEo+dKzAUutsdRPvV1a+OSgfn/KDCaPm90
UbUARyz+x+DNBmS7muClCALCoQNkb5IRgSzVAckuRpanadtT5TLSSxQFP8LCoHSQ
evPgwtPFHUWdgudEh5Oz20sblGyml0jtkDbmh0bRDz5xdQudr9q8IPBFAoGBAPRb
bvmCeYsEke9zN6lZceBP6wfQLVeJhqV+63JG/qAMzUR4KD+/gfH0XWLDLA1pbp2C
VYrZl6LhBx9DKuU8HCzsxA0uBvTx+JJUfxcuPZ6fX5/kD4Npvta7nsjJ+nmDR29l
Q4dJMe3u/abNDGOc+RqPQN5F+rXM3Yx/7SkQj+6rAoGAeB8Fq8K7pUuZdwnX2UUb
P83hi1WdcEsZNgJ+V/4rpNRDWJB163QPTIQKtIwnnW/YrBSImX+CVx1CoR5QZM4B
pZX0ZbPl+i7SAOptvfIkgNi2/N7cltUbrNYZb3llDxM8FYLbV7/0fgFYA/63CEbU
2Atylgg3sLg+Lx4c6rxIKt0CgYEAjCA6vV5y8KOIRHYf/z9JrEZoEyzwM3ir/A+S
WRAZSBLPS2pUOmpJzERDoTUm9/Hz+uMYxu0MpdzBRs4vtREJX0HPE3fHiYOQ9ej6
kIJ115axMXGI6+UiCOXCooYg2rnLpze8x8HTngwk7Rg8+Iq11uM7YbtjkAmRKtbZ
W2kiAM0CgYBsDwsSIHT6FsogaxHMejv88UKmqIiAIKudtU3jdfRVGE938WPpfyuL
1+iYI3eWyHzBvco4Ghv2icnWOC+DS5XBP3s9D3ueVEh8j/49bd/4mUeyiZMB5Pdr
/tAqEyeNU5iYf5XwQwPUm6QMRkCCVwM3kSLkhyWF2wPE/XhVsIKxZQ==
-----END RSA PRIVATE KEY-----

17
t/cert/ocsp/cfssl/ca.csr Normal file
View file

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICwTCCAakCAQAwfDELMAkGA1UEBhMCQ0ExEDAOBgNVBAgTB09udGFyaW8xDzAN
BgNVBAcTBk90dGF3YTESMBAGA1UEChMJTHVhIE5naW54MRowGAYDVQQLExFMdWEg
TmdpbnggUm9vdCBDQTEaMBgGA1UEAxMRTHVhIE5naW54IFJvb3QgQ0EwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhT52y7wIBX5PKGf7PVQVInofsJRC6
rsB4Yfl1/cPycTJbzc3w2MiYQPdImSezy/PAcs//v9So88NZku78qUhojbvjRbdm
KfgSrhv1N9u74dMj4J9WjjrVaUoycoYbufOYSVJEDThxCb8z8uFqNBLsTAzQe2j4
YQYYuMlJUw49jfO+eq5tExZ/Maflww431tVyVkedXCHA15H0QxjAKk3+aBeMWULY
7m8c+Mzt61GfZzcQhc/fvRhDSILZSRQHi21f13XehvCqqmtPJkf0WXVfVe7Iksgw
HlqFrDJyTsl/00HZ0An252KUYQ7W4uJjpK1tgX/0jG9bjtC0U3nP66QXAgMBAAGg
ADANBgkqhkiG9w0BAQsFAAOCAQEACSfvzpO2ENkOEPDznNPHLXIPpNwdxBXoJPNs
61vIMK4t5qBraAqUTrw2hCs/7CEez0TDCCiZkHNzwpSzKmFBh98D4rdaGTdrN3XG
NaZd7yacQ2ZB+vY45GbM5LNqXfKA4uwISqEKL8nFWkwQceTF52L9rIJTwcBjUcQg
23iU1fjsDFXuSP+RxL4hsO2imcrQHuouIW0/iQW3ZB7gYLqN+OqOm0Fj369UeFUo
I0NAGt1u3p+oxQ22FfoZJ2F9jDVvzRJe9TE+KrZv7QhRNQftSOu86m6EqjZKP88k
zGIuY6NB4N1K1fua6Rh/or68ERvT4aPIvzLklzCSbzS1qsR0Bw==
-----END CERTIFICATE REQUEST-----

23
t/cert/ocsp/cfssl/ca.pem Normal file
View file

@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIIDyDCCArCgAwIBAgIUUw9rlqc2DnJNFZ9gw/zRLPRQ4zMwDQYJKoZIhvcNAQEL
BQAwfDELMAkGA1UEBhMCQ0ExEDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90
dGF3YTESMBAGA1UEChMJTHVhIE5naW54MRowGAYDVQQLExFMdWEgTmdpbnggUm9v
dCBDQTEaMBgGA1UEAxMRTHVhIE5naW54IFJvb3QgQ0EwHhcNMjQwMzEwMTQxODAw
WhcNMjkwMzA5MTQxODAwWjB8MQswCQYDVQQGEwJDQTEQMA4GA1UECBMHT250YXJp
bzEPMA0GA1UEBxMGT3R0YXdhMRIwEAYDVQQKEwlMdWEgTmdpbngxGjAYBgNVBAsT
EUx1YSBOZ2lueCBSb290IENBMRowGAYDVQQDExFMdWEgTmdpbnggUm9vdCBDQTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOFPnbLvAgFfk8oZ/s9VBUie
h+wlELquwHhh+XX9w/JxMlvNzfDYyJhA90iZJ7PL88Byz/+/1Kjzw1mS7vypSGiN
u+NFt2Yp+BKuG/U327vh0yPgn1aOOtVpSjJyhhu585hJUkQNOHEJvzPy4Wo0EuxM
DNB7aPhhBhi4yUlTDj2N8756rm0TFn8xp+XDDjfW1XJWR51cIcDXkfRDGMAqTf5o
F4xZQtjubxz4zO3rUZ9nNxCFz9+9GENIgtlJFAeLbV/Xdd6G8Kqqa08mR/RZdV9V
7siSyDAeWoWsMnJOyX/TQdnQCfbnYpRhDtbi4mOkrW2Bf/SMb1uO0LRTec/rpBcC
AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
BBYEFOnsOYUW8U3ak+h1LUisz1czYQo+MA0GCSqGSIb3DQEBCwUAA4IBAQDHySN4
lWLHa12vYPvRVLNeWq3RaHQfKc2F2PhHriGCegY4lyZJqfC0XGI4LBnJ5GK//D0B
Hb8jcbGyortGBEwGuqjuOMdv0HOWibqZ7LPZ98GegtAjAJWMp/sQXkIYiRM8hlNC
pl9Vp9vsnUjfCrMaLVkZCC2Nwixc5mhSeH0aYHxxFwqh88oWbXzW7xobcTaYx/1P
kPdCy+jiBMCZII7J1u/e1B0J1VFad+IVJpQW+DzVIzJz9ClNAsJZjx1BBwIJGGEZ
fS1XXw+HgGeH2cVFnThMy0PIvx70b//GxEoXwuJhL2+z/tNhRRBN2eMa2zrZS94k
z+yCDRXP/rDxf+b7
-----END CERTIFICATE-----

View file

@ -0,0 +1,16 @@
{
"CN": "Lua Nginx Root CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CA",
"L": "Ottawa",
"O": "Lua Nginx",
"OU": "Lua Nginx Root CA",
"ST": "Ontario"
}
]
}

Binary file not shown.

View file

@ -0,0 +1,32 @@
{
"signing": {
"default": {
"ocsp_url": "https://ocsp-responder.test",
"expiry": "2190000h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
},
"profiles": {
"ocsp": {
"usages": ["digital signature", "ocsp signing"],
"expiry": "876000h"
},
"intermediate": {
"usages": ["cert sign", "crl sign"],
"expiry": "2190000h",
"ca_constraint": {"is_ca": true}
},
"server": {
"usages": ["signing", "key encipherment", "server auth"],
"expiry": "876000h"
},
"client": {
"usages": ["signing", "key encipherment", "client auth"],
"expiry": "876000h"
}
}
}
}

View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAncpy3Iqw4E71BI2Bt5P1+70lHHt2sBvFu9UM0+6z/mwSqi1B
/APeSDAEpUptQTPk2gdaJB2G1IpH5pcYU6I+YOzQ02XPmtlRlFxizP3lx8f6JJnM
w194YD3JOayz9n+njKfonS2/EwpetopCKrHwh0FsQd0qHx78RuojTKMr2LNzBfyt
UujVyM/AR1nPMh85g+Tvr9FRzEaVSpD8r2x3erJ3AtdSbYCsIEqEGPWX82IvFQjQ
zm26bQoZjYl1sNa36+c5Sah9RtV3fkkiGM/fsXPcMJo97zd8Jg4ZkqAaM6zscRTB
v13neSYEIMt9835jJxh8aWja4pYF/5bW6EsfQwIDAQABAoIBAH5z5PMbbr6EaFV6
tg8R05soLNqTkz11NFTgW4RokvT9VUPuOyglTXkaik6Qw9fyJ6AXLkUtKIWiQBbq
1cMIjecNQhl4SRT2visgkslnXENr3uqAGxojo4u1WFMRNbQA/5x4X7G/HJa8w8SU
Loyax4ENjB2IiZ4hLdoC/8EGLzhc7VP6BhlYekeU35188VEyVk4Ls/6QTlqgFz/X
4DXOPNVeTtRap/6YtzTjmgrzP5aIqZA++qZMmRGVHoasb/f8qAXS3gyMXae1xpMA
XFv6DGwd2P3V9LGPuy9MppB6MNSB3pJFGHtoodY7wI39t+omQmHhJQTIDWBMJGE1
Ml4gO7ECgYEAyx8kC01gT5uBh/grI3isgqWOYlAm7F2kpyupK8XMlnD6m1BmTQh7
rjlwbPQDDwTOsfcJY0UDnyRKKmUJvcZsJzEQfysl8tJO5/15SxXg44hBE0c2eqBb
WsBIR0TKtocp+BdSClJu++QTUYSdPmaLqi9F7lnIeNcf+iLRR4CqdnkCgYEAxt5G
jTEy5TH0b3vkGIqJBDOLbsRccCGmx9f4WCejJsQRyXbSgRKGPjWlG5UCeJW1LxN+
+j64bJDudBRqzgcuVZVdu/+k6vl6at1VxIRWd9MRuOk9JYf+YMvxR+i6dml0BPna
D3npryH0iXQHu4IO6F1PtNiCG7ouPZeyL+g3hJsCgYBuolePkGWU9q5m0NUuTNwp
jOMwyVdqBtdX9n/+R45XotHdJr2R170F+GMz9PR1ibjLVjLWzxBZ7fo3fTEBHMJr
1l2V5nqU99fipD0cmJ4VUHGhfng98nnPxEuaBe4j3RsO9iTJWnz41hFvpTvAcTpB
R95fJKf8qa/RHoW+3GX8gQKBgFLa/xgKfIMDei0MuC8FYSrP8vL2evD5BEzVDZJl
CVO4cxS2HeRK/IVkwmKohbwJ29A+VjQa96m8BK12aD1ovoRH1CLk0yhXQwrNJtPW
s1P/K64X9zLw4yofLmrgave03fLIynKSP6uJASJXpnUYLe/gGLpnTmYQ/v0Ie+P7
402rAoGBAKdrA+ZpL0gY1D/RZ34OokkcA+xiR5jyUODM4L95gJVuKz+N1IZN9DiV
6oPBnSg24nxBHAdAKco0qQUOZtsvfiZCkZbMxcKaz7kI/ovttREZ4BQY74pga6Hk
oCUHskJ9jhaei57irMB4VU68ZY33+NqXS+yPIR1XoKpmeipjaLQH
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIC0jCCAboCAQAwgYwxCzAJBgNVBAYTAkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ8w
DQYDVQQHEwZPdHRhd2ExEjAQBgNVBAoTCUx1YSBOZ2lueDEiMCAGA1UECxMZTHVh
IE5naW54IEludGVybWVkaWF0ZSBDQTEiMCAGA1UEAxMZTHVhIE5naW54IEludGVy
bWVkaWF0ZSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ3KctyK
sOBO9QSNgbeT9fu9JRx7drAbxbvVDNPus/5sEqotQfwD3kgwBKVKbUEz5NoHWiQd
htSKR+aXGFOiPmDs0NNlz5rZUZRcYsz95cfH+iSZzMNfeGA9yTmss/Z/p4yn6J0t
vxMKXraKQiqx8IdBbEHdKh8e/EbqI0yjK9izcwX8rVLo1cjPwEdZzzIfOYPk76/R
UcxGlUqQ/K9sd3qydwLXUm2ArCBKhBj1l/NiLxUI0M5tum0KGY2JdbDWt+vnOUmo
fUbVd35JIhjP37Fz3DCaPe83fCYOGZKgGjOs7HEUwb9d53kmBCDLffN+YycYfGlo
2uKWBf+W1uhLH0MCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQBWJcqNaqgqKDdy
xsGJpK3oriWE+caQnM51OGLjSBqyUfGf9ObgvKIQWbsPL6uMtgldf3Ctb1tjrKcz
0Fe6I8Ea8zrHrwg+gpx5M+O8ZVQmdM6kCYvX0/fMLM3p8NKBG1ZInf5N/Q6ACIVw
hkmjmgGIJ4Wqlgvc+qOr4P0AmNJytNh1fn9evRGeZ3cskdgLXqqV5fC8a+3EwcgU
X6Wb5eNDRDnA6cOqnwBY6ovxoGAHhinOtMkcD1X4I5zfvkBNfUZiimewQHS/xjW3
4Pst9Cj7aOSfblKo5+4LJ8fZFvgap9Yyf+JwmvpZYXidwGQQkU3YuXxPSsEaNYYA
HKk+W7eh
-----END CERTIFICATE REQUEST-----

View file

@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIENTCCAx2gAwIBAgIUQDB0IZF7HnvGlF2VrPKOW/M04mYwDQYJKoZIhvcNAQEL
BQAwfDELMAkGA1UEBhMCQ0ExEDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90
dGF3YTESMBAGA1UEChMJTHVhIE5naW54MRowGAYDVQQLExFMdWEgTmdpbnggUm9v
dCBDQTEaMBgGA1UEAxMRTHVhIE5naW54IFJvb3QgQ0EwHhcNMjQwMzEwMTQxODAw
WhcNNDkwMzA0MTQxODAwWjCBjDELMAkGA1UEBhMCQ0ExEDAOBgNVBAgTB09udGFy
aW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJTHVhIE5naW54MSIwIAYDVQQL
ExlMdWEgTmdpbnggSW50ZXJtZWRpYXRlIENBMSIwIAYDVQQDExlMdWEgTmdpbngg
SW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
ncpy3Iqw4E71BI2Bt5P1+70lHHt2sBvFu9UM0+6z/mwSqi1B/APeSDAEpUptQTPk
2gdaJB2G1IpH5pcYU6I+YOzQ02XPmtlRlFxizP3lx8f6JJnMw194YD3JOayz9n+n
jKfonS2/EwpetopCKrHwh0FsQd0qHx78RuojTKMr2LNzBfytUujVyM/AR1nPMh85
g+Tvr9FRzEaVSpD8r2x3erJ3AtdSbYCsIEqEGPWX82IvFQjQzm26bQoZjYl1sNa3
6+c5Sah9RtV3fkkiGM/fsXPcMJo97zd8Jg4ZkqAaM6zscRTBv13neSYEIMt9835j
Jxh8aWja4pYF/5bW6EsfQwIDAQABo4GdMIGaMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTyYaPSfXE2gAY8vzZpIIYNOonSdDAfBgNV
HSMEGDAWgBTp7DmFFvFN2pPodS1IrM9XM2EKPjA3BggrBgEFBQcBAQQrMCkwJwYI
KwYBBQUHMAGGG2h0dHBzOi8vb2NzcC1yZXNwb25kZXIudGVzdDANBgkqhkiG9w0B
AQsFAAOCAQEAxiW331eII3W71aedBZPTH1c1axyHoN+hkWb8hL3Whg0K2ftm6SKJ
uIi4dIYc9qbjfvIpbC/jkMGdy5tWu4m0RNBESIKc//kce0NBOQDUXH3Qp8G7qhUx
J+MvAsDey4Iv/Jh1olwgiB7lVIm7gwdQSzY0XcFfxKJ+lvckv3sh8oI5/zprkJ0n
y1QIrsJ1fB0maOtxF/DF2u4s2h2REPqvAIrxXZmnog+DOwG7vwjWcosEsX9qQJC7
Ho8X6+vHUENW9tpvlCmG+Nrci7T+p5s2DLUrq5gcmZkNGhCdjk3gMyeBjYgRTXUI
5KutV99z9qVO2wNB7HQz1/Q5Y5cB4Nr4Jw==
-----END CERTIFICATE-----

View file

@ -0,0 +1,16 @@
{
"CN": "Lua Nginx Intermediate CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CA",
"L": "Ottawa",
"O": "Lua Nginx",
"OU": "Lua Nginx Intermediate CA",
"ST": "Ontario"
}
]
}

View file

@ -0,0 +1,74 @@
-----BEGIN CERTIFICATE-----
MIIEYjCCA0qgAwIBAgIUAoYyuXu96S6RvXoSk2udnewBcmMwDQYJKoZIhvcNAQEL
BQAwgYwxCzAJBgNVBAYTAkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ8wDQYDVQQHEwZP
dHRhd2ExEjAQBgNVBAoTCUx1YSBOZ2lueDEiMCAGA1UECxMZTHVhIE5naW54IElu
dGVybWVkaWF0ZSBDQTEiMCAGA1UEAxMZTHVhIE5naW54IEludGVybWVkaWF0ZSBD
QTAgFw0yNDAzMTAxNDI3MDBaGA8yMTI0MDIxNTE0MjcwMFowcjELMAkGA1UEBhMC
VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28x
ETAPBgNVBAoTCEN1c3RvbWVyMRAwDgYDVQQLEwdXZWJzaXRlMREwDwYDVQQDEwh0
ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPbhwznauUQ4
K7smP0GUX7a4toKxMboTr0NNMMDlA+98dKMMWhSe3/eJUqUr0zFF59rFqwA1bWUK
i67zHbIZnlWvfFV8lq2QuXt5CBeUBAT00YHdPb6pdYdWHZ32tSuqJpAVEqtbuya6
K85hBMT37yfxu58LreGSkKvwVOBoKFQzHZVDvYRs+hX8mHBqhAy0AiNfrf3AbdqD
sI1p8YPr2k8varTE6lpUlhcO+dYnZHhyC8mDk5AD0kAgsnH0VvmRZwZPZmcmkeM0
aZJFdi++wmetlSv9DpEDzSVNHRuQaHEyq70jq/WKFJUlGtu6i/GhsGciSHnGfmXD
qWGabXGX3L0CAwEAAaOB0jCBzzAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYI
KwYBBQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUmZFUgNg7zMS9YorjH6KC
hHmgmE0wHwYDVR0jBBgwFoAU8mGj0n1xNoAGPL82aSCGDTqJ0nQwNwYIKwYBBQUH
AQEEKzApMCcGCCsGAQUFBzABhhtodHRwczovL29jc3AtcmVzcG9uZGVyLnRlc3Qw
IQYDVR0RBBowGIIIdGVzdC5jb22CDHd3dy50ZXN0LmNvbTANBgkqhkiG9w0BAQsF
AAOCAQEAfCbc7XXaLVMt0JCOcON4yzY+0GZ9RG6O/QBTFd25YfUxruvIHaDTcuAK
tO8Q/iO/jybOHau9mwzwBe2aHhlKGYMJyvXlsQrGspcFsoyX8m5oXH3mBQhw1YhK
cjNZGDNq4c8m+2EU2nFmHAQd+/inGg3N4dtBLdiE8jlhb+Cfdaa1l7YRHgD4KafY
Oj5udG6FuOypcRoRerkUmizpgGofErHXmfTo14uo4FNxOhjJ57JPEBpf1Xq61k2L
QTptCbpSij4ElgWMAhNhBRpp11nfg37vP/wbxOInZK4oCzf3s0OAlKvCc01QBvIr
K59xzh9DRxpLjHsXphp9/XcFIlXfwQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIENTCCAx2gAwIBAgIUQDB0IZF7HnvGlF2VrPKOW/M04mYwDQYJKoZIhvcNAQEL
BQAwfDELMAkGA1UEBhMCQ0ExEDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90
dGF3YTESMBAGA1UEChMJTHVhIE5naW54MRowGAYDVQQLExFMdWEgTmdpbnggUm9v
dCBDQTEaMBgGA1UEAxMRTHVhIE5naW54IFJvb3QgQ0EwHhcNMjQwMzEwMTQxODAw
WhcNNDkwMzA0MTQxODAwWjCBjDELMAkGA1UEBhMCQ0ExEDAOBgNVBAgTB09udGFy
aW8xDzANBgNVBAcTBk90dGF3YTESMBAGA1UEChMJTHVhIE5naW54MSIwIAYDVQQL
ExlMdWEgTmdpbnggSW50ZXJtZWRpYXRlIENBMSIwIAYDVQQDExlMdWEgTmdpbngg
SW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
ncpy3Iqw4E71BI2Bt5P1+70lHHt2sBvFu9UM0+6z/mwSqi1B/APeSDAEpUptQTPk
2gdaJB2G1IpH5pcYU6I+YOzQ02XPmtlRlFxizP3lx8f6JJnMw194YD3JOayz9n+n
jKfonS2/EwpetopCKrHwh0FsQd0qHx78RuojTKMr2LNzBfytUujVyM/AR1nPMh85
g+Tvr9FRzEaVSpD8r2x3erJ3AtdSbYCsIEqEGPWX82IvFQjQzm26bQoZjYl1sNa3
6+c5Sah9RtV3fkkiGM/fsXPcMJo97zd8Jg4ZkqAaM6zscRTBv13neSYEIMt9835j
Jxh8aWja4pYF/5bW6EsfQwIDAQABo4GdMIGaMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTyYaPSfXE2gAY8vzZpIIYNOonSdDAfBgNV
HSMEGDAWgBTp7DmFFvFN2pPodS1IrM9XM2EKPjA3BggrBgEFBQcBAQQrMCkwJwYI
KwYBBQUHMAGGG2h0dHBzOi8vb2NzcC1yZXNwb25kZXIudGVzdDANBgkqhkiG9w0B
AQsFAAOCAQEAxiW331eII3W71aedBZPTH1c1axyHoN+hkWb8hL3Whg0K2ftm6SKJ
uIi4dIYc9qbjfvIpbC/jkMGdy5tWu4m0RNBESIKc//kce0NBOQDUXH3Qp8G7qhUx
J+MvAsDey4Iv/Jh1olwgiB7lVIm7gwdQSzY0XcFfxKJ+lvckv3sh8oI5/zprkJ0n
y1QIrsJ1fB0maOtxF/DF2u4s2h2REPqvAIrxXZmnog+DOwG7vwjWcosEsX9qQJC7
Ho8X6+vHUENW9tpvlCmG+Nrci7T+p5s2DLUrq5gcmZkNGhCdjk3gMyeBjYgRTXUI
5KutV99z9qVO2wNB7HQz1/Q5Y5cB4Nr4Jw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDyDCCArCgAwIBAgIUUw9rlqc2DnJNFZ9gw/zRLPRQ4zMwDQYJKoZIhvcNAQEL
BQAwfDELMAkGA1UEBhMCQ0ExEDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90
dGF3YTESMBAGA1UEChMJTHVhIE5naW54MRowGAYDVQQLExFMdWEgTmdpbnggUm9v
dCBDQTEaMBgGA1UEAxMRTHVhIE5naW54IFJvb3QgQ0EwHhcNMjQwMzEwMTQxODAw
WhcNMjkwMzA5MTQxODAwWjB8MQswCQYDVQQGEwJDQTEQMA4GA1UECBMHT250YXJp
bzEPMA0GA1UEBxMGT3R0YXdhMRIwEAYDVQQKEwlMdWEgTmdpbngxGjAYBgNVBAsT
EUx1YSBOZ2lueCBSb290IENBMRowGAYDVQQDExFMdWEgTmdpbnggUm9vdCBDQTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOFPnbLvAgFfk8oZ/s9VBUie
h+wlELquwHhh+XX9w/JxMlvNzfDYyJhA90iZJ7PL88Byz/+/1Kjzw1mS7vypSGiN
u+NFt2Yp+BKuG/U327vh0yPgn1aOOtVpSjJyhhu585hJUkQNOHEJvzPy4Wo0EuxM
DNB7aPhhBhi4yUlTDj2N8756rm0TFn8xp+XDDjfW1XJWR51cIcDXkfRDGMAqTf5o
F4xZQtjubxz4zO3rUZ9nNxCFz9+9GENIgtlJFAeLbV/Xdd6G8Kqqa08mR/RZdV9V
7siSyDAeWoWsMnJOyX/TQdnQCfbnYpRhDtbi4mOkrW2Bf/SMb1uO0LRTec/rpBcC
AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
BBYEFOnsOYUW8U3ak+h1LUisz1czYQo+MA0GCSqGSIb3DQEBCwUAA4IBAQDHySN4
lWLHa12vYPvRVLNeWq3RaHQfKc2F2PhHriGCegY4lyZJqfC0XGI4LBnJ5GK//D0B
Hb8jcbGyortGBEwGuqjuOMdv0HOWibqZ7LPZ98GegtAjAJWMp/sQXkIYiRM8hlNC
pl9Vp9vsnUjfCrMaLVkZCC2Nwixc5mhSeH0aYHxxFwqh88oWbXzW7xobcTaYx/1P
kPdCy+jiBMCZII7J1u/e1B0J1VFad+IVJpQW+DzVIzJz9ClNAsJZjx1BBwIJGGEZ
fS1XXw+HgGeH2cVFnThMy0PIvx70b//GxEoXwuJhL2+z/tNhRRBN2eMa2zrZS94k
z+yCDRXP/rDxf+b7
-----END CERTIFICATE-----

View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA9uHDOdq5RDgruyY/QZRftri2grExuhOvQ00wwOUD73x0owxa
FJ7f94lSpSvTMUXn2sWrADVtZQqLrvMdshmeVa98VXyWrZC5e3kIF5QEBPTRgd09
vql1h1Ydnfa1K6omkBUSq1u7JrorzmEExPfvJ/G7nwut4ZKQq/BU4GgoVDMdlUO9
hGz6FfyYcGqEDLQCI1+t/cBt2oOwjWnxg+vaTy9qtMTqWlSWFw751idkeHILyYOT
kAPSQCCycfRW+ZFnBk9mZyaR4zRpkkV2L77CZ62VK/0OkQPNJU0dG5BocTKrvSOr
9YoUlSUa27qL8aGwZyJIecZ+ZcOpYZptcZfcvQIDAQABAoIBAGP/I6UeW6YvHj9q
iXqVj4MiJAKhpOOar4WSEWpAGKz6+v9DtITfqRXJUGlIa/1sNDIfmFi4Szv+3n8Z
R/DogYJxVuoFUb6xfP9vEYEDWfFr/CQeqbC9ULZlgg+GavFptL7tWieAOzi/dZjd
ISJqzjqepgEQqPhR9jk+WhKe/Z7EXcuLDEHBVyHGoN9ss60jppbRzvpB7etqS/iV
ZPw7Nu2Rd4SWvGx0gah4rXBGgS5YG+pM2oPp3telF0yMVFLXGMN6WxyiULIrrtyh
zBxRhdmSKjbodZNYun90FF2wynD666SHzi856NHqJPySL3Cs9sMESpKGxFDA9ZQM
XD+Nkr0CgYEA92sgmnYk4OinG577S9vHlq3N8RufDNtENCpK/hNAYYhW/CTj22qx
p+q9vIx5qGSNkgVpq3uINUzgJtIbRCvFuip8EKQlfSfMWGOVqo8qIWHurQcFSipa
X9TdHdU/Ega3GjOQ07Lp69lg8PUB/2lckc5cY0NgARKuSGMkBYO7Y/8CgYEA/3He
773w/DSUMj2TpNeKLc9tofTmBLNd7aNJ3vNB3lINgvpTwRtuNxT8Onji9xTG5R58
rCx5Md4uPdvRY2+M5Yfr6+jGkVF2qH5jVKNyyVzF5pnE/KMWlE2bMcNjpnae+atB
eygh9RAGt8biZ2AUXWiIgW/7PXnq0ROVXrhPT0MCgYA9+2Zli6ddeKs0bjWCIYL0
qoHnHwZPUDbb4qR61hPQ2zj/XbZ/Z1EuQc5ah86KcvZMWHLKdN4AjEuzLfuKrnSQ
WMhP2u9RVUEJ+5io68igKEqEqjeXBtkxHMBwEtYEDA6ez8A+aJnVbdWtR5PCioCY
PlxCucQ5QJbMp5mEkCXHvQKBgQDNExgNlInRkEyhgPn1Tu0qFetIKJo5j96Kl5sI
mHZ7C5i5XEq9L05ufjR4pPBhuJZs/urMNvAdbufk1YLmt3mAFHz86eXwaFxArScF
nirbKdXfaffRcwT/jsZXTyvDSlwayLhLLU8FtRYPmGXO5D21N+TPNZ2YHza7H2O9
pW5WjQKBgQCf+n6L6EZ0Nd5Ci5hQNSNyG/ptFlfPF250jEn95Ikln4ctT3fzuyP8
pOqbcp0+sM1TyQavXh4DnE41DGt5QIOdCAwpxe5ZdUXlLS/0+dO/R0kglwMbqRHQ
zx7iwdrFGuVszMbVUBncOfje6NT4BKC9E3Ai2RX2nNPYeTP1XWDEYg==
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIC6zCCAdMCAQAwcjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx
FjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xETAPBgNVBAoTCEN1c3RvbWVyMRAwDgYD
VQQLEwdXZWJzaXRlMREwDwYDVQQDEwh0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAPbhwznauUQ4K7smP0GUX7a4toKxMboTr0NNMMDlA+98
dKMMWhSe3/eJUqUr0zFF59rFqwA1bWUKi67zHbIZnlWvfFV8lq2QuXt5CBeUBAT0
0YHdPb6pdYdWHZ32tSuqJpAVEqtbuya6K85hBMT37yfxu58LreGSkKvwVOBoKFQz
HZVDvYRs+hX8mHBqhAy0AiNfrf3AbdqDsI1p8YPr2k8varTE6lpUlhcO+dYnZHhy
C8mDk5AD0kAgsnH0VvmRZwZPZmcmkeM0aZJFdi++wmetlSv9DpEDzSVNHRuQaHEy
q70jq/WKFJUlGtu6i/GhsGciSHnGfmXDqWGabXGX3L0CAwEAAaA0MDIGCSqGSIb3
DQEJDjElMCMwIQYDVR0RBBowGIIIdGVzdC5jb22CDHd3dy50ZXN0LmNvbTANBgkq
hkiG9w0BAQsFAAOCAQEACBrQqSJVP2h83H3VVb3IF+Diy4m209qRFOdXn79cQ646
aMscLPKpS4BXaiTvSUckyzNlL7q+QRjSYcfhc7XuzQ8FtiR+oaPCmSpmYrFC7tGq
9bE4ZajI2QWGkK6UiPBh5HD+KxFlKMktGeBd6wG5EscREafNAHaDSqFaFOEguH6D
GW29oX4Qn1Pm5Cs0OwGjWOg4KvjknVnRF6LC6WXy6NQ7Kc/fqVRFlqLv3Vn8pWXE
ryNlajq429O1vvNBAXjPdfOjKWVSz1CoeBgVwdGG8nC9FdvgWBc1di8Z/X6gbypk
FAHTY6FsBSFLsIMqqg/QNcUSWwW5Espmi2qvDQ6hHQ==
-----END CERTIFICATE REQUEST-----

View file

@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE-----
MIIEYjCCA0qgAwIBAgIUAoYyuXu96S6RvXoSk2udnewBcmMwDQYJKoZIhvcNAQEL
BQAwgYwxCzAJBgNVBAYTAkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ8wDQYDVQQHEwZP
dHRhd2ExEjAQBgNVBAoTCUx1YSBOZ2lueDEiMCAGA1UECxMZTHVhIE5naW54IElu
dGVybWVkaWF0ZSBDQTEiMCAGA1UEAxMZTHVhIE5naW54IEludGVybWVkaWF0ZSBD
QTAgFw0yNDAzMTAxNDI3MDBaGA8yMTI0MDIxNTE0MjcwMFowcjELMAkGA1UEBhMC
VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28x
ETAPBgNVBAoTCEN1c3RvbWVyMRAwDgYDVQQLEwdXZWJzaXRlMREwDwYDVQQDEwh0
ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPbhwznauUQ4
K7smP0GUX7a4toKxMboTr0NNMMDlA+98dKMMWhSe3/eJUqUr0zFF59rFqwA1bWUK
i67zHbIZnlWvfFV8lq2QuXt5CBeUBAT00YHdPb6pdYdWHZ32tSuqJpAVEqtbuya6
K85hBMT37yfxu58LreGSkKvwVOBoKFQzHZVDvYRs+hX8mHBqhAy0AiNfrf3AbdqD
sI1p8YPr2k8varTE6lpUlhcO+dYnZHhyC8mDk5AD0kAgsnH0VvmRZwZPZmcmkeM0
aZJFdi++wmetlSv9DpEDzSVNHRuQaHEyq70jq/WKFJUlGtu6i/GhsGciSHnGfmXD
qWGabXGX3L0CAwEAAaOB0jCBzzAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYI
KwYBBQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUmZFUgNg7zMS9YorjH6KC
hHmgmE0wHwYDVR0jBBgwFoAU8mGj0n1xNoAGPL82aSCGDTqJ0nQwNwYIKwYBBQUH
AQEEKzApMCcGCCsGAQUFBzABhhtodHRwczovL29jc3AtcmVzcG9uZGVyLnRlc3Qw
IQYDVR0RBBowGIIIdGVzdC5jb22CDHd3dy50ZXN0LmNvbTANBgkqhkiG9w0BAQsF
AAOCAQEAfCbc7XXaLVMt0JCOcON4yzY+0GZ9RG6O/QBTFd25YfUxruvIHaDTcuAK
tO8Q/iO/jybOHau9mwzwBe2aHhlKGYMJyvXlsQrGspcFsoyX8m5oXH3mBQhw1YhK
cjNZGDNq4c8m+2EU2nFmHAQd+/inGg3N4dtBLdiE8jlhb+Cfdaa1l7YRHgD4KafY
Oj5udG6FuOypcRoRerkUmizpgGofErHXmfTo14uo4FNxOhjJ57JPEBpf1Xq61k2L
QTptCbpSij4ElgWMAhNhBRpp11nfg37vP/wbxOInZK4oCzf3s0OAlKvCc01QBvIr
K59xzh9DRxpLjHsXphp9/XcFIlXfwQ==
-----END CERTIFICATE-----

View file

@ -0,0 +1,20 @@
{
"CN": "test.com",
"hosts": [
"test.com",
"www.test.com"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "San Francisco",
"O": "Customer",
"OU": "Website",
"ST": "California"
}
]
}

View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAq3Crdfl19L2Tffp2+1R74p0iR/51RLgX2QGoh8PdWRf7GTo8
Jsho/7FSUaWdfSLmsHSpZCg6eZpXJqCJ67EzZK2I8bm1tv+9m7V6FLUn2mBsEQWB
b8zPIc7dcMhALc1/+9dDJB781ZEt6GiV8vDp8ymErBtb2l2YpJuU7vXX0Kj7bBL2
jx+mn5YGDL3RW4TaFF8Eh6hXHFMKH7STL/XUUyNx4s7H4VDFZULBSLU3g7p37b5w
O0ni8IZIhx2E459vFp8Cpv2Z3jTpXOPAgY+Br9lXBd/yEFN5pkzt6OrfLm5wV+ck
3HHLy4tsY2SMz5V/w6aQJmoeP7Xxoev8/m5GNQIDAQABAoIBAF1phbNBWpkg1oWU
/FGTRfFDBxPNPR5VZIEUWzymZywNWf7z8SR8nGF9v8nHAJnXc3UAC/ALz1jE1Omy
HZQzuDoKKAz10GJG1IxMBJnV30IouZlIs680HERij9vM8NNEHpEdSHMdA0xmz2nL
2rBFvmOE4spYGeNQjkRalXrir1X8aLYBoe3iPY9UzHRFq0shUobjuwjfCVi3060F
m3+Z5BhHvjxSJLe4g1iFqeg/eiIwuuz8NgoilGAgPXSmYRyBIqWBGSjaKLL5Immh
l+0LKpE9Izz1AVH/1dWdg+CKmN/vE/W94LMHdxNtCReVSDAbDulqPkDZj9uR6sD8
ilM4Yt0CgYEA1OCymV0xC3b/88yRGIuj8SQR7VsAyCKUpx7MNyUWzILj39+QewW2
6rvnxy7yHJONkGPZsqDP3pWSElRjUt1Q2Xe5hOmL51BxmIaMO80nV7QIpWnzZN5+
+aQYZ51taRgCRaC4D6OYKFeUeHrWrt6bAzDBQ8e+B2ooT+gA9nT2VbcCgYEAzisf
RPlo8znydeSYojzzjyFdRYojeWJU9n5kkvo8d5IbqfxNDcrlOqtbAKderaQc1nbH
olKaM9LheYuLxwb40A7sCfeavISPH0snjalWUq/KGEbKKNlptf0IpXraSIY+8fdw
/fk1jzcrk77QLrKxICAYrm10xlp2S0v2zVRgY3MCgYEAy5TT2I1iAPfeEXbacCHj
OBLpvhegqMVBao2ueTJUGmM2r/vq/WvaoaPwJfHEgwWthZ+oKwdVpCVgW30uu6mB
z2eLGQwMyruI13gdFne9H0fCWQb5SMbroayH1lecsbvPOG1aeUJXmoUfLRU0yGmE
z0lKGpskJY0lXj2e5hO3HQMCgYBWsvurXdcssamsuj0VvNwPzNAUdksEuL1SC0Tw
KhtTjTXk/hzJOBG94mGanMfL7b/S0JCTSnleYcg//NcDE4N+u0e3yVBhBr3JQymX
ASc0DojGPL62/vbdeVMxg8BXz1yZFJ2HsE09tM22i/+wI6UpBVZbw9vfrhsg/wkC
wADo0QKBgQCs4t7HnOtZd4TchUtjWkJ9wJ6yzeD56H/0XGoSUbjyD4ls46ZlDUUM
XcyrBOGkQ6yfpQS9+NNpyC5TA/mCKS9JEe0RULGnpaU4VOJ3W2ZCNxjp7eIPK29o
Q/9jmKqiu5rEWlJ79bC+NhE8RVWosA6t56RUjutDn8W6PG8q7yadiA==
-----END RSA PRIVATE KEY-----

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIC0DCCAbgCAQAwgYoxCzAJBgNVBAYTAkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ8w
DQYDVQQHEwZPdHRhd2ExEjAQBgNVBAoTCUx1YSBOZ2lueDEhMB8GA1UECxMYTHVh
IE5naW54IE9DU1AgUmVzcG9uZGVyMSEwHwYDVQQDExhMdWEgTmdpbnggT0NTUCBS
ZXNwb25kZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrcKt1+XX0
vZN9+nb7VHvinSJH/nVEuBfZAaiHw91ZF/sZOjwmyGj/sVJRpZ19IuawdKlkKDp5
mlcmoInrsTNkrYjxubW2/72btXoUtSfaYGwRBYFvzM8hzt1wyEAtzX/710MkHvzV
kS3oaJXy8OnzKYSsG1vaXZikm5Tu9dfQqPtsEvaPH6aflgYMvdFbhNoUXwSHqFcc
UwoftJMv9dRTI3HizsfhUMVlQsFItTeDunftvnA7SeLwhkiHHYTjn28WnwKm/Zne
NOlc48CBj4Gv2VcF3/IQU3mmTO3o6t8ubnBX5yTcccvLi2xjZIzPlX/DppAmah4/
tfGh6/z+bkY1AgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAHJ5WraOQEhwMJpyB
wjCSHydomosRpoawtu5OsUt1E7iZ4P4DFRFKUy6iYRkXgacUnKtBBVqjECJa665b
oh7Q2YE655dyTLL7tI2uyQpGXV1Ko3YH6S/UnojZKMIbenCSnBYB1FklRG4MmfBg
KSCqVcViCdKNmAleF+i0xUvEkVfCHG9hMkuKhfN8T22Vq350fPRpyVuX0HD7uJC2
9j+ZLMZDMQjhnuioCf4aTKB1dXZHSwgvhJ58oYhsTGgP3fQMa68hHYIWWNILsJCz
Jt6pf5NNfYAigbnY/78SuDGi58JEH+5TAC/dSM1uZe5k4kXuwpDlclzUgctEiVjs
NEBM1Q==
-----END CERTIFICATE REQUEST-----

View file

@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE-----
MIIEWDCCA0CgAwIBAgIUe+huEvFGQccuZsZy8aDHeEGGtHswDQYJKoZIhvcNAQEL
BQAwgYwxCzAJBgNVBAYTAkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ8wDQYDVQQHEwZP
dHRhd2ExEjAQBgNVBAoTCUx1YSBOZ2lueDEiMCAGA1UECxMZTHVhIE5naW54IElu
dGVybWVkaWF0ZSBDQTEiMCAGA1UEAxMZTHVhIE5naW54IEludGVybWVkaWF0ZSBD
QTAgFw0yNDAzMTAxNDI3MDBaGA8yMTI0MDIxNTE0MjcwMFowgYoxCzAJBgNVBAYT
AkNBMRAwDgYDVQQIEwdPbnRhcmlvMQ8wDQYDVQQHEwZPdHRhd2ExEjAQBgNVBAoT
CUx1YSBOZ2lueDEhMB8GA1UECxMYTHVhIE5naW54IE9DU1AgUmVzcG9uZGVyMSEw
HwYDVQQDExhMdWEgTmdpbnggT0NTUCBSZXNwb25kZXIwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCrcKt1+XX0vZN9+nb7VHvinSJH/nVEuBfZAaiHw91Z
F/sZOjwmyGj/sVJRpZ19IuawdKlkKDp5mlcmoInrsTNkrYjxubW2/72btXoUtSfa
YGwRBYFvzM8hzt1wyEAtzX/710MkHvzVkS3oaJXy8OnzKYSsG1vaXZikm5Tu9dfQ
qPtsEvaPH6aflgYMvdFbhNoUXwSHqFccUwoftJMv9dRTI3HizsfhUMVlQsFItTeD
unftvnA7SeLwhkiHHYTjn28WnwKm/ZneNOlc48CBj4Gv2VcF3/IQU3mmTO3o6t8u
bnBX5yTcccvLi2xjZIzPlX/DppAmah4/tfGh6/z+bkY1AgMBAAGjga8wgawwDgYD
VR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMJMAwGA1UdEwEB/wQCMAAw
HQYDVR0OBBYEFBPZYcWqsm+j1OTwnv/2SM3Ws1HJMB8GA1UdIwQYMBaAFPJho9J9
cTaABjy/Nmkghg06idJ0MDcGCCsGAQUFBwEBBCswKTAnBggrBgEFBQcwAYYbaHR0
cHM6Ly9vY3NwLXJlc3BvbmRlci50ZXN0MA0GCSqGSIb3DQEBCwUAA4IBAQAs3SAT
nif5b+ii4ItnpGIcniA7sYgjv+6hYrTUTj+vWENbmEd6FAJwJYJHrno99qfN2t97
CWNadxkRR/qN0xATxE0dY2gsxBpbwICoA3k8lz/9VBl+p3g9kOqbSQYxrxOEoQov
EvlV/n8zCq8eOjoHU/IwV3IP1Ik0KKj8rAeIGzV/M403LhahyxlZZVF5Qo7MszQ5
8hwPHSfgcbCRh/XSS6Y8N6RDvBVUoHofeikXsy+di7cYfT1PEC2bhdsbLi/0WvDm
ZrotJOHoZrhqEuEgMrMDg5E8s17QLL+Vd078DMSSqG6HDPwMckdjDMhlI+OBZKwc
Dnb4OMHJnL+of2Kh
-----END CERTIFICATE-----

View file

@ -0,0 +1,16 @@
{
"CN": "Lua Nginx OCSP Responder",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CA",
"L": "Ottawa",
"O": "Lua Nginx",
"OU": "Lua Nginx OCSP Responder",
"ST": "Ontario"
}
]
}

BIN
t/cert/test_der.crt Normal file

Binary file not shown.

BIN
t/cert/test_der.key Normal file

Binary file not shown.

194
t/ocsp.t
View file

@ -869,13 +869,13 @@ failed to create OCSP request: no issuer certificate in chain
local resp = f:read("*a")
f:close()
local ok, err = ocsp.validate_ocsp_response(resp, cert_data)
local ok, next_update_or_err = ocsp.validate_ocsp_response(resp, cert_data)
if not ok then
ngx.log(ngx.ERR, "failed to validate OCSP response: ", err)
ngx.log(ngx.ERR, "failed to validate OCSP response: ", next_update_or_err)
return
end
ngx.log(ngx.WARN, "OCSP response validation ok")
ngx.log(ngx.WARN, "OCSP response validation ok, next_update: ", next_update_or_err)
}
ssl_certificate ../../cert/test.crt;
ssl_certificate_key ../../cert/test.key;
@ -926,7 +926,7 @@ ssl handshake: cdata
--- error_log
lua ssl server name: "test.com"
OCSP response validation ok
OCSP response validation ok, next_update: nil
--- no_error_log
[error]
@ -1564,3 +1564,189 @@ ocsp status resp set ok: no status req,
[error]
[alert]
[emerg]
=== TEST 18: good OCSP response with nextUpdate present
--- http_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
server {
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
server_name test.com;
ssl_certificate_by_lua_block {
local ssl = require "ngx.ssl"
local ocsp = require "ngx.ocsp"
local f = assert(io.open("t/cert/ocsp/cfssl/leaf-bundle.pem"))
local cert_data = f:read("*a")
f:close()
local err
cert_data, err = ssl.cert_pem_to_der(cert_data)
if not cert_data then
ngx.log(ngx.ERR, "failed to convert pem cert to der cert: ", err)
return
end
local f = assert(io.open("t/cert/ocsp/cfssl/ocsp-response-good-response.der"))
local resp = f:read("*a")
f:close()
local ok, next_update_or_err = ocsp.validate_ocsp_response(resp, cert_data)
if not ok then
ngx.log(ngx.ERR, "failed to validate OCSP response: ", next_update_or_err)
return
end
ngx.log(ngx.WARN, "OCSP response validation ok, next_update: ", next_update_or_err)
}
ssl_certificate ../../cert/ocsp/cfssl/leaf-bundle.pem;
ssl_certificate_key ../../cert/ocsp/cfssl/leaf-key.pem;
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;
lua_ssl_trusted_certificate ../../cert/ocsp/cfssl/leaf-bundle.pem;
lua_ssl_verify_depth 3;
location /t {
content_by_lua_block {
do
local sock = ngx.socket.tcp()
sock:settimeout(3000)
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", true)
if not sess then
ngx.say("failed to do SSL handshake: ", err)
return
end
ngx.say("ssl handshake: ", type(sess))
end -- do
}
}
--- request
GET /t
--- response_body
connected: 1
ssl handshake: cdata
--- error_log
lua ssl server name: "test.com"
OCSP response validation ok, next_update: 1587585600
--- no_error_log
[error]
[alert]
[emerg]
--- SKIP
=== TEST 19: revoked OCSP response with nextUpdate present
--- http_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
server {
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
server_name test.com;
ssl_certificate_by_lua_block {
local ssl = require "ngx.ssl"
local ocsp = require "ngx.ocsp"
local f = assert(io.open("t/cert/ocsp/cfssl/leaf-bundle.pem"))
local cert_data = f:read("*a")
f:close()
local err
cert_data, err = ssl.cert_pem_to_der(cert_data)
if not cert_data then
ngx.log(ngx.ERR, "failed to convert pem cert to der cert: ", err)
return
end
local f = assert(io.open("t/cert/ocsp/cfssl/ocsp-response-revoked-response.der"))
local resp = f:read("*a")
f:close()
local ok, next_update_or_err = ocsp.validate_ocsp_response(resp, cert_data)
if not ok then
ngx.log(ngx.ERR, "failed to validate OCSP response: ", next_update_or_err)
return
end
ngx.log(ngx.WARN, "OCSP response validation ok")
}
ssl_certificate ../../cert/ocsp/cfssl/leaf-bundle.pem;
ssl_certificate_key ../../cert/ocsp/cfssl/leaf-key.pem;
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;
lua_ssl_trusted_certificate ../../cert/ocsp/cfssl/leaf-bundle.pem;
lua_ssl_verify_depth 3;
location /t {
content_by_lua_block {
do
local sock = ngx.socket.tcp()
sock:settimeout(3000)
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", true)
if not sess then
ngx.say("failed to do SSL handshake: ", err)
return
end
ngx.say("ssl handshake: ", type(sess))
end -- do
}
}
--- request
GET /t
--- response_body
connected: 1
ssl handshake: cdata
--- error_log
lua ssl server name: "test.com"
failed to validate OCSP response: certificate status "revoked" in the OCSP response. next_update: nil
--- no_error_log
OCSP response validation ok
[alert]
[emerg]
--- SKIP

View file

@ -4,7 +4,7 @@ use t::TestCore;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3 + 19) + 2;
plan tests => repeat_each() * (blocks() * 3 + 20) + 2;
add_block_preprocessor(sub {
my $block = shift;

578
t/ssl.t
View file

@ -8,7 +8,7 @@ use t::TestCore;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 6 + 1);
plan tests => repeat_each() * (blocks() * 6 - 1);
no_long_string();
#no_diff();
@ -2354,7 +2354,7 @@ got TLS1 version: TLSv1.3,
return
end
local ok, err = ssl.verify_client(cert, 1)
local ok, err = ssl.verify_client(cert, 1, nil)
if not ok then
ngx.log(ngx.ERR, "failed to verify client: ", err)
return
@ -2468,7 +2468,7 @@ client certificate subject: emailAddress=agentzh@gmail.com,CN=test.com
return
end
local ok, err = ssl.verify_client(cert, 1)
local ok, err = ssl.verify_client(cert, 1, nil)
if not ok then
ngx.log(ngx.ERR, "failed to verify client: ", err)
return
@ -2837,3 +2837,575 @@ lua ssl server name: "test.com"
[error]
[alert]
[emerg]
=== TEST 29: parse PEM cert and key to cdata
--- http_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
server {
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
server_name test.com;
ssl_certificate_by_lua_block {
local ssl = require "ngx.ssl"
ssl.clear_certs()
local f = assert(io.open("t/cert/chain/chain.der"))
local cert_data = f:read("*a")
f:close()
local cert, err = ssl.parse_der_cert(cert_data)
if not cert then
ngx.log(ngx.ERR, "failed to parse pem cert: ", err)
return
end
local ok, err = ssl.set_cert(cert)
if not ok then
ngx.log(ngx.ERR, "failed to set cert: ", err)
return
end
local f = assert(io.open("t/cert/chain/test-com.key.der"))
local pkey_data = f:read("*a")
f:close()
local pkey, err = ssl.parse_der_priv_key(pkey_data)
if not pkey then
ngx.log(ngx.ERR, "failed to parse pem key: ", err)
return
end
local ok, err = ssl.set_priv_key(pkey)
if not ok then
ngx.log(ngx.ERR, "failed to set private key: ", err)
return
end
}
ssl_certificate ../../cert/test2.crt;
ssl_certificate_key ../../cert/test2.key;
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;
lua_ssl_trusted_certificate ../../cert/chain/root-ca.crt;
lua_ssl_verify_depth 3;
location /t {
content_by_lua_block {
do
local sock = ngx.socket.tcp()
sock:settimeout(3000)
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", true)
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 receive 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: cdata
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]
[emerg]
=== TEST 30: read client-random via ssl.get_client_random()
--- http_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
server {
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
server_name test.com;
ssl_certificate_by_lua_block {
local ssl = require "ngx.ssl"
local client_random_len = ssl.get_client_random(0)
print("client-random length: ", client_random_len)
local init_v = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
local client_random = ssl.get_client_random()
if client_random == init_v then
print("maybe the client random value is incorrect")
end
}
ssl_certificate ../../cert/test.crt;
ssl_certificate_key ../../cert/test.key;
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;
lua_ssl_trusted_certificate ../../cert/test.crt;
location /t {
content_by_lua_block {
do
local sock = ngx.socket.tcp()
sock:settimeout(3000)
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", true)
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 receive 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: cdata
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
client-random length: 32
--- no_error_log
[error]
[alert]
[emerg]
=== TEST 31: export_keying_material
--- http_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
server {
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
server_name test.com;
access_by_lua_block {
local ssl = require "ngx.ssl"
local key_length = 16
local label = "EXPERIMENTAL my label"
local context = "\x00\x01\x02\x03"
local key, err = ssl.export_keying_material(key_length, label, context)
if not key then
ngx.log(ngx.ERR, "failed to derive key ", err)
return
end
ngx.log(ngx.INFO, "output key length: ", #key)
}
ssl_certificate ../../cert/test.crt;
ssl_certificate_key ../../cert/test.key;
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;
lua_ssl_trusted_certificate ../../cert/test.crt;
location /t {
content_by_lua_block {
do
local sock = ngx.socket.tcp()
sock:settimeout(3000)
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", true)
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 receive 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: cdata
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
output key length: 16
--- no_error_log
[error]
[alert]
[emerg]
=== TEST 32: get SSL pointer
--- http_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
server {
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
server_name test.com;
ssl_certificate_by_lua_block {
local ssl = require "ngx.ssl"
local ssl_pointer, err = ssl.get_req_ssl_pointer()
if not ssl_pointer then
ngx.log(ngx.ERR, "cann't get SSL pointer")
end
}
ssl_certificate ../../cert/test.crt;
ssl_certificate_key ../../cert/test.key;
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;
lua_ssl_trusted_certificate ../../cert/test.crt;
location /t {
content_by_lua_block {
do
local sock = ngx.socket.tcp()
sock:settimeout(3000)
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", true)
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 receive 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: cdata
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]
[emerg]
[crit]
=== TEST 33: verify client, but server not trust root ca
--- http_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
server {
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
server_name test.com;
ssl_certificate_by_lua_block {
local ssl = require "ngx.ssl"
local f = assert(io.open("t/cert/mtls_server.crt"))
local cert_data = f:read("*a")
f:close()
local cert, err = ssl.parse_pem_cert(cert_data)
if not cert then
ngx.log(ngx.ERR, "failed to parse pem cert: ", err)
return
end
local ok, err = ssl.verify_client(cert, 1, nil)
if not ok then
ngx.log(ngx.ERR, "failed to verify client: ", err)
return
end
}
ssl_certificate ../../cert/mtls_server.crt;
ssl_certificate_key ../../cert/mtls_server.key;
location / {
default_type 'text/plain';
content_by_lua_block {
ngx.say(ngx.var.ssl_client_verify)
}
more_clear_headers Date;
}
}
--- config
location /t {
proxy_pass https://unix:$TEST_NGINX_HTML_DIR/nginx.sock;
proxy_ssl_certificate ../../cert/mtls_client.crt;
proxy_ssl_certificate_key ../../cert/mtls_client.key;
proxy_ssl_session_reuse off;
}
--- request
GET /t
--- response_body
FAILED:unable to verify the first certificate
--- no_error_log
[error]
[alert]
[emerg]
=== TEST 34: verify client and server trust root ca
--- http_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
server {
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
server_name test.com;
ssl_certificate_by_lua_block {
local ssl = require "ngx.ssl"
local f = assert(io.open("t/cert/mtls_server.crt"))
local cert_data = f:read("*a")
f:close()
local cert, err = ssl.parse_pem_cert(cert_data)
if not cert then
ngx.log(ngx.ERR, "failed to parse pem cert: ", err)
return
end
local f = assert(io.open("t/cert/mtls_ca.crt"))
local cert_data = f:read("*a")
f:close()
local trusted_cert, err = ssl.parse_pem_cert(cert_data)
if not trusted_cert then
ngx.log(ngx.ERR, "failed to parse pem trusted cert: ", err)
return
end
local ok, err = ssl.verify_client(cert, 1, trusted_cert)
if not ok then
ngx.log(ngx.ERR, "failed to verify client: ", err)
return
end
}
ssl_certificate ../../cert/mtls_server.crt;
ssl_certificate_key ../../cert/mtls_server.key;
location / {
default_type 'text/plain';
content_by_lua_block {
ngx.say(ngx.var.ssl_client_verify)
}
more_clear_headers Date;
}
}
--- config
location /t {
proxy_pass https://unix:$TEST_NGINX_HTML_DIR/nginx.sock;
proxy_ssl_certificate ../../cert/mtls_client.crt;
proxy_ssl_certificate_key ../../cert/mtls_client.key;
proxy_ssl_session_reuse off;
}
--- request
GET /t
--- response_body
SUCCESS
--- no_error_log
[error]
[alert]
[emerg]

109
t/stream/balancer-bind.t Normal file
View file

@ -0,0 +1,109 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use lib '.';
use t::TestCore::Stream;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 4);
$ENV{TEST_NGINX_LUA_PACKAGE_PATH} = "$t::TestCore::Stream::lua_package_path";
$ENV{TEST_NGINX_UPSTREAM_PORT} ||= get_unused_port 12345;
no_long_string();
run_tests();
__DATA__
=== TEST 1: balancer
--- stream_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
upstream backend {
server 0.0.0.1:1234 down;
balancer_by_lua_block {
local b = require "ngx.balancer"
assert(b.set_current_peer("127.0.0.1", $TEST_NGINX_UPSTREAM_PORT))
}
}
server {
listen 127.0.0.1:$TEST_NGINX_UPSTREAM_PORT;
content_by_lua_block {
ngx.print(ngx.var.remote_addr, ":", ngx.var.remote_port)
}
}
--- stream_server_config
proxy_pass backend;
--- request
GET /t
--- response_body eval
[
qr/127.0.0.1/,
]
--- error_code: 200
--- no_error_log
[error]
[warn]
=== TEST 2: balancer with bind_to_local_addr (addr)
--- stream_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
upstream backend {
server 0.0.0.1:1234 down;
balancer_by_lua_block {
local b = require "ngx.balancer"
assert(b.set_current_peer("127.0.0.1", $TEST_NGINX_UPSTREAM_PORT))
assert(b.bind_to_local_addr("127.0.0.4"))
}
}
server {
listen 127.0.0.1:$TEST_NGINX_UPSTREAM_PORT;
content_by_lua_block {
ngx.print(ngx.var.remote_addr, ":", ngx.var.remote_port)
}
}
--- stream_server_config
proxy_pass backend;
--- request
GET /t
--- response_body eval
[
qr/127.0.0.4/,
]
--- error_code: 200
--- no_error_log
[error]
[warn]
=== TEST 3: balancer with bind_to_local_addr (addr and port)
--- stream_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
upstream backend {
server 0.0.0.1:1234 down;
balancer_by_lua_block {
local b = require "ngx.balancer"
assert(b.set_current_peer("127.0.0.1", $TEST_NGINX_UPSTREAM_PORT))
assert(b.bind_to_local_addr("127.0.0.8:23456"))
}
}
server {
listen 127.0.0.1:$TEST_NGINX_UPSTREAM_PORT;
content_by_lua_block {
ngx.print(ngx.var.remote_addr, ":", ngx.var.remote_port)
}
}
--- stream_server_config
proxy_pass backend;
--- request
GET /t
--- response_body eval
[
qr/127.0.0.8/,
]
--- error_code: 200
--- no_error_log
[error]
[warn]

View file

@ -0,0 +1,52 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use lib '.';
use t::TestCore::Stream;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 2);
no_long_string();
run_tests();
__DATA__
=== TEST 1: set_current_peer: NYI 'opts' argument
--- stream_config
upstream backend {
server 127.0.0.1:12345;
balancer_by_lua_block {
local b = require "ngx.balancer"
local pok, perr = pcall(b.set_current_peer, "127.0.0.3", 12345, "abc")
if not pok then
ngx.log(ngx.ERR, perr)
end
}
}
--- stream_server_config
proxy_pass backend;
--- error_log eval
qr/balancer_by_lua:\d+: bad argument #3 to 'set_current_peer' \('host' not yet implemented in stream subsystem\)/
=== TEST 2: enable_keepalive: NYI
--- stream_config
upstream backend {
server 127.0.0.1:12345;
balancer_by_lua_block {
local b = require "ngx.balancer"
local pok, perr = pcall(b.enable_keepalive)
if not pok then
ngx.log(ngx.ERR, perr)
end
}
}
--- stream_server_config
proxy_pass backend;
--- error_log eval
qr/balancer_by_lua:\d+: 'enable_keepalive' not yet implemented in stream subsystem/

View file

@ -1,7 +1,15 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
our $SkipReason;
BEGIN {
if ($ENV{TEST_NGINX_CHECK_LEAK}) {
$SkipReason = "unavailable for the hup tests";
}
}
use lib '.';
use t::TestCore::Stream;
use t::TestCore::Stream $SkipReason ? (skip_all => $SkipReason) : ();
repeat_each(2);

View file

@ -5,7 +5,7 @@ use t::TestCore::Stream;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 4) - 2;
plan tests => repeat_each() * (blocks() * 4 - 1);
add_block_preprocessor(sub {
my $block = shift;

View file

@ -67,8 +67,6 @@ $Test::Nginx::Util::PcreVersion == 2 ?
--- no_error_log
[error]
--- ONLY
=== TEST 3: UTF-8 mode without UTF-8 sequence checks

View file

@ -2140,3 +2140,188 @@ lua ssl server name: "test.com"
[error]
[alert]
[emerg]
=== TEST 27: parse DER cert and key to cdata
--- stream_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
server {
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
ssl_certificate_by_lua_block {
local ssl = require "ngx.ssl"
ssl.clear_certs()
local f = assert(io.open("t/cert/chain/chain.der"))
local cert_data = f:read("*a")
f:close()
local cert, err = ssl.parse_der_cert(cert_data)
if not cert then
ngx.log(ngx.ERR, "failed to parse DER cert: ", err)
return
end
local ok, err = ssl.set_cert(cert)
if not ok then
ngx.log(ngx.ERR, "failed to set cert: ", err)
return
end
local f = assert(io.open("t/cert/chain/test-com.key.der"))
local pkey_data = f:read("*a")
f:close()
local pkey, err = ssl.parse_der_priv_key(pkey_data)
if not pkey then
ngx.log(ngx.ERR, "failed to parse DER key: ", err)
return
end
local ok, err = ssl.set_priv_key(pkey)
if not ok then
ngx.log(ngx.ERR, "failed to set private key: ", err)
return
end
}
ssl_certificate ../../cert/test2.crt;
ssl_certificate_key ../../cert/test2.key;
return 'it works!\n';
}
--- stream_server_config
lua_ssl_trusted_certificate ../../cert/chain/root-ca.crt;
lua_ssl_verify_depth 3;
content_by_lua_block {
do
local sock = ngx.socket.tcp()
sock:settimeout(3000)
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", true)
if not sess then
ngx.say("failed to do SSL handshake: ", err)
return
end
ngx.say("ssl handshake: ", type(sess))
while true do
local line, err = sock:receive()
if not line then
-- ngx.say("failed to receive response status line: ", err)
break
end
ngx.say("received: ", line)
end
local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
end -- do
-- collectgarbage()
}
--- stream_response
connected: 1
ssl handshake: userdata
received: it works!
close: 1 nil
--- error_log
lua ssl server name: "test.com"
--- no_error_log
[error]
[alert]
[emerg]
=== TEST 28: read client random via ssl.get_client_random()
--- stream_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
server {
listen 127.0.0.1:$TEST_NGINX_RAND_PORT_1 ssl;
ssl_certificate_by_lua_block {
local ssl = require "ngx.ssl"
local client_random_len = ssl.get_client_random(0)
print("client-random length: ", client_random_len)
local init_v = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
local client_random = ssl.get_client_random()
if client_random == init_v then
print("maybe the client random value is incorrect")
end
}
ssl_certificate ../../cert/test.crt;
ssl_certificate_key ../../cert/test.key;
return 'it works!\n';
}
--- stream_server_config
lua_ssl_trusted_certificate ../../cert/test.crt;
content_by_lua_block {
do
local sock = ngx.socket.tcp()
sock:settimeout(3000)
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_RAND_PORT_1)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local sess, err = sock:sslhandshake(nil, nil, true)
if not sess then
ngx.say("failed to do SSL handshake: ", err)
return
end
ngx.say("ssl handshake: ", type(sess))
while true do
local line, err = sock:receive()
if not line then
-- ngx.say("failed to receive response status line: ", err)
break
end
ngx.say("received: ", line)
end
local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
end -- do
-- collectgarbage()
}
--- stream_response
connected: 1
ssl handshake: userdata
received: it works!
close: 1 nil
--- error_log
client-random length: 32
--- no_error_log
[error]
[alert]
[emerg]

View file

@ -113,3 +113,88 @@
fun:ngx_pass_open_channel
fun:ngx_start_privileged_agent_processes
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
...
fun:ssl_session_dup
fun:tls_process_new_session_ticket
...
fun:read_state_machine
...
fun:ssl3_read_bytes
...
fun:SSL_read
fun:ngx_ssl_recv
fun:ngx_http_upstream_process_header
fun:ngx_http_upstream_handler
...
fun:ngx_process_events_and_timers
...
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:CRYPTO_malloc
fun:ssl_session_dup
fun:tls_process_new_session_ticket
...
fun:read_state_machine
...
fun:ssl3_read_bytes
...
fun:SSL_read
fun:ngx_ssl_recv
fun:ngx_http_upstream_process_header
fun:ngx_http_upstream_handler
...
fun:ngx_process_events_and_timers
...
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:CRYPTO_zalloc
fun:SSL_SESSION_new
fun:ssl_get_new_session
fun:tls_construct_client_hello
fun:write_state_machine
...
fun:ngx_ssl_handshake
fun:ngx_http_upstream_ssl_init_connection
fun:ngx_http_upstream_send_request_handler
fun:ngx_http_upstream_handler
...
fun:ngx_process_events_and_timers
...
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:CRYPTO_malloc
fun:CRYPTO_zalloc
fun:SSL_SESSION_new
fun:ssl_get_new_session
fun:tls_construct_client_hello
fun:write_state_machine
...
fun:ngx_ssl_handshake
fun:ngx_http_upstream_ssl_init_connection
fun:ngx_http_upstream_send_request_handler
fun:ngx_http_upstream_handler
...
fun:ngx_process_events_and_timers
...
fun:main
}