lua-nginx-module
lua-nginx-module copied to clipboard
feature: ngx_http_lua_ffi_ssl_ciphers
Add ngx_http_lua_ffi_ssl_ciphers that returns a uint16_t array of tls_protocol_id supported (and enabled) by both server and client
consider this pull request a request for comment example usage from resty-core:
ffi.cdef[[
int ngx_http_lua_ffi_ssl_ciphers(ngx_http_request_t *r, uint16_t *ciphers,
uint16_t *nciphers, char **err);
typedef struct {
uint16_t nciphers;
uint16_t ciphers[?];
} ngx_lua_ssl_ciphers;
]]
do
local tls_proto_id = {
[0x1305] = {
iana_name = "TLS_AES_128_CCM_8_SHA256",
tls_version = 1.3,
kex = "none",
auth = "none",
enc = "AES 128 CCM 8",
hash = "SHA256"
},
...
}
local unknown_cipher = {
iana_name = "UNKNOWN",
tls_version = 0,
kex = "UNKNOWN",
auth = "UNKNOWN",
enc = "UNKNOWN",
hash = "UNKNOWN"
}
setmetatable(tls_proto_id, {
__index = function(t,k)
t[k] = unknown_cipher
return unknown_cipher
end
})
local iterate_ciphers = function(ciphers, n)
if ciphers.nciphers > n then
return n+1, tls_proto_id[ciphers.ciphers[n]]
end
end
local ciphers_t = {}
ffi.metatype('ngx_lua_ssl_ciphers', {
__ipairs = function(ciphers)
return iterate_ciphers, ciphers, 0
end,
__tostring = function(ciphers)
for n,c in ipairs(ciphers) do
ciphers_t[n] = type(c) == "table" and c.iana_name or format("0x%.4x", c)
end
return concat(ciphers_t, ":", 1, ciphers.nciphers)
end
})
end
local ciphers_typ = ffi.typeof("ngx_lua_ssl_ciphers")
local ciphers_buf = ffi.new("uint16_t [?]", 256)
_M.ciphers = function()
local r = get_request()
if not r then
ngx.log(ngx.ERR, "no request found")
end
ciphers_buf[0] = 255
local rc = C.ngx_http_lua_ffi_ssl_ciphers(r, ciphers_buf+1, ciphers_buf, errmsg)
if rc ~= FFI_OK then
return nil, ffi_str(errmsg[0])
end
local ciphers = ciphers_typ(ciphers_buf[0])
ffi.copy(ciphers, ciphers_buf, (ciphers_buf[0] + 1) * ffi.sizeof('uint16_t'))
return ciphers
end
I hereby granted the copyright of the changes in this pull request to the authors of this lua-nginx-module project.
need to add some test cases. @bjne
need to add some test cases. @bjne
Yeah absolutely, just wanted to know if this is a way you would accept this implemented first
@bjne this implementation is OK. But this only works in openssl, boringssl does not have the APIs in your PR. we need to add macro to guard the code.