singe/thirdparty/copas/tests/tls-params.lua

96 lines
3.7 KiB
Lua

-- test normalization of the 'sslparams' table passed to copas.wrap()/copas.handler()
--
-- Covers the fix for https://github.com/lunarmodules/copas/issues/210:
-- * an empty (or otherwise malformed) sslparams table used to silently
-- disable TLS -- identical to passing nil -- even though the doc-comment
-- claimed it enabled TLS "with defaults". No such defaults exist (a
-- certificate is mandatory), so normalize_sslt() now only recognizes the
-- current {wrap=..., sni=...} shape by the presence of those two keys;
-- anything else (an empty table, a garbage-key table, or the legacy flat
-- luasec-context table) is passed straight through as 'wrap' parameters,
-- which LuaSec itself validates and errors on when actually used for a
-- handshake. This never fails open into silent plaintext.
-- Also checks the other supported shapes still normalize as before: no
-- params at all, the legacy flat luasec-context table, and the current
-- {wrap=..., sni=...} table.
local copas = require("copas")
local socket = require("socket")
local failures = 0
local function check(cond, msg)
if cond then
print("OK: "..msg)
else
print("FAILED: "..msg)
failures = failures + 1
end
end
-- no ssl params at all: TLS fully disabled, no error
do
local skt = copas.wrap(socket.tcp())
check(skt.ssl_params.wrap == false, "nil sslparams: wrap is false")
check(skt.ssl_params.sni == false, "nil sslparams: sni is false")
end
-- empty table: has neither 'wrap' nor 'sni' keys, so it is treated as a
-- (malformed) flat luasec-context table rather than silently disabling TLS.
-- It must never normalize to wrap==false, and using it for a handshake must
-- error rather than silently proceed unencrypted.
do
local sslt = {}
local skt = copas.wrap(socket.tcp(), sslt)
check(skt.ssl_params.wrap == sslt, "empty sslparams table: wrap is the table itself, not false")
check(skt.ssl_params.sni == false, "empty sslparams table: sni is false")
local ok, err = pcall(skt.dohandshake, skt)
check(not ok, "empty sslparams table: handshake throws instead of silently succeeding")
check(tostring(err):match("create") ~= nil,
"empty sslparams table: LuaSec's own error surfaces, got: "..tostring(err))
end
-- table with unrelated/misspelled keys: same as the empty-table case, this
-- must not be mistaken for the current {wrap=..., sni=...} format either.
do
local sslt = { just_some_key = true }
local skt = copas.wrap(socket.tcp(), sslt)
check(skt.ssl_params.wrap == sslt, "garbage-key sslparams table: wrap is the table itself, not false")
check(skt.ssl_params.sni == false, "garbage-key sslparams table: sni is false")
local ok, err = pcall(skt.dohandshake, skt)
check(not ok, "garbage-key sslparams table: handshake throws instead of silently succeeding")
check(tostring(err):match("create") ~= nil,
"garbage-key sslparams table: LuaSec's own error surfaces, got: "..tostring(err))
end
-- legacy flat table (luasec context params directly, no wrap/sni keys)
do
local sslt = {
mode = "client",
protocol = "any",
}
local skt = copas.wrap(socket.tcp(), sslt)
check(skt.ssl_params.wrap == sslt, "legacy sslparams: wrap is the sslparams table itself")
check(skt.ssl_params.sni == false, "legacy sslparams: sni is false")
end
-- current-style table with both wrap and sni set
do
local sslt = {
wrap = { mode = "client", protocol = "any" },
sni = { names = "myhost.com", strict = true },
}
local skt = copas.wrap(socket.tcp(), sslt)
check(skt.ssl_params.wrap == sslt.wrap, "current sslparams: wrap matches provided table")
check(skt.ssl_params.sni == sslt.sni, "current sslparams: sni matches provided table")
end
if failures > 0 then
print(failures.." check(s) failed")
os.exit(1)
end
print("all checks passed")
os.exit(0)