diff --git a/.travis.yml b/.travis.yml index 3f5cf76bf..143a70aba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ install: - git clone https://github.com/openresty/openresty.git ../openresty - git clone https://github.com/openresty/openresty-devel-utils.git - git clone https://github.com/simpl/ngx_devel_kit.git ../ndk-nginx-module - - git clone https://github.com/openresty/lua-nginx-module.git ../lua-nginx-module + - git clone -b lua-ffi-api-sslctx https://github.com/detailyang/lua-nginx-module.git ../lua-nginx-module - git clone https://github.com/openresty/no-pool-nginx.git ../no-pool-nginx - git clone https://github.com/openresty/echo-nginx-module.git ../echo-nginx-module - git clone https://github.com/openresty/lua-resty-lrucache.git diff --git a/lib/ngx/ssl.lua b/lib/ngx/ssl.lua index 89d42a533..5d7795856 100644 --- a/lib/ngx/ssl.lua +++ b/lib/ngx/ssl.lua @@ -3,11 +3,13 @@ local ffi = require "ffi" local base = require "resty.core.base" +local bit = require "bit" local C = ffi.C local ffi_str = ffi.string local ffi_gc = ffi.gc +local ffi_copy = ffi.copy local getfenv = getfenv local error = error local tonumber = tonumber @@ -16,6 +18,8 @@ local get_string_buf = base.get_string_buf local get_size_ptr = base.get_size_ptr local FFI_DECLINED = base.FFI_DECLINED local FFI_OK = base.FFI_OK +local bor = bit.bor +local ERR_BUF_SIZE = 256 ffi.cdef[[ @@ -58,6 +62,39 @@ int ngx_http_lua_ffi_set_priv_key(void *r, void *cdata, char **err); void ngx_http_lua_ffi_free_cert(void *cdata); void ngx_http_lua_ffi_free_priv_key(void *cdata); + +void *ngx_http_lua_ffi_ssl_ctx_init(unsigned int protocols, char **err); + +void ngx_http_lua_ffi_ssl_ctx_free(void *cdata); + +int ngx_http_lua_ffi_ssl_ctx_add_ca_cert(void *cdata_ctx, + const unsigned char *cert, size_t size, + unsigned char *err, size_t *err_len); + +int ngx_http_lua_ffi_ssl_ctx_set_priv_key(void *cdata_ctx, void *cdata_key, + unsigned char *err, size_t *err_len); + +int ngx_http_lua_ffi_ssl_ctx_set_cert(void *cdata_ctx, void *cdata_cert, + unsigned char *err, size_t *err_len); + +int ngx_http_lua_ffi_ssl_ctx_set_ciphers(void *cdata_ctx, const char *cipher, + unsigned char *err, size_t *err_len); + +int ngx_http_lua_ffi_ssl_ctx_set_crl(void *cdata_ctx, const unsigned char *crl, + size_t size, unsigned char *err, size_t *err_len); + +int ngx_http_lua_ffi_ssl_ctx_set_cert_store(void *cdata_ctx, void *cdata_store, + int up_ref, unsigned char *err, size_t *err_len); + +void *ngx_http_lua_ffi_ssl_x509_store_init(unsigned char *err, + size_t *err_len); + +void ngx_http_lua_ffi_ssl_x509_store_free(void *cdata_store); + +int ngx_http_lua_ffi_ssl_x509_store_add_cert(void *cdata_store, + const unsigned char *cert, size_t size, unsigned char *err, + size_t *err_len); + ]] @@ -261,6 +298,120 @@ function _M.set_priv_key(priv_key) end +function _M.create_x509_store(...) + local err_buf = get_string_buf(ERR_BUF_SIZE) + local err_buf_len = get_size_ptr() + err_buf_len[0] = ERR_BUF_SIZE + + local store = C.ngx_http_lua_ffi_ssl_x509_store_init(err_buf, err_buf_len) + if store == nil then + return nil, ffi_str(err_buf, err_buf_len[0]) + end + + ffi_gc(store, C.ngx_http_lua_ffi_ssl_x509_store_free) + + for i = 1, select('#', ...) do + local cert = select(i, ...) + local rc = C.ngx_http_lua_ffi_ssl_x509_store_add_cert(store, cert, + #cert, err_buf, + err_buf_len) + if rc ~= FFI_OK then + return nil, ffi_str(err_buf, err_buf_len[0]) + end + end + + return store +end + + +_M.SSLv2 = 0x0002 +_M.SSLv3 = 0x0004 +_M.TLSv1 = 0x0008 +_M.TLSv1_1 = 0x0010 +_M.TLSv1_2 = 0x0020 +local default_protocols = bor(_M.SSLv3, _M.TLSv1, _M.TLSv1_1, _M.TLSv1_2) + + +function _M.create_ctx(options) + if type(options) ~= 'table' then + return nil, "no options found" + end + + local protocols = options.protocols or default_protocols + local ca = options.ca + local cert_store = options.cert_store + local cert = options.cert + local priv_key = options.priv_key + local ciphers = options.ciphers + local crl = options.crl + + local ctx = C.ngx_http_lua_ffi_ssl_ctx_init(protocols, errmsg) + if ctx == nil then + return nil, ffi_str(errmsg[0]) + end + + ffi_gc(ctx, C.ngx_http_lua_ffi_ssl_ctx_free) + + local err_buf = get_string_buf(ERR_BUF_SIZE) + local err_buf_len = get_size_ptr() + err_buf_len[0] = ERR_BUF_SIZE + + if cert_store ~= nil then + local rc = C.ngx_http_lua_ffi_ssl_ctx_set_cert_store(ctx, cert_store, 1, + err_buf, + err_buf_len) + if rc ~= FFI_OK then + return nil, ffi_str(err_buf, err_buf_len[0]) + end + end + + if ca ~= nil then + local rc = C.ngx_http_lua_ffi_ssl_ctx_add_ca_cert(ctx, ca, #ca, err_buf, + err_buf_len) + if rc ~= FFI_OK then + return nil, ffi_str(err_buf, err_buf_len[0]) + end + end + + if cert ~= nil then + local rc = C.ngx_http_lua_ffi_ssl_ctx_set_cert(ctx, cert, + err_buf, err_buf_len) + if rc ~= FFI_OK then + return nil, ffi_str(err_buf, err_buf_len[0]) + end + end + + if priv_key ~= nil then + local rc = C.ngx_http_lua_ffi_ssl_ctx_set_priv_key(ctx, priv_key, + err_buf, err_buf_len) + if rc ~= FFI_OK then + return nil, ffi_str(err_buf, err_buf_len[0]) + end + end + + if ciphers ~= nil then + local ciphers_buf = get_string_buf(#ciphers + 1) + ffi_copy(ciphers_buf, ciphers) + + local rc = C.ngx_http_lua_ffi_ssl_ctx_set_ciphers(ctx, ciphers_buf, + err_buf, err_buf_len) + if rc ~= FFI_OK then + return nil, ffi_str(err_buf, err_buf_len[0]) + end + end + + if crl ~= nil then + local rc = C.ngx_http_lua_ffi_ssl_ctx_set_crl(ctx, crl, #crl, err_buf, + err_buf_len) + if rc ~= FFI_OK then + return nil, ffi_str(err_buf, err_buf_len[0]) + end + end + + return ctx +end + + do _M.SSL3_VERSION = 0x0300 _M.TLS1_VERSION = 0x0301 diff --git a/lib/resty/core.lua b/lib/resty/core.lua index 71bb94642..8ac51e5d9 100644 --- a/lib/resty/core.lua +++ b/lib/resty/core.lua @@ -14,6 +14,7 @@ require "resty.core.request" require "resty.core.response" require "resty.core.time" require "resty.core.worker" +require "resty.core.socket.tcp" local base = require "resty.core.base" diff --git a/lib/resty/core/socket/tcp.lua b/lib/resty/core/socket/tcp.lua new file mode 100644 index 000000000..1720a908d --- /dev/null +++ b/lib/resty/core/socket/tcp.lua @@ -0,0 +1,67 @@ +-- Copyright (C) Yichun Zhang (agentzh) + + +local ffi = require "ffi" +local debug = require 'debug' +local base = require "resty.core.base" + + +local C = ffi.C +local ffi_str = ffi.string +local registry = debug.getregistry() +local error = error +local errmsg = base.get_errmsg_ptr() +local FFI_OK = base.FFI_OK + + +ffi.cdef[[ + +int ngx_http_lua_ffi_socket_tcp_setsslctx(ngx_http_request_t *r, void *u, + void *cdata_ctx, char **err); + +]] + + +local function check_tcp(tcp) + if not tcp or type(tcp) ~= "table" then + return error("bad \"tcp\" argument") + end + + tcp = tcp[1] + if type(tcp) ~= "userdata" then + return error("bad \"tcp\" argument") + end + + return tcp +end + + +local function setsslctx(tcp, ssl_ctx) + tcp = check_tcp(tcp) + + local r = getfenv(0).__ngx_req + if not r then + return error("no request found") + end + + local rc = C.ngx_http_lua_ffi_socket_tcp_setsslctx(r, tcp, ssl_ctx, errmsg) + if rc ~= FFI_OK then + return nil, ffi_str(errmsg[0]) + end + + return true +end + + +local mt = registry.__ngx_socket_tcp_mt +if mt then + mt = mt.__index + if mt then + mt.setsslctx = setsslctx + end +end + + +return { + version = base.version +} diff --git a/t/cert/ca-client-server/ca.crt b/t/cert/ca-client-server/ca.crt new file mode 100644 index 000000000..c2c4c8468 --- /dev/null +++ b/t/cert/ca-client-server/ca.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7TCCAdWgAwIBAgIJAO8bo8Y6NOllMA0GCSqGSIb3DQEBCwUAMA0xCzAJBgNV +BAMMAmNhMB4XDTE3MDUyNzIxNDYwOFoXDTE3MDYyNjIxNDYwOFowDTELMAkGA1UE +AwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7mHzd9g+5Gthe +h5sr7a6/0JVTw+LtKA08IxRb7LqvHHiKsgoweKo+RomYtYvlNSZkROzJVscd85ND +xja2VfEGQ75Jf01+27pOgT+Gt5ZPVGIzr0KI/R9pWPLHeuWz6HkoLe4KTRJiLnPF +gvDWXKkMaGSTgul4W8PHWk+9ybEG/Tmm+48VlRMFrs1Y32GYsX4dA/CmPPbQeEQh +wIgMMu5NbTebxnK4AJ3sY3tZrm0kzXUePE4gXcj5GQNbnIr5cM2BsUb9QPCf+Ooe +PjBZiS9Ek8vDD+rVwZTVXiiSfWG4/7CJF/vPuoi/BhbsFKrZtqXWUR5MUaVs83mf +9aIDybjhAgMBAAGjUDBOMB0GA1UdDgQWBBT3QiA6YNIPWK5th89XtcHs6jv03jAf +BgNVHSMEGDAWgBT3QiA6YNIPWK5th89XtcHs6jv03jAMBgNVHRMEBTADAQH/MA0G +CSqGSIb3DQEBCwUAA4IBAQBIcwH1BFK/cRc88XQQFEHOkvFLlfPnnHPdLv+iyQ9v +BsoJZVh8lzLFzYLJRRPdyqbBxCwRAna86v7MfwGAEBseH5EnIFsne1iV7o7+wOKx +WY/p+Q4B/fOWVdzxVd7naDIeH00dvhxWP3+E7F2KRJyUUehQOP4XXVy9sVlny/U+ +kloGu4i/k5y4wkn+kdmO9buH5hPEbaLv7Ud2A6J5brvqhktT1UIeA+jBycz0a5kH +h3x3DLq6+eeE8WuI1vLtPDJIAQXvSlKss3IpXcRf1r6kOtec6rpyjRtCGobL1CxV +QWWNRRLGjMRZSMlQAgp3QAmWbIvpKxxLwkEJUCtuujuR +-----END CERTIFICATE----- diff --git a/t/cert/ca-client-server/ca.key b/t/cert/ca-client-server/ca.key new file mode 100644 index 000000000..da7e22cb8 --- /dev/null +++ b/t/cert/ca-client-server/ca.key @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIEjDowCzAg4ACAggA +MBQGCCqGSIb3DQMHBAh3lw0oluucPASCBMgFFN7lYaWHeb7Hv7f9+zc2kD0k1sgV +S6N1uHwAxrhYouFqrYI2wtvs+8ow4oefTUU9gTyouQXzhoykHFaSJw3FixbeQB56 +Jk/5X9Raq7zLZvTapkINWUE3q2ZOpzfXPlyCw9GkVjYhUSM2S0O+sKl2lco2SsNS +T7Vb8lNLaIJs8IMg+yDpGquoEMh3rQ4dywOuQ2to8/bxJYXo8o3L3lciaLTCGVCn +SOkjX6sUuFZJ8hR527z9u7/W4W2/HN0zRcGpyCDEswJGrDVV+b5nqHvy8KN3Yu5e +dwUErUvQmOpbDog9C+aNgtVHcD46rt21v9/FnQ/hEFNMx515lZVuH69BlaHWikUg +6QmUPAw7xb6kMgeVntFadPEMBghbqEXZtgXWyV8bxUggRRcE+pGphYcotMfx+6dR +JF6BBqo0dTlhPzzCqoV0wlumnnMbNwUSRlRsg25D+WC8dz5O0kj1Pv5HW/ccmiyx +8warzJlxGUSlz1wnysQ+Irgw11/ZnH3hcAywDP/8Jai2Mcml588KLm9QuPCS2F3d +QUmX9i7lYz3rJO0uNkC5eLrzB/LGRHFsvdxWUgUXh1HBweoJUN37CXY5UC7NQclA +xPI7Ocea3HgPChZ7/y9P0mVVEp9gFIpD5+uVb9GSR+zRv9y0aA8NrFyPWI+IBZdG +QDdC37LXjooueYXgDNMGsulb1UXOkUol2+UCxYiq12wjJ1eo3kfezswGCm7sSfl8 +7hve78KeaoJwFFJTgDKY5O8xZMbKDl1SMcfsZT/z2yu4tmIXlDUq3iLaWy1u2Spt +tUa8fsGOkP+bprsFVQIyJO1cg9nrd2FLei5wkQZWDGq5nTjJfIDO4cUJx+vlGDQP +AWh8qy1CNRQoFwZ/xrqqwYiO8nZv64FMweVun2R96PvnoaD8hB1pfTfQ6kg7q8lg +uNQvTgCfiF+6dR3KFOf29GpxGqGsvBe89k5EVOW2nmxvBoPb/VKXOC8zEcRvn71n +dgrEK0nd/AhGEdvnIR1RT3+42Hae50XV8sF1tX8ODNgPCON4f3qECe5F1RTVJdx0 +ZG/Jab/zOA1n1GyOqVSMWWZFIbKLt0U+XAhIO1HWruvgBDiMVxqk0cfjbMPFtD9n +yPHQPAMLZy7gqa96UD3BdS2YPSxJhLUqBtqaHwC4tU+LRoTBpC/Uiv6Ee5ZF2/OE +EnXSlCaPzzgW3KcPlf5q9/b4YikqSPVo3G76ouCdyHC/XA6uwd1ik2SpVQlZddth +rQra+UcQs6000hg1VP4yPOz/R5Jsd2GT+eA2ziYLKr959Lh32iBK+pnepWxdgW/y +jAHvfh9ysyUYUyGTIMQuMZ87r5DrsGcOoWIyuQeqFehlFze1RxGn0e7/ZcIUJhI3 +dnPFPpM9uGnNMpK+qzewj+zLBtVJ4rZJ5x81A65cSXL389aHOTuRxrqK7K0Vslk9 +EWmAd+XcuKEXnhWMtrugm9zxlEWbJzVDsX7IeR3kd5ewajTeOmS/fV8D5K57JQhH +YhlITCOHTWeUz68IQ2Dwb+XvmFM+Ijqp0YJq0cxOXy9ieuhbAjpG15P2xYmib9J6 +4WivnLS8srLkumTmMmTng3HCVHiJTxvsELJBWBYvegrQiCo5MYZEs8ql3N17XNXW +0io= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/t/cert/ca-client-server/ca.unsecure.key b/t/cert/ca-client-server/ca.unsecure.key new file mode 100644 index 000000000..f5629b2f8 --- /dev/null +++ b/t/cert/ca-client-server/ca.unsecure.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAu5h83fYPuRrYXoebK+2uv9CVU8Pi7SgNPCMUW+y6rxx4irIK +MHiqPkaJmLWL5TUmZETsyVbHHfOTQ8Y2tlXxBkO+SX9Nftu6ToE/hreWT1RiM69C +iP0faVjyx3rls+h5KC3uCk0SYi5zxYLw1lypDGhkk4LpeFvDx1pPvcmxBv05pvuP +FZUTBa7NWN9hmLF+HQPwpjz20HhEIcCIDDLuTW03m8ZyuACd7GN7Wa5tJM11HjxO +IF3I+RkDW5yK+XDNgbFG/UDwn/jqHj4wWYkvRJPLww/q1cGU1V4okn1huP+wiRf7 +z7qIvwYW7BSq2bal1lEeTFGlbPN5n/WiA8m44QIDAQABAoIBADMPaD1J8jGh2u6v +3k5wnTXcYiiwkp2WXzPVIH98ybtL9otZtmhHD59vt5f3IiK6+r4j/Ic4tW2zlIvH +8bBjZ/0ahzqeCcvTprwjddUHN0RUZX5H38ZFjz0vVrVxAACd8Aw9pCLto2lR13UV +FNRj2Cdmaqmz4jQ+VeV28Wlo8mRCJQnEXXr4P78lxPqaWYE8CTh+Xw7PdyaAaMTz +I1uZCVeNhaks9SABXdCU2vAgSS9OtDco3QAHbkOfJAhuxPDygDOBDXuD6Cjno246 +ChND68PdTjTa3Itn9M0/KsaWQAwUQjp0chlp7I318ukGFGt4FI/2P5mbJy2gNLp/ +0v8tQAECgYEA4jZJQKtK++14CJPj0GTjRs70JxbkLLvyE2OYzeimJTFhwg+e39uM +fiHbuUfX506VOLalsxJIgO0qvhFlvm3sWBPzIZREQjl5SYjeOcemV038cm/T8MxE +s0VtCceGQVENld9Zw3lJg5JYEkVbNVrnveUF8R0siZtRTPer4Eheh+ECgYEA1Exs +vdlQy9+PxiupgSKBHSYrsWAQ3F1DaNZTAafV2W7XAHV4dCoAXlXQst8wUKCwy2AG +JHE+uVmb5g9rVYTHwA5JvgO7gH41vdVjv2JpaoXNeziGf2o8150lRdxficTo24G4 +wjL260lKCK80zYEnmN2mOlxepX6w+uBsPGwNUQECgYEAgw2QQrb6KhnZgJ6tTP4l +7c/YAw1wA7qe9DyvOhuepc2GJTeHg4leS3SyJxVIL+mG6eRm+ueMuaStLpBFsZ1d +X2mvYbTUFsnVSpTQqgjQhaPYrTO8RbUR2ApQsWm2jgC3LizHhEewH1mZTHyB6tdP +iuQ0HQwZ0V76Ku0R1k4W9gECgYBnOp4pllD2QUfMyZBLbXawsM3QGvE35dWQVZ7Z +ED4o0v+ShoxCl+XD+SBYybPZkLlGuvNhpvsj71GiBV9gnwbt+UScM35p1XTWULuG +5RhzJoqq3upvbD4XbZ8hIC4IdInxqlsnetabw/BO1rrrLmENsMFSYXXYLQlrg9K9 +cqDrAQKBgBTzs/jwX3cVdc+lOxTqJ7FdSTJ+RAZx1oD9ZQxrnG+ELYAo964Xp3iO +XhDTthN+PkDoBlLi/fikyhMCHSZjmcHBP+E+XteRKs4Sm/Jfc+gKs8IYfrR7j1z2 +jeo/Nc/CCyNnyPmZ3yRiDasCbZDZntrlLFlmfxjg3MvBKLZlTJVl +-----END RSA PRIVATE KEY----- diff --git a/t/cert/ca-client-server/client.cer b/t/cert/ca-client-server/client.cer new file mode 100644 index 000000000..2bd437134 --- /dev/null +++ b/t/cert/ca-client-server/client.cer @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAc4CAQEwDQYJKoZIhvcNAQELBQAwDTELMAkGA1UEAwwCY2EwIBcNMTcw +NTI3MjE0NjA4WhgPMjEwMTA0MjcyMTQ2MDhaMGMxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRYwFAYDVQQK +DA1PcGVuUmVzdHkgSW5jMQ8wDQYDVQQDDAZjbGllbnQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCyeiP+hYpqsoFsD6vQ5UT4CZOIg+vy15G8SacwMZOs +pOSnREYBtdZqmC64HV54chD2UQYnyBDbXZKd89//jAqCbwdadwKX9DtyLMTnZ7i5 +xhYxkMRWKEKrPkFQwbLlNGXkJzhkwYlJ+JX8M/wbHTn+sg2r1/G2uY9bjp68kpcm +dKHqm6ue7qEFaNrnX7G2nfXuCWImWsO0OvpRaanHMVR3cChAb/kfB/NMhwAOZjCt +UrggbMaW5zPGFl8d86iMLLrDoM1nzzb4vm4T99blDJPiq5XarDIHe+F+vuhEKZyF +v1w83Z2L/dM5sgDdViptaxk8CHb7xSd+VvWi1DxKjyIpAgMBAAEwDQYJKoZIhvcN +AQELBQADggEBAEXHdn0CGB7Lb3IAgbIXAbxT/ffSRS0OlE6gpI2szFH1g6REsEvl +oghATvdlZ5qCO3YumBmv05fAV5kw6GC3cdl9EW7BM1eHQXihxnOrJKz0etCZHabY +zW8LtDywLa0oMgBO6ob4WofiJ/Axh6rCksOvC7OuquNVj7mYjmQnz/OvQJpq90LJ +EyQ5WAY4Qx8g12feJwsNj20Vv/c30X6sFA9PcRinyMmDZzMoRuYmu596O8FCTIoF +kdXiBCRGMtgySSZS+RNWICtat3JmnNau9Ku//4WFJ4i/SlJ+uMwaBqsIPrz6dPbo +7twC0LkAtMeAfrp07hn4aoBWXBFeUlsLNfo= +-----END CERTIFICATE----- diff --git a/t/cert/ca-client-server/client.crt b/t/cert/ca-client-server/client.crt new file mode 100644 index 000000000..2bd437134 --- /dev/null +++ b/t/cert/ca-client-server/client.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAc4CAQEwDQYJKoZIhvcNAQELBQAwDTELMAkGA1UEAwwCY2EwIBcNMTcw +NTI3MjE0NjA4WhgPMjEwMTA0MjcyMTQ2MDhaMGMxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRYwFAYDVQQK +DA1PcGVuUmVzdHkgSW5jMQ8wDQYDVQQDDAZjbGllbnQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCyeiP+hYpqsoFsD6vQ5UT4CZOIg+vy15G8SacwMZOs +pOSnREYBtdZqmC64HV54chD2UQYnyBDbXZKd89//jAqCbwdadwKX9DtyLMTnZ7i5 +xhYxkMRWKEKrPkFQwbLlNGXkJzhkwYlJ+JX8M/wbHTn+sg2r1/G2uY9bjp68kpcm +dKHqm6ue7qEFaNrnX7G2nfXuCWImWsO0OvpRaanHMVR3cChAb/kfB/NMhwAOZjCt +UrggbMaW5zPGFl8d86iMLLrDoM1nzzb4vm4T99blDJPiq5XarDIHe+F+vuhEKZyF +v1w83Z2L/dM5sgDdViptaxk8CHb7xSd+VvWi1DxKjyIpAgMBAAEwDQYJKoZIhvcN +AQELBQADggEBAEXHdn0CGB7Lb3IAgbIXAbxT/ffSRS0OlE6gpI2szFH1g6REsEvl +oghATvdlZ5qCO3YumBmv05fAV5kw6GC3cdl9EW7BM1eHQXihxnOrJKz0etCZHabY +zW8LtDywLa0oMgBO6ob4WofiJ/Axh6rCksOvC7OuquNVj7mYjmQnz/OvQJpq90LJ +EyQ5WAY4Qx8g12feJwsNj20Vv/c30X6sFA9PcRinyMmDZzMoRuYmu596O8FCTIoF +kdXiBCRGMtgySSZS+RNWICtat3JmnNau9Ku//4WFJ4i/SlJ+uMwaBqsIPrz6dPbo +7twC0LkAtMeAfrp07hn4aoBWXBFeUlsLNfo= +-----END CERTIFICATE----- diff --git a/t/cert/ca-client-server/client.csr b/t/cert/ca-client-server/client.csr new file mode 100644 index 000000000..07c10f146 --- /dev/null +++ b/t/cert/ca-client-server/client.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICqDCCAZACAQAwYzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx +FjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFjAUBgNVBAoMDU9wZW5SZXN0eSBJbmMx +DzANBgNVBAMMBmNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALJ6I/6FimqygWwPq9DlRPgJk4iD6/LXkbxJpzAxk6yk5KdERgG11mqYLrgdXnhy +EPZRBifIENtdkp3z3/+MCoJvB1p3Apf0O3IsxOdnuLnGFjGQxFYoQqs+QVDBsuU0 +ZeQnOGTBiUn4lfwz/BsdOf6yDavX8ba5j1uOnrySlyZ0oeqbq57uoQVo2udfsbad +9e4JYiZaw7Q6+lFpqccxVHdwKEBv+R8H80yHAA5mMK1SuCBsxpbnM8YWXx3zqIws +usOgzWfPNvi+bhP31uUMk+KrldqsMgd74X6+6EQpnIW/XDzdnYv90zmyAN1WKm1r +GTwIdvvFJ35W9aLUPEqPIikCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQAzXOCe +MYTJrWkTi7OLAOq4RfLrz0EC+k/PS3VwifJi2j3SDD5b+oL3+8ZCr7RK0UvYSJ8H +zMAzc8Cig/8wZRJSRYs3gXYaDjVeAVDti0/mg0BJVhMvksAoswhcquitXdchvw6B +mYIMMTgQkInZUN39oLZiXBqj2urlW+8UHV0w3rWAlS7o2AILu+vcvFtcy+E//2F+ +0RDghpRGF3djAtl29MDpoPzrEroo1oV38/sRfD+TbS4YoMcXPBC2TKchaTQNxlO3 ++6vnjDYLXgQM0dVs5j1EaDVNz7ZUP7SFapV/2Hd5KZL6ZMAZ+e+xR7b6pFF416Si +bDMMjfWOv7hKkafa +-----END CERTIFICATE REQUEST----- diff --git a/t/cert/ca-client-server/client.key b/t/cert/ca-client-server/client.key new file mode 100644 index 000000000..f06b48708 --- /dev/null +++ b/t/cert/ca-client-server/client.key @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,473429D543CEAD77 + +EmFlzvrxaD0EyCASkIGiW6/hhLB1/yZr+O61dBPQ8rkbluXXlwCfxWDgNpelGpVq +fdACt0CdwkAiGoBfu889X1wd+rn9y028mgoXNgF7/NRbP4UL4+/bZ5YX4RwXtts8 +mwRIyV2Fq90g+AoL/7DfixJn+VcAq8AbFjE2fkS/TysaHAoafS/hn6Wv+2EhfGgS +VnezTgZFOYflRxVxCooiL8Kc/EonJIPar5iRRPADZa1p3HOOqTEIKyxg8eH7M/sV +mrfC8myoKYGqckOUrZaVtDh3zbDkn1RUZ2eoZTX8fiTUHq1CZy4KAf4DeNKJH14C +rmpRbachRBm1KjpmPGk9OqFk7YMQJSU1GbKgOcFpdhCmZ9yyQgQtVtla5SF0aT2s +yr0Vg5bRRT9wGmKRjbhTt3r6g5BLVYEjOANEtcdNsbvOWuI26ZzBrmimjBGwVULV +rcaYX7NEHroNQ3XF8XRhR7zja0bjgBXFOod9tNZv0HxN9rMB+wX7ychOzoA9E0hN +O/Orcg/2I6yLpSck/pZn6E8m3k2Uvw5VEcdnfYTDEkbFeSbZBwtqwKaCJiGz7Z/x +a+UWQJys4n+sLKpx1m9gIho6b6MVIXvLgCayEVUF5I6jdCTNvxpZesEgc7UFy9DZ +majP7T4KZj2rH4OEv1eQ7OAFfMKVycaJSzoFa1Fs7XgQY9lDUvo/ua3sXoMyIWhh +FXMtCzkkqjRJ+myX9hfU1W2qgkjQ57CnrTbyoIE699dCNEYlW88jtV2hQxZud9M5 +m4mj1fdFZlDPgFo20b5MFv4j7nUnpv7nC2xzp+nCQe179UqwIIKbI/2YgzRaCN7Z +nWSDLIFOGHqTTWN5L1lrO5ZvhT+hgu+BGJErfACGdtX8Gpxg68MgETAoCcw6qpBy +8tERCylsEiOkXB1PIoe7TEbwZnSQ0LUGwH9XYxGeX/8Cgt+DPdg43MkF8uMOl4cg +Th9NXjv1p54Dz1998NQmbMercg/BKVA4+QLoQC/ZfOSeYsphklGt73gCDlYAz3Qr +8istSa6BkK/d0i/Zbt4l2CPbvOoIo2b7wPsGawIqa6xN3T188OlfCBQRP2V5doYM +YhNS8DtfaRxrBaDCiPVRwp4LpTcg3yG9zX1/lhwYWGcUAHXdn6oDQJQfUqUSRT4D +3uDdWkldjaM6dkoywuP0tOP8RQTxYUqLzFNs2k64lYFj8+2FkKBcxbr1Ltu1NnUj +pV8w9atgTXY3pQA2llSbhcQ3naygPD7/gAndDXQqakhZjWNaHb+t9afPg25Yp/h1 +f0Mbv9+80FzApVypcBc+g4uei9YZz36JjWATlAW1+74+3/WeKxKqR28JzsPSrICD +OYq3jNQccvHiThB79aUym857+XYkp+YrAgOPyuyf8W1KsaQMtkDwT/drEOBQ/uFm +rZMBfZusyY1iOcOUSstNAnsZPRZsOaY9mHsF/ZLWhvY01kNivO2g7xcQhz3ONO9f +h0M8kv69+9byn85bGTCtOkNuPks0Ju6HYoBEf6NsAvnN6YuVvNfouoC52cgDE1c5 +f9TTY5BI80tfXS8e/lED9f6Su85it8WSWwfM7Ia9CFrvaEWk6zpMBgrYtN8ehMgJ +-----END RSA PRIVATE KEY----- diff --git a/t/cert/ca-client-server/client.p12 b/t/cert/ca-client-server/client.p12 new file mode 100644 index 000000000..74ce2cd0a Binary files /dev/null and b/t/cert/ca-client-server/client.p12 differ diff --git a/t/cert/ca-client-server/client.pfx b/t/cert/ca-client-server/client.pfx new file mode 100644 index 000000000..586fc3551 Binary files /dev/null and b/t/cert/ca-client-server/client.pfx differ diff --git a/t/cert/ca-client-server/client.unsecure.key b/t/cert/ca-client-server/client.unsecure.key new file mode 100644 index 000000000..447c15713 --- /dev/null +++ b/t/cert/ca-client-server/client.unsecure.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAsnoj/oWKarKBbA+r0OVE+AmTiIPr8teRvEmnMDGTrKTkp0RG +AbXWapguuB1eeHIQ9lEGJ8gQ212SnfPf/4wKgm8HWncCl/Q7cizE52e4ucYWMZDE +VihCqz5BUMGy5TRl5Cc4ZMGJSfiV/DP8Gx05/rINq9fxtrmPW46evJKXJnSh6pur +nu6hBWja51+xtp317gliJlrDtDr6UWmpxzFUd3AoQG/5HwfzTIcADmYwrVK4IGzG +luczxhZfHfOojCy6w6DNZ882+L5uE/fW5QyT4quV2qwyB3vhfr7oRCmchb9cPN2d +i/3TObIA3VYqbWsZPAh2+8Unflb1otQ8So8iKQIDAQABAoIBAQCotANqBti72lez +yWxjXRRAUOz/0ZMqTNIY5JYAXBx2yLbJ1SNHYpZ207r1le1CdK/L5PKoj9g/Qsfg +PjGx4LHecQzGWlA9SkMWvXKyObzG/ZLk7y5nMk8yhvo+V5m+RjU54EjSFI6tOSis +6IaZKpszQSLjGJAGZIg5xyoMnZP6aBfW5uPCIfV+KY5ioDAiK3rwu5j4Kbye6Xw/ +clU4UXO1gLHvd1KRkinAjQ58eWoeXxIpBrgYRArfU0i2oOzA0VB7DFXDVyDeMGWC +0VmcVIf5tFOKSzruKiIB5NJzjNxUEP2zRBC83QIQVM8ts49U1wiiMRgQ4pLoHAkd +6fiZFHIBAoGBAORyVpsPoj77pzsc+BWkz1WPIpeMhpVqZif0/vRDMxoodsBXMLJc +g64mH9Kc4s84KaSs+ULDcE8QqmPQeMXCK3KIQoV9mEzu5OjreFpcexAVTAQmBTr9 +wwMaw6OPoYA1y1w78G2qyeFBsAsnDBymKlEBR8F3y6GmkUTMmruJmAFZAoGBAMgA +6XYEQevIM8tpnGlcwXbHxhrFuKe3DYXn61e64M3kgL1BOysmqzvufKukwbAkLNN6 +wPyEBU2HKXb9GrvFZrA0PZCQyJeZE6yE9HeqrW7Ii5mUZAeti+gLQNu0hJtTMANb +r3bKHqzvGkcHfWRHM7NpxgF+59Yq47AJCqWFOL1RAoGBAK+DBPTnAwEeuPHapOOE +FuMmMC59AZ1j/I5wVTz3MBjFw86sbjZqi6TNl59pd3w7Kwtg9bSMkQm9xRsgvNk6 +/8Rj2a/TuaJJ3EbzOik6ajYGFrwNNfGHqz8EXhCYtjzZl58KUgL/t1C/9e/rlQuh +wlsv/6AtWJ6eaXeRNsQkx0spAoGBAJUFUO51R6Tl2+nBPCCpUyEswufp0KduVi4i +2pDYlm3yxxW8h9ikDEwwa0X9EbArlBbSzP6ZY9YbUoLtHcEw2U2K7yBLMJr8HNOb +kQek7WqxFIsPLOUnoyn3UJEjVPbiqdCmvPtWqDqUQVERPJW+E8CnnDg7FYTXGiVs +5zjjJZ6xAoGAF6kcrtg4P7OvsXG96wfPHATo7Z15Jx266cVYduCqoK8jJ7WTRkPS +SVa0CNqwKZjiCXbsIYMx4tASP2339+/oGPAkBCUqHM6aEqLQlUxqbIlSWbdzDOlA +EYRmhx/gYjwl0mm6Sd+SWS4boY86sq0J2c1jVRLRtv26ZrPZNews8hs= +-----END RSA PRIVATE KEY----- diff --git a/t/cert/ca-client-server/ecc-server.crt b/t/cert/ca-client-server/ecc-server.crt new file mode 100644 index 000000000..92963f20d --- /dev/null +++ b/t/cert/ca-client-server/ecc-server.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICHzCCAQcCAQMwDQYJKoZIhvcNAQELBQAwDTELMAkGA1UEAwwCY2EwIBcNMTcw +NTI3MjE0NjA4WhgPMjEwMTA0MjcyMTQ2MDhaMGcxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRYwFAYDVQQK +DA1PcGVuUmVzdHkgSW5jMRMwEQYDVQQDDAplY2Mtc2VydmVyMFkwEwYHKoZIzj0C +AQYIKoZIzj0DAQcDQgAEAbsNz8EIQQpLS6iPEoNzNFVYJookgePmDkU9VdnJ+jBR +G2xOYcd6dTY+rABVW8EJmm/XCefdpmz8VQafthp3zzANBgkqhkiG9w0BAQsFAAOC +AQEAK/ixrarrfx7WJguNKdtB1Cr0RDiWxBNIZ//p2xnv9m9J6JRDzpkLgt1lAFlu +YBFXE74w42XOqFkUzgSU0NKSpidIqyfiJfjgUrUSpS81E3ZvNi75Awrfr53kwxo9 +65VUD2cXwkDcx8Zl/SLgcotBaCALg6zB3QTiPZHqvTpUJEtDA87r2c6HblxlzSyH +6G7JWElV/wN1BAv1se7NnpCmrZrzh3FCThqxC6HBJHDBHk+qrGEx1ksk+tguIvy5 +7OiRaAzvWsD7TtmTl2Bi6IbJ24GhI6FkBfn45HV3yiQMSNUu6LlZdRSEOpq7RRA9 +/4O7q+86nZKGku19MscU8UtjOA== +-----END CERTIFICATE----- diff --git a/t/cert/ca-client-server/ecc-server.csr b/t/cert/ca-client-server/ecc-server.csr new file mode 100644 index 000000000..4a34168a8 --- /dev/null +++ b/t/cert/ca-client-server/ecc-server.csr @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBIjCByQIBADBnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEW +MBQGA1UEBwwNTW91bnRhaW4gVmlldzEWMBQGA1UECgwNT3BlblJlc3R5IEluYzET +MBEGA1UEAwwKZWNjLXNlcnZlcjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAG7 +Dc/BCEEKS0uojxKDczRVWCaKJIHj5g5FPVXZyfowURtsTmHHenU2PqwAVVvBCZpv +1wnn3aZs/FUGn7Yad8+gADAKBggqhkjOPQQDAgNIADBFAiEAu4VpDBYzdYzzsKJ8 +r/Rg91VQw0Mx+NlPWfSiZDGUfCkCIEzcGJ9cs+gqK9r58nc69iyQU+ZRX2eIgtfg +i9ZkDlje +-----END CERTIFICATE REQUEST----- diff --git a/t/cert/ca-client-server/ecc-server.key b/t/cert/ca-client-server/ecc-server.key new file mode 100644 index 000000000..4ebacd17b --- /dev/null +++ b/t/cert/ca-client-server/ecc-server.key @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIDONg16zBG/jKn8/BgDm3mEgkf0WPAn9H2fjXjeluN9+oAoGCCqGSM49 +AwEHoUQDQgAEAbsNz8EIQQpLS6iPEoNzNFVYJookgePmDkU9VdnJ+jBRG2xOYcd6 +dTY+rABVW8EJmm/XCefdpmz8VQafthp3zw== +-----END EC PRIVATE KEY----- diff --git a/t/cert/ca-client-server/generate-cert.sh b/t/cert/ca-client-server/generate-cert.sh new file mode 100755 index 000000000..843a9d2c4 --- /dev/null +++ b/t/cert/ca-client-server/generate-cert.sh @@ -0,0 +1,40 @@ +#! /bin/bash + +cd "$( dirname "${BASH_SOURCE[0]}" )" + +SUBJECT="/C=US/ST=California/L=Mountain View/O=OpenResty Inc" + +PASSWORD=${PASSWORD:-openresty} + +# Server key、no password key、csr +openssl genrsa -des3 -passout "pass:$PASSWORD" -out server.key 2048 +openssl rsa -passin "pass:$PASSWORD" -in server.key -out server.unsecure.key +openssl req -passin "pass:$PASSWORD" -new -subj "$SUBJECT/CN=server" -key server.key -out server.csr + +# Server ecc-key、csr +openssl ecparam -genkey -name secp256r1 | openssl ec -out ecc-server.key +openssl req -passin "pass:$PASSWORD" -new -subj "$SUBJECT/CN=ecc-server" -key ecc-server.key -out ecc-server.csr + +# Client key、no password key、csr +openssl genrsa -des3 -passout "pass:$PASSWORD" -out client.key 2048 +openssl rsa -passin "pass:$PASSWORD" -in client.key -out client.unsecure.key +openssl req -passin "pass:$PASSWORD" -new -subj "$SUBJECT/CN=client" -key client.key -out client.csr + +# CA key、crt +openssl req -passin "pass:$PASSWORD" -passout "pass:$PASSWORD" -new -x509 -subj "$SUBJET/CN=ca" -keyout ca.key -out ca.crt +openssl rsa -passin "pass:$PASSWORD" -in ca.key -out ca.unsecure.key + +# Client key、Server key、 ECC-Server key +openssl x509 -req -sha256 -days 30650 -passin "pass:$PASSWORD" -in client.csr -CA ca.crt -CAkey ca.key -set_serial 1 -out client.crt +openssl x509 -req -sha256 -days 30650 -passin "pass:$PASSWORD" -in server.csr -CA ca.crt -CAkey ca.key -set_serial 2 -out server.crt +openssl x509 -req -sha256 -days 30650 -passin "pass:$PASSWORD" -in ecc-server.csr -CA ca.crt -CAkey ca.key -set_serial 3 -out ecc-server.crt + +# Client p12、pfx +openssl pkcs12 -passin "pass:$PASSWORD" -passout "pass:$PASSWORD" -export -clcerts -in client.crt -inkey client.key -out client.p12 +openssl pkcs12 -passin "pass:$PASSWORD" -passout "pass:$PASSWORD" -export -in client.crt -inkey client.key -out client.pfx + +# Client cer、Server cer、ECC-server cer +openssl x509 -in client.crt -out client.cer +openssl x509 -in server.crt -out server.cer +openssl x509 -in ecc-server.crt -out ecc-server.crt + diff --git a/t/cert/ca-client-server/server.cer b/t/cert/ca-client-server/server.cer new file mode 100644 index 000000000..dc4cfbe79 --- /dev/null +++ b/t/cert/ca-client-server/server.cer @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAc4CAQIwDQYJKoZIhvcNAQELBQAwDTELMAkGA1UEAwwCY2EwIBcNMTcw +NTI3MjE0NjA4WhgPMjEwMTA0MjcyMTQ2MDhaMGMxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRYwFAYDVQQK +DA1PcGVuUmVzdHkgSW5jMQ8wDQYDVQQDDAZzZXJ2ZXIwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDByBisoJSrhiGjzVbrthgDoE4lD1T4N4js7m41D/RY +wUjeRU4GDt87st6oOv5/5QDeSJbF9SP4OnCMzVp8YXxNV5RB6+04w0p4K3FVhAdy +rrFhHNzSPGSm9iRffgyI1q/m6eTnlgizenUB1BMOD+Tc5tnSfvnnNcrHcesYWHnr +/GNR0yn/smoeN6557LgV+pvP5OZ//27+9eD8y8/zK4Z7Da0vMZ/p3qfu4OnNQhv8 +grBWhQ3XwRMs5zw2mXIwwynC/68+l9SMqT9Glf/g8dwKzy0k8QJZNH84JbmbufkV +4Wam0ATqe++b52LZzvFaAl6SZW0nWNb6jzUsYkgz1A0fAgMBAAEwDQYJKoZIhvcN +AQELBQADggEBAIkajUIN3rrmRsRwezhew6ooeguxzjL0q8Bqc/bvshKwuKu7RTdu +fqgiv6TqX+6GVD4C8wQflwMnILykIMq7cHjI3JaWec9jUOAqaF2eVY6LqfPL2KhS +NfQUaNNJ2dE1CWsqjQ/F2IMppybDl0/0r/RJLG8NeV0iEPYCLvcPr+zvy1UYVjFU +2h7qQyALYzvv785LWnhmH9G2Z9N5ngX/JhTieUr10q8F3BmCgo9u4pdcqpTMeN++ +0aRUue+Js7RttP1rP9l5lJgOhaNddPVp6gy3/GGMqhOO+oFRtT9WMydaCGJVsyRg +h79zgwwwW9Lr+SgVFrRTq/wsXR01TWUJ++Q= +-----END CERTIFICATE----- diff --git a/t/cert/ca-client-server/server.crt b/t/cert/ca-client-server/server.crt new file mode 100644 index 000000000..dc4cfbe79 --- /dev/null +++ b/t/cert/ca-client-server/server.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAc4CAQIwDQYJKoZIhvcNAQELBQAwDTELMAkGA1UEAwwCY2EwIBcNMTcw +NTI3MjE0NjA4WhgPMjEwMTA0MjcyMTQ2MDhaMGMxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRYwFAYDVQQK +DA1PcGVuUmVzdHkgSW5jMQ8wDQYDVQQDDAZzZXJ2ZXIwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDByBisoJSrhiGjzVbrthgDoE4lD1T4N4js7m41D/RY +wUjeRU4GDt87st6oOv5/5QDeSJbF9SP4OnCMzVp8YXxNV5RB6+04w0p4K3FVhAdy +rrFhHNzSPGSm9iRffgyI1q/m6eTnlgizenUB1BMOD+Tc5tnSfvnnNcrHcesYWHnr +/GNR0yn/smoeN6557LgV+pvP5OZ//27+9eD8y8/zK4Z7Da0vMZ/p3qfu4OnNQhv8 +grBWhQ3XwRMs5zw2mXIwwynC/68+l9SMqT9Glf/g8dwKzy0k8QJZNH84JbmbufkV +4Wam0ATqe++b52LZzvFaAl6SZW0nWNb6jzUsYkgz1A0fAgMBAAEwDQYJKoZIhvcN +AQELBQADggEBAIkajUIN3rrmRsRwezhew6ooeguxzjL0q8Bqc/bvshKwuKu7RTdu +fqgiv6TqX+6GVD4C8wQflwMnILykIMq7cHjI3JaWec9jUOAqaF2eVY6LqfPL2KhS +NfQUaNNJ2dE1CWsqjQ/F2IMppybDl0/0r/RJLG8NeV0iEPYCLvcPr+zvy1UYVjFU +2h7qQyALYzvv785LWnhmH9G2Z9N5ngX/JhTieUr10q8F3BmCgo9u4pdcqpTMeN++ +0aRUue+Js7RttP1rP9l5lJgOhaNddPVp6gy3/GGMqhOO+oFRtT9WMydaCGJVsyRg +h79zgwwwW9Lr+SgVFrRTq/wsXR01TWUJ++Q= +-----END CERTIFICATE----- diff --git a/t/cert/ca-client-server/server.csr b/t/cert/ca-client-server/server.csr new file mode 100644 index 000000000..2afb5d0d5 --- /dev/null +++ b/t/cert/ca-client-server/server.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICqDCCAZACAQAwYzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx +FjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFjAUBgNVBAoMDU9wZW5SZXN0eSBJbmMx +DzANBgNVBAMMBnNlcnZlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AMHIGKyglKuGIaPNVuu2GAOgTiUPVPg3iOzubjUP9FjBSN5FTgYO3zuy3qg6/n/l +AN5IlsX1I/g6cIzNWnxhfE1XlEHr7TjDSngrcVWEB3KusWEc3NI8ZKb2JF9+DIjW +r+bp5OeWCLN6dQHUEw4P5Nzm2dJ++ec1ysdx6xhYeev8Y1HTKf+yah43rnnsuBX6 +m8/k5n//bv714PzLz/MrhnsNrS8xn+nep+7g6c1CG/yCsFaFDdfBEyznPDaZcjDD +KcL/rz6X1IypP0aV/+Dx3ArPLSTxAlk0fzgluZu5+RXhZqbQBOp775vnYtnO8VoC +XpJlbSdY1vqPNSxiSDPUDR8CAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQAwuIaH +x5EKFMOoS5ONbXMtrMZh3NM/jiS93P9ZuR8RmcOv3ebTXAvsEmXtAK+k+/gwnotM +yIw2yRyUXD4Fos2eLuubv2Y4HBPKgfcPTfCJqap4xKIGRyab9Ri6XqFxgTr46NG5 +LqqpG6+MkZDHVtDbyjMkeEElkrX/1lA3VXoxoEXZxZB4pbL0wQvLQaBt6PkVin3z +kpnq2+20BbYWBDQ/wCgYhm7lIUjQqWH/ReZpyHIUiFziPNpjKM+U+tvrLDQuHgmr +yDGHZ7oRxUrjNlabroj7GJg08KIJV5GsNfkNEwfA6LaX88Q9N1Ifhxb4CJPMo+Pq +yPesFkS0ulHaOsKZ +-----END CERTIFICATE REQUEST----- diff --git a/t/cert/ca-client-server/server.key b/t/cert/ca-client-server/server.key new file mode 100644 index 000000000..440754d2a --- /dev/null +++ b/t/cert/ca-client-server/server.key @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,1CD6CA20A16EDE9C + +XnM7NGuKT6Oc3+N3q9jOi5VEV63+7B/OG29Aa7qu8a2a+PPB9JLMT8ih+YKXOEOO +hOtVdbTalGvgJlyMq32IzHd2CQGm3sCcG0rfuIM82TPKE6iAO5tFx4FjuIxIHeza +abjqwwOyd/eVltuCgGHyTyPTC26L2WVXTUX+ZeGR8fkdjOexUgNCrNWdgldC5BXJ +EBG6JIHIyxhTp8n4qAo4bEVwtlPzP2rumFfSPyVo74uDXCbj+wGGM0h7ov3zaZFH +aw9Oa/++rLV7f4GZGNlr7RQGfdtV0KsfSonOZ0Ds1UmmvLN33lU/Y5wai3Dw7lkB +vuJuQGCA7VCOtfmfFH2RquCpp2OCPcPQC/EwpI4R/XcgxLNvjpfP0ovXFESCVvKm +yNmR9t5wR66vatPd2LEVzyPYr4xC/PUTmIns2/9r7I9X4DxBKhcss1MXfKqwSvQ8 +RScAMDAZVb8LLz/4oTBggC/kz0m9JmWOYVj1r/zZR+3ct4aZDlqW63aU4XGiCmE/ +aIQl2uvz7BbndQV/h7LI1OY4SUjxru3E5+N3MhK+0idy/C3oOVaC9yl+z75CSfNI +zWXtS+dIDIojKru/4cAlnGkEnc00YVyIHxL8FauLm2OJeSO0SBsjEsqdfLxxd+u7 +84IkZRGqeqIYlldkvZTC1Osyk0ZO2yGyqtP1CKm6MiLK50Jh5RnVSwJm2PvkRAhO +q5tPbT8vY2skkO+7uVjm6s/IaaO8KD/cRZpjPTzxkPy+pTNYFp0G6IxsODfp+S62 +1ir41+kkUh9WU/0whLXXDIHG3fLK5wbWcOwd6TvIfPiR9kEAFNIiEF4qo+Ib6QwA +zGI4UAJm4nt/UlaVZ7RNSDTGy2Q55CKlwEWL0ygVFOQmMXnejKWBZV7lons/lJSx +CU14ohk43EvP//hw5BP9y/nCkyEQY1xvhFh+ZRDpemp1Lboe09qalI16VZsd6AVc +32dIxTTczCx7PFBQiHcoDi9GyZLMPFw1dxA+5ZyqdUbKQGu2AbvZDl3y8bPMyX4m +NLU7mZYN3/IWe5eLfJPgi+IBgBU5OmvHI8vlg8mguj4Yk8JrKADW0LLlGnAg5tt2 +/08L/WvOQCAn5/3xEOQyBBAc5jzFzHXXuxOH6sMRne/xygwdScgY2lUxnkZn/2aG +EEli7HGxBI4NgTUQjsz1B4rDYUU8Ixr+0AjbbfI8yIZhi6DJPOZuzcfrXiRvDbJa +5sRsGISQNtJgiEeDT6c8wxLkqNY7EqY4R+uU2N1A69GVwoJhs3lwzgTUHgB7ccf7 +tTwWStK7N4bGIoZ3J2h/nflxIfuThfIFF6xsivcrdwgg+UL61IcnCbhVMFm8XM7q +JFER5H3Eakte7K9TNRwptKi829pT9ZgQkcm3sFdK210ErNlEi5pXSAQ2nGWOeeDj +x8dc9HDKe/mtMa9rj1h0vsMQmcIzq9pVO2JExxSemAiME3qZEp/E7r2W/vp05fSa +XRTn04Lcv2JErtAnbekOUPGshc2nArqR7F9NAVgYmfxnB6olqPQBABz6K5IMXvJO +LgBB0f6lDbK+Y4gklioxka7lpNA8dSQ5wEXqkpzZma5bYgipBv3qew== +-----END RSA PRIVATE KEY----- diff --git a/t/cert/ca-client-server/server.unsecure.key b/t/cert/ca-client-server/server.unsecure.key new file mode 100644 index 000000000..25fe236f2 --- /dev/null +++ b/t/cert/ca-client-server/server.unsecure.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAwcgYrKCUq4Yho81W67YYA6BOJQ9U+DeI7O5uNQ/0WMFI3kVO +Bg7fO7LeqDr+f+UA3kiWxfUj+DpwjM1afGF8TVeUQevtOMNKeCtxVYQHcq6xYRzc +0jxkpvYkX34MiNav5unk55YIs3p1AdQTDg/k3ObZ0n755zXKx3HrGFh56/xjUdMp +/7JqHjeueey4Ffqbz+Tmf/9u/vXg/MvP8yuGew2tLzGf6d6n7uDpzUIb/IKwVoUN +18ETLOc8NplyMMMpwv+vPpfUjKk/RpX/4PHcCs8tJPECWTR/OCW5m7n5FeFmptAE +6nvvm+di2c7xWgJekmVtJ1jW+o81LGJIM9QNHwIDAQABAoIBAFQGMHTB2FUbfwCo +q9TfC0CfROMa58wNQIkDxbOqbFgDz1XZlUBZOICJSbSGiA3qvVqk/QNvDR64ME9N +R7wBBUYAAKAo7Z6cR3Ed3TGoYxZeGzmxqypZ14bx2cmyPTskY/drWb71NmakZZHa +ZDzHtYP3cWGtfyy7DWc3xSm0S4GAGE/DrKNJNVAtBP32i1jWzFivOyDchf+p/Wxg +Yz7880vdGVcD9LvNBeUiu+0vhk2COjNbH2UWb5HvLA5Qr7XujyVjZVDc0KWSr4Mg +z7DXce1NyNd5dcEfeX7HwV6aVurJF6RSxV3ifSwuIJJ8Acl2XkTe678jIRFfcFsI +RbZUB1kCgYEA5WRYZQ/urag4tM1J/1qSpw3+TP7Ur9M9tYV/egME8ByqpextvQQT +4EZ6yMrVMzcBLpTq0q2iCB3OOnUqww1IxwNKh4MMxmBSZ3gSU7lz1Te53CobEa48 +JYSegjy5XIn7adYCHlTD4+ds1Juoqb65i84iYkK9Ite/lMpjvwcqKr0CgYEA2EJS +1INRwLf0Y3j75Vby54vch5OQ3I4xiwkyFnftj068NB0yPrwDEaddxLBqTSVjvqil +PfJCiBG7BO5n9FQq6Q0IitW68zKbNY2F0XQQoI9lAYMGwZL8pqa3L6yo8Xhk/P34 +XInrOTznVnuC8x5sL1HeKFwi/D78VH+SuyrUAwsCgYA9dNLR0KDrWYRHvDA0/3kG +1JLq4eLtcDS6KxfqAmESSzvU1DDaUPtaPMesf9r6q6PfbPo0k1wzvHiB5N4d/7Md +zl3rTErh4vBw1BRk5eyIlTNwLr+tzvZCPvOQhOBMUJNQ2YsbwS3yIxBfLYzUXUqs +j/9aP/MYIKEtJcPva+X6KQKBgCJrlAFtEVMKNGSsufMLvsep1CTkENd57lrB0O4Q +kogPsRbeWsPvatGhgOQwbArxW4naD8rnRz2fDNRBGdyilN3ZDDYExKe2s0t3xgfL +YGYdzKbL8wRWX84qlNeKtK0SS4iU57Xa4cyPbAawy+vkOLXjYuermonpgIH2eCVA +MNR3AoGBAJxeIsJYDjiMaDIRutKS/Gjete+Dlvi2xx0esRcgrWMj2Uju0TvNeo9d +xT+9IbSwpfEg5dbp6i6clBR3PIAb/KFNB0S+ZE/kQxzxLP1mGWiu6FoIj1O+A1A0 +G/Dm+I8fbT8g70E30Y/fK0dsw6UB1ynDp4gYU6yArpsTtMqt6/ks +-----END RSA PRIVATE KEY----- diff --git a/t/cert/test.crl b/t/cert/test.crl new file mode 100644 index 000000000..098fd54bf --- /dev/null +++ b/t/cert/test.crl @@ -0,0 +1,11 @@ +-----BEGIN X509 CRL----- +MIIBjzCB+QIBATANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UEBhMCVVMxEzARBgNV +BAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xEjAQBgNVBAoM +CU9wZW5SZXN0eTESMBAGA1UECwwJT3BlblJlc3R5MREwDwYDVQQDDAh0ZXN0LmNv +bTEgMB4GCSqGSIb3DQEJARYRYWdlbnR6aEBnbWFpbC5jb20XDTE0MDcyMTIxNDEy +MloXDTE0MDgyMDIxNDEyMlowHDAaAgkApQ5tVpK3luIXDTE0MDcyMTIxNDEwMlqg +DzANMAsGA1UdFAQEAgIQATANBgkqhkiG9w0BAQUFAAOBgQBDZ6UY0Qg7qDoLrXXl +gJElFilZ7LiKPqjE3+Rfx7XkgdbPxjGCr77TfMm+smdvawk7WHv1AOvRH7kGrgGT +kGJZwqJ4vKa/NpEWJIMAZ1Gq9BIH/Ig6ffmPk+S9ozcVHKJDW7x4nMuotyj1hILN +EePv78DZCYMZgf8WwMElNgz6Hw== +-----END X509 CRL----- diff --git a/t/ssl-ctx.t b/t/ssl-ctx.t new file mode 100644 index 000000000..67c197568 --- /dev/null +++ b/t/ssl-ctx.t @@ -0,0 +1,809 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: + +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); +use Digest::MD5 qw(md5_hex); + +repeat_each(2); + +plan tests => repeat_each() * (blocks() + 14); + +our $CWD = cwd(); +$ENV{TEST_NGINX_LUA_PACKAGE_PATH} = "$::CWD/lib/?.lua;;"; +$ENV{TEST_NGINX_HTML_DIR} ||= html_dir(); +$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8'; +our $TEST_NGINX_LUA_PACKAGE_PATH = $ENV{TEST_NGINX_LUA_PACKAGE_PATH}; +our $TEST_NGINX_HTML_DIR = $ENV{TEST_NGINX_HTML_DIR}; + +log_level 'debug'; + +sub read_file { + my $infile = shift; + open my $in, $infile + or die "cannot open $infile for reading: $!"; + my $cert = do { local $/; <$in> }; + close $in; + $cert; +} + +our $system_cert_path = "/etc/pki/tls/cert.pem"; + +if (-e "/usr/local/share/ca-certificates/ca.crt") { + $system_cert_path = "/usr/local/share/ca-certificates/ca.crt"; +} + +if (-e "/etc/ssl/certs/ca-certificates.crt") { + $system_cert_path = "/etc/ssl/certs/ca-certificates.crt"; +} + +our $SystemCerts = read_file($system_cert_path); +our $TestCertificate = read_file("t/cert/test.crt"); +our $TestCertificateKey = read_file("t/cert/test.key"); +our $TestCRL = read_file("t/cert/test.crl"); +our $clientKey = read_file("t/cert/ca-client-server/client.key"); +our $clientUnsecureKey = read_file("t/cert/ca-client-server/client.unsecure.key"); +our $clientCrt = read_file("t/cert/ca-client-server/client.crt"); +our $clientCrtMd5 = md5_hex($clientCrt); +our $serverKey = read_file("t/cert/ca-client-server/server.key"); +our $serverUnsecureKey = read_file("t/cert/ca-client-server/server.unsecure.key"); +our $serverCrt = read_file("t/cert/ca-client-server/server.crt"); +our $caKey = read_file("t/cert/ca-client-server/ca.key"); +our $caCrt = read_file("t/cert/ca-client-server/ca.crt"); +our $http_config = <<_EOS_; +lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH/?.lua;;../lua-resty-lrucache/lib/?.lua;"; + +init_by_lua_block { + require "resty.core.socket.tcp" + + function read_file(file) + local f = io.open(file, "rb") + if f == nil then + return error(file) + end + local content = f:read("*all") + f:close() + return content + end + + local lrucache = require "resty.lrucache" + local c, err = lrucache.new(10) + if not c then + return error("failed to create the cache: " .. (err or "unknown")) + end + local ssl = require "ngx.ssl" + local cert = ssl.parse_pem_cert(read_file("$TEST_NGINX_HTML_DIR/client.crt")) + local priv_key = ssl.parse_pem_priv_key(read_file("$TEST_NGINX_HTML_DIR/client.unsecure.key")) + + local ssl_ctx, err = ssl.create_ctx{ + priv_key = priv_key, + cert = cert + } + + c:set("sslctx", ssl_ctx) + + local system_cert = read_file("$system_cert_path") + local cert_store, err = ssl.create_x509_store(system_cert) + if cert_store == nil then + return ngx.say(err) + end + + c:set("cert_store", cert_store) + + function lrucache_getsslctx() + return c:get("sslctx") + end + + function lrucache_getcertstore() + return c:get("cert_store") + end + + function get_response_body(response) + for k, v in ipairs(response) do + if #v == 0 then + return table.concat(response, "\\r\\n", k + 1) + end + end + + return nil, "CRLF not found" + end + + function https_get(host, port, domain, path, ssl_ctx, verify) + local sock = ngx.socket.tcp() + domain = domain or "server" + verify = verify or false + + local ok, err = sock:connect(host, port) + if not ok then + return nil, err + end + + local ok, err = sock:setsslctx(ssl_ctx) + if not ok then + return nil, err + end + + local sess, err = sock:sslhandshake(nil, domain, verify) + if not sess then + return nil, err + end + + local req = "GET " .. path .. " HTTP/1.0\\r\\nHost: " .. domain .. "\\r\\nConnection: close\\r\\n\\r\\n" + local bytes, err = sock:send(req) + if not bytes then + return nil, err + end + + local response = {} + while true do + local line, err, partial = sock:receive() + if not line then + if not partial then + response[#response+1] = partial + end + break + end + + response[#response+1] = line + end + + sock:close() + + return response + end +} + +server { + listen 1983 ssl; + server_name server; + ssl_certificate ../html/server.crt; + ssl_certificate_key ../html/server.unsecure.key; + + ssl on; + ssl_client_certificate ../html/ca.crt; + ssl_verify_client on; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + + ssl_prefer_server_ciphers on; + + server_tokens off; + more_clear_headers Date; + default_type 'text/plain'; + + location / { + content_by_lua_block { + ngx.say("foo") + } + } + + location /protocol { + content_by_lua_block {ngx.say(ngx.var.ssl_protocol)} + } + + location /cert { + content_by_lua_block { + ngx.say(ngx.md5(ngx.var.ssl_client_raw_cert)) + } + } + + location /cipher { + content_by_lua_block { + ngx.say(ngx.var.ssl_cipher) + } + } +} +_EOS_ +our $user_files = <<_EOS_; +>>> client.key +$clientKey +>>> client.unsecure.key +$clientUnsecureKey +>>> client.crt +$clientCrt +>>> server.key +$serverKey +>>> server.unsecure.key +$serverUnsecureKey +>>> server.crt +$serverCrt +>>> ca.key +$caKey +>>> ca.crt +$caCrt +>>> wrong.crt +OpenResty +>>> wrong.key +OpenResty +>>> system.crt +$SystemCerts +_EOS_ + +add_block_preprocessor(sub { + my $block = shift; + + if (!defined $block->http_config) { + $block->set_value("http_config", $http_config); + } + + if (!defined $block->user_files) { + $block->set_value("user_files", $user_files); + } +}); + + +no_shuffle(); +no_long_string(); +run_tests(); + +__DATA__ + +=== TEST 1: ssl ctx - create_ctx must pass options +--- config + location /t{ + content_by_lua_block { + local ssl = require "ngx.ssl" + local ssl_ctx, err = ssl.create_ctx() + if ssl_ctx == nil then + ngx.say(err) + end + } + } +--- request +GET /t +--- response_body +no options found + + + +=== TEST 2: ssl ctx - specify ssl protocols TLSv1、TLSv1.1、TLSv1.2 +--- config + location /t { + content_by_lua_block { + local ssl = require "ngx.ssl" + function test_ssl_protocol(protocols) + local ssl = require "ngx.ssl" + local cert = ssl.parse_pem_cert(read_file("$TEST_NGINX_HTML_DIR/client.crt")) + local priv_key = ssl.parse_pem_priv_key(read_file("$TEST_NGINX_HTML_DIR/client.unsecure.key")) + local ssl_ctx, err = ssl.create_ctx{ + protocols = protocols, + priv_key = priv_key, + cert = cert + } + if ssl_ctx == nil then + return err + end + + local response, err = https_get('127.0.0.1', 1983, 'server', '/protocol', ssl_ctx) + + if not response then + return err + end + + local body, err = get_response_body(response) + if not body then + return err + end + return body + end + + local bit = require "bit" + local bor = bit.bor + + ngx.say(test_ssl_protocol(ssl.TLSv1)) + ngx.say(test_ssl_protocol(ssl.TLSv1_1)) + ngx.say(test_ssl_protocol(ssl.TLSv1_2)) + ngx.say(test_ssl_protocol(bor(ssl.SSLv2, ssl.TLSv1_2))) + } + } + +--- request +GET /t +--- response_body +TLSv1 +TLSv1.1 +TLSv1.2 +TLSv1.2 + +--- no_error_log +[error] + + + +=== TEST 3: ssl ctx - dismatch priv_key and cert +--- config + location /t { + content_by_lua_block { + local ssl = require "ngx.ssl" + local cert = ssl.parse_pem_cert(read_file("$TEST_NGINX_HTML_DIR/server.crt")) + local priv_key = ssl.parse_pem_priv_key(read_file("$TEST_NGINX_HTML_DIR/client.unsecure.key")) + local ssl_ctx, err = ssl.create_ctx{ + priv_key = priv_key, + cert = cert + } + if ssl_ctx == nil then + ngx.say(err) + end + } + } + +--- request +GET /t +--- response_body +error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch + + + +=== TEST 4: ssl ctx - send client certificate +--- config + location /t { + content_by_lua_block { + local ssl = require "ngx.ssl" + local cert = ssl.parse_pem_cert(read_file("$TEST_NGINX_HTML_DIR/client.crt")) + local priv_key = ssl.parse_pem_priv_key(read_file("$TEST_NGINX_HTML_DIR/client.unsecure.key")) + + local ssl_ctx, err = ssl.create_ctx{ + priv_key = priv_key, + cert = cert + } + + if ssl_ctx == nil then + ngx.say("failed to init ssl ctx: ", err) + return + end + local response = https_get("127.0.0.1", 1983, "server", "/cert", ssl_ctx) + ngx.say(get_response_body(response)) + } + } +--- request +GET /t +--- response_body eval +"$::clientCrtMd5 +" + + + +=== TEST 5: ssl ctx - setsslctx with cached ssl_ctx +--- config + location /t { + content_by_lua_block { + local ssl_ctx = lrucache_getsslctx() + local response = https_get("127.0.0.1", 1983, "server", "/cert", ssl_ctx) + ngx.say(get_response_body(response)) + } + } +--- request +GET /t +--- response_body eval +"$::clientCrtMd5 +" + + + +=== TEST 6: ssl ctx - set error ciphers +--- config + location /t { + content_by_lua_block { + local ssl = require "ngx.ssl" + local cert = ssl.parse_pem_cert(read_file("$TEST_NGINX_HTML_DIR/client.crt")) + local priv_key = ssl.parse_pem_priv_key(read_file("$TEST_NGINX_HTML_DIR/client.unsecure.key")) + + local ssl_ctx, err = ssl.create_ctx{ + priv_key = priv_key, + cert = cert, + ciphers = "ECDHE-RSA-AES256-SHA-openresty", + } + + if ssl_ctx == nil then + ngx.say("failed to init ssl ctx: ", err) + return + end + local response = https_get("127.0.0.1", 1983, "server", "/ciphers", ssl_ctx) + ngx.say(get_response_body(response)) + } + } +--- request +GET /t +--- response_body +failed to init ssl ctx: error:1410D0B9:SSL routines:SSL_CTX_set_cipher_list:no cipher match + + + +=== TEST 7: ssl ctx - set right ciphers +--- config + location /t { + content_by_lua_block { + local ssl = require "ngx.ssl" + local cert = ssl.parse_pem_cert(read_file("$TEST_NGINX_HTML_DIR/client.crt")) + local priv_key = ssl.parse_pem_priv_key(read_file("$TEST_NGINX_HTML_DIR/client.unsecure.key")) + + local ssl_ctx, err = ssl.create_ctx{ + priv_key = priv_key, + cert = cert, + ciphers = "ECDHE-RSA-AES256-SHA", + } + + if ssl_ctx == nil then + ngx.say("failed to init ssl ctx: ", err) + return + end + local response = https_get("127.0.0.1", 1983, "server", "/cipher", ssl_ctx) + ngx.say(get_response_body(response)) + } + } +--- request +GET /t +--- response_body +ECDHE-RSA-AES256-SHA + + + +=== TEST 8: ssl ctx - set ca cert +--- config + location /t { + content_by_lua_block { + local ssl = require "ngx.ssl" + local ca = read_file("$TEST_NGINX_HTML_DIR/ca.crt") + local cert = ssl.parse_pem_cert(read_file("$TEST_NGINX_HTML_DIR/client.crt")) + local priv_key = ssl.parse_pem_priv_key(read_file("$TEST_NGINX_HTML_DIR/client.unsecure.key")) + + local ssl_ctx, err = ssl.create_ctx{ + priv_key = priv_key, + cert = cert, + ca = ca + } + + if ssl_ctx == nil then + ngx.say("failed to init ssl ctx: ", err) + return + end + local response = https_get("127.0.0.1", 1983, "server", "/", ssl_ctx) + ngx.say(get_response_body(response)) + + local no_ca_ssl_ctx, err = ssl.create_ctx{ + priv_key = priv_key, + cert = cert, + } + + if ssl_ctx == nil then + ngx.say("failed to init ssl ctx: ", err) + return + end + local response, err = https_get("127.0.0.1", 1983, "server", "/", no_ca_ssl_ctx, true) + ngx.say(err) + } + } +--- request +GET /t +--- response_body +foo +20: unable to get local issuer certificate + + + +=== TEST 9: ssl ctx - set crl +--- http_config + lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH/?.lua;;../lua-resty-lrucache/lib/?.lua;"; + server { + listen 1985 ssl; + server_name test.com; + ssl_certificate ../html/test.crt; + ssl_certificate_key ../html/test.key; + + location / { + content_by_lua_block {ngx.say("hello")} + } + } +--- config + location /t { + content_by_lua_block { + require "resty.core" + function read_file(file) + local f = io.open(file, "rb") + local content = f:read("*all") + f:close() + return content + end + + local ssl = require "ngx.ssl" + local crl = read_file("$TEST_NGINX_HTML_DIR/test.crl"); + local server_cert = read_file("$TEST_NGINX_HTML_DIR/test.crt"); + + local ssl_ctx, err = ssl.create_ctx{ + crl = crl, + ca = server_cert, + } + + if ssl_ctx == nil then + ngx.say("failed to init ssl ctx: ", err) + return + end + + local sock = ngx.socket.tcp() + local ok, err = sock:connect("127.0.0.1", 1985) + if not ok then + return ngx.say(err) + end + + local ok, err = sock:setsslctx(ssl_ctx) + if not ok then + return ngx.say(err) + end + + local sess, err = sock:sslhandshake(nil, "test.com", true) + return ngx.say("sslhandshake:", err) + } + } + +--- request +GET /t +--- response_body +sslhandshake:12: CRL has expired +--- user_files eval +">>> test.key +$::TestCertificateKey +>>> test.crt +$::TestCertificate +>>> test.crl +$::TestCRL" + + + +=== TEST 10: ssl ctx - set cert store +--- config + location /t { + content_by_lua_block { + local ssl = require "ngx.ssl" + local ca = read_file("$TEST_NGINX_HTML_DIR/ca.crt") + local cert = ssl.parse_pem_cert(read_file("$TEST_NGINX_HTML_DIR/client.crt")) + local priv_key = ssl.parse_pem_priv_key(read_file("$TEST_NGINX_HTML_DIR/client.unsecure.key")) + + local no_cert_store_ssl_ctx, err = ssl.create_ctx{ + priv_key = priv_key, + cert = cert, + } + + if no_cert_store_ssl_ctx == nil then + ngx.say("failed to init ssl ctx: ", err) + return + end + local response, err = https_get("127.0.0.1", 1983, "server", "/", + no_cert_store_ssl_ctx, true) + ngx.say(err) + + local cert_store, err = ssl.create_x509_store(ca) + if cert_store == nil then + return ngx.say(err) + end + + local ssl_ctx, err = ssl.create_ctx{ + priv_key = priv_key, + cert = cert, + cert_store = cert_store + } + + if ssl_ctx == nil then + ngx.say("failed to init ssl ctx: ", err) + return + end + local response = https_get("127.0.0.1", 1983, "server", "/", ssl_ctx) + ngx.say(get_response_body(response)) + } + } +--- request +GET /t +--- response_body +20: unable to get local issuer certificate +foo + + + +=== TEST 11: ssl ctx - set cert store with system cert +--- config + resolver $TEST_NGINX_RESOLVER; + location /t { + content_by_lua_block { + local ssl = require "ngx.ssl" + local ca = read_file("$TEST_NGINX_HTML_DIR/system.crt") + local cert = ssl.parse_pem_cert(read_file("$TEST_NGINX_HTML_DIR/client.crt")) + local priv_key = ssl.parse_pem_priv_key(read_file("$TEST_NGINX_HTML_DIR/client.unsecure.key")) + + local no_cert_store_ssl_ctx, err = ssl.create_ctx{ + priv_key = priv_key, + cert = cert, + } + + if no_cert_store_ssl_ctx == nil then + ngx.say("failed to init ssl ctx: ", err) + return + end + + local response, err = https_get("openresty.org", 443, "openresty.org", "/", + no_cert_store_ssl_ctx, true) + + ngx.say(err) + + local cert_store, err = ssl.create_x509_store(ca) + if cert_store == nil then + return ngx.say(err) + end + + local ssl_ctx, err = ssl.create_ctx{ + priv_key = priv_key, + cert = cert, + cert_store = cert_store + } + + if ssl_ctx == nil then + ngx.say("failed to init ssl ctx: ", err) + return + end + local response, err = https_get("openresty.org", 443, "openresty.org", "/", ssl_ctx, true) + if not err then + ngx.say("success") + else + ngx.say("failed") + end + } + } +--- request +GET /t +--- response_body +20: unable to get local issuer certificate +success +--- timeout: 5 + + +=== TEST 12: ssl ctx - set cert store with lrucache +--- config + resolver $TEST_NGINX_RESOLVER; + location /t { + content_by_lua_block { + local ssl = require "ngx.ssl" + local ca = read_file("$TEST_NGINX_HTML_DIR/system.crt") + local cert = ssl.parse_pem_cert(read_file("$TEST_NGINX_HTML_DIR/client.crt")) + local priv_key = ssl.parse_pem_priv_key(read_file("$TEST_NGINX_HTML_DIR/client.unsecure.key")) + + local cert_store = lrucache_getcertstore() + local ssl_ctx, err = ssl.create_ctx{ + priv_key = priv_key, + cert = cert, + cert_store = cert_store + } + + if ssl_ctx == nil then + ngx.say("failed to init ssl ctx: ", err) + return + end + local response, err = https_get("openresty.org", 443, "openresty.org", "/", ssl_ctx, true) + if not err then + ngx.say("success") + else + ngx.say("failed") + end + } + } +--- request +GET /t +--- response_body +success +--- timeout: 5 + + +=== TEST 13: ssl ctx - set cert store self-signed and system cert +--- config +--- config + resolver $TEST_NGINX_RESOLVER; + location /t { + content_by_lua_block { + local ssl = require "ngx.ssl" + local system_cert = read_file("$TEST_NGINX_HTML_DIR/system.crt") + local local_cert = read_file("$TEST_NGINX_HTML_DIR/ca.crt") + local cert = ssl.parse_pem_cert(read_file("$TEST_NGINX_HTML_DIR/client.crt")) + local priv_key = ssl.parse_pem_priv_key(read_file("$TEST_NGINX_HTML_DIR/client.unsecure.key")) + + local cert_store, err = ssl.create_x509_store(local_cert, system_cert) + if cert_store == nil then + return ngx.say(err) + end + + local ssl_ctx, err = ssl.create_ctx{ + priv_key = priv_key, + cert = cert, + cert_store = cert_store + } + + if ssl_ctx == nil then + ngx.say("failed to init ssl ctx: ", err) + return + end + + local response, err = https_get("openresty.org", 443, "openresty.org", "/", ssl_ctx, true) + if not err then + ngx.say("openresty.org success") + else + ngx.say("openresty.org failed: ", err) + end + local response, err = https_get("127.0.0.1", 1983, "server", "/", ssl_ctx, true) + if not err then + ngx.say("self-signed success") + else + ngx.say("self-signed failed: ", err) + end + } + } +--- request +GET /t +--- response_body +openresty.org success +self-signed success +--- timeout: 5 + + + +=== TEST 14: ssl ctx - cert store init and free +--- config + location /t { + content_by_lua_block { + local ssl = require "ngx.ssl" + local local_cert = read_file("$TEST_NGINX_HTML_DIR/ca.crt") + local cert = ssl.parse_pem_cert(read_file("$TEST_NGINX_HTML_DIR/client.crt")) + local priv_key = ssl.parse_pem_priv_key(read_file("$TEST_NGINX_HTML_DIR/client.unsecure.key")) + + local cert_store, err = ssl.create_x509_store(local_cert) + if cert_store == nil then + return ngx.say(err) + end + cert_store = nil + collectgarbage("collect") + } + } +--- request +GET /t +--- ignore_response +--- grep_error_log eval: qr/lua ssl x509 store (?:init|free): [0-9A-F]+:\d+/ +--- grep_error_log_out eval +qr/^lua ssl x509 store init: ([0-9A-F]+):1 +lua ssl x509 store free: ([0-9A-F]+):1 +$/ + + + +=== TEST 15: ssl ctx - cert store init and up reference then free +--- config + location /t { + content_by_lua_block { + local ssl = require "ngx.ssl" + local local_cert = read_file("$TEST_NGINX_HTML_DIR/ca.crt") + local cert = ssl.parse_pem_cert(read_file("$TEST_NGINX_HTML_DIR/client.crt")) + local priv_key = ssl.parse_pem_priv_key(read_file("$TEST_NGINX_HTML_DIR/client.unsecure.key")) + + local cert_store, err = ssl.create_x509_store(local_cert) + if cert_store == nil then + return ngx.say(err) + end + + local ssl_ctx, err = ssl.create_ctx{ + priv_key = priv_key, + cert = cert, + cert_store = cert_store + } + + cert_store = nil + collectgarbage("collect") + ssl_ctx = nil + collectgarbage("collect") + } + } +--- request +GET /t +--- ignore_response +--- grep_error_log eval: qr/lua ssl (?:x509 store|ctx) (?:init|free|up reference|x509 store reference): [0-9A-F]+:\d+/ +--- grep_error_log_out eval +qr/^lua ssl x509 store init: ([0-9A-F]+):1 +lua ssl ctx init: ([0-9A-F]+):1 +lua ssl x509 store up reference: ([0-9A-F]+):2 +lua ssl x509 store free: ([0-9A-F]+):2 +lua ssl ctx x509 store reference: ([0-9A-F]+):1 +lua ssl ctx free: ([0-9A-F]+):1 +$/ +