diff --git a/lib/ngx/ssl.lua b/lib/ngx/ssl.lua index 89d42a533..aece0dc5f 100644 --- a/lib/ngx/ssl.lua +++ b/lib/ngx/ssl.lua @@ -58,6 +58,9 @@ 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); + +int ngx_http_lua_ffi_ssl_set_ciphers(ngx_http_request_t *r, + const char *ciphers, char **err); ]] @@ -261,6 +264,21 @@ function _M.set_priv_key(priv_key) end +function _M.set_ciphers(ciphers) + 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_ciphers(r, ciphers, errmsg) + if rc == FFI_OK then + return true + end + + return nil, ffi_str(errmsg[0]) +end + + do _M.SSL3_VERSION = 0x0300 _M.TLS1_VERSION = 0x0301 diff --git a/lib/ngx/ssl.md b/lib/ngx/ssl.md index fc7ecae5f..a321b0ac3 100644 --- a/lib/ngx/ssl.md +++ b/lib/ngx/ssl.md @@ -23,6 +23,7 @@ Table of Contents * [parse_pem_priv_key](#parse_pem_priv_key) * [set_cert](#set_cert) * [set_priv_key](#set_priv_key) + * [set_ciphers](#set_ciphers) * [Community](#community) * [English Mailing List](#english-mailing-list) * [Chinese Mailing List](#chinese-mailing-list) @@ -381,6 +382,20 @@ This function was first added in version `0.1.7`. [Back to TOC](#table-of-contents) +set_ciphers +------------ +**syntax:** *ok, err = ssl.set_ciphers(ciphers)* + +**context:** *ssl_certificate_by_lua** + +Sets the enabled SSL ciphers for the current SSL connection. The `ciphers` string format is the same as the one accepted by OpenSSL. + +Returns `true` on success, or a `nil` value and a string describing the error otherwise. + +This function was first added in version `0.2.0`. + +[Back to TOC](#table-of-contents) + Community ========= diff --git a/t/ssl.t b/t/ssl.t index a1c5e2f49..1f6442496 100644 --- a/t/ssl.t +++ b/t/ssl.t @@ -2062,3 +2062,113 @@ qr/\[error\] .*? failed to parse pem key: PEM_read_bio_PrivateKey\(\) failed/ [alert] [emerg] [crit] + + + +=== TEST 20: set ciphers +--- http_config + lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH/?.lua;;"; + + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name test.com; + + ssl_ciphers AES128; + + ssl_certificate_by_lua_block { + local ssl = require "ngx.ssl" + + local ok, err = ssl.set_ciphers("AES256") + if not ok then + ngx.say("failed to connect: ", err) + return + end + } + + ssl_certificate ../../cert/chain/chain.pem; + ssl_certificate_key ../../cert/chain/test-com.key.pem; + + server_tokens off; + location /foo { + default_type 'text/plain'; + content_by_lua_block { ngx.status = 201 ngx.say("foo") ngx.exit(201) } + more_clear_headers Date; + } + } +--- config + server_tokens off; + lua_ssl_trusted_certificate ../../cert/chain/root-ca.crt; + lua_ssl_verify_depth 3; + lua_ssl_ciphers AES256; + + location /t { + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(3000) + + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local sess, err = sock:sslhandshake(nil, "test.com", true) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + + ngx.say("ssl handshake: ", type(sess)) + + local req = "GET /foo HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n" + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send http request: ", err) + return + end + + ngx.say("sent http request: ", bytes, " bytes.") + + while true do + local line, err = sock:receive() + if not line then + -- ngx.say("failed to recieve response status line: ", err) + break + end + + ngx.say("received: ", line) + end + + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + -- collectgarbage() + } + } + +--- request +GET /t +--- response_body +connected: 1 +ssl handshake: userdata +sent http request: 56 bytes. +received: HTTP/1.1 201 Created +received: Server: nginx +received: Content-Type: text/plain +received: Content-Length: 4 +received: Connection: close +received: +received: foo +close: 1 nil + +--- error_log +lua ssl server name: "test.com" +cipher: "ECDHE-RSA-AES256-GCM-SHA384 + +--- no_error_log +[error] +[alert]