Comparison

net/tls_luasec.lua @ 12802:4a8740e01813

Merge 0.12->trunk
author Kim Alvefur <zash@zash.se>
date Mon, 12 Dec 2022 07:10:54 +0100
parent 12486:ee93df086926
child 13115:749376d75b40
comparison
equal deleted inserted replaced
12801:ebd6b4d8bf04 12802:4a8740e01813
1 -- Prosody IM
2 -- Copyright (C) 2021 Prosody folks
3 --
4 -- This project is MIT/X11 licensed. Please see the
5 -- COPYING file in the source package for more information.
6 --
7
8 --[[
9 This file provides a shim abstraction over LuaSec, consolidating some code
10 which was previously spread between net.server backends, portmanager and
11 certmanager.
12
13 The goal is to provide a more or less well-defined API on top of LuaSec which
14 abstracts away some of the things which are not needed and simplifies usage of
15 commonly used things (such as SNI contexts). Eventually, network backends
16 which do not rely on LuaSocket+LuaSec should be able to provide *this* API
17 instead of having to mimic LuaSec.
18 ]]
19 local ssl = require "ssl";
20 local ssl_newcontext = ssl.newcontext;
21 local ssl_context = ssl.context or require "ssl.context";
22 local io_open = io.open;
23
24 local context_api = {};
25 local context_mt = {__index = context_api};
26
27 function context_api:set_sni_host(host, cert, key)
28 local ctx, err = self._builder:clone():apply({
29 certificate = cert,
30 key = key,
31 }):build();
32 if not ctx then
33 return false, err
34 end
35
36 self._sni_contexts[host] = ctx._inner
37
38 return true, nil
39 end
40
41 function context_api:remove_sni_host(host)
42 self._sni_contexts[host] = nil
43 end
44
45 function context_api:wrap(sock)
46 local ok, conn, err = pcall(ssl.wrap, sock, self._inner);
47 if not ok then
48 return nil, err
49 end
50 return conn, nil
51 end
52
53 local function new_context(cfg, builder)
54 -- LuaSec expects dhparam to be a callback that takes two arguments.
55 -- We ignore those because it is mostly used for having a separate
56 -- set of params for EXPORT ciphers, which we don't have by default.
57 if type(cfg.dhparam) == "string" then
58 local f, err = io_open(cfg.dhparam);
59 if not f then return nil, "Could not open DH parameters: "..err end
60 local dhparam = f:read("*a");
61 f:close();
62 cfg.dhparam = function() return dhparam; end
63 end
64
65 local inner, err = ssl_newcontext(cfg);
66 if not inner then
67 return nil, err
68 end
69
70 -- COMPAT Older LuaSec ignores the cipher list from the config, so we have to take care
71 -- of it ourselves (W/A for #x)
72 if inner and cfg.ciphers then
73 local success;
74 success, err = ssl_context.setcipher(inner, cfg.ciphers);
75 if not success then
76 return nil, err
77 end
78 end
79
80 return setmetatable({
81 _inner = inner,
82 _builder = builder,
83 _sni_contexts = {},
84 }, context_mt), nil
85 end
86
87 return {
88 new_context = new_context,
89 };