local fs = require "fs" Key = fs.readFileSync("certs/"..Config.key) Cert = fs.readFileSync("certs/"..Config.cert) if not (Key and Cert) then l:error "Certificate or key file not found" os.exit(1) end local openssl = require "openssl" local x509 = openssl.x509 local ca = assert(x509.read(Cert)) local cakey = assert(openssl.pkey.read(Key, true)) local ccache = {} -- Inspired from https://github.com/zhaozg/lua-openssl/issues/208. Thanks xdays! -- Bilal(bilalzero) + Nameless(truemedian) also helped me on it. -- TODO: A mess. Try to reduce the mess. Please. function GenCert(names) if type(names) == "string" then names = {names} end local c = ccache[names[1]] if c and c[1]:validat() then return unpack(c) end local now = os.time() local ckey = assert(openssl.pkey.new("rsa", Config.secure.tls.key_length)) local name = openssl.x509.name.new {{CN=names[1]}} local hosts, ips = {}, {} for _, v in pairs(names) do if v:match("^[0-9.]+$") then table.insert(ips, v) else table.insert(hosts, v) end end local w = "" if #ips > 0 then w = w .. "IP:"..table.concat(ips, ",IP:") end if #hosts > 0 then w = w .. "DNS:"..table.concat(hosts, ",DNS:") end local san = { object = "subjectAltName", value = w } local req = x509.req.new(name, ckey) req:extensions({x509.extension.new_extension(san)}) req:public(ckey) req:sign(ckey, "sha256") c = req:to_x509(ckey, 1) c:serial(openssl.bn.random(128)) c:subject(name) c:validat(now - One.hour, now + One.hour * 24) c:extensions({x509.extension.new_extension(san)}) c:sign(cakey, ca, "sha256") ccache[names[1]] = {c, ckey} return c, ckey end