Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: ngx_http_lua_ffi_ssl_ciphers #1962

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

bjne
Copy link

@bjne bjne commented Nov 3, 2021

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.

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
@zhuizhuhaomeng
Copy link
Contributor

need to add some test cases. @bjne

@bjne
Copy link
Author

bjne commented Nov 12, 2021

need to add some test cases. @bjne

Yeah absolutely, just wanted to know if this is a way you would accept this implemented first

@zhuizhuhaomeng
Copy link
Contributor

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants