summaryrefslogtreecommitdiffstats
path: root/openssl-model.lua
diff options
context:
space:
mode:
Diffstat (limited to 'openssl-model.lua')
-rw-r--r--openssl-model.lua92
1 files changed, 48 insertions, 44 deletions
diff --git a/openssl-model.lua b/openssl-model.lua
index 4806d9d..13eafc9 100644
--- a/openssl-model.lua
+++ b/openssl-model.lua
@@ -18,6 +18,7 @@ local configfile = "openssl-ca-acf.cnf"
local requestdir = "req/"
local certdir = "cert/"
local openssldir = "/etc/ssl/"
+local basedir = openssldir
-- Save the config in a variable so isn't loaded each and every time needed
local config = nil
@@ -33,10 +34,13 @@ local ca_mandatory_entries = { "new_certs_dir", "certificate", "private_key", "d
local initializecfe = function(self, clientdata, label)
local retval = cfe({ type="group", value={}, label=label or "" })
- retval.value.basedir = cfe({ type="hidden", label="Base Directory", key=true })
+ retval.value.cadir = cfe({ type="hidden", label="CA Directory", key=true })
self.handle_clientdata(retval, clientdata)
- if retval.value.basedir.value ~= "" then
- openssldir = posix.dirname(retval.value.basedir.value.."/tmp").."/"
+ basedir = openssldir
+ if string.find(retval.value.cadir.value, "%.%.") then
+ retval.value.cadir.errtxt = "Invalid Directory"
+ elseif retval.value.cadir.value ~= "" then
+ basedir = string.gsub(basedir..retval.value.cadir.value.."/", "//", "/")
end
return retval
end
@@ -44,7 +48,7 @@ end
-- Create a cfe with the distinguished name defaults
local getdefaults = function(self, clientdata)
local defaults = initializecfe(self, clientdata, "OpenSSL Request")
- config = config or format.parse_ini_file(fs.read_file(openssldir..configfile) or "")
+ config = config or format.parse_ini_file(fs.read_file(basedir..configfile) or "")
local distinguished_name = config.req.distinguished_name or ""
-- Define the order of the parameters in the form
@@ -66,7 +70,7 @@ end
-- Validate the values of distinguished names using the min/max found in the config file
local validate_distinguished_names = function(values)
- config = config or format.parse_ini_file(fs.read_file(openssldir..configfile) or "")
+ config = config or format.parse_ini_file(fs.read_file(basedir..configfile) or "")
local distinguished_name = config.req.distinguished_name or ""
local success = true
@@ -137,7 +141,7 @@ local create_subject_string = function(values, ignorevalues)
end
local getconfigentry = function(section, value)
- config = config or format.parse_ini_file(fs.read_file(openssldir..configfile) or "")
+ config = config or format.parse_ini_file(fs.read_file(basedir..configfile) or "")
local result = config[section][value] or config[""][value] or ""
while string.find(result, "%$[%w_]+") do
local sub = string.match(result, "%$[%w_]+")
@@ -148,7 +152,7 @@ end
-- Find the sections of the config file that define ca's (ca -name option)
local find_ca_sections = function()
- config = config or format.parse_ini_file(fs.read_file(openssldir..configfile) or "")
+ config = config or format.parse_ini_file(fs.read_file(basedir..configfile) or "")
local cert_types = {}
for section in pairs(config) do
@@ -186,7 +190,7 @@ local validate_request = function(defaults, noextensionsections)
end
if defaults.value.extensions then
- config = config or format.parse_ini_file(fs.read_file(openssldir..configfile) or "")
+ config = config or format.parse_ini_file(fs.read_file(basedir..configfile) or "")
local extensions = format.parse_ini_file(defaults.value.extensions.value)
for name,value in pairs(extensions or {}) do
if name ~= "" and noextensionsections then
@@ -203,7 +207,7 @@ local validate_request = function(defaults, noextensionsections)
end
local copyca = function(cacert, cakey)
- config = config or format.parse_ini_file(fs.read_file(openssldir..configfile) or "")
+ config = config or format.parse_ini_file(fs.read_file(basedir..configfile) or "")
local certpath = getconfigentry(config.ca.default_ca, "certificate")
fs.move_file(cacert, certpath)
local keypath = getconfigentry(config.ca.default_ca, "private_key")
@@ -264,7 +268,7 @@ end
local listrequests = function(user)
user = user or "*"
local list={}
- local files = posix.glob(openssldir..requestdir..user..".*\\.csr") or {}
+ local files = posix.glob(basedir..requestdir..user..".*\\.csr") or {}
for i,x in ipairs(files) do
local name = string.gsub(posix.basename(x), ".csr$", "")
local a,b,c = string.match(name, "([^%.]*)%.([^%.]*)%.([^%.]*)")
@@ -276,7 +280,7 @@ end
local listcerts = function(user)
user = user or "*"
local list={}
- local files = posix.glob(openssldir..certdir..user..".*\\.pfx") or {}
+ local files = posix.glob(basedir..certdir..user..".*\\.pfx") or {}
-- Do this in two steps - saves forking openssl for each cert, which
-- speeds things up noticably for > 100 certs
local crtlist = {}
@@ -287,7 +291,7 @@ local listcerts = function(user)
list[#list + 1] = {cert=name, user=a, certtype=b,
commonName=unhashname(c), serial=d, enddate=enddate,
daysremaining=time}
- crtlist[#crtlist+1] = "x509 -in "..openssldir..certdir..name..".crt -noout -enddate"
+ crtlist[#crtlist+1] = "x509 -in "..basedir..certdir..name..".crt -noout -enddate"
end
local out = modelfunctions.run_executable({"openssl"}, false, table.concat(crtlist, "\n").."\nexit\n")
@@ -314,7 +318,7 @@ local listcerts = function(user)
end
local listrevoked = function()
- config = config or format.parse_ini_file(fs.read_file(openssldir..configfile) or "")
+ config = config or format.parse_ini_file(fs.read_file(basedir..configfile) or "")
local databasepath = getconfigentry(config.ca.default_ca, "database")
local revoked = {}
local database = fs.read_file_as_array(databasepath) or {}
@@ -331,12 +335,12 @@ local checkenvironment = function()
local cmdline = {}
-- First check for the openssl, req, and cert directories
- errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("openssl directory", openssldir)
- errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("new certificate directory", openssldir..certdir)
- errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("request directory", openssldir..requestdir)
+ errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("openssl directory", basedir)
+ errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("new certificate directory", basedir..certdir)
+ errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("request directory", basedir..requestdir)
-- Then check for the config file entries
- config = config or format.parse_ini_file(fs.read_file(openssldir..configfile) or "")
+ config = config or format.parse_ini_file(fs.read_file(basedir..configfile) or "")
if config then
local chkpath = getconfigentry(config.ca.default_ca, "new_certs_dir")
@@ -384,21 +388,21 @@ end
mymodule.getstatus = function(self, clientdata)
-- set the working directory and umask once for model
posix.umask("rw-------")
- posix.chdir(openssldir)
+ posix.chdir(basedir)
local retval = initializecfe(self, clientdata, "OpenSSL status")
local value,errtxt=processinfo.package_version(packagename)
retval.value.version = cfe({ value=value, errtxt=errtxt, label="Program version", name=packagename })
- retval.value.conffile = cfe({ value=openssldir..configfile, label="Configuration file" })
+ retval.value.conffile = cfe({ value=basedir..configfile, label="Configuration file" })
retval.value.cacert = cfe({ label="CA Certificate" })
retval.value.cacertcontents = cfe({ type="longtext", label="CA Certificate contents" })
retval.value.cakey = cfe({ label="CA Key" })
- if not fs.is_file(openssldir..configfile) then
+ if not fs.is_file(basedir..configfile) then
retval.value.conffile.errtxt="File not found"
retval.value.cacert.errtxt="File not defined"
retval.value.cacertcontents.errtxt=""
retval.value.cakey.errtxt="File not defined"
else
- config = config or format.parse_ini_file(fs.read_file(openssldir..configfile) or "")
+ config = config or format.parse_ini_file(fs.read_file(basedir..configfile) or "")
if (not config) or (not config.ca) or (not config.ca.default_ca) then
retval.value.conffile.errtxt="Invalid config file"
retval.value.cacert.errtxt="File not defined"
@@ -449,7 +453,7 @@ mymodule.getreqdefaults = function(self, clientdata)
value=config.ca.default_ca, option=find_ca_sections(), seq=96 })
-- Add in the extensions
local extensions = ""
- local content = fs.read_file(openssldir..configfile) or ""
+ local content = fs.read_file(basedir..configfile) or ""
config = config or format.parse_ini_file(content)
if config.req.req_extensions then
extensions = format.get_ini_section(content, config.req.req_extensions)
@@ -464,7 +468,7 @@ mymodule.setreqdefaults = function(self, defaults)
-- If success, write the values to the config file
if success then
- local fileval = fs.read_file(openssldir..configfile) or ""
+ local fileval = fs.read_file(basedir..configfile) or ""
config = config or format.parse_ini_file(fileval)
local ext_section
if not config.req or not config.req.req_extensions then
@@ -479,7 +483,7 @@ mymodule.setreqdefaults = function(self, defaults)
fileval = format.set_ini_section(fileval, ext_section, format.dostounix(defaults.value.extensions.value))
fileval = format.update_ini_file(fileval, "ca", "default_ca", defaults.value.certtype.value)
fileval = write_distinguished_names(fileval, defaults, {"certtype", "extensions", "validdays"})
- fs.write_file(openssldir..configfile, fileval)
+ fs.write_file(basedir..configfile, fileval)
end
if not success then
@@ -515,7 +519,7 @@ mymodule.submitrequest = function(self, defaults, submit, user)
success = false
end
- local reqname = openssldir..requestdir..user.."."..defaults.value.certtype.value.."."..hashname(defaults.value.commonName.value)
+ local reqname = basedir..requestdir..user.."."..defaults.value.certtype.value.."."..hashname(defaults.value.commonName.value)
if fs.is_file(reqname..".csr") then
defaults.errtxt = "Failed to submit request\nRequest already exists"
success = false
@@ -531,7 +535,7 @@ mymodule.submitrequest = function(self, defaults, submit, user)
local subject = create_subject_string(defaults, {"password", "password_confirm", "certtype", "extensions"})
-- Generate a temp config file for this request
- local fileval = fs.read_file(openssldir..configfile) or ""
+ local fileval = fs.read_file(basedir..configfile) or ""
config = config or format.parse_ini_file(fileval)
local ext_section = "v3_req"
while config[ext_section] do ext_section = "v3_req_"..tostring(os.time()) end
@@ -596,7 +600,7 @@ mymodule.viewrequest = function(self, clientdata)
self.handle_clientdata(retval, clientdata)
local request = retval.value.request.value
- local reqpath = openssldir..requestdir .. request
+ local reqpath = basedir..requestdir .. request
local cmdresult = modelfunctions.run_executable({"openssl", "req", "-in", reqpath..".csr", "-text", "-noout"})
local a,b,c = string.match(request, "([^%.]*)%.([^%.]*)%.([^%.]*)")
retval.value.details = cfe({ type="table", value={request=request, user=a, certtype=b, commonName=unhashname(c), value=cmdresult}, label="Request Details" })
@@ -610,7 +614,7 @@ mymodule.getapproverequest = function(self, clientdata)
end
mymodule.approverequest = function(self, apprequest)
- local reqpath = openssldir..requestdir .. apprequest.value.request.value
+ local reqpath = basedir..requestdir .. apprequest.value.request.value
if fs.is_file(reqpath..".csr") then
-- Request file exists, so try to sign
local user,certtype,commonName = string.match(apprequest.value.request.value, "([^%.]*)%.([^%.]*)%.([^%.]*)")
@@ -619,7 +623,7 @@ mymodule.approverequest = function(self, apprequest)
local serialpath = getconfigentry(certtype, "serial")
local serialfile = fs.read_file(serialpath) or ""
local serial = string.match(serialfile, "%x+")
- local certname = openssldir..certdir..apprequest.value.request.value.."."..serial
+ local certname = basedir..certdir..apprequest.value.request.value.."."..serial
-- Now, sign the certificate
apprequest.descr, apprequest.errtxt = modelfunctions.run_executable({"openssl", "ca", "-config", reqpath..".cfg", "-in", reqpath..".csr", "-out", certname..".crt", "-name", certtype, "-batch"}, true)
@@ -665,11 +669,11 @@ end
mymodule.deleterequest = function(self, delrequest, submit, user)
user = user or ".*"
- if (not fs.is_file(openssldir..requestdir..delrequest.value.request.value..".csr")) or (not string.find(delrequest.value.request.value, "^"..user.."%.")) then
+ if (not fs.is_file(basedir..requestdir..delrequest.value.request.value..".csr")) or (not string.find(delrequest.value.request.value, "^"..user.."%.")) then
delrequest.value.request.errtxt = "Request not found"
delrequest.errtxt = "Failed to Delete Request"
else
- local reqpath = openssldir..requestdir..delrequest.value.request.value
+ local reqpath = basedir..requestdir..delrequest.value.request.value
os.remove(reqpath..".pwd")
os.remove(reqpath..".sbj")
os.remove(reqpath..".pem")
@@ -685,7 +689,7 @@ mymodule.viewcert = function(self, clientdata)
self.handle_clientdata(retval, clientdata)
local cert = retval.value.cert.value
- local cmdresult = modelfunctions.run_executable({"openssl", "x509", "-in", openssldir..certdir..cert..".crt", "-noout", "-text"})
+ local cmdresult = modelfunctions.run_executable({"openssl", "x509", "-in", basedir..certdir..cert..".crt", "-noout", "-text"})
local a,b,c,d = string.match(cert, "([^%.]*)%.([^%.]*)%.([^%.]*).([^%.]*)")
retval.value.details = cfe({ type="table", value={cert=cert, user=a, certtype=b, commonName=unhashname(c), serial=d, value=cmdresult}, label="Certificate Details" })
return retval
@@ -698,7 +702,7 @@ mymodule.getcert = function(self, clientdata)
local cert = retval.value.cert.value
if cert ~= "" then
- local f = fs.read_file(openssldir..certdir..cert..".pfx") or ""
+ local f = fs.read_file(basedir..certdir..cert..".pfx") or ""
local a,b,c,d = string.match(cert, "([^%.]*)%.([^%.]*)%.([^%.]*).([^%.]*)")
c = string.gsub(unhashname(c), "[^%w_-]", "")
retval.value.details = cfe({ type="raw", value=f, label=c..".pfx", option="application/x-pkcs12" })
@@ -714,7 +718,7 @@ mymodule.getrevokecert = function(self, clientdata)
end
mymodule.revokecert = function(self, revreq)
- revreq.descr, revreq.errtxt = modelfunctions.run_executable({"openssl", "ca", "-config", openssldir..configfile, "-revoke", openssldir..certdir..revreq.value.cert.value..".crt", "-batch"}, true)
+ revreq.descr, revreq.errtxt = modelfunctions.run_executable({"openssl", "ca", "-config", basedir..configfile, "-revoke", basedir..certdir..revreq.value.cert.value..".crt", "-batch"}, true)
return revreq
end
@@ -726,7 +730,7 @@ end
mymodule.deletecert = function(self, delcert)
-- The certificate will still be in the ca directories and index.txt, just not available for web interface
- local certname = openssldir..certdir..delcert.value.cert.value
+ local certname = basedir..certdir..delcert.value.cert.value
os.remove(certname..".cfg")
os.remove(certname..".crt")
os.remove(certname..".pem")
@@ -745,7 +749,7 @@ end
mymodule.renewcert = function(self, recert, submit, approve)
local success = true
local user,certtype,commonName,serialnum = string.match(recert.value.cert.value, "([^%.]*)%.([^%.]*)%.([^%.]*).([^%.]*)")
- local reqname = openssldir..requestdir..user.."."..certtype.."."..commonName
+ local reqname = basedir..requestdir..user.."."..certtype.."."..commonName
if fs.is_file(reqname..".csr") then
recert.errtxt = "Failed to submit request"
recert.value.cert.errtxt = "Request already exists"
@@ -755,7 +759,7 @@ mymodule.renewcert = function(self, recert, submit, approve)
if success then
-- Submit the request
-- First, put the subject, config file and password in place
- local certname = openssldir..certdir..recert.value.cert.value
+ local certname = basedir..certdir..recert.value.cert.value
fs.copy_file(certname..".pwd", reqname..".pwd")
fs.copy_file(certname..".sbj", reqname..".sbj")
fs.copy_file(certname..".cfg", reqname..".cfg")
@@ -800,8 +804,8 @@ mymodule.getcrl = function(self, clientdata)
local crltype = retval.value.crltype.value
if modelfunctions.validateselect(retval.value.crltype) then
retval.value.details = cfe({ type="raw", option="application/pkix-crl" })
- modelfunctions.run_executable({"openssl", "ca", "-config", openssldir..configfile, "-gencrl", "-out", openssldir.."ca-crl.crl"})
- modelfunctions.run_executable({"openssl", "crl", "-in", openssldir.."ca-crl.crl", "-out", openssldir.."ca-der-crl.crl", "-outform", "DER"})
+ modelfunctions.run_executable({"openssl", "ca", "-config", basedir..configfile, "-gencrl", "-out", basedir.."ca-crl.crl"})
+ modelfunctions.run_executable({"openssl", "crl", "-in", basedir.."ca-crl.crl", "-out", basedir.."ca-der-crl.crl", "-outform", "DER"})
if crltype == "DER" then
retval.value.details.label = "ca-der-crl.crl"
retval.value.details.value = fs.read_file(retval.value.details.label) or ""
@@ -826,8 +830,8 @@ mymodule.getca = function(self, clientdata)
retval.value.details = cfe({ type="raw", option="application/x-x509-ca-cert" })
local fname = "cacert."
if certtype == "DER" then
- if not posix.stat(openssldir.."cacert.der") then
- modelfunctions.run_executable({"openssl", "x509", "-in", openssldir.."cacert.pem", "-outform", "der", "-out", openssldir.."cacert.der"})
+ if not posix.stat(basedir.."cacert.der") then
+ modelfunctions.run_executable({"openssl", "x509", "-in", basedir.."cacert.pem", "-outform", "der", "-out", basedir.."cacert.der"})
end
fname = fname.."der"
retval.value.details.label = fname
@@ -928,7 +932,7 @@ mymodule.generateca = function(self, defaults)
-- Submit the request
local subject = create_subject_string(defaults, {"days"})
- local cmdresult = modelfunctions.run_executable({"openssl", "req", "-x509", "-nodes", "-new", "-config", openssldir..configfile, "-keyout", "/tmp/cakey.pem", "-out", "/tmp/cacert.pem", "-subj", subject, "-days", defaults.value.days.value}, true)
+ local cmdresult = modelfunctions.run_executable({"openssl", "req", "-x509", "-nodes", "-new", "-config", basedir..configfile, "-keyout", "/tmp/cakey.pem", "-out", "/tmp/cacert.pem", "-subj", subject, "-days", defaults.value.days.value}, true)
local certfilestats = posix.stat("/tmp/cacert.pem")
local keyfilestats = posix.stat("/tmp/cakey.pem")
if not certfilestats or certfilestats.size == 0 or not keyfilestats or keyfilestats.size == 0 then
@@ -955,7 +959,7 @@ end
mymodule.getconfigfile = function(self, clientdata)
local retval = initializecfe(self, clientdata, "")
- local retval2 = modelfunctions.getfiledetails(openssldir..configfile)
+ local retval2 = modelfunctions.getfiledetails(basedir..configfile)
for name,value in pairs(retval.value) do
retval2.value[name] = value
end
@@ -964,7 +968,7 @@ end
mymodule.setconfigfile = function(self, filedetails)
-- validate
- return modelfunctions.setfiledetails(self, filedetails, {openssldir..configfile})
+ return modelfunctions.setfiledetails(self, filedetails, {basedir..configfile})
end
mymodule.getenvironment = function(self, clientdata)