aboutsummaryrefslogtreecommitdiffstats
path: root/core/certmanager.lua
diff options
context:
space:
mode:
Diffstat (limited to 'core/certmanager.lua')
-rw-r--r--core/certmanager.lua118
1 files changed, 40 insertions, 78 deletions
diff --git a/core/certmanager.lua b/core/certmanager.lua
index 6a46588c..9e0ace6a 100644
--- a/core/certmanager.lua
+++ b/core/certmanager.lua
@@ -6,15 +6,13 @@
-- COPYING file in the source package for more information.
--
-local ssl = require "ssl";
-local configmanager = require "core.configmanager";
-local log = require "util.logger".init("certmanager");
-local ssl_context = ssl.context or require "ssl.context";
-local ssl_newcontext = ssl.newcontext;
-local new_config = require"util.sslconfig".new;
+local configmanager = require "prosody.core.configmanager";
+local log = require "prosody.util.logger".init("certmanager");
+local new_config = require"prosody.net.server".tls_builder;
+local tls = require "prosody.net.tls_luasec";
local stat = require "lfs".attributes;
-local x509 = require "util.x509";
+local x509 = require "prosody.util.x509";
local lfs = require "lfs";
local tonumber, tostring = tonumber, tostring;
@@ -28,33 +26,10 @@ local next = next;
local pcall = pcall;
local prosody = prosody;
-local pathutil = require"util.paths";
+local pathutil = require"prosody.util.paths";
local resolve_path = pathutil.resolve_relative_path;
local config_path = prosody.paths.config or ".";
-local function test_option(option)
- return not not ssl_newcontext({mode="server",protocol="sslv23",options={ option }});
-end
-
-local luasec_major, luasec_minor = ssl._VERSION:match("^(%d+)%.(%d+)");
-local luasec_version = tonumber(luasec_major) * 100 + tonumber(luasec_minor);
-local luasec_has = ssl.config or {
- algorithms = {
- ec = luasec_version >= 5;
- };
- capabilities = {
- curves_list = luasec_version >= 7;
- };
- options = {
- cipher_server_preference = test_option("cipher_server_preference");
- no_ticket = test_option("no_ticket");
- no_compression = test_option("no_compression");
- single_dh_use = test_option("single_dh_use");
- single_ecdh_use = test_option("single_ecdh_use");
- no_renegotiation = test_option("no_renegotiation");
- };
-};
-
local _ENV = nil;
-- luacheck: std none
@@ -122,7 +97,7 @@ local function index_certs(dir, files_by_name, depth_limit)
local firstline = f:read();
if firstline == "-----BEGIN CERTIFICATE-----" and lfs.attributes(find_matching_key(full), "mode") == "file" then
f:seek("set")
- local cert = ssl.loadcertificate(f:read("*a"))
+ local cert = tls.load_certificate(f:read("*a"))
-- TODO if more than one cert is found for a name, the most recently
-- issued one should be used.
-- for now, just filter out expired certs
@@ -207,18 +182,18 @@ local core_defaults = {
protocol = "tlsv1+";
verify = "none";
options = {
- cipher_server_preference = luasec_has.options.cipher_server_preference;
- no_ticket = luasec_has.options.no_ticket;
- no_compression = luasec_has.options.no_compression and configmanager.get("*", "ssl_compression") ~= true;
- single_dh_use = luasec_has.options.single_dh_use;
- single_ecdh_use = luasec_has.options.single_ecdh_use;
- no_renegotiation = luasec_has.options.no_renegotiation;
+ cipher_server_preference = tls.features.options.cipher_server_preference;
+ no_ticket = tls.features.options.no_ticket;
+ no_compression = tls.features.options.no_compression and configmanager.get("*", "ssl_compression") ~= true;
+ single_dh_use = tls.features.options.single_dh_use;
+ single_ecdh_use = tls.features.options.single_ecdh_use;
+ no_renegotiation = tls.features.options.no_renegotiation;
};
verifyext = {
"lsec_continue", -- Continue past certificate verification errors
"lsec_ignore_purpose", -- Validate client certificates as if they were server certificates
};
- curve = luasec_has.algorithms.ec and not luasec_has.capabilities.curves_list and "secp384r1";
+ curve = tls.features.algorithms.ec and not tls.features.capabilities.curves_list and "secp384r1";
curveslist = {
"X25519",
"P-384",
@@ -235,9 +210,21 @@ local core_defaults = {
"!3DES", -- 3DES - slow and of questionable security
"!aNULL", -- Ciphers that does not authenticate the connection
};
- dane = luasec_has.capabilities.dane and configmanager.get("*", "use_dane") and { "no_ee_namechecks" };
+ dane = tls.features.capabilities.dane and configmanager.get("*", "use_dane") and { "no_ee_namechecks" };
}
+-- https://datatracker.ietf.org/doc/html/rfc7919#appendix-A.1
+local ffdhe2048 = [[
+-----BEGIN DH PARAMETERS-----
+MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
+87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
+YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
+7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
+ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
+-----END DH PARAMETERS-----
+]]
+
local mozilla_ssl_configs = {
-- https://wiki.mozilla.org/Security/Server_Side_TLS
-- Version 5.7 as of 2023-07-09
@@ -250,7 +237,7 @@ local mozilla_ssl_configs = {
};
intermediate = {
protocol = "tlsv1_2+";
- dhparam = nil; -- ffdhe2048.txt
+ dhparam = ffdhe2048;
options = { cipher_server_preference = false };
ciphers = {
"ECDHE-ECDSA-AES128-GCM-SHA256";
@@ -304,9 +291,9 @@ local mozilla_ssl_configs = {
};
-if luasec_has.curves then
+if tls.features.curves then
for i = #core_defaults.curveslist, 1, -1 do
- if not luasec_has.curves[ core_defaults.curveslist[i] ] then
+ if not tls.features.curves[ core_defaults.curveslist[i] ] then
t_remove(core_defaults.curveslist, i);
end
end
@@ -314,10 +301,6 @@ else
core_defaults.curveslist = nil;
end
-local path_options = { -- These we pass through resolve_path()
- key = true, certificate = true, cafile = true, capath = true, dhparam = true
-}
-
local function create_context(host, mode, ...)
local cfg = new_config();
cfg:apply(core_defaults);
@@ -351,39 +334,12 @@ local function create_context(host, mode, ...)
if mode == "server" then
if not user_ssl_config.certificate then
- log("info", "No certificate present in SSL/TLS configuration for %s. SNI will be required.", host);
+ log("debug", "No certificate present in SSL/TLS configuration for %s. SNI will be required.", host);
end
if user_ssl_config.certificate and not user_ssl_config.key then return nil, "No key present in SSL/TLS configuration for "..host; end
end
- for option in pairs(path_options) do
- if type(user_ssl_config[option]) == "string" then
- user_ssl_config[option] = resolve_path(config_path, user_ssl_config[option]);
- else
- user_ssl_config[option] = nil;
- end
- end
-
- -- LuaSec expects dhparam to be a callback that takes two arguments.
- -- We ignore those because it is mostly used for having a separate
- -- set of params for EXPORT ciphers, which we don't have by default.
- if type(user_ssl_config.dhparam) == "string" then
- local f, err = io_open(user_ssl_config.dhparam);
- if not f then return nil, "Could not open DH parameters: "..err end
- local dhparam = f:read("*a");
- f:close();
- user_ssl_config.dhparam = function() return dhparam; end
- end
-
- local ctx, err = ssl_newcontext(user_ssl_config);
-
- -- COMPAT Older LuaSec ignores the cipher list from the config, so we have to take care
- -- of it ourselves (W/A for #x)
- if ctx and user_ssl_config.ciphers then
- local success;
- success, err = ssl_context.setcipher(ctx, user_ssl_config.ciphers);
- if not success then ctx = nil; end
- end
+ local ctx, err = cfg:build();
if not ctx then
err = err or "invalid ssl config"
@@ -422,10 +378,16 @@ end
local function reload_ssl_config()
global_ssl_config = configmanager.get("*", "ssl");
global_certificates = configmanager.get("*", "certificates") or "certs";
- if luasec_has.options.no_compression then
+ if tls.features.options.no_compression then
core_defaults.options.no_compression = configmanager.get("*", "ssl_compression") ~= true;
end
- core_defaults.dane = configmanager.get("*", "use_dane") or false;
+ if not configmanager.get("*", "use_dane") then
+ core_defaults.dane = false;
+ elseif tls.features.capabilities.dane then
+ core_defaults.dane = { "no_ee_namechecks" };
+ else
+ core_defaults.dane = true;
+ end
cert_index = index_certs(resolve_path(config_path, global_certificates));
end