Software /
code /
prosody
Comparison
util/sslconfig.lua @ 12480:7e9ebdc75ce4
net: isolate LuaSec-specifics
For this, various accessor functions are now provided directly on the
sockets, which reach down into the LuaSec implementation to obtain the
information.
While this may seem of little gain at first, it hides the implementation
detail of the LuaSec+LuaSocket combination that the actual socket and
the TLS layer are separate objects.
The net gain here is that an alternative implementation does not have to
emulate that specific implementation detail and "only" has to expose
LuaSec-compatible data structures on the new functions.
author | Jonas Schäfer <jonas@wielicki.name> |
---|---|
date | Wed, 27 Apr 2022 17:44:14 +0200 |
parent | 10920:c171b4c59bd1 |
child | 12481:2ee27587fec7 |
comparison
equal
deleted
inserted
replaced
12478:82270a6b1234 | 12480:7e9ebdc75ce4 |
---|---|
1 -- util to easily merge multiple sets of LuaSec context options | 1 -- util to easily merge multiple sets of LuaSec context options |
2 | 2 |
3 local type = type; | 3 local type = type; |
4 local pairs = pairs; | 4 local pairs = pairs; |
5 local rawset = rawset; | 5 local rawset = rawset; |
6 local rawget = rawget; | |
7 local error = error; | |
6 local t_concat = table.concat; | 8 local t_concat = table.concat; |
7 local t_insert = table.insert; | 9 local t_insert = table.insert; |
8 local setmetatable = setmetatable; | 10 local setmetatable = setmetatable; |
11 local config_path = prosody.paths.config or "."; | |
12 local resolve_path = require"util.paths".resolve_relative_path; | |
13 | |
14 -- TODO: use net.server directly here | |
15 local tls_impl = require"net.tls_luasec"; | |
9 | 16 |
10 local _ENV = nil; | 17 local _ENV = nil; |
11 -- luacheck: std none | 18 -- luacheck: std none |
12 | 19 |
13 local handlers = { }; | 20 local handlers = { }; |
32 options[key] = value; | 39 options[key] = value; |
33 else -- list item | 40 else -- list item |
34 options[value] = true; | 41 options[value] = true; |
35 end | 42 end |
36 end | 43 end |
37 config[field] = options; | 44 rawset(config, field, options) |
38 end | 45 end |
39 | 46 |
40 handlers.verifyext = handlers.options; | 47 handlers.verifyext = handlers.options; |
41 | 48 |
42 -- finalisers take something produced by handlers and return what luasec | 49 -- finalisers take something produced by handlers and return what luasec |
68 finalisers.curveslist = finalisers.ciphers; | 75 finalisers.curveslist = finalisers.ciphers; |
69 | 76 |
70 -- TLS 1.3 ciphers | 77 -- TLS 1.3 ciphers |
71 finalisers.ciphersuites = finalisers.ciphers; | 78 finalisers.ciphersuites = finalisers.ciphers; |
72 | 79 |
80 -- Path expansion | |
81 function finalisers.key(path) | |
82 if type(path) == "string" then | |
83 return resolve_path(config_path, path); | |
84 else | |
85 return nil | |
86 end | |
87 end | |
88 finalisers.certificate = finalisers.key; | |
89 finalisers.cafile = finalisers.key; | |
90 finalisers.capath = finalisers.key; | |
91 -- XXX: copied from core/certmanager.lua, but this seems odd, because it would remove a dhparam function from the config | |
92 finalisers.dhparam = finalisers.key; | |
93 | |
73 -- protocol = "x" should enable only that protocol | 94 -- protocol = "x" should enable only that protocol |
74 -- protocol = "x+" should enable x and later versions | 95 -- protocol = "x+" should enable x and later versions |
75 | 96 |
76 local protocols = { "sslv2", "sslv3", "tlsv1", "tlsv1_1", "tlsv1_2", "tlsv1_3" }; | 97 local protocols = { "sslv2", "sslv3", "tlsv1", "tlsv1_1", "tlsv1_2", "tlsv1_3" }; |
77 for i = 1, #protocols do protocols[protocols[i] .. "+"] = i - 1; end | 98 for i = 1, #protocols do protocols[protocols[i] .. "+"] = i - 1; end |
87 end | 108 end |
88 end | 109 end |
89 | 110 |
90 -- Merge options from 'new' config into 'config' | 111 -- Merge options from 'new' config into 'config' |
91 local function apply(config, new) | 112 local function apply(config, new) |
113 -- 0 == cache | |
114 rawset(config, 0, nil); | |
92 if type(new) == "table" then | 115 if type(new) == "table" then |
93 for field, value in pairs(new) do | 116 for field, value in pairs(new) do |
94 (handlers[field] or rawset)(config, field, value); | 117 (handlers[field] or rawset)(config, field, value); |
95 end | 118 end |
96 end | 119 end |
120 return config | |
97 end | 121 end |
98 | 122 |
99 -- Finalize the config into the form LuaSec expects | 123 -- Finalize the config into the form LuaSec expects |
100 local function final(config) | 124 local function final(config) |
101 local output = { }; | 125 local output = { }; |
105 -- Need to handle protocols last because it adds to the options list | 129 -- Need to handle protocols last because it adds to the options list |
106 protocol(output); | 130 protocol(output); |
107 return output; | 131 return output; |
108 end | 132 end |
109 | 133 |
134 local function build(config) | |
135 local cached = rawget(config, 0); | |
136 if cached then | |
137 return cached, nil | |
138 end | |
139 | |
140 local ctx, err = tls_impl.new_context(config:final(), config); | |
141 if ctx then | |
142 rawset(config, 0, ctx); | |
143 end | |
144 return ctx, err | |
145 end | |
146 | |
110 local sslopts_mt = { | 147 local sslopts_mt = { |
111 __index = { | 148 __index = { |
112 apply = apply; | 149 apply = apply; |
113 final = final; | 150 final = final; |
151 build = build; | |
114 }; | 152 }; |
153 __newindex = function() | |
154 error("SSL config objects cannot be modified directly. Use :apply()") | |
155 end; | |
115 }; | 156 }; |
157 | |
116 | 158 |
117 local function new() | 159 local function new() |
118 return setmetatable({options={}}, sslopts_mt); | 160 return setmetatable({options={}}, sslopts_mt); |
119 end | 161 end |
162 | |
163 local function clone(config) | |
164 local result = new(); | |
165 for k, v in pairs(config) do | |
166 rawset(result, k, v); | |
167 end | |
168 return result | |
169 end | |
170 | |
171 sslopts_mt.__index.clone = clone; | |
120 | 172 |
121 return { | 173 return { |
122 apply = apply; | 174 apply = apply; |
123 final = final; | 175 final = final; |
124 new = new; | 176 new = new; |