-
Notifications
You must be signed in to change notification settings - Fork 71
/
tls-sni.lua
110 lines (92 loc) · 3 KB
/
tls-sni.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
-- Tests Copas with a simple Echo server
--
-- Run the test file and the connect to the server using telnet on the used port.
-- The server should be able to echo any input, to stop the test just send the command "quit"
local port = 20000
local copas = require("copas")
local socket = require("socket")
local ssl = require("ssl")
local server
if _VERSION=="Lua 5.1" and not jit then -- obsolete: only for Lua 5.1 compatibility
pcall = require("coxpcall").pcall -- luacheck: ignore
end
local server_params = {
wrap = {
mode = "server",
protocol = "any",
key = "tests/certs/serverAkey.pem",
certificate = "tests/certs/serverA.pem",
cafile = "tests/certs/rootA.pem",
verify = {"peer", "fail_if_no_peer_cert"},
options = {"all", "no_sslv2", "no_sslv3", "no_tlsv1"},
},
sni = {
strict = true, -- only allow connection 'myhost.com'
names = {}
}
}
server_params.sni.names["myhost.com"] = ssl.newcontext(server_params.wrap)
local client_params = {
wrap = {
mode = "client",
protocol = "any",
key = "tests/certs/clientAkey.pem",
certificate = "tests/certs/clientA.pem",
cafile = "tests/certs/rootA.pem",
verify = {"peer", "fail_if_no_peer_cert"},
options = {"all", "no_sslv2", "no_sslv3", "no_tlsv1"},
},
sni = {
names = "" -- will be added in test below
}
}
local function echoHandler(skt)
while true do
local data, err = skt:receive()
if not data then
if err ~= "closed" then
return error("client connection error: "..tostring(err))
else
return -- client closed the connection
end
elseif data == "quit" then
return -- close this client connection
elseif data == "exit" then
copas.removeserver(server)
return -- close this client connection, after stopping the server
end
skt:send(data.."\n")
end
end
server = assert(socket.bind("*", port))
copas.addserver(server, copas.handler(echoHandler, server_params))
copas.addthread(function()
copas.pause(0.5) -- allow server socket to be ready
----------------------
-- Tests start here --
----------------------
-- try with a bad SNI (non matching)
client_params.sni.names = "badhost.com"
local skt = copas.wrap(socket.tcp(), client_params)
local _, err = pcall(skt.connect, skt, "localhost", port)
if not tostring(err):match("TLS/SSL handshake failed:") then
print "expected handshake to fail"
os.exit(1)
end
-- try again with a proper SNI (matching)
client_params.sni.names = "myhost.com"
local skt = copas.wrap(socket.tcp(), client_params)
local success, ok = pcall(skt.connect, skt, "localhost", port)
if not (success and ok) then
print("expected connection to be completed", success, ok)
os.exit(1)
end
assert(skt:send("hello world\n"))
assert(skt:receive() == "hello world")
print "succesfully completed test"
-- send exit signal to server
skt:send("exit\n")
end)
-- no ugly errors please, comment out when debugging
copas.setErrorHandler(function() end, true)
copas.loop()