From 4799967e0bd6e37245f7fc0c7bc30d5a9a12ef46 Mon Sep 17 00:00:00 2001 From: Thibault Charbonnier Date: Sat, 23 May 2015 01:06:15 +0200 Subject: [PATCH] chore: add vendor/ssl.lua and remove reset_db() --- kong/vendor/ssl.lua | 333 ++++++++++++++++++++++++++++++++++++++ spec/plugins/ssl_spec.lua | 7 +- spec/spec_helpers.lua | 9 -- 3 files changed, 336 insertions(+), 13 deletions(-) create mode 100644 kong/vendor/ssl.lua diff --git a/kong/vendor/ssl.lua b/kong/vendor/ssl.lua new file mode 100644 index 00000000000..9f909981664 --- /dev/null +++ b/kong/vendor/ssl.lua @@ -0,0 +1,333 @@ +-- Copyright (C) 2014 Yichun Zhang + + +local ffi = require "ffi" +local base = require "resty.core.base" + + +local C = ffi.C +local ffi_str = ffi.string +local getfenv = getfenv +local errmsg = base.get_errmsg_ptr() +local get_string_buf = base.get_string_buf +local get_string_buf_size = base.get_string_buf_size +local get_size_ptr = base.get_size_ptr +local FFI_DECLINED = base.FFI_DECLINED +local FFI_OK = base.FFI_OK +local FFI_BUSY = base.FFI_BUSY +local FFI_DECLINED = base.FFI_DECLINED + + +ffi.cdef[[ + +struct ngx_ssl_conn_s; +typedef struct ngx_ssl_conn_s ngx_ssl_conn_t; + +int ngx_http_lua_ffi_ssl_set_der_certificate(ngx_http_request_t *r, + const char *data, size_t len, char **err); + +int ngx_http_lua_ffi_ssl_clear_certs(ngx_http_request_t *r, char **err); + +int ngx_http_lua_ffi_ssl_set_der_private_key(ngx_http_request_t *r, + const char *data, size_t len, char **err); + +int ngx_http_lua_ffi_ssl_raw_server_addr(ngx_http_request_t *r, char **addr, + size_t *addrlen, int *addrtype, char **err); + +int ngx_http_lua_ffi_ssl_server_name(ngx_http_request_t *r, char **name, + size_t *namelen, char **err); + +int ngx_http_lua_ffi_cert_pem_to_der(const unsigned char *pem, size_t pem_len, + unsigned char *der, char **err); + +int ngx_http_lua_ffi_ssl_get_ocsp_responder_from_der_chain( + const char *chain_data, size_t chain_len, char *out, size_t *out_size, + char **err); + +int ngx_http_lua_ffi_ssl_create_ocsp_request(const char *chain_data, + size_t chain_len, unsigned char *out, size_t *out_size, char **err); + +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); + +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); + +int ngx_http_lua_ffi_ssl_get_tls1_version(ngx_http_request_t *r, char **err); +]] + + +local _M = {} + + +local charpp = ffi.new("char*[1]") +local intp = ffi.new("int[1]") + + +function _M.clear_certs(data) + local r = getfenv(0).__ngx_req + if not r then + return error("no request found") + end + + local rc = C.ngx_http_lua_ffi_ssl_clear_certs(r, errmsg) + if rc == FFI_OK then + return true + end + + return nil, ffi_str(errmsg[0]) +end + + +function _M.set_der_cert(data) + local r = getfenv(0).__ngx_req + if not r then + return error("no request found") + end + + local rc = C.ngx_http_lua_ffi_ssl_set_der_certificate(r, data, #data, + errmsg) + if rc == FFI_OK then + return true + end + + return nil, ffi_str(errmsg[0]) +end + + +function _M.set_der_priv_key(data) + local r = getfenv(0).__ngx_req + if not r then + return error("no request found") + end + + local rc = C.ngx_http_lua_ffi_ssl_set_der_private_key(r, data, #data, + errmsg) + if rc == FFI_OK then + return true + end + + return nil, ffi_str(errmsg[0]) +end + + +local addr_types = { + [1] = "unix", + [2] = "inet", + [10] = "inet6", +} + + +function _M.raw_server_addr() + local r = getfenv(0).__ngx_req + if not r then + return error("no request found") + end + + local sizep = get_size_ptr() + + local rc = C.ngx_http_lua_ffi_ssl_raw_server_addr(r, charpp, sizep, + intp, errmsg) + if rc == FFI_OK then + local typ = addr_types[intp[0]] + if not typ then + return nil, nil, "unknown address type: " .. intp[0] + end + return ffi_str(charpp[0], sizep[0]), typ + end + + return nil, nil, ffi_str(errmsg[0]) +end + + +function _M.server_name() + local r = getfenv(0).__ngx_req + if not r then + return error("no request found") + end + + local sizep = get_size_ptr() + + local rc = C.ngx_http_lua_ffi_ssl_server_name(r, charpp, sizep, errmsg) + if rc == FFI_OK then + return ffi_str(charpp[0], sizep[0]) + end + + if rc == FFI_DECLINED then + return nil + end + + return nil, ffi_str(errmsg[0]) +end + + +function _M.cert_pem_to_der(pem) + local r = getfenv(0).__ngx_req + if not r then + return error("no request found") + end + + local outbuf = get_string_buf(#pem) + + local sz = C.ngx_http_lua_ffi_cert_pem_to_der(pem, #pem, outbuf, errmsg) + if sz > 0 then + return ffi_str(outbuf, sz) + end + + return nil, ffi_str(errmsg[0]) +end + + +function _M.get_ocsp_responder_from_der_chain(data, maxlen) + + local buf_size = maxlen + if not buf_size then + buf_size = get_string_buf_size() + end + local buf = get_string_buf(buf_size) + + local sizep = get_size_ptr() + sizep[0] = buf_size + + local rc = C.ngx_http_lua_ffi_ssl_get_ocsp_responder_from_der_chain(data, + #data, buf, sizep, errmsg) + + if rc == FFI_DECLINED then + return nil + end + + if rc == FFI_OK then + return ffi_str(buf, sizep[0]) + end + + if rc == FFI_BUSY then + return ffi_str(buf, sizep[0]), "truncated" + end + + return nil, ffi_str(errmsg[0]) +end + + +function _M.create_ocsp_request(data, maxlen) + + local buf_size = maxlen + if not buf_size then + buf_size = get_string_buf_size() + end + local buf = get_string_buf(buf_size) + + local sizep = get_size_ptr() + sizep[0] = buf_size + + local rc = C.ngx_http_lua_ffi_ssl_create_ocsp_request(data, + #data, buf, sizep, + errmsg) + + if rc == FFI_OK then + return ffi_str(buf, sizep[0]) + end + + if rc == FFI_BUSY then + return nil, ffi_str(errmsg[0]) .. ": " .. tonumber(sizep[0]) + .. " > " .. buf_size + end + + return nil, ffi_str(errmsg[0]) +end + + +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() + end + local errbuf = get_string_buf(errbuf_size) + + 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) + + if rc == FFI_OK then + return true + end + + -- rc == FFI_ERROR + + return nil, ffi_str(errbuf, sizep[0]) +end + + +function _M.set_ocsp_status_resp(data) + local r = getfenv(0).__ngx_req + if not r then + return error("no request found") + end + + local rc = C.ngx_http_lua_ffi_ssl_set_ocsp_status_resp(r, data, #data, + errmsg) + + if rc == FFI_DECLINED then + -- no client status req + return true, "no status req" + end + + if rc == FFI_OK then + return true + end + + -- rc == FFI_ERROR + + return nil, ffi_str(errmsg[0]) +end + + +local function get_tls1_version() + + local r = getfenv(0).__ngx_req + if not r then + return error("no request found") + end + + local ver = C.ngx_http_lua_ffi_ssl_get_tls1_version(r, errmsg) + + ver = tonumber(ver) + + if ver >= 0 then + return ver + end + + -- rc == FFI_ERROR + + return nil, ffi_str(errmsg[0]) +end +_M.get_tls1_version = get_tls1_version + + +do + _M.SSL3_VERSION = 0x0300 + _M.TLS1_VERSION = 0x0301 + _M.TLS1_1_VERSION = 0x0302 + _M.TLS1_2_VERSION = 0x0303 + + local map = { + [_M.SSL3_VERSION] = "SSLv3", + [_M.TLS1_VERSION] = "TLSv1", + [_M.TLS1_1_VERSION] = "TLSv1.1", + [_M.TLS1_2_VERSION] = "TLSv1.2", + } + + function _M.get_tls1_version_str() + local ver, err = get_tls1_version() + if not ver then + return nil, err + end + return map[ver] + end +end + + +return _M diff --git a/spec/plugins/ssl_spec.lua b/spec/plugins/ssl_spec.lua index c074e2e856e..55b67597844 100644 --- a/spec/plugins/ssl_spec.lua +++ b/spec/plugins/ssl_spec.lua @@ -92,9 +92,8 @@ JkHk9MH9WKKGIchn0LvfUFHxTeBFERoREQo2A82B/WpO teardown(function() spec_helper.stop_kong() - spec_helper.reset_db() end) - + describe("SSL Util", function() it("should not convert an invalid cert to DER", function() @@ -152,14 +151,14 @@ IN2a44ptbkUjN8U0WeTGMBP/XfK3SvV6wAKAE3cDB2c= it("should return default CERTIFICATE when requesting other APIs", function() local parsed_url = url.parse(STUB_GET_SSL_URL) local res = IO.os_execute("(echo \"GET /\"; sleep 2) | openssl s_client -connect "..parsed_url.host..":"..tostring(parsed_url.port).." -servername test4.com") - + assert.truthy(res:match("US/ST=California/L=San Francisco/O=Kong/OU=IT/CN=localhost")) end) it("should work when requesting a specific API", function() local parsed_url = url.parse(STUB_GET_SSL_URL) local res = IO.os_execute("(echo \"GET /\"; sleep 2) | openssl s_client -connect "..parsed_url.host..":"..tostring(parsed_url.port).." -servername ssl1.com") - + assert.truthy(res:match("US/ST=California/L=San Francisco/O=Kong/OU=IT/CN=ssl1.com")) end) diff --git a/spec/spec_helpers.lua b/spec/spec_helpers.lua index 775e4978c0e..9a4f436d109 100644 --- a/spec/spec_helpers.lua +++ b/spec/spec_helpers.lua @@ -213,15 +213,6 @@ function _M.insert_fixtures(fixtures, conf_file) return env.faker:insert_from_table(fixtures) end -function _M.reset_db(conf_file) - local env = _M.get_env(conf_file) - env.migrations:reset(function(_, err) - if err then - error(err) - end - end) -end - -- Add the default env to our spec_helper _M.add_env(_M.TEST_CONF_FILE)