Comparison

util/x509.lua @ 10259:9df135b06c2f

util.x509: Return sets of services per identity
author Kim Alvefur <zash@zash.se>
date Tue, 10 Sep 2019 18:41:36 +0200
parent 10256:b2e7b07f8b74
child 10494:69e55b03d5cf
comparison
equal deleted inserted replaced
10258:4ff2f14f9ac7 10259:9df135b06c2f
21 local nameprep = require "util.encodings".stringprep.nameprep; 21 local nameprep = require "util.encodings".stringprep.nameprep;
22 local idna_to_ascii = require "util.encodings".idna.to_ascii; 22 local idna_to_ascii = require "util.encodings".idna.to_ascii;
23 local idna_to_unicode = require "util.encodings".idna.to_unicode; 23 local idna_to_unicode = require "util.encodings".idna.to_unicode;
24 local base64 = require "util.encodings".base64; 24 local base64 = require "util.encodings".base64;
25 local log = require "util.logger".init("x509"); 25 local log = require "util.logger".init("x509");
26 local mt = require "util.multitable";
26 local s_format = string.format; 27 local s_format = string.format;
28 local ipairs = ipairs;
27 29
28 local _ENV = nil; 30 local _ENV = nil;
29 -- luacheck: std none 31 -- luacheck: std none
30 32
31 local oid_commonname = "2.5.4.3"; -- [LDAP] 2.3 33 local oid_commonname = "2.5.4.3"; -- [LDAP] 2.3
216 -- If all else fails, well, why should we be any different? 218 -- If all else fails, well, why should we be any different?
217 return false 219 return false
218 end 220 end
219 221
220 -- TODO Support other SANs 222 -- TODO Support other SANs
221 local function get_identities(cert) --> set of names 223 local function get_identities(cert) --> map of names to sets of services
222 if cert.setencode then 224 if cert.setencode then
223 cert:setencode("utf8"); 225 cert:setencode("utf8");
224 end 226 end
225 227
226 local names = {}; 228 local names = mt.new();
227 229
228 local ext = cert:extensions(); 230 local ext = cert:extensions();
229 local sans = ext[oid_subjectaltname]; 231 local sans = ext[oid_subjectaltname];
230 if sans and sans["dNSName"] then 232 if sans then
231 for i = 1, #sans["dNSName"] do 233 if sans["dNSName"] then -- Valid for any service
232 names[ idna_to_unicode(sans["dNSName"][i]) ] = true; 234 for _, name in ipairs(sans["dNSName"]) do
235 name = idna_to_unicode(nameprep(name));
236 if name then
237 names:set(name, "*", true);
238 end
239 end
240 end
241 if sans[oid_xmppaddr] then
242 for _, name in ipairs(sans[oid_xmppaddr]) do
243 name = nameprep(name);
244 if name then
245 names:set(name, "xmpp-client", true);
246 names:set(name, "xmpp-server", true);
247 end
248 end
249 end
250 if sans[oid_dnssrv] then
251 for _, srvname in ipairs(sans[oid_dnssrv]) do
252 local srv, name = srvname:match("^_([^.]+)%.(.*)");
253 if srv then
254 name = nameprep(name);
255 if name then
256 names:set(name, srv, true);
257 end
258 end
259 end
233 end 260 end
234 end 261 end
235 262
236 local subject = cert:subject(); 263 local subject = cert:subject();
237 for i = 1, #subject do 264 for i = 1, #subject do
238 local dn = subject[i]; 265 local dn = subject[i];
239 if dn.oid == oid_commonname then 266 if dn.oid == oid_commonname then
240 local name = nameprep(dn.value); 267 local name = nameprep(dn.value);
241 if name and idna_to_ascii(name) then 268 if name and idna_to_ascii(name) then
242 names[name] = true; 269 names:set("*", name, true);
243 end 270 end
244 end 271 end
245 end 272 end
246 return names; 273 return names.data;
247 end 274 end
248 275
249 local pat = "%-%-%-%-%-BEGIN ([A-Z ]+)%-%-%-%-%-\r?\n".. 276 local pat = "%-%-%-%-%-BEGIN ([A-Z ]+)%-%-%-%-%-\r?\n"..
250 "([0-9A-Za-z+/=\r\n]*)\r?\n%-%-%-%-%-END %1%-%-%-%-%-"; 277 "([0-9A-Za-z+/=\r\n]*)\r?\n%-%-%-%-%-END %1%-%-%-%-%-";
251 278