# HG changeset patch # User Kim Alvefur # Date 1327093153 -3600 # Node ID f04db5e7e90d18873265ed171f880545ca8478f4 # Parent abfd27b59fa87c473f2d8410307e84855bdb3758 user.x509: Add some utility functions for generating OpenSSL configs diff -r abfd27b59fa8 -r f04db5e7e90d util/x509.lua --- a/util/x509.lua Fri Jan 20 21:58:04 2012 +0100 +++ b/util/x509.lua Fri Jan 20 21:59:13 2012 +0100 @@ -21,6 +21,10 @@ local nameprep = require "util.encodings".stringprep.nameprep; local idna_to_ascii = require "util.encodings".idna.to_ascii; local log = require "util.logger".init("x509"); +local pairs, ipairs = pairs, ipairs; +local s_format = string.format; +local t_insert = table.insert; +local t_concat = table.concat; module "x509" @@ -208,4 +212,109 @@ return false end +-- TODO Rename? Split out subroutines? +-- Also, this is probably openssl specific, what TODO about that? +function genx509san(hosts, config, certhosts, raw) -- recive config through that or some better way? + local function utf8string(s) + -- This is how we tell openssl not to encode UTF-8 strings as Latin1 + return s_format("FORMAT:UTF8,UTF8:%s", s); + end + + local function ia5string(s) + return s_format("IA5STRING:%s", s); + end + + local function dnsname(t, host) + t_insert(t.DNS, idna_to_ascii(host)); + end + + local function srvname(t, host, service) + t_insert(t.otherName, s_format("%s;%s", oid_dnssrv, ia5string("_" .. service .."." .. idna_to_ascii(host)))); + end + + local function xmppAddr(t, host) + t_insert(t.otherName, s_format("%s;%s", oid_xmppaddr, utf8string(host))); + end + + ----------------------------- + + local san = { + DNS = {}; + otherName = {}; + }; + + local sslsanconf = { }; + + for i = 1,#certhosts do + local certhost = certhosts[i]; + for name, host in pairs(hosts) do + if name == certhost or name:sub(-1-#certhost) == "."..certhost then + dnsname(san, name); + --print(name .. "#component_module: " .. (config.get(name, "core", "component_module") or "nil")); + if config.get(name, "core", "component_module") == nil then + srvname(san, name, "xmpp-client"); + end + --print(name .. "#anonymous_login: " .. tostring(config.get(name, "core", "anonymous_login"))); + if not (config.get(name, "core", "anonymous_login") or + config.get(name, "core", "authentication") == "anonymous") then + srvname(san, name, "xmpp-server"); + end + xmppAddr(san, name); + end + end + end + + for t, n in pairs(san) do + for i = 1,#n do + t_insert(sslsanconf, s_format("%s.%d = %s", t, i -1, n[i])); + end + end + + return raw and sslsanconf or t_concat(sslsanconf, "\n"); +end + +function baseconf() + return { + req = { + distinguished_name = "distinguished_name", + req_extensions = "v3_extensions", + x509_extensions = "v3_extensions", + prompt = "no", + }, + distinguished_name = { + commonName = "example.com", + countryName = "GB", + localityName = "The Internet", + organizationName = "Your Organisation", + organizationalUnitName = "XMPP Department", + emailAddress = "xmpp@example.com", + }, + v3_extensions = { + basicConstraints = "CA:FALSE", + keyUsage = "digitalSignature,keyEncipherment", + extendedKeyUsage = "serverAuth,clientAuth", + subjectAltName = "@subject_alternative_name", + }, + subject_alternative_name = { }, + } +end + +function serialize_conf(conf) + local s = ""; + for k, t in pairs(conf) do + s = s .. ("[%s]\n"):format(k); + if t[1] then + for i, v in ipairs(t) do + s = s .. ("%s\n"):format(v); + end + else + for k, v in pairs(t) do + s = s .. ("%s = %s\n"):format(k, v); + end + end + s = s .. "\n"; + end + return s; +end + return _M;