Skip to content

Commit ba4ef82

Browse files
climagabrielzhuizhuhaomeng
authored andcommitted
1 parent eac2a10 commit ba4ef82

File tree

2 files changed

+152
-10
lines changed

2 files changed

+152
-10
lines changed

lib/ngx/ssl/clienthello.lua

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@ local ngx_phase = ngx.get_phase
2020
local byte = string.byte
2121
local lshift = bit.lshift
2222
local table_insert = table.insert
23+
local table_new = require "table.new"
24+
local intp = ffi.new("int*[1]")
2325

2426

2527
local ngx_lua_ffi_ssl_get_client_hello_server_name
2628
local ngx_lua_ffi_ssl_get_client_hello_ext
2729
local ngx_lua_ffi_ssl_set_protocols
30+
local ngx_lua_ffi_ssl_get_client_hello_ext_present
2831

2932

3033
if subsystem == 'http' then
@@ -38,13 +41,18 @@ if subsystem == 'http' then
3841

3942
int ngx_http_lua_ffi_ssl_set_protocols(ngx_http_request_t *r,
4043
int protocols, char **err);
44+
int ngx_http_lua_ffi_ssl_get_client_hello_ext_present(ngx_http_request_t *r,
45+
int **extensions, size_t *extensions_len, char **err);
4146
]]
4247

4348
ngx_lua_ffi_ssl_get_client_hello_server_name =
4449
C.ngx_http_lua_ffi_ssl_get_client_hello_server_name
4550
ngx_lua_ffi_ssl_get_client_hello_ext =
4651
C.ngx_http_lua_ffi_ssl_get_client_hello_ext
4752
ngx_lua_ffi_ssl_set_protocols = C.ngx_http_lua_ffi_ssl_set_protocols
53+
ngx_lua_ffi_ssl_get_client_hello_ext_present =
54+
C.ngx_http_lua_ffi_ssl_get_client_hello_ext_present
55+
4856

4957
elseif subsystem == 'stream' then
5058
ffi.cdef[[
@@ -102,6 +110,39 @@ function _M.get_client_hello_server_name()
102110
return nil, ffi_str(errmsg[0])
103111
end
104112

113+
-- return extensions_table, err
114+
function _M.get_client_hello_ext_present()
115+
local r = get_request()
116+
if not r then
117+
error("no request found")
118+
end
119+
120+
if ngx_phase() ~= "ssl_client_hello" then
121+
error("API disabled in the current context")
122+
end
123+
124+
local sizep = get_size_ptr()
125+
126+
local rc = ngx_lua_ffi_ssl_get_client_hello_ext_present(r, intp,
127+
sizep, errmsg)
128+
if rc == FFI_OK then -- Convert C array to Lua table
129+
local array = intp[0]
130+
local size = tonumber(sizep[0])
131+
local extensions_table = table_new(size, 0)
132+
for i=0, size-1, 1 do
133+
extensions_table[i + 1] = array[i]
134+
end
135+
136+
return extensions_table
137+
end
138+
139+
-- NGX_DECLINED: no extensions; very unlikely
140+
if rc == -5 then
141+
return nil
142+
end
143+
144+
return nil, ffi_str(errmsg[0])
145+
end
105146

106147
-- return ext, err
107148
function _M.get_client_hello_ext(ext_type)

t/ssl-client-hello.t

Lines changed: 111 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,8 @@ read SNI name from Lua: nil, type: nil
479479
ngx.exit(ngx.ERROR)
480480
end
481481
}
482-
ssl_protocols TLSv1 TLSv1.1;
482+
483+
ssl_protocols TLSv1.3;
483484
ssl_certificate ../../cert/test.crt;
484485
ssl_certificate_key ../../cert/test.key;
485486

@@ -585,7 +586,7 @@ close: 1 nil
585586
ngx.exit(ngx.ERROR)
586587
end
587588
}
588-
ssl_protocols TLSv1 TLSv1.1;
589+
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
589590
ssl_certificate ../../cert/test.crt;
590591
ssl_certificate_key ../../cert/test.key;
591592

@@ -675,7 +676,7 @@ close: 1 nil
675676

676677

677678

678-
=== TEST 7: dynamically set ssl protocol - deny TLSv1.1
679+
=== TEST 7: dynamically set ssl protocol - deny TLSv1.2
679680
--- skip_nginx: 5: < 1.19.9
680681
--- http_config
681682
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
@@ -685,13 +686,13 @@ close: 1 nil
685686
server_name test.com;
686687
ssl_client_hello_by_lua_block {
687688
local ssl_clt = require "ngx.ssl.clienthello"
688-
local ok = ssl_clt.set_protocols({"TLSv1.2", "TLSv1.3"})
689+
local ok = ssl_clt.set_protocols({"TLSv1.3"})
689690
if not ok then
690691
print("failed to set_protocols")
691692
ngx.exit(ngx.ERROR)
692693
end
693694
}
694-
ssl_protocols TLSv1 TLSv1.1;
695+
ssl_protocols TLSv1 TLSv1.1 TLSV1.2 TLSV1.3;
695696
ssl_certificate ../../cert/test.crt;
696697
ssl_certificate_key ../../cert/test.key;
697698

@@ -705,7 +706,7 @@ close: 1 nil
705706
--- config
706707
server_tokens off;
707708
lua_ssl_trusted_certificate ../../cert/test.crt;
708-
lua_ssl_protocols TLSv1.1;
709+
lua_ssl_protocols TLSv1.1 TLSV1.2;
709710

710711
location /t {
711712
content_by_lua_block {
@@ -772,7 +773,8 @@ failed to do SSL handshake: handshake failed
772773

773774

774775
=== TEST 8: dynamically set ssl protocol - deny TLSv1
775-
--- skip_nginx: 5: < 1.19.9
776+
openssl3 does not support TLSv1
777+
--- skip_nginx: 5: < 100.0.0
776778
--- http_config
777779
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
778780

@@ -880,15 +882,15 @@ failed to do SSL handshake: handshake failed
880882
local types, err = ssl_clt.get_supported_versions()
881883
if not err and types then
882884
for _, ssl_type in pairs(types) do
883-
if ssl_type == "TLSv1.2" then
885+
if ssl_type == "TLSv1.3" then
884886
ngx.exit(ngx.OK)
885887
end
886888
end
887889
end
888890
ngx.log(ngx.ERR, "failed to get_supported_versions")
889891
ngx.exit(ngx.ERROR)
890892
}
891-
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
893+
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
892894
ssl_certificate ../../cert/test.crt;
893895
ssl_certificate_key ../../cert/test.key;
894896

@@ -902,7 +904,7 @@ failed to do SSL handshake: handshake failed
902904
--- config
903905
server_tokens off;
904906
lua_ssl_trusted_certificate ../../cert/test.crt;
905-
lua_ssl_protocols TLSv1 TLSv1.1 ;
907+
lua_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
906908

907909
location /t {
908910
content_by_lua_block {
@@ -964,3 +966,102 @@ failed to get_supported_versions
964966

965967
--- no_error_log
966968
[alert]
969+
970+
971+
972+
=== TEST 10: log all_extensions in the clienthello packet
973+
--- http_config
974+
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";
975+
976+
server {
977+
listen 127.0.0.2:$TEST_NGINX_RAND_PORT_1 ssl;
978+
server_name test.com;
979+
ssl_client_hello_by_lua_block {
980+
local ssl_clt = require "ngx.ssl.clienthello"
981+
local all_extensions, err = ssl_clt.get_client_hello_ext_present()
982+
if not err and all_extensions then
983+
for i, ext in ipairs(all_extensions) do
984+
ngx.log(ngx.INFO, i, ": TLS EXT ", ext)
985+
end
986+
else
987+
ngx.log(ngx.ERR, "failed to get all_extensions")
988+
end
989+
ngx.exit(ngx.ERROR)
990+
}
991+
992+
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
993+
ssl_certificate ../../cert/test.crt;
994+
ssl_certificate_key ../../cert/test.key;
995+
996+
server_tokens off;
997+
location /foo {
998+
default_type 'text/plain';
999+
content_by_lua_block {ngx.status = 201 ngx.say("foo") ngx.exit(201)}
1000+
more_clear_headers Date;
1001+
}
1002+
}
1003+
--- config
1004+
server_tokens off;
1005+
lua_ssl_trusted_certificate ../../cert/test.crt;
1006+
lua_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
1007+
1008+
location /t {
1009+
content_by_lua_block {
1010+
do
1011+
local sock = ngx.socket.tcp()
1012+
1013+
sock:settimeout(3000)
1014+
1015+
local ok, err = sock:connect("127.0.0.2", $TEST_NGINX_RAND_PORT_1)
1016+
if not ok then
1017+
ngx.say("failed to connect: ", err)
1018+
return
1019+
end
1020+
1021+
ngx.say("connected: ", ok)
1022+
1023+
local sess, err = sock:sslhandshake(nil, nil, true)
1024+
if not sess then
1025+
ngx.say("failed to do SSL handshake: ", err)
1026+
return
1027+
end
1028+
1029+
ngx.say("ssl handshake: ", type(sess))
1030+
1031+
local req = "GET /foo HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n"
1032+
local bytes, err = sock:send(req)
1033+
if not bytes then
1034+
ngx.say("failed to send http request: ", err)
1035+
return
1036+
end
1037+
1038+
ngx.say("sent http request: ", bytes, " bytes.")
1039+
1040+
while true do
1041+
local line, err = sock:receive()
1042+
if not line then
1043+
-- ngx.say("failed to receive response status line: ", err)
1044+
break
1045+
end
1046+
1047+
ngx.say("received: ", line)
1048+
end
1049+
1050+
local ok, err = sock:close()
1051+
ngx.say("close: ", ok, " ", err)
1052+
end -- do
1053+
-- collectgarbage()
1054+
}
1055+
}
1056+
1057+
--- request
1058+
GET /t
1059+
--- response_body
1060+
connected: 1
1061+
failed to do SSL handshake: handshake failed
1062+
--- error_log eval
1063+
qr/1: TLS EXT \d+, context: ssl_client_hello_by_lua/
1064+
--- no_error_log
1065+
[alert]
1066+
[crit]
1067+
[placeholder]

0 commit comments

Comments
 (0)