Software / code / prosody
Annotate
net/tls_luasec.lua @ 13436:1ce18cb3e6cc
mod_server_info: New module to manage the serverinfo disco extension form
This allows multiple modules to populate the form dynamically. Currently the
form is "owned" by mod_server_contact_info, which prevents other modules from
contributing to it.
A further commit will port mod_server_contact_info to use this module.
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Fri, 23 Feb 2024 21:13:10 +0000 |
| parent | 13116:58e793288d9c |
| child | 13502:61da4491eebc |
| rev | line source |
|---|---|
|
12480
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
1 -- Prosody IM |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
2 -- Copyright (C) 2021 Prosody folks |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
3 -- |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
4 -- This project is MIT/X11 licensed. Please see the |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
5 -- COPYING file in the source package for more information. |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
6 -- |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
7 |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
8 --[[ |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
9 This file provides a shim abstraction over LuaSec, consolidating some code |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
10 which was previously spread between net.server backends, portmanager and |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
11 certmanager. |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
12 |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
13 The goal is to provide a more or less well-defined API on top of LuaSec which |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
14 abstracts away some of the things which are not needed and simplifies usage of |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
15 commonly used things (such as SNI contexts). Eventually, network backends |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
16 which do not rely on LuaSocket+LuaSec should be able to provide *this* API |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
17 instead of having to mimic LuaSec. |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
18 ]] |
|
12486
ee93df086926
net.tls_luasec: Harden dependency on LuaSec
Kim Alvefur <zash@zash.se>
parents:
12480
diff
changeset
|
19 local ssl = require "ssl"; |
|
12480
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
20 local ssl_newcontext = ssl.newcontext; |
|
12486
ee93df086926
net.tls_luasec: Harden dependency on LuaSec
Kim Alvefur <zash@zash.se>
parents:
12480
diff
changeset
|
21 local ssl_context = ssl.context or require "ssl.context"; |
|
12480
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
22 local io_open = io.open; |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
23 |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
24 local context_api = {}; |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
25 local context_mt = {__index = context_api}; |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
26 |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
27 function context_api:set_sni_host(host, cert, key) |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
28 local ctx, err = self._builder:clone():apply({ |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
29 certificate = cert, |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
30 key = key, |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
31 }):build(); |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
32 if not ctx then |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
33 return false, err |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
34 end |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
35 |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
36 self._sni_contexts[host] = ctx._inner |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
37 |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
38 return true, nil |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
39 end |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
40 |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
41 function context_api:remove_sni_host(host) |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
42 self._sni_contexts[host] = nil |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
43 end |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
44 |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
45 function context_api:wrap(sock) |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
46 local ok, conn, err = pcall(ssl.wrap, sock, self._inner); |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
47 if not ok then |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
48 return nil, err |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
49 end |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
50 return conn, nil |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
51 end |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
52 |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
53 local function new_context(cfg, builder) |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
54 -- LuaSec expects dhparam to be a callback that takes two arguments. |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
55 -- We ignore those because it is mostly used for having a separate |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
56 -- set of params for EXPORT ciphers, which we don't have by default. |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
57 if type(cfg.dhparam) == "string" then |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
58 local f, err = io_open(cfg.dhparam); |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
59 if not f then return nil, "Could not open DH parameters: "..err end |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
60 local dhparam = f:read("*a"); |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
61 f:close(); |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
62 cfg.dhparam = function() return dhparam; end |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
63 end |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
64 |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
65 local inner, err = ssl_newcontext(cfg); |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
66 if not inner then |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
67 return nil, err |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
68 end |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
69 |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
70 -- COMPAT Older LuaSec ignores the cipher list from the config, so we have to take care |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
71 -- of it ourselves (W/A for #x) |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
72 if inner and cfg.ciphers then |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
73 local success; |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
74 success, err = ssl_context.setcipher(inner, cfg.ciphers); |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
75 if not success then |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
76 return nil, err |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
77 end |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
78 end |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
79 |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
80 return setmetatable({ |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
81 _inner = inner, |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
82 _builder = builder, |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
83 _sni_contexts = {}, |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
84 }, context_mt), nil |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
85 end |
|
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
86 |
|
13115
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
87 -- Feature detection / guessing |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
88 local function test_option(option) |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
89 return not not ssl_newcontext({mode="server",protocol="sslv23",options={ option }}); |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
90 end |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
91 local luasec_major, luasec_minor = ssl._VERSION:match("^(%d+)%.(%d+)"); |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
92 local luasec_version = tonumber(luasec_major) * 100 + tonumber(luasec_minor); |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
93 local luasec_has = ssl.config or { |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
94 algorithms = { |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
95 ec = luasec_version >= 5; |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
96 }; |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
97 capabilities = { |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
98 curves_list = luasec_version >= 7; |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
99 }; |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
100 options = { |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
101 cipher_server_preference = test_option("cipher_server_preference"); |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
102 no_ticket = test_option("no_ticket"); |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
103 no_compression = test_option("no_compression"); |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
104 single_dh_use = test_option("single_dh_use"); |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
105 single_ecdh_use = test_option("single_ecdh_use"); |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
106 no_renegotiation = test_option("no_renegotiation"); |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
107 }; |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
108 }; |
|
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
109 |
|
12480
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
110 return { |
|
13115
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
111 features = luasec_has; |
|
12480
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
112 new_context = new_context, |
|
13116
58e793288d9c
net.tls_luasec: Expose method for loading a certificate
Kim Alvefur <zash@zash.se>
parents:
13115
diff
changeset
|
113 load_certificate = ssl.loadcertificate; |
|
12480
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
114 }; |