diff options
Diffstat (limited to 'util/x509.lua')
-rw-r--r-- | util/x509.lua | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/util/x509.lua b/util/x509.lua index 15cc4d3c..76b50076 100644 --- a/util/x509.lua +++ b/util/x509.lua @@ -20,9 +20,12 @@ local nameprep = require "util.encodings".stringprep.nameprep; local idna_to_ascii = require "util.encodings".idna.to_ascii; +local idna_to_unicode = require "util.encodings".idna.to_unicode; local base64 = require "util.encodings".base64; local log = require "util.logger".init("x509"); +local mt = require "util.multitable"; local s_format = string.format; +local ipairs = ipairs; local _ENV = nil; -- luacheck: std none @@ -216,6 +219,63 @@ local function verify_identity(host, service, cert) return false end +-- TODO Support other SANs +local function get_identities(cert) --> map of names to sets of services + if cert.setencode then + cert:setencode("utf8"); + end + + local names = mt.new(); + + local ext = cert:extensions(); + local sans = ext[oid_subjectaltname]; + if sans then + if sans["dNSName"] then -- Valid for any service + for _, name in ipairs(sans["dNSName"]) do + local is_wildcard = name:sub(1, 2) == "*."; + if is_wildcard then name = name:sub(3); end + name = idna_to_unicode(nameprep(name)); + if name then + if is_wildcard then name = "*." .. name; end + names:set(name, "*", true); + end + end + end + if sans[oid_xmppaddr] then + for _, name in ipairs(sans[oid_xmppaddr]) do + name = nameprep(name); + if name then + names:set(name, "xmpp-client", true); + names:set(name, "xmpp-server", true); + end + end + end + if sans[oid_dnssrv] then + for _, srvname in ipairs(sans[oid_dnssrv]) do + local srv, name = srvname:match("^_([^.]+)%.(.*)"); + if srv then + name = nameprep(name); + if name then + names:set(name, srv, true); + end + end + end + end + end + + local subject = cert:subject(); + for i = 1, #subject do + local dn = subject[i]; + if dn.oid == oid_commonname then + local name = nameprep(dn.value); + if name and idna_to_ascii(name) then + names:set(name, "*", true); + end + end + end + return names.data; +end + local pat = "%-%-%-%-%-BEGIN ([A-Z ]+)%-%-%-%-%-\r?\n".. "([0-9A-Za-z+/=\r\n]*)\r?\n%-%-%-%-%-END %1%-%-%-%-%-"; @@ -237,6 +297,7 @@ end return { verify_identity = verify_identity; + get_identities = get_identities; pem2der = pem2der; der2pem = der2pem; }; |