Annotate

util/x509.lua @ 13745:994ea8d54b72 13.0

core.configmanager: Pass name and line number in context Delays the string interpolation until the warning is logged, which may slightly lower memory usage. Allows retrieving the filename and line number easily.
author Kim Alvefur <zash@zash.se>
date Sat, 22 Feb 2025 00:04:51 +0100
parent 13729:b50eadfddd57
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3651
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
1 -- Prosody IM
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
2 -- Copyright (C) 2010 Matthew Wild
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
3 -- Copyright (C) 2010 Paul Aurich
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
4 --
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
5 -- This project is MIT/X11 licensed. Please see the
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
6 -- COPYING file in the source package for more information.
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
7 --
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
8
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
9 -- TODO: I feel a fair amount of this logic should be integrated into Luasec,
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
10 -- so that everyone isn't re-inventing the wheel. Dependencies on
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
11 -- IDN libraries complicate that.
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
12
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
13
13729
b50eadfddd57 util.x509: Per RFC 9525, remove obsolete Common Name check
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
14 -- [TLS-CERTS] - https://www.rfc-editor.org/rfc/rfc6125.html -- Obsolete
b50eadfddd57 util.x509: Per RFC 9525, remove obsolete Common Name check
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
15 -- [TLS-IDENT] - https://www.rfc-editor.org/rfc/rfc9525.html
12604
bd9e006a7a74 various: Update IETF RFC URLs for tools.ietf.org transition
Kim Alvefur <zash@zash.se>
parents: 12106
diff changeset
16 -- [XMPP-CORE] - https://www.rfc-editor.org/rfc/rfc6120.html
bd9e006a7a74 various: Update IETF RFC URLs for tools.ietf.org transition
Kim Alvefur <zash@zash.se>
parents: 12106
diff changeset
17 -- [SRV-ID] - https://www.rfc-editor.org/rfc/rfc4985.html
bd9e006a7a74 various: Update IETF RFC URLs for tools.ietf.org transition
Kim Alvefur <zash@zash.se>
parents: 12106
diff changeset
18 -- [IDNA] - https://www.rfc-editor.org/rfc/rfc5890.html
bd9e006a7a74 various: Update IETF RFC URLs for tools.ietf.org transition
Kim Alvefur <zash@zash.se>
parents: 12106
diff changeset
19 -- [LDAP] - https://www.rfc-editor.org/rfc/rfc4519.html
bd9e006a7a74 various: Update IETF RFC URLs for tools.ietf.org transition
Kim Alvefur <zash@zash.se>
parents: 12106
diff changeset
20 -- [PKIX] - https://www.rfc-editor.org/rfc/rfc5280.html
3651
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
21
12975
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12812
diff changeset
22 local nameprep = require "prosody.util.encodings".stringprep.nameprep;
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12812
diff changeset
23 local idna_to_ascii = require "prosody.util.encodings".idna.to_ascii;
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12812
diff changeset
24 local idna_to_unicode = require "prosody.util.encodings".idna.to_unicode;
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12812
diff changeset
25 local base64 = require "prosody.util.encodings".base64;
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12812
diff changeset
26 local log = require "prosody.util.logger".init("x509");
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12812
diff changeset
27 local mt = require "prosody.util.multitable";
4486
f04db5e7e90d user.x509: Add some utility functions for generating OpenSSL configs
Kim Alvefur <zash@zash.se>
parents: 4330
diff changeset
28 local s_format = string.format;
10259
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
29 local ipairs = ipairs;
3651
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
30
6777
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6708
diff changeset
31 local _ENV = nil;
8555
4f0f5b49bb03 vairious: Add annotation when an empty environment is set [luacheck]
Kim Alvefur <zash@zash.se>
parents: 6777
diff changeset
32 -- luacheck: std none
3651
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
33
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
34 local oid_commonname = "2.5.4.3"; -- [LDAP] 2.3
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
35 local oid_subjectaltname = "2.5.29.17"; -- [PKIX] 4.2.1.6
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
36 local oid_xmppaddr = "1.3.6.1.5.5.7.8.5"; -- [XMPP-CORE]
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
37 local oid_dnssrv = "1.3.6.1.5.5.7.8.7"; -- [SRV-ID]
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
38
13729
b50eadfddd57 util.x509: Per RFC 9525, remove obsolete Common Name check
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
39 -- Compare a hostname (possibly international) with asserted names extracted from a certificate.
b50eadfddd57 util.x509: Per RFC 9525, remove obsolete Common Name check
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
40 -- This function follows the rules laid out in section 6.3 of [TLS-IDENT]
3651
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
41 --
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
42 -- A wildcard ("*") all by itself is allowed only as the left-most label
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
43 local function compare_dnsname(host, asserted_names)
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
44 -- TODO: Sufficient normalization? Review relevant specs.
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
45 local norm_host = idna_to_ascii(host)
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
46 if norm_host == nil then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
47 log("info", "Host %s failed IDNA ToASCII operation", host)
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
48 return false
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
49 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
50
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
51 norm_host = norm_host:lower()
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
52
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
53 local host_chopped = norm_host:gsub("^[^.]+%.", "") -- everything after the first label
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
54
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
55 for i=1,#asserted_names do
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
56 local name = asserted_names[i]
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
57 if norm_host == name:lower() then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
58 log("debug", "Cert dNSName %s matched hostname", name);
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
59 return true
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
60 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
61
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
62 -- Allow the left most label to be a "*"
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
63 if name:match("^%*%.") then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
64 local rest_name = name:gsub("^[^.]+%.", "")
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
65 if host_chopped == rest_name:lower() then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
66 log("debug", "Cert dNSName %s matched hostname", name);
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
67 return true
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
68 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
69 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
70 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
71
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
72 return false
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
73 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
74
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
75 -- Compare an XMPP domain name with the asserted id-on-xmppAddr
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
76 -- identities extracted from a certificate. Both are UTF8 strings.
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
77 --
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
78 -- Per [XMPP-CORE], matches against asserted identities don't include
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
79 -- wildcards, so we just do a normalize on both and then a string comparison
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
80 --
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
81 -- TODO: Support for full JIDs?
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
82 local function compare_xmppaddr(host, asserted_names)
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
83 local norm_host = nameprep(host)
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
84
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
85 for i=1,#asserted_names do
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
86 local name = asserted_names[i]
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
87
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
88 -- We only want to match against bare domains right now, not
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
89 -- those crazy full-er JIDs.
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
90 if name:match("[@/]") then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
91 log("debug", "Ignoring xmppAddr %s because it's not a bare domain", name)
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
92 else
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
93 local norm_name = nameprep(name)
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
94 if norm_name == nil then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
95 log("info", "Ignoring xmppAddr %s, failed nameprep!", name)
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
96 else
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
97 if norm_host == norm_name then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
98 log("debug", "Cert xmppAddr %s matched hostname", name)
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
99 return true
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
100 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
101 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
102 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
103 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
104
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
105 return false
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
106 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
107
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
108 -- Compare a host + service against the asserted id-on-dnsSRV (SRV-ID)
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
109 -- identities extracted from a certificate.
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
110 --
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
111 -- Per [SRV-ID], the asserted identities will be encoded in ASCII via ToASCII.
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
112 -- Comparison is done case-insensitively, and a wildcard ("*") all by itself
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
113 -- is allowed only as the left-most non-service label.
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
114 local function compare_srvname(host, service, asserted_names)
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
115 local norm_host = idna_to_ascii(host)
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
116 if norm_host == nil then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
117 log("info", "Host %s failed IDNA ToASCII operation", host);
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
118 return false
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
119 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
120
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
121 -- Service names start with a "_"
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
122 if service:match("^_") == nil then service = "_"..service end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
123
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
124 norm_host = norm_host:lower();
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
125 local host_chopped = norm_host:gsub("^[^.]+%.", "") -- everything after the first label
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
126
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
127 for i=1,#asserted_names do
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
128 local asserted_service, name = asserted_names[i]:match("^(_[^.]+)%.(.*)");
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
129 if service == asserted_service then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
130 if norm_host == name:lower() then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
131 log("debug", "Cert SRVName %s matched hostname", name);
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
132 return true;
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
133 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
134
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
135 -- Allow the left most label to be a "*"
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
136 if name:match("^%*%.") then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
137 local rest_name = name:gsub("^[^.]+%.", "")
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
138 if host_chopped == rest_name:lower() then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
139 log("debug", "Cert SRVName %s matched hostname", name)
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
140 return true
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
141 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
142 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
143 if norm_host == name:lower() then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
144 log("debug", "Cert SRVName %s matched hostname", name);
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
145 return true
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
146 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
147 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
148 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
149
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
150 return false
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
151 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
152
6777
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6708
diff changeset
153 local function verify_identity(host, service, cert)
6708
d2beb98ece29 util.x509: Tell LuaSec we want UTF-8 data
Kim Alvefur <zash@zash.se>
parents: 6153
diff changeset
154 if cert.setencode then
d2beb98ece29 util.x509: Tell LuaSec we want UTF-8 data
Kim Alvefur <zash@zash.se>
parents: 6153
diff changeset
155 cert:setencode("utf8");
d2beb98ece29 util.x509: Tell LuaSec we want UTF-8 data
Kim Alvefur <zash@zash.se>
parents: 6153
diff changeset
156 end
3651
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
157 local ext = cert:extensions()
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
158 if ext[oid_subjectaltname] then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
159 local sans = ext[oid_subjectaltname];
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
160
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
161 if sans[oid_xmppaddr] then
5845
c48f717c2fd6 util.x509: Only compare identity with oid-on-xmppAddr for XMPP services
Kim Alvefur <zash@zash.se>
parents: 4825
diff changeset
162 if service == "_xmpp-client" or service == "_xmpp-server" then
c48f717c2fd6 util.x509: Only compare identity with oid-on-xmppAddr for XMPP services
Kim Alvefur <zash@zash.se>
parents: 4825
diff changeset
163 if compare_xmppaddr(host, sans[oid_xmppaddr]) then return true end
c48f717c2fd6 util.x509: Only compare identity with oid-on-xmppAddr for XMPP services
Kim Alvefur <zash@zash.se>
parents: 4825
diff changeset
164 end
3651
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
165 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
166
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
167 if sans[oid_dnssrv] then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
168 -- Only check srvNames if the caller specified a service
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
169 if service and compare_srvname(host, service, sans[oid_dnssrv]) then return true end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
170 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
171
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
172 if sans["dNSName"] then
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
173 if compare_dnsname(host, sans["dNSName"]) then return true end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
174 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
175 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
176
13729
b50eadfddd57 util.x509: Per RFC 9525, remove obsolete Common Name check
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
177 -- Per [TLS-IDENT] ignore the Common Name
b50eadfddd57 util.x509: Per RFC 9525, remove obsolete Common Name check
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
178 -- The server identity can only be expressed in the subjectAltNames extension;
b50eadfddd57 util.x509: Per RFC 9525, remove obsolete Common Name check
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
179 -- it is no longer valid to use the commonName RDN, known as CN-ID in [TLS-CERTS].
3651
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
180
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
181 -- If all else fails, well, why should we be any different?
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
182 return false
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
183 end
337391d34b70 s2s: SASL EXTERNAL
Paul Aurich <paul@darkrain42.org>
parents:
diff changeset
184
9907
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
185 -- TODO Support other SANs
10259
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
186 local function get_identities(cert) --> map of names to sets of services
9907
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
187 if cert.setencode then
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
188 cert:setencode("utf8");
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
189 end
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
190
10259
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
191 local names = mt.new();
9907
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
192
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
193 local ext = cert:extensions();
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
194 local sans = ext[oid_subjectaltname];
10259
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
195 if sans then
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
196 if sans["dNSName"] then -- Valid for any service
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
197 for _, name in ipairs(sans["dNSName"]) do
12106
c0cb8e86ad21 util.x509: Fix to include wildcard identity
Kim Alvefur <zash@zash.se>
parents: 10494
diff changeset
198 local is_wildcard = name:sub(1, 2) == "*.";
c0cb8e86ad21 util.x509: Fix to include wildcard identity
Kim Alvefur <zash@zash.se>
parents: 10494
diff changeset
199 if is_wildcard then name = name:sub(3); end
10259
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
200 name = idna_to_unicode(nameprep(name));
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
201 if name then
12106
c0cb8e86ad21 util.x509: Fix to include wildcard identity
Kim Alvefur <zash@zash.se>
parents: 10494
diff changeset
202 if is_wildcard then name = "*." .. name; end
10259
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
203 names:set(name, "*", true);
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
204 end
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
205 end
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
206 end
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
207 if sans[oid_xmppaddr] then
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
208 for _, name in ipairs(sans[oid_xmppaddr]) do
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
209 name = nameprep(name);
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
210 if name then
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
211 names:set(name, "xmpp-client", true);
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
212 names:set(name, "xmpp-server", true);
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
213 end
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
214 end
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
215 end
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
216 if sans[oid_dnssrv] then
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
217 for _, srvname in ipairs(sans[oid_dnssrv]) do
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
218 local srv, name = srvname:match("^_([^.]+)%.(.*)");
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
219 if srv then
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
220 name = nameprep(name);
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
221 if name then
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
222 names:set(name, srv, true);
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
223 end
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
224 end
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
225 end
9907
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
226 end
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
227 end
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
228
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
229 local subject = cert:subject();
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
230 for i = 1, #subject do
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
231 local dn = subject[i];
10255
8e8d3b3a55da util.x509: Nameprep commonName once
Kim Alvefur <zash@zash.se>
parents: 9907
diff changeset
232 if dn.oid == oid_commonname then
8e8d3b3a55da util.x509: Nameprep commonName once
Kim Alvefur <zash@zash.se>
parents: 9907
diff changeset
233 local name = nameprep(dn.value);
10256
b2e7b07f8b74 util.x509: Only collect commonNames that pass idna
Kim Alvefur <zash@zash.se>
parents: 10255
diff changeset
234 if name and idna_to_ascii(name) then
10494
69e55b03d5cf util.x509: Fix recording of CommonNames in get_identities
Kim Alvefur <zash@zash.se>
parents: 10259
diff changeset
235 names:set(name, "*", true);
10255
8e8d3b3a55da util.x509: Nameprep commonName once
Kim Alvefur <zash@zash.se>
parents: 9907
diff changeset
236 end
9907
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
237 end
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
238 end
10259
9df135b06c2f util.x509: Return sets of services per identity
Kim Alvefur <zash@zash.se>
parents: 10256
diff changeset
239 return names.data;
9907
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
240 end
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
241
12812
b2d422b88cd6 Revert unintentionally committed parts of 12bd40b8e105
Kim Alvefur <zash@zash.se>
parents: 12808
diff changeset
242 local pat = "%-%-%-%-%-BEGIN ([A-Z ]+)%-%-%-%-%-\r?\n"..
b2d422b88cd6 Revert unintentionally committed parts of 12bd40b8e105
Kim Alvefur <zash@zash.se>
parents: 12808
diff changeset
243 "([0-9A-Za-z+/=\r\n]*)\r?\n%-%-%-%-%-END %1%-%-%-%-%-";
6152
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
244
6777
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6708
diff changeset
245 local function pem2der(pem)
6152
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
246 local typ, data = pem:match(pat);
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
247 if typ and data then
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
248 return base64.decode(data), typ;
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
249 end
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
250 end
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
251
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
252 local wrap = ('.'):rep(64);
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
253 local envelope = "-----BEGIN %s-----\n%s\n-----END %s-----\n"
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
254
6777
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6708
diff changeset
255 local function der2pem(data, typ)
6152
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
256 typ = typ and typ:upper() or "CERTIFICATE";
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
257 data = base64.encode(data);
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
258 return s_format(envelope, typ, data:gsub(wrap, '%0\n', (#data-1)/64), typ);
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
259 end
fbab74c28e31 util.x509: And functions for converting between DER and PEM
Kim Alvefur <zash@zash.se>
parents: 5845
diff changeset
260
6777
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6708
diff changeset
261 return {
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6708
diff changeset
262 verify_identity = verify_identity;
9907
54e36a8677bc util.x509: Add function that extracts usable names from a certificate
Kim Alvefur <zash@zash.se>
parents: 8555
diff changeset
263 get_identities = get_identities;
6777
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6708
diff changeset
264 pem2der = pem2der;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6708
diff changeset
265 der2pem = der2pem;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6708
diff changeset
266 };