Skip to content

Commit 1755f40

Browse files
author
mengxiangwei
committed
feat: add server random and master key fetch api
1 parent f4c76d8 commit 1755f40

2 files changed

Lines changed: 351 additions & 0 deletions

File tree

‎src/ngx_http_lua_ssl_certby.c‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,4 +1754,54 @@ ngx_http_lua_ffi_ssl_client_random(ngx_http_request_t *r,
17541754
}
17551755

17561756

1757+
int
1758+
ngx_http_lua_ffi_ssl_server_random(ngx_http_request_t *r,
1759+
unsigned char *out, size_t *outlen, char **err)
1760+
{
1761+
ngx_ssl_conn_t *ssl_conn;
1762+
1763+
if (r->connection == NULL || r->connection->ssl == NULL) {
1764+
*err = "bad request";
1765+
return NGX_ERROR;
1766+
}
1767+
1768+
ssl_conn = r->connection->ssl->connection;
1769+
if (ssl_conn == NULL) {
1770+
*err = "bad ssl conn";
1771+
return NGX_ERROR;
1772+
}
1773+
1774+
*outlen = SSL_get_server_random(ssl_conn, out, *outlen);
1775+
1776+
return NGX_OK;
1777+
}
1778+
1779+
1780+
int
1781+
ngx_http_lua_ffi_ssl_session_master_key(ngx_http_request_t *r,
1782+
unsigned char *out, size_t *outlen, char **err)
1783+
{
1784+
ngx_ssl_conn_t *ssl_conn;
1785+
SSL_SESSION *sess;
1786+
1787+
if (r->connection == NULL || r->connection->ssl == NULL) {
1788+
*err = "bad request";
1789+
return NGX_ERROR;
1790+
}
1791+
1792+
ssl_conn = r->connection->ssl->connection;
1793+
if (ssl_conn == NULL) {
1794+
*err = "bad ssl conn";
1795+
return NGX_ERROR;
1796+
}
1797+
1798+
sess = SSL_get0_session(ssl_conn);
1799+
1800+
1801+
*outlen = SSL_SESSION_get_master_key(sess, out, *outlen);
1802+
1803+
return NGX_OK;
1804+
}
1805+
1806+
17571807
#endif /* NGX_HTTP_SSL */

‎t/140-ssl-c-api.t‎

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ ffi.cdef[[
8080
int ngx_http_lua_ffi_ssl_client_random(ngx_http_request_t *r,
8181
unsigned char *out, size_t *outlen, char **err);
8282
83+
int ngx_http_lua_ffi_ssl_server_random(ngx_http_request_t *r,
84+
const unsigned char *out, size_t *outlen, char **err);
85+
86+
int ngx_http_lua_ffi_ssl_session_master_key(ngx_http_request_t *r,
87+
const unsigned char *out, size_t *outlen, char **err);
88+
8389
int ngx_http_lua_ffi_req_shared_ssl_ciphers(void *r, uint16_t *ciphers,
8490
uint16_t *nciphers, int filter_grease, char **err);
8591
]]
@@ -2074,3 +2080,298 @@ without_filter:\[.*\]
20742080
with_filter:\[.*\]
20752081
--- error_log chomp
20762082
TLSv1.2, cipher: "ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD"
2083+
2084+
2085+
2086+
=== TEST 20: get server random
2087+
--- http_config
2088+
server {
2089+
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
2090+
server_name test.com;
2091+
2092+
ssl_certificate ../../cert/test.crt;
2093+
ssl_certificate_key ../../cert/test.key;
2094+
2095+
server_tokens off;
2096+
location /foo {
2097+
default_type 'text/plain';
2098+
content_by_lua_block {
2099+
collectgarbage()
2100+
2101+
local ffi = require "ffi"
2102+
require "defines"
2103+
2104+
local errmsg = ffi.new("char *[1]")
2105+
2106+
local r = require "resty.core.base" .get_request()
2107+
if r == nil then
2108+
ngx.log(ngx.ERR, "no request found")
2109+
ngx.status = 201 ngx.say("foo") ngx.exit(201)
2110+
return
2111+
end
2112+
2113+
-- test server random length
2114+
local out = ffi.new("unsigned char[?]", 0)
2115+
local sizep = ffi.new("size_t[1]", 0)
2116+
2117+
local rc = ffi.C.ngx_http_lua_ffi_ssl_server_random(r, out, sizep, errmsg)
2118+
if rc ~= 0 then
2119+
ngx.log(ngx.ERR, "failed to get server random length: ",
2120+
ffi.string(errmsg[0]))
2121+
ngx.status = 201 ngx.say("foo") ngx.exit(201)
2122+
return
2123+
end
2124+
2125+
if tonumber(sizep[0]) ~= 32 then
2126+
ngx.log(ngx.ERR, "server random length does not equal 32")
2127+
ngx.status = 201 ngx.say("foo") ngx.exit(201)
2128+
return
2129+
end
2130+
2131+
-- test server random value
2132+
out = ffi.new("unsigned char[?]", 50)
2133+
sizep = ffi.new("size_t[1]", 50)
2134+
2135+
rc = ffi.C.ngx_http_lua_ffi_ssl_server_random(r, out, sizep, errmsg)
2136+
if rc ~= 0 then
2137+
ngx.log(ngx.ERR, "failed to get server random: ",
2138+
ffi.string(errmsg[0]))
2139+
ngx.status = 201 ngx.say("foo") ngx.exit(201)
2140+
return
2141+
end
2142+
2143+
local init_v = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
2144+
if ffi.string(out, sizep[0]) == init_v then
2145+
ngx.log(ngx.ERR, "maybe the server random value is incorrect")
2146+
ngx.status = 201 ngx.say("foo") ngx.exit(201)
2147+
return
2148+
end
2149+
2150+
ngx.status = 201 ngx.say("foo") ngx.exit(201)
2151+
}
2152+
more_clear_headers Date;
2153+
}
2154+
}
2155+
--- config
2156+
server_tokens off;
2157+
lua_ssl_trusted_certificate ../../cert/test.crt;
2158+
2159+
location /t {
2160+
content_by_lua_block {
2161+
do
2162+
local sock = ngx.socket.tcp()
2163+
2164+
sock:settimeout(2000)
2165+
2166+
local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock")
2167+
if not ok then
2168+
ngx.say("failed to connect: ", err)
2169+
return
2170+
end
2171+
2172+
ngx.say("connected: ", ok)
2173+
2174+
local sess, err = sock:sslhandshake(nil, "test.com", true)
2175+
if not sess then
2176+
ngx.say("failed to do SSL handshake: ", err)
2177+
return
2178+
end
2179+
2180+
ngx.say("ssl handshake: ", type(sess))
2181+
2182+
local req = "GET /foo HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n"
2183+
local bytes, err = sock:send(req)
2184+
if not bytes then
2185+
ngx.say("failed to send http request: ", err)
2186+
return
2187+
end
2188+
2189+
ngx.say("sent http request: ", bytes, " bytes.")
2190+
2191+
while true do
2192+
local line, err = sock:receive()
2193+
if not line then
2194+
-- ngx.say("failed to receive response status line: ", err)
2195+
break
2196+
end
2197+
2198+
ngx.say("received: ", line)
2199+
end
2200+
2201+
local ok, err = sock:close()
2202+
ngx.say("close: ", ok, " ", err)
2203+
end -- do
2204+
-- collectgarbage()
2205+
}
2206+
}
2207+
2208+
--- request
2209+
GET /t
2210+
--- response_body
2211+
connected: 1
2212+
ssl handshake: cdata
2213+
sent http request: 56 bytes.
2214+
received: HTTP/1.1 201 Created
2215+
received: Server: nginx
2216+
received: Content-Type: text/plain
2217+
received: Content-Length: 4
2218+
received: Connection: close
2219+
received:
2220+
received: foo
2221+
close: 1 nil
2222+
2223+
--- error_log
2224+
lua ssl server name: "test.com"
2225+
2226+
--- no_error_log
2227+
[error]
2228+
[alert]
2229+
2230+
2231+
2232+
=== TEST 21: get session master key
2233+
--- http_config
2234+
server {
2235+
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
2236+
server_name test.com;
2237+
2238+
ssl_protocols TLSv1.2;
2239+
2240+
ssl_certificate ../../cert/test.crt;
2241+
ssl_certificate_key ../../cert/test.key;
2242+
2243+
server_tokens off;
2244+
location /foo {
2245+
default_type 'text/plain';
2246+
content_by_lua_block {
2247+
collectgarbage()
2248+
2249+
local ffi = require "ffi"
2250+
require "defines"
2251+
2252+
local errmsg = ffi.new("char *[1]")
2253+
2254+
local r = require "resty.core.base" .get_request()
2255+
if r == nil then
2256+
ngx.log(ngx.ERR, "no request found")
2257+
ngx.status = 201 ngx.say("foo") ngx.exit(201)
2258+
return
2259+
end
2260+
2261+
-- test session master key length
2262+
local out = ffi.new("unsigned char[?]", 0)
2263+
local sizep = ffi.new("size_t[1]", 0)
2264+
2265+
local rc = ffi.C.ngx_http_lua_ffi_ssl_session_master_key(r, out, sizep, errmsg)
2266+
if rc ~= 0 then
2267+
ngx.log(ngx.ERR, "failed to get session master key length: ",
2268+
ffi.string(errmsg[0]))
2269+
ngx.status = 201 ngx.say("foo") ngx.exit(201)
2270+
return
2271+
end
2272+
2273+
if tonumber(sizep[0]) ~= 48 then
2274+
ngx.log(ngx.ERR, "session master key length does not equal 48, got: ",
2275+
tonumber(sizep[0]))
2276+
ngx.status = 201 ngx.say("foo") ngx.exit(201)
2277+
return
2278+
end
2279+
2280+
-- test session master key value
2281+
out = ffi.new("unsigned char[?]", 64)
2282+
sizep = ffi.new("size_t[1]", 64)
2283+
2284+
rc = ffi.C.ngx_http_lua_ffi_ssl_session_master_key(r, out, sizep, errmsg)
2285+
if rc ~= 0 then
2286+
ngx.log(ngx.ERR, "failed to get session master key: ",
2287+
ffi.string(errmsg[0]))
2288+
ngx.status = 201 ngx.say("foo") ngx.exit(201)
2289+
return
2290+
end
2291+
2292+
local init_v = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
2293+
if ffi.string(out, sizep[0]) == init_v then
2294+
ngx.log(ngx.ERR, "maybe the session master key value is incorrect")
2295+
ngx.status = 201 ngx.say("foo") ngx.exit(201)
2296+
return
2297+
end
2298+
2299+
ngx.status = 201 ngx.say("foo") ngx.exit(201)
2300+
}
2301+
more_clear_headers Date;
2302+
}
2303+
}
2304+
--- config
2305+
server_tokens off;
2306+
lua_ssl_trusted_certificate ../../cert/test.crt;
2307+
2308+
location /t {
2309+
content_by_lua_block {
2310+
do
2311+
local sock = ngx.socket.tcp()
2312+
2313+
sock:settimeout(2000)
2314+
2315+
local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock")
2316+
if not ok then
2317+
ngx.say("failed to connect: ", err)
2318+
return
2319+
end
2320+
2321+
ngx.say("connected: ", ok)
2322+
2323+
local sess, err = sock:sslhandshake(nil, "test.com", true)
2324+
if not sess then
2325+
ngx.say("failed to do SSL handshake: ", err)
2326+
return
2327+
end
2328+
2329+
ngx.say("ssl handshake: ", type(sess))
2330+
2331+
local req = "GET /foo HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n"
2332+
local bytes, err = sock:send(req)
2333+
if not bytes then
2334+
ngx.say("failed to send http request: ", err)
2335+
return
2336+
end
2337+
2338+
ngx.say("sent http request: ", bytes, " bytes.")
2339+
2340+
while true do
2341+
local line, err = sock:receive()
2342+
if not line then
2343+
-- ngx.say("failed to receive response status line: ", err)
2344+
break
2345+
end
2346+
2347+
ngx.say("received: ", line)
2348+
end
2349+
2350+
local ok, err = sock:close()
2351+
ngx.say("close: ", ok, " ", err)
2352+
end -- do
2353+
-- collectgarbage()
2354+
}
2355+
}
2356+
2357+
--- request
2358+
GET /t
2359+
--- response_body
2360+
connected: 1
2361+
ssl handshake: cdata
2362+
sent http request: 56 bytes.
2363+
received: HTTP/1.1 201 Created
2364+
received: Server: nginx
2365+
received: Content-Type: text/plain
2366+
received: Content-Length: 4
2367+
received: Connection: close
2368+
received:
2369+
received: foo
2370+
close: 1 nil
2371+
2372+
--- error_log
2373+
lua ssl server name: "test.com"
2374+
2375+
--- no_error_log
2376+
[error]
2377+
[alert]

0 commit comments

Comments
 (0)