comparison util/tlsref.lua @ 14221:565debd9c37a

Merge 13.0->trunk
author Matthew Wild <mwild1@gmail.com>
date Fri, 12 Jun 2026 13:05:10 +0100
parents 926f25af2ffe
children ad7f7b5f4792
comparison
equal deleted inserted replaced
14216:2ec517d8d43e 14221:565debd9c37a
1 local array = require "prosody.util.array";
2 local it = require "prosody.util.iterators";
3 local version_compare = require "prosody.util.human.io".simple_version_compare;
4
5 local latest_version = "6.0"
6 local default_version = "5.7";
7 local default_profile = "intermediate"; -- should exist in all profiles
8
9 -- https://datatracker.ietf.org/doc/html/rfc7919#appendix-A.1
10 local ffdhe2048 = [[
11 -----BEGIN DH PARAMETERS-----
12 MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
13 +8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
14 87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
15 YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
16 7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
17 ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
18 -----END DH PARAMETERS-----
19 ]];
20
21 local profiles = {
22 -- https://wiki.mozilla.org/Security/Server_Side_TLS
23 ["6.0"] = {
24 -- Version 6.0 as of 2026-04-08
25 modern = {
26 protocol = "tlsv1_3";
27 options = { cipher_server_preference = false };
28 ciphers = "DEFAULT"; -- TLS 1.3 uses 'ciphersuites' rather than these
29 curveslist = { "X25519MLKEM768"; "X25519"; "prime256v1"; "secp384r1" };
30 ciphersuites = { "TLS_AES_128_GCM_SHA256"; "TLS_AES_256_GCM_SHA384"; "TLS_CHACHA20_POLY1305_SHA256" };
31 };
32 intermediate = {
33 protocol = "tlsv1_2+";
34 dhparam = ffdhe2048;
35 options = { cipher_server_preference = false };
36 ciphers = {
37 "ECDHE-ECDSA-AES128-GCM-SHA256";
38 "ECDHE-RSA-AES128-GCM-SHA256";
39 "ECDHE-ECDSA-AES256-GCM-SHA384";
40 "ECDHE-RSA-AES256-GCM-SHA384";
41 "ECDHE-ECDSA-CHACHA20-POLY1305";
42 "ECDHE-RSA-CHACHA20-POLY1305";
43 };
44 curveslist = { "X25519MLKEM768"; "X25519"; "prime256v1"; "secp384r1" };
45 ciphersuites = { "TLS_AES_128_GCM_SHA256"; "TLS_AES_256_GCM_SHA384"; "TLS_CHACHA20_POLY1305_SHA256" };
46 };
47 };
48
49 ["5.8"] = {
50 -- Version 5.8 as of 2026-04-08
51 modern = {
52 protocol = "tlsv1_3";
53 options = { cipher_server_preference = false };
54 ciphers = "DEFAULT"; -- TLS 1.3 uses 'ciphersuites' rather than these
55 curveslist = { "X25519MLKEM768"; "X25519"; "prime256v1"; "secp384r1" };
56 ciphersuites = { "TLS_AES_128_GCM_SHA256"; "TLS_AES_256_GCM_SHA384"; "TLS_CHACHA20_POLY1305_SHA256" };
57 };
58 intermediate = {
59 protocol = "tlsv1_2+";
60 dhparam = ffdhe2048;
61 options = { cipher_server_preference = false };
62 ciphers = {
63 "ECDHE-ECDSA-AES128-GCM-SHA256";
64 "ECDHE-RSA-AES128-GCM-SHA256";
65 "ECDHE-ECDSA-AES256-GCM-SHA384";
66 "ECDHE-RSA-AES256-GCM-SHA384";
67 "ECDHE-ECDSA-CHACHA20-POLY1305";
68 "ECDHE-RSA-CHACHA20-POLY1305";
69 };
70 curveslist = { "X25519MLKEM768"; "X25519"; "prime256v1"; "secp384r1" };
71 ciphersuites = { "TLS_AES_128_GCM_SHA256"; "TLS_AES_256_GCM_SHA384"; "TLS_CHACHA20_POLY1305_SHA256" };
72 };
73 old = {
74 protocol = "tlsv1+";
75 dhparam = ffdhe2048;
76 options = { cipher_server_preference = true };
77 ciphers = {
78 "ECDHE-ECDSA-AES128-GCM-SHA256";
79 "ECDHE-RSA-AES128-GCM-SHA256";
80 "ECDHE-ECDSA-AES256-GCM-SHA384";
81 "ECDHE-RSA-AES256-GCM-SHA384";
82 "ECDHE-ECDSA-CHACHA20-POLY1305";
83 "ECDHE-RSA-CHACHA20-POLY1305";
84 "ECDHE-ECDSA-AES128-SHA256";
85 "ECDHE-RSA-AES128-SHA256";
86 "ECDHE-ECDSA-AES128-SHA";
87 "ECDHE-RSA-AES128-SHA";
88 "ECDHE-ECDSA-AES256-SHA384";
89 "ECDHE-RSA-AES256-SHA384";
90 "ECDHE-ECDSA-AES256-SHA";
91 "ECDHE-RSA-AES256-SHA";
92 "AES128-GCM-SHA256";
93 "AES256-GCM-SHA384";
94 "AES128-SHA256";
95 "AES256-SHA256";
96 "AES128-SHA";
97 "AES256-SHA";
98 "DES-CBC3-SHA";
99 };
100 curveslist = { "X25519MLKEM768"; "X25519"; "prime256v1"; "secp384r1" };
101 ciphersuites = { "TLS_AES_128_GCM_SHA256"; "TLS_AES_256_GCM_SHA384"; "TLS_CHACHA20_POLY1305_SHA256" };
102 };
103 };
104
105 ["5.7"] = {
106 -- Version 5.7 as of 2023-07-09
107 modern = {
108 protocol = "tlsv1_3";
109 options = { cipher_server_preference = false };
110 ciphers = "DEFAULT"; -- TLS 1.3 uses 'ciphersuites' rather than these
111 curveslist = { "X25519"; "prime256v1"; "secp384r1" };
112 ciphersuites = { "TLS_AES_128_GCM_SHA256"; "TLS_AES_256_GCM_SHA384"; "TLS_CHACHA20_POLY1305_SHA256" };
113 };
114 intermediate = {
115 protocol = "tlsv1_2+";
116 dhparam = ffdhe2048;
117 options = { cipher_server_preference = false };
118 ciphers = {
119 "ECDHE-ECDSA-AES128-GCM-SHA256";
120 "ECDHE-RSA-AES128-GCM-SHA256";
121 "ECDHE-ECDSA-AES256-GCM-SHA384";
122 "ECDHE-RSA-AES256-GCM-SHA384";
123 "ECDHE-ECDSA-CHACHA20-POLY1305";
124 "ECDHE-RSA-CHACHA20-POLY1305";
125 "DHE-RSA-AES128-GCM-SHA256";
126 "DHE-RSA-AES256-GCM-SHA384";
127 "DHE-RSA-CHACHA20-POLY1305";
128 };
129 curveslist = { "X25519"; "prime256v1"; "secp384r1" };
130 ciphersuites = { "TLS_AES_128_GCM_SHA256"; "TLS_AES_256_GCM_SHA384"; "TLS_CHACHA20_POLY1305_SHA256" };
131 };
132 old = {
133 protocol = "tlsv1+";
134 dhparam = nil; -- openssl dhparam 1024
135 options = { cipher_server_preference = true };
136 ciphers = {
137 "ECDHE-ECDSA-AES128-GCM-SHA256";
138 "ECDHE-RSA-AES128-GCM-SHA256";
139 "ECDHE-ECDSA-AES256-GCM-SHA384";
140 "ECDHE-RSA-AES256-GCM-SHA384";
141 "ECDHE-ECDSA-CHACHA20-POLY1305";
142 "ECDHE-RSA-CHACHA20-POLY1305";
143 "DHE-RSA-AES128-GCM-SHA256";
144 "DHE-RSA-AES256-GCM-SHA384";
145 "DHE-RSA-CHACHA20-POLY1305";
146 "ECDHE-ECDSA-AES128-SHA256";
147 "ECDHE-RSA-AES128-SHA256";
148 "ECDHE-ECDSA-AES128-SHA";
149 "ECDHE-RSA-AES128-SHA";
150 "ECDHE-ECDSA-AES256-SHA384";
151 "ECDHE-RSA-AES256-SHA384";
152 "ECDHE-ECDSA-AES256-SHA";
153 "ECDHE-RSA-AES256-SHA";
154 "DHE-RSA-AES128-SHA256";
155 "DHE-RSA-AES256-SHA256";
156 "AES128-GCM-SHA256";
157 "AES256-GCM-SHA384";
158 "AES128-SHA256";
159 "AES256-SHA256";
160 "AES128-SHA";
161 "AES256-SHA";
162 "DES-CBC3-SHA";
163 };
164 curveslist = { "X25519"; "prime256v1"; "secp384r1" };
165 ciphersuites = { "TLS_AES_128_GCM_SHA256"; "TLS_AES_256_GCM_SHA384"; "TLS_CHACHA20_POLY1305_SHA256" };
166 };
167 };
168 };
169
170 local function get_valid_versions()
171 return array.collect(it.keys(profiles)):sort(version_compare):reverse();
172 end
173
174 local pref_order = { modern = 100, intermediate = 50, old = 0 };
175
176 local function sort_profile_by_pref(a, b)
177 local pref_a, pref_b = pref_order[a] or 0, pref_order[b] or 0;
178 return pref_a > pref_b; -- Best first
179 end
180
181 local function get_valid_profile_names(version)
182 if version == "latest" then
183 version = latest_version;
184 end
185 local version_profiles = profiles[version or default_version];
186 if not version_profiles then
187 return nil, "unknown-version";
188 end
189 return array.collect(it.keys(version_profiles)):sort(sort_profile_by_pref);
190 end
191
192 local function get_profile(version, profile_name)
193 if version == "latest" then
194 version = latest_version;
195 end
196 local version_profiles = profiles[version or default_version];
197 if not version_profiles then
198 return nil, "unknown-version";
199 end
200 local profile = version_profiles[profile_name or default_profile];
201 if not profile then
202 return nil, "unknown-profile";
203 end
204 return profile;
205 end
206
207 local function get_default_version()
208 return default_version;
209 end
210
211 local function get_latest_version()
212 return latest_version;
213 end
214
215 local function get_default_profile_name(version)
216 -- Default profile name is currently the same across all versions,
217 -- but can't guarantee this in the future - ensure valid version
218 if version ~= "latest" and not profiles[version or default_version] then
219 return nil, "unknown-version";
220 end
221 return default_profile;
222 end
223
224 return {
225 profiles = profiles;
226 get_default_version = get_default_version;
227 get_latest_version = get_latest_version;
228 get_default_profile_name = get_default_profile_name;
229 get_valid_versions = get_valid_versions;
230 get_valid_profile_names = get_valid_profile_names;
231 get_profile = get_profile;
232 };