Software /
code /
prosody
Annotate
net/tls_luasec.lua @ 13724:650f3869de82
Merge 13.0->trunk
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sun, 16 Feb 2025 14:29:02 +0000 |
parent | 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. |
13502
61da4491eebc
util.sslconfig: Support DH parameters as literal string
Kim Alvefur <zash@zash.se>
parents:
13116
diff
changeset
|
57 if type(cfg.dhparam) == "string" and cfg.dhparam:sub(1, 10) == "-----BEGIN" then |
61da4491eebc
util.sslconfig: Support DH parameters as literal string
Kim Alvefur <zash@zash.se>
parents:
13116
diff
changeset
|
58 local dhparam = cfg.dhparam; |
61da4491eebc
util.sslconfig: Support DH parameters as literal string
Kim Alvefur <zash@zash.se>
parents:
13116
diff
changeset
|
59 cfg.dhparam = function() return dhparam; end |
61da4491eebc
util.sslconfig: Support DH parameters as literal string
Kim Alvefur <zash@zash.se>
parents:
13116
diff
changeset
|
60 elseif type(cfg.dhparam) == "string" then |
12480
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
61 local f, err = io_open(cfg.dhparam); |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
62 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
|
63 local dhparam = f:read("*a"); |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
64 f:close(); |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
65 cfg.dhparam = function() return dhparam; end |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
66 end |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
67 |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
68 local inner, err = ssl_newcontext(cfg); |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
69 if not inner then |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
70 return nil, err |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
71 end |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
72 |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
73 -- 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
|
74 -- of it ourselves (W/A for #x) |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
75 if inner and cfg.ciphers then |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
76 local success; |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
77 success, err = ssl_context.setcipher(inner, cfg.ciphers); |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
78 if not success then |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
79 return nil, err |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
80 end |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
81 end |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
82 |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
83 return setmetatable({ |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
84 _inner = inner, |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
85 _builder = builder, |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
86 _sni_contexts = {}, |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
87 }, context_mt), nil |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
88 end |
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
89 |
13115
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
90 -- Feature detection / guessing |
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
91 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
|
92 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
|
93 end |
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
94 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
|
95 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
|
96 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
|
97 algorithms = { |
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
98 ec = luasec_version >= 5; |
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 capabilities = { |
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
101 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
|
102 }; |
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
103 options = { |
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
104 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
|
105 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
|
106 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
|
107 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
|
108 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
|
109 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
|
110 }; |
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
111 }; |
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
112 |
12480
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
113 return { |
13115
749376d75b40
net.certmanager: Move LuaSec feature detection to net.tls_luasec
Kim Alvefur <zash@zash.se>
parents:
12486
diff
changeset
|
114 features = luasec_has; |
12480
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
115 new_context = new_context, |
13116
58e793288d9c
net.tls_luasec: Expose method for loading a certificate
Kim Alvefur <zash@zash.se>
parents:
13115
diff
changeset
|
116 load_certificate = ssl.loadcertificate; |
12480
7e9ebdc75ce4
net: isolate LuaSec-specifics
Jonas Schäfer <jonas@wielicki.name>
parents:
diff
changeset
|
117 }; |