aboutsummaryrefslogtreecommitdiffstats
path: root/server/resty/openssl/auxiliary
diff options
context:
space:
mode:
authorFiete Ostkamp <Fiete.Ostkamp@telekom.de>2023-04-14 11:59:32 +0000
committerFiete Ostkamp <Fiete.Ostkamp@telekom.de>2023-04-14 11:59:32 +0000
commitd68841d9f75636575cd778838a8ceea5fd5aada3 (patch)
tree778c84203ed9bfa4dc1c8234e4e2cf60da6ebd8c /server/resty/openssl/auxiliary
parent42af09588f1f839b9ab36356f02f34c89559bcfa (diff)
Upload ui
Issue-ID: PORTAL-1084 Signed-off-by: Fiete Ostkamp <Fiete.Ostkamp@telekom.de> Change-Id: Id0c94859a775094e67b0bb9c91ca5e776a08c068
Diffstat (limited to 'server/resty/openssl/auxiliary')
-rw-r--r--server/resty/openssl/auxiliary/bio.lua43
-rw-r--r--server/resty/openssl/auxiliary/ctypes.lua28
-rw-r--r--server/resty/openssl/auxiliary/jwk.lua261
-rw-r--r--server/resty/openssl/auxiliary/nginx.lua318
-rw-r--r--server/resty/openssl/auxiliary/nginx_c.lua154
5 files changed, 804 insertions, 0 deletions
diff --git a/server/resty/openssl/auxiliary/bio.lua b/server/resty/openssl/auxiliary/bio.lua
new file mode 100644
index 0000000..3eed9f0
--- /dev/null
+++ b/server/resty/openssl/auxiliary/bio.lua
@@ -0,0 +1,43 @@
+local ffi = require "ffi"
+local C = ffi.C
+local ffi_gc = ffi.gc
+local ffi_new = ffi.new
+local ffi_str = ffi.string
+
+require "resty.openssl.include.bio"
+local format_error = require("resty.openssl.err").format_error
+
+local function read_wrap(f, ...)
+ if type(f) ~= "cdata" then -- should be explictly a function
+ return nil, "bio_util.read_wrap: expect a function at #1"
+ end
+
+ local bio_method = C.BIO_s_mem()
+ if bio_method == nil then
+ return nil, "bio_util.read_wrap: BIO_s_mem() failed"
+ end
+ local bio = C.BIO_new(bio_method)
+ ffi_gc(bio, C.BIO_free)
+
+ -- BIO_reset; #define BIO_CTRL_RESET 1
+ local code = C.BIO_ctrl(bio, 1, 0, nil)
+ if code ~= 1 then
+ return nil, "bio_util.read_wrap: BIO_ctrl() failed: " .. code
+ end
+
+ local code = f(bio, ...)
+ if code ~= 1 then
+ return nil, format_error(f, code)
+ end
+
+ local buf = ffi_new("char *[1]")
+
+ -- BIO_get_mem_data; #define BIO_CTRL_INFO 3
+ local length = C.BIO_ctrl(bio, 3, 0, buf)
+
+ return ffi_str(buf[0], length)
+end
+
+return {
+ read_wrap = read_wrap,
+} \ No newline at end of file
diff --git a/server/resty/openssl/auxiliary/ctypes.lua b/server/resty/openssl/auxiliary/ctypes.lua
new file mode 100644
index 0000000..933822b
--- /dev/null
+++ b/server/resty/openssl/auxiliary/ctypes.lua
@@ -0,0 +1,28 @@
+-- Put common type definition at the same place for convenience
+-- and standarlization
+local ffi = require "ffi"
+
+--[[
+ TYPE_ptr: usually used to define a pointer (to cast or something)
+ char* var_name; // <- we use char_ptr
+
+ ptr_of_TYPE: usually used to pass the pointer of an object that
+ is already allocated. so that we can also set value of it as well
+
+ int p = 2; // ptr_of_int(); ptr_of_int[0] = 2;
+ plus_one(&p); // <- we use ptr_of_int
+]]
+
+return {
+ void_ptr = ffi.typeof("void *"),
+ ptr_of_uint64 = ffi.typeof("uint64_t[1]"),
+ ptr_of_uint = ffi.typeof("unsigned int[1]"),
+ ptr_of_size_t = ffi.typeof("size_t[1]"),
+ ptr_of_int = ffi.typeof("int[1]"),
+ null = ffi.new("void *"), -- hack wher ngx.null is not available
+
+ uchar_array = ffi.typeof("unsigned char[?]"),
+ uchar_ptr = ffi.typeof("unsigned char*"),
+
+ SIZE_MAX = math.pow(2, 64), -- nginx set _FILE_OFFSET_BITS to 64
+} \ No newline at end of file
diff --git a/server/resty/openssl/auxiliary/jwk.lua b/server/resty/openssl/auxiliary/jwk.lua
new file mode 100644
index 0000000..5a505a9
--- /dev/null
+++ b/server/resty/openssl/auxiliary/jwk.lua
@@ -0,0 +1,261 @@
+
+local ffi = require "ffi"
+local C = ffi.C
+
+local cjson = require("cjson.safe")
+local b64 = require("ngx.base64")
+
+local evp_macro = require "resty.openssl.include.evp"
+local rsa_lib = require "resty.openssl.rsa"
+local ec_lib = require "resty.openssl.ec"
+local ecx_lib = require "resty.openssl.ecx"
+local bn_lib = require "resty.openssl.bn"
+local digest_lib = require "resty.openssl.digest"
+
+local _M = {}
+
+local rsa_jwk_params = {"n", "e", "d", "p", "q", "dp", "dq", "qi"}
+local rsa_openssl_params = rsa_lib.params
+
+local function load_jwk_rsa(tbl)
+ if not tbl["n"] or not tbl["e"] then
+ return nil, "at least \"n\" and \"e\" parameter is required"
+ end
+
+ local params = {}
+ local err
+ for i, k in ipairs(rsa_jwk_params) do
+ local v = tbl[k]
+ if v then
+ v = b64.decode_base64url(v)
+ if not v then
+ return nil, "cannot decode parameter \"" .. k .. "\" from base64 " .. tbl[k]
+ end
+
+ params[rsa_openssl_params[i]], err = bn_lib.from_binary(v)
+ if err then
+ return nil, "cannot use parameter \"" .. k .. "\": " .. err
+ end
+ end
+ end
+
+ local key = C.RSA_new()
+ if key == nil then
+ return nil, "RSA_new() failed"
+ end
+
+ local _, err = rsa_lib.set_parameters(key, params)
+ if err ~= nil then
+ C.RSA_free(key)
+ return nil, err
+ end
+
+ return key
+end
+
+local ec_curves = {
+ ["P-256"] = C.OBJ_ln2nid("prime256v1"),
+ ["P-384"] = C.OBJ_ln2nid("secp384r1"),
+ ["P-521"] = C.OBJ_ln2nid("secp521r1"),
+}
+
+local ec_curves_reverse = {}
+for k, v in pairs(ec_curves) do
+ ec_curves_reverse[v] = k
+end
+
+local ec_jwk_params = {"x", "y", "d"}
+
+local function load_jwk_ec(tbl)
+ local curve = tbl['crv']
+ if not curve then
+ return nil, "\"crv\" not defined for EC key"
+ end
+ if not tbl["x"] or not tbl["y"] then
+ return nil, "at least \"x\" and \"y\" parameter is required"
+ end
+ local curve_nid = ec_curves[curve]
+ if not curve_nid then
+ return nil, "curve \"" .. curve .. "\" is not supported by this library"
+ elseif curve_nid == 0 then
+ return nil, "curve \"" .. curve .. "\" is not supported by linked OpenSSL"
+ end
+
+ local params = {}
+ local err
+ for _, k in ipairs(ec_jwk_params) do
+ local v = tbl[k]
+ if v then
+ v = b64.decode_base64url(v)
+ if not v then
+ return nil, "cannot decode parameter \"" .. k .. "\" from base64 " .. tbl[k]
+ end
+
+ params[k], err = bn_lib.from_binary(v)
+ if err then
+ return nil, "cannot use parameter \"" .. k .. "\": " .. err
+ end
+ end
+ end
+
+ -- map to the name we expect
+ if params["d"] then
+ params["private"] = params["d"]
+ params["d"] = nil
+ end
+ params["group"] = curve_nid
+
+ local key = C.EC_KEY_new()
+ if key == nil then
+ return nil, "EC_KEY_new() failed"
+ end
+
+ local _, err = ec_lib.set_parameters(key, params)
+ if err ~= nil then
+ C.EC_KEY_free(key)
+ return nil, err
+ end
+
+ return key
+end
+
+local function load_jwk_okp(key_type, tbl)
+ local params = {}
+ if tbl["d"] then
+ params.private = b64.decode_base64url(tbl["d"])
+ elseif tbl["x"] then
+ params.public = b64.decode_base64url(tbl["x"])
+ else
+ return nil, "at least \"x\" or \"d\" parameter is required"
+ end
+ local key, err = ecx_lib.set_parameters(key_type, nil, params)
+ if err ~= nil then
+ return nil, err
+ end
+ return key
+end
+
+local ecx_curves_reverse = {}
+for k, v in pairs(evp_macro.ecx_curves) do
+ ecx_curves_reverse[v] = k
+end
+
+function _M.load_jwk(txt)
+ local tbl, err = cjson.decode(txt)
+ if err then
+ return nil, "error decoding JSON from JWK: " .. err
+ elseif type(tbl) ~= "table" then
+ return nil, "except input to be decoded as a table, got " .. type(tbl)
+ end
+
+ local key, key_free, key_type, err
+
+ if tbl["kty"] == "RSA" then
+ key_type = evp_macro.EVP_PKEY_RSA
+ if key_type == 0 then
+ return nil, "the linked OpenSSL library doesn't support RSA key"
+ end
+ key, err = load_jwk_rsa(tbl)
+ key_free = C.RSA_free
+ elseif tbl["kty"] == "EC" then
+ key_type = evp_macro.EVP_PKEY_EC
+ if key_type == 0 then
+ return nil, "the linked OpenSSL library doesn't support EC key"
+ end
+ key, err = load_jwk_ec(tbl)
+ key_free = C.EC_KEY_free
+ elseif tbl["kty"] == "OKP" then
+ local curve = tbl["crv"]
+ key_type = evp_macro.ecx_curves[curve]
+ if not key_type then
+ return nil, "unknown curve \"" .. tostring(curve)
+ elseif key_type == 0 then
+ return nil, "the linked OpenSSL library doesn't support \"" .. curve .. "\" key"
+ end
+ key, err = load_jwk_okp(key_type, tbl)
+ if key ~= nil then
+ return key
+ end
+ else
+ return nil, "not yet supported jwk type \"" .. (tbl["kty"] or "nil") .. "\""
+ end
+
+ if err then
+ return nil, "failed to construct " .. tbl["kty"] .. " key from JWK: " .. err
+ end
+
+ local ctx = C.EVP_PKEY_new()
+ if ctx == nil then
+ key_free(key)
+ return nil, "EVP_PKEY_new() failed"
+ end
+
+ local code = C.EVP_PKEY_assign(ctx, key_type, key)
+ if code ~= 1 then
+ key_free(key)
+ C.EVP_PKEY_free(ctx)
+ return nil, "EVP_PKEY_assign() failed"
+ end
+
+ return ctx
+end
+
+function _M.dump_jwk(pkey, is_priv)
+ local jwk
+ if pkey.key_type == evp_macro.EVP_PKEY_RSA then
+ local param_keys = { "n" , "e" }
+ if is_priv then
+ param_keys = rsa_jwk_params
+ end
+ local params, err = pkey:get_parameters()
+ if err then
+ return nil, "jwk.dump_jwk: " .. err
+ end
+ jwk = {
+ kty = "RSA",
+ }
+ for i, p in ipairs(param_keys) do
+ local v = params[rsa_openssl_params[i]]:to_binary()
+ jwk[p] = b64.encode_base64url(v)
+ end
+ elseif pkey.key_type == evp_macro.EVP_PKEY_EC then
+ local params, err = pkey:get_parameters()
+ if err then
+ return nil, "jwk.dump_jwk: " .. err
+ end
+ jwk = {
+ kty = "EC",
+ crv = ec_curves_reverse[params.group],
+ x = b64.encode_base64url(params.x:to_binary()),
+ y = b64.encode_base64url(params.x:to_binary()),
+ }
+ if is_priv then
+ jwk.d = b64.encode_base64url(params.private:to_binary())
+ end
+ elseif ecx_curves_reverse[pkey.key_type] then
+ local params, err = pkey:get_parameters()
+ if err then
+ return nil, "jwk.dump_jwk: " .. err
+ end
+ jwk = {
+ kty = "OKP",
+ crv = ecx_curves_reverse[pkey.key_type],
+ d = b64.encode_base64url(params.private),
+ x = b64.encode_base64url(params.public),
+ }
+ else
+ return nil, "jwk.dump_jwk: not implemented for this key type"
+ end
+
+ local der = pkey:tostring(is_priv and "private" or "public", "DER")
+ local dgst = digest_lib.new("sha256")
+ local d, err = dgst:final(der)
+ if err then
+ return nil, "jwk.dump_jwk: failed to calculate digest for key"
+ end
+ jwk.kid = b64.encode_base64url(d)
+
+ return cjson.encode(jwk)
+end
+
+return _M
diff --git a/server/resty/openssl/auxiliary/nginx.lua b/server/resty/openssl/auxiliary/nginx.lua
new file mode 100644
index 0000000..8adeceb
--- /dev/null
+++ b/server/resty/openssl/auxiliary/nginx.lua
@@ -0,0 +1,318 @@
+local get_req_ssl, get_req_ssl_ctx
+local get_socket_ssl, get_socket_ssl_ctx
+
+local pok, nginx_c = pcall(require, "resty.openssl.auxiliary.nginx_c")
+
+if pok and not os.getenv("CI_SKIP_NGINX_C") then
+ get_req_ssl = nginx_c.get_req_ssl
+ get_req_ssl_ctx = nginx_c.get_req_ssl_ctx
+ get_socket_ssl = nginx_c.get_socket_ssl
+ get_socket_ssl_ctx = nginx_c.get_socket_ssl
+else
+ local ffi = require "ffi"
+
+ ffi.cdef [[
+ // Nginx seems to always config _FILE_OFFSET_BITS=64, this should always be 8 byte
+ typedef long long off_t;
+ typedef unsigned int socklen_t; // windows uses int, same size
+ typedef unsigned short in_port_t;
+
+ typedef struct ssl_st SSL;
+ typedef struct ssl_ctx_st SSL_CTX;
+
+ typedef long (*ngx_recv_pt)(void *c, void *buf, size_t size);
+ typedef long (*ngx_recv_chain_pt)(void *c, void *in,
+ off_t limit);
+ typedef long (*ngx_send_pt)(void *c, void *buf, size_t size);
+ typedef void *(*ngx_send_chain_pt)(void *c, void *in,
+ off_t limit);
+
+ typedef struct {
+ size_t len;
+ void *data;
+ } ngx_str_t;
+
+ typedef struct {
+ SSL *connection;
+ SSL_CTX *session_ctx;
+ // trimmed
+ } ngx_ssl_connection_s;
+ ]]
+
+ local ngx_version = ngx.config.nginx_version
+ if ngx_version == 1017008 or ngx_version == 1019003 or ngx_version == 1019009
+ or ngx_version == 1021004 then
+ -- 1.17.8, 1.19.3, 1.19.9, 1.21.4
+ -- https://github.com/nginx/nginx/blob/master/src/core/ngx_connection.h
+ ffi.cdef [[
+ typedef struct {
+ ngx_str_t src_addr;
+ ngx_str_t dst_addr;
+ in_port_t src_port;
+ in_port_t dst_port;
+ } ngx_proxy_protocol_t;
+
+ typedef struct {
+ void *data;
+ void *read;
+ void *write;
+
+ int fd;
+
+ ngx_recv_pt recv;
+ ngx_send_pt send;
+ ngx_recv_chain_pt recv_chain;
+ ngx_send_chain_pt send_chain;
+
+ void *listening;
+
+ off_t sent;
+
+ void *log;
+
+ void *pool;
+
+ int type;
+
+ void *sockaddr;
+ socklen_t socklen;
+ ngx_str_t addr_text;
+
+ // https://github.com/nginx/nginx/commit/be932e81a1531a3ba032febad968fc2006c4fa48
+ ngx_proxy_protocol_t *proxy_protocol;
+
+ ngx_ssl_connection_s *ssl;
+ // trimmed
+ } ngx_connection_s;
+ ]]
+ else
+ error("resty.openssl.auxiliary.nginx doesn't support Nginx version " .. ngx_version, 2)
+ end
+
+ ffi.cdef [[
+ typedef struct {
+ ngx_connection_s *connection;
+ // trimmed
+ } ngx_stream_lua_request_s;
+
+ typedef struct {
+ unsigned int signature; /* "HTTP" */
+
+ ngx_connection_s *connection;
+ // trimmed
+ } ngx_http_request_s;
+ ]]
+
+ local get_request
+ do
+ local ok, exdata = pcall(require, "thread.exdata")
+ if ok and exdata then
+ function get_request()
+ local r = exdata()
+ if r ~= nil then
+ return r
+ end
+ end
+
+ else
+ local getfenv = getfenv
+
+ function get_request()
+ return getfenv(0).__ngx_req
+ end
+ end
+ end
+
+ local SOCKET_CTX_INDEX = 1
+
+ local NO_C_MODULE_WARNING_MSG_SHOWN = false
+ local NO_C_MODULE_WARNING_MSG = "note resty.openssl.auxiliary.nginx is using plain FFI " ..
+ "and it's only intended to be used in development, " ..
+ "consider using lua-resty-openssl.aux-module in production."
+
+ local function get_ngx_ssl_from_req()
+ if not NO_C_MODULE_WARNING_MSG_SHOWN then
+ ngx.log(ngx.WARN, NO_C_MODULE_WARNING_MSG)
+ NO_C_MODULE_WARNING_MSG_SHOWN = true
+ end
+
+ local c = get_request()
+ if ngx.config.subsystem == "stream" then
+ c = ffi.cast("ngx_stream_lua_request_s*", c)
+ else -- http
+ c = ffi.cast("ngx_http_request_s*", c)
+ end
+
+ local ngx_ssl = c.connection.ssl
+ if ngx_ssl == nil then
+ return nil, "c.connection.ssl is nil"
+ end
+ return ngx_ssl
+ end
+
+ get_req_ssl = function()
+ local ssl, err = get_ngx_ssl_from_req()
+ if err then
+ return nil, err
+ end
+
+ return ssl.connection
+ end
+
+ get_req_ssl_ctx = function()
+ local ssl, err = get_ngx_ssl_from_req()
+ if err then
+ return nil, err
+ end
+
+ return ssl.session_ctx
+ end
+
+ ffi.cdef[[
+ typedef struct ngx_http_lua_socket_tcp_upstream_s
+ ngx_http_lua_socket_tcp_upstream_t;
+
+ typedef struct {
+ ngx_connection_s *connection;
+ // trimmed
+ } ngx_peer_connection_s;
+
+ typedef
+ int (*ngx_http_lua_socket_tcp_retval_handler_masked)(void *r,
+ void *u, void *L);
+
+ typedef void (*ngx_http_lua_socket_tcp_upstream_handler_pt_masked)
+ (void *r, void *u);
+
+
+ typedef
+ int (*ngx_stream_lua_socket_tcp_retval_handler)(void *r,
+ void *u, void *L);
+
+ typedef void (*ngx_stream_lua_socket_tcp_upstream_handler_pt)
+ (void *r, void *u);
+
+ typedef struct {
+ ngx_stream_lua_socket_tcp_retval_handler read_prepare_retvals;
+ ngx_stream_lua_socket_tcp_retval_handler write_prepare_retvals;
+ ngx_stream_lua_socket_tcp_upstream_handler_pt read_event_handler;
+ ngx_stream_lua_socket_tcp_upstream_handler_pt write_event_handler;
+
+ void *socket_pool;
+
+ void *conf;
+ void *cleanup;
+ void *request;
+
+ ngx_peer_connection_s peer;
+ // trimmed
+ } ngx_stream_lua_socket_tcp_upstream_s;
+ ]]
+
+ local ngx_lua_version = ngx.config and
+ ngx.config.ngx_lua_version and
+ ngx.config.ngx_lua_version
+
+ if ngx_lua_version >= 10019 and ngx_lua_version <= 10021 then
+ -- https://github.com/openresty/lua-nginx-module/blob/master/src/ngx_http_lua_socket_tcp.h
+ ffi.cdef[[
+ typedef struct {
+ ngx_http_lua_socket_tcp_retval_handler_masked read_prepare_retvals;
+ ngx_http_lua_socket_tcp_retval_handler_masked write_prepare_retvals;
+ ngx_http_lua_socket_tcp_upstream_handler_pt_masked read_event_handler;
+ ngx_http_lua_socket_tcp_upstream_handler_pt_masked write_event_handler;
+
+ void *udata_queue; // 0.10.19
+
+ void *socket_pool;
+
+ void *conf;
+ void *cleanup;
+ void *request;
+ ngx_peer_connection_s peer;
+ // trimmed
+ } ngx_http_lua_socket_tcp_upstream_s;
+ ]]
+ elseif ngx_lua_version < 10019 then
+ -- the struct doesn't seem to get changed a long time since birth
+ ffi.cdef[[
+ typedef struct {
+ ngx_http_lua_socket_tcp_retval_handler_masked read_prepare_retvals;
+ ngx_http_lua_socket_tcp_retval_handler_masked write_prepare_retvals;
+ ngx_http_lua_socket_tcp_upstream_handler_pt_masked read_event_handler;
+ ngx_http_lua_socket_tcp_upstream_handler_pt_masked write_event_handler;
+
+ void *socket_pool;
+
+ void *conf;
+ void *cleanup;
+ void *request;
+ ngx_peer_connection_s peer;
+ // trimmed
+ } ngx_http_lua_socket_tcp_upstream_s;
+ ]]
+ else
+ error("resty.openssl.auxiliary.nginx doesn't support lua-nginx-module version " .. (ngx_lua_version or "nil"), 2)
+ end
+
+ local function get_ngx_ssl_from_socket_ctx(sock)
+ if not NO_C_MODULE_WARNING_MSG_SHOWN then
+ ngx.log(ngx.WARN, NO_C_MODULE_WARNING_MSG)
+ NO_C_MODULE_WARNING_MSG_SHOWN = true
+ end
+
+ local u = sock[SOCKET_CTX_INDEX]
+ if u == nil then
+ return nil, "lua_socket_tcp_upstream_t not found"
+ end
+
+ if ngx.config.subsystem == "stream" then
+ u = ffi.cast("ngx_stream_lua_socket_tcp_upstream_s*", u)
+ else -- http
+ u = ffi.cast("ngx_http_lua_socket_tcp_upstream_s*", u)
+ end
+
+ local p = u.peer
+ if p == nil then
+ return nil, "u.peer is nil"
+ end
+
+ local uc = p.connection
+ if uc == nil then
+ return nil, "u.peer.connection is nil"
+ end
+
+ local ngx_ssl = uc.ssl
+ if ngx_ssl == nil then
+ return nil, "u.peer.connection.ssl is nil"
+ end
+ return ngx_ssl
+ end
+
+ get_socket_ssl = function(sock)
+ local ssl, err = get_ngx_ssl_from_socket_ctx(sock)
+ if err then
+ return nil, err
+ end
+
+ return ssl.connection
+ end
+
+ get_socket_ssl_ctx = function(sock)
+ local ssl, err = get_ngx_ssl_from_socket_ctx(sock)
+ if err then
+ return nil, err
+ end
+
+ return ssl.session_ctx
+ end
+
+end
+
+
+return {
+ get_req_ssl = get_req_ssl,
+ get_req_ssl_ctx = get_req_ssl_ctx,
+ get_socket_ssl = get_socket_ssl,
+ get_socket_ssl_ctx = get_socket_ssl_ctx,
+}
diff --git a/server/resty/openssl/auxiliary/nginx_c.lua b/server/resty/openssl/auxiliary/nginx_c.lua
new file mode 100644
index 0000000..f50db36
--- /dev/null
+++ b/server/resty/openssl/auxiliary/nginx_c.lua
@@ -0,0 +1,154 @@
+local ffi = require "ffi"
+local C = ffi.C
+
+local SOCKET_CTX_INDEX = 1
+local NGX_OK = ngx.OK
+
+
+local get_req_ssl, get_req_ssl_ctx
+local get_socket_ssl, get_socket_ssl_ctx
+
+local get_request
+do
+ local ok, exdata = pcall(require, "thread.exdata")
+ if ok and exdata then
+ function get_request()
+ local r = exdata()
+ if r ~= nil then
+ return r
+ end
+ end
+
+ else
+ local getfenv = getfenv
+
+ function get_request()
+ return getfenv(0).__ngx_req
+ end
+ end
+end
+
+
+local stream_subsystem = false
+if ngx.config.subsystem == "stream" then
+ stream_subsystem = true
+
+ ffi.cdef [[
+ typedef struct ngx_stream_lua_request_s ngx_stream_lua_request_t;
+ typedef struct ngx_stream_lua_socket_tcp_upstream_s ngx_stream_lua_socket_tcp_upstream_t;
+
+ int ngx_stream_lua_resty_openssl_aux_get_request_ssl(ngx_stream_lua_request_t *r,
+ void **_ssl_conn);
+
+ int ngx_stream_lua_resty_openssl_aux_get_request_ssl_ctx(ngx_stream_lua_request_t *r,
+ void **_sess);
+
+ int ngx_stream_lua_resty_openssl_aux_get_socket_ssl(ngx_stream_lua_socket_tcp_upstream_t *u,
+ void **_ssl_conn);
+
+ int ngx_stream_lua_resty_openssl_aux_get_socket_ssl_ctx(ngx_stream_lua_socket_tcp_upstream_t *u,
+ void **_sess);
+ ]]
+
+ -- sanity test
+ local _ = C.ngx_stream_lua_resty_openssl_aux_get_request_ssl
+else
+ ffi.cdef [[
+ typedef struct ngx_http_request_s ngx_http_request_t;
+ typedef struct ngx_http_lua_socket_tcp_upstream_s ngx_http_lua_socket_tcp_upstream_t;
+
+ int ngx_http_lua_resty_openssl_aux_get_request_ssl(ngx_http_request_t *r,
+ void **_ssl_conn);
+
+ int ngx_http_lua_resty_openssl_aux_get_request_ssl_ctx(ngx_http_request_t *r,
+ void **_sess);
+
+ int ngx_http_lua_resty_openssl_aux_get_socket_ssl(ngx_http_lua_socket_tcp_upstream_t *u,
+ void **_ssl_conn);
+
+ int ngx_http_lua_resty_openssl_aux_get_socket_ssl_ctx(ngx_http_lua_socket_tcp_upstream_t *u,
+ void **_sess);
+ ]]
+
+ -- sanity test
+ local _ = C.ngx_http_lua_resty_openssl_aux_get_request_ssl
+end
+
+local void_pp = ffi.new("void *[1]")
+local ssl_type = ffi.typeof("SSL*")
+local ssl_ctx_type = ffi.typeof("SSL_CTX*")
+
+get_req_ssl = function()
+ local c = get_request()
+
+ local ret
+ if stream_subsystem then
+ ret = C.ngx_stream_lua_resty_openssl_aux_get_request_ssl(c, void_pp)
+ else
+ ret = C.ngx_http_lua_resty_openssl_aux_get_request_ssl(c, void_pp)
+ end
+
+ if ret ~= NGX_OK then
+ return nil, "cannot read r->connection->ssl->connection"
+ end
+
+ return ffi.cast(ssl_type, void_pp[0])
+end
+
+get_req_ssl_ctx = function()
+ local c = get_request()
+
+ local ret
+ if stream_subsystem then
+ ret = C.ngx_stream_lua_resty_openssl_aux_get_request_ssl_ctx(c, void_pp)
+ else
+ ret = C.ngx_http_lua_resty_openssl_aux_get_request_ssl_ctx(c, void_pp)
+ end
+
+ if ret ~= NGX_OK then
+ return nil, "cannot read r->connection->ssl->session_ctx"
+ end
+
+ return ffi.cast(ssl_ctx_type, void_pp[0])
+end
+
+get_socket_ssl = function(sock)
+ local u = sock[SOCKET_CTX_INDEX]
+
+ local ret
+ if stream_subsystem then
+ ret = C.ngx_stream_lua_resty_openssl_aux_get_socket_ssl(u, void_pp)
+ else
+ ret = C.ngx_http_lua_resty_openssl_aux_get_socket_ssl(u, void_pp)
+ end
+
+ if ret ~= NGX_OK then
+ return nil, "cannot read u->peer.connection->ssl->connection"
+ end
+
+ return ffi.cast(ssl_type, void_pp[0])
+end
+
+get_socket_ssl_ctx = function(sock)
+ local u = sock[SOCKET_CTX_INDEX]
+
+ local ret
+ if stream_subsystem then
+ ret = C.ngx_stream_lua_resty_openssl_aux_get_socket_ssl_ctx(u, void_pp)
+ else
+ ret = C.ngx_http_lua_resty_openssl_aux_get_socket_ssl_ctx(u, void_pp)
+ end
+
+ if ret ~= NGX_OK then
+ return nil, "cannot read u->peer.connection->ssl->session_ctx"
+ end
+
+ return ffi.cast(ssl_ctx_type, void_pp[0])
+end
+
+return {
+ get_req_ssl = get_req_ssl,
+ get_req_ssl_ctx = get_req_ssl_ctx,
+ get_socket_ssl = get_socket_ssl,
+ get_socket_ssl_ctx = get_socket_ssl_ctx,
+} \ No newline at end of file