local testimony = require("testimony") local lev = require("lev") local testify = testimony.new("== LITLS TLS 1.3 Client ==") -- Test 1: Basic TLS handshake (no verify) to 1.1.1.1:853 (DNS over TLS) testify:that("TLS 1.3 connect to 1.1.1.1:853 (no verify)", function() lev.run(function() local sock, err = lev.connect("1.1.1.1", 853, { timeout = 5, tls = { mode = "client", verify = false, server_name = "cloudflare-dns.com", }, }) testimony.assert_not_nil(sock, "TLS connect failed: " .. tostring(err)) sock:close() end) end) -- Test 2: TLS handshake with verification to 1.1.1.1:853 testify:that("TLS 1.3 connect to 1.1.1.1:853 (with verify)", function() lev.run(function() local sock, err = lev.connect("1.1.1.1", 853, { timeout = 5, tls = { mode = "client", verify = true, server_name = "cloudflare-dns.com", cafile = "/etc/ssl/certs/ca-certificates.crt", }, }) testimony.assert_not_nil(sock, "TLS connect failed: " .. tostring(err)) sock:close() end) end) -- Test 3: HTTPS round-trip testify:that("HTTPS GET to 1.1.1.1:443", function() lev.run(function() local sock, err = lev.connect("1.1.1.1", 443, { timeout = 5, tls = { mode = "client", verify = false, server_name = "cloudflare-dns.com", }, }) testimony.assert_not_nil(sock, "TLS connect failed: " .. tostring(err)) local req = "GET / HTTP/1.1\r\nHost: 1.1.1.1\r\nConnection: close\r\n\r\n" local n, werr = sock:send(req) testimony.assert_not_nil(n, "send failed: " .. tostring(werr)) local response = "" while true do local data, rerr = sock:recv() if data then response = response .. data elseif rerr == "closed" then break else break end end testimony.assert_true(#response > 0, "empty response") testimony.assert_true(response:find("HTTP/") ~= nil, "response should contain HTTP status line") sock:close() end) end) -- Test 4: TLS handshake with verification to example.com (P-384 intermediate chain) testify:that("TLS 1.3 connect to example.com:443 (P-384 chain, with verify)", function() lev.run(function() local sock, err = lev.connect("example.com", 443, { timeout = 5, tls = { mode = "client", verify = true, server_name = "example.com", cafile = "/etc/ssl/certs/ca-certificates.crt", }, }) testimony.assert_not_nil(sock, "TLS connect failed: " .. tostring(err)) if sock then sock:close() end end) end) -- Test 5: HTTPS request to lilush.link (P-384 chain) testify:that("HTTPS GET to lilush.link (P-384 chain)", function() lev.run(function() local http = require("http") local resp, err = http.request("https://lilush.link", {}, 10) testimony.assert_not_nil(resp, "HTTP request failed: " .. tostring(err)) testimony.assert_true(resp.status == 200, "expected 200, got " .. tostring(resp and resp.status)) end) end) -- Test 6: Reject connection when verify=true but no CA file testify:that("TLS 1.3 reject untrusted cert with verify=true", function() lev.run(function() -- verify=true but no cafile => starttls_init should fail with "no trust anchors" local sock, err = lev.connect("1.1.1.1", 853, { timeout = 5, tls = { mode = "client", verify = true, server_name = "cloudflare-dns.com", -- no cafile => should fail }, }) -- Should fail during init or handshake testimony.assert_nil(sock, "should have rejected connection without trust anchors") end) end) testify:conclude()