Skip to content

Commit 8dc57c6

Browse files
author
mengxiangwei
committed
feat: add server random and master key fetch api
1 parent cac9cbc commit 8dc57c6

2 files changed

Lines changed: 348 additions & 2 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: 298 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ if ($openssl_version =~ m/built with OpenSSL (0|1\.0\.(?:0|1[^\d]|2[a-d]).*)/) {
1212
plan(skip_all => "too old OpenSSL, need >= 1.0.2e, was $1");
1313
} elsif ($openssl_version =~ m/BoringSSL/) {
1414
$ENV{TEST_NGINX_USE_BORINGSSL} = 1;
15-
plan tests => repeat_each() * (blocks() * 6 - 6);
15+
plan tests => repeat_each() * (blocks() * 6 - 3);
1616
} else {
17-
plan tests => repeat_each() * (blocks() * 5 - 5);
17+
plan tests => repeat_each() * (blocks() * 5 - 2);
1818
$ENV{TEST_NGINX_USE_OPENSSL} = 1;
1919
}
2020

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

0 commit comments

Comments
 (0)