summaryrefslogtreecommitdiffstats
path: root/openssl-model.lua
diff options
context:
space:
mode:
Diffstat (limited to 'openssl-model.lua')
-rw-r--r--openssl-model.lua110
1 files changed, 109 insertions, 1 deletions
diff --git a/openssl-model.lua b/openssl-model.lua
index a80ade4..a572f92 100644
--- a/openssl-model.lua
+++ b/openssl-model.lua
@@ -10,6 +10,8 @@ require("html")
local configfile = "/etc/ssl/openssl.cnf"
local requestdir = "/etc/ssl/req/"
+local certdir = "/etc/ssl/cert/"
+local openssldir = "/etc/ssl/"
-- list of request entries that can be edited
local distinguished_names = { {name="countryName", label="Country Name", short="C"},
@@ -70,7 +72,6 @@ local create_subject_string = function(values)
for i,name in ipairs(distinguished_names) do
outstr[#outstr + 1] = (name.short or name.name) .. "=" .. values.value[name.name].value
end
- outstr[#outstr + 1] = "password="..values.value.password.value
return "/"..table.concat(outstr, "/")
end
@@ -123,6 +124,15 @@ local handle_req_clientdata = function(clientdata, defaults, config)
return success, defaults, config
end
+local getconfigpath = function(config, section, value)
+ result=config[section][value] or ""
+ while string.find(result, "%$[%w_]+") do
+ local sub = string.match(result, "%$[%w_]+")
+ result = string.gsub(result, sub, config[section][string.sub(sub,2)] or config[""][string.sub(sub,2)])
+ end
+ return result
+end
+
-- FIXME we need to make sure necessary files / directories / private key are there
verifyopenssl = function()
local retval = false
@@ -218,6 +228,9 @@ submitrequest = function(clientdata, user)
local cmdresult = f:read("*a")
f:close()
defaults.descr = cmdresult
+ if fs.is_file(reqname..".csr") then
+ fs.write_file(reqname..".pwd", defaults.value.password.value)
+ end
end
if not success then
@@ -238,3 +251,98 @@ listrequests = function(user)
end
return cfe({ type="list", value=list, label="List of pending requests" })
end
+
+viewrequest = function(request)
+ local path = requestdir .. request
+ local cmd = "openssl req -in "..path..".csr -text -noout"
+ local f = io.popen(cmd)
+ local cmdresult = f:read("*a")
+ f:close()
+ local a,b,c = string.match(request, "([^%.]*)%.([^%.]*)%.([^%.]*)")
+ local request = cfe({ type="table", value={name=name, user=a, certtype=b, commonName=c, value=cmdresult}, label="Request" })
+ return request
+end
+
+approverequest = function(request)
+ local cmdresult = cfe({ value="Failed to approve request", label="Approve result" })
+ local path = requestdir .. request
+ if fs.is_file(path..".csr") then
+ -- Request file exists, so try to sign
+ local user,certtype,commonName = string.match(request, "([^%.]*)%.([^%.]*)%.([^%.]*)")
+
+ -- Add the serial number to the end of the cert file name
+ local config = getopts.getoptsfromfile(configfile)
+ local serialpath = getconfigpath(config, certtype, "serial")
+ local serialfile = fs.read_file(openssldir..serialpath)
+ local serial = string.match(serialfile, "%x%x")
+ local certname = certdir..request.."."..serial
+
+ -- Now, sign the certificate
+ local cwd = posix.getcwd()
+ posix.chdir(openssldir)
+ local cmd = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin openssl ca -config "..configfile.." -in "..path..".csr -out "..certname..".crt -name "..certtype.." -batch 2>&1"
+APP.logevent(cmd)
+ local f = io.popen(cmd)
+ cmdresult.value = f:read("*a")
+ f:close()
+ posix.chdir(cwd)
+
+ -- If certificate created, create the wrapped up pkcs12
+ if fs.is_file(certname..".crt") then
+ cmd = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin openssl pkcs12 -export -inkey "..path..".pem -in "..certname..".crt -out "..certname..".pfx -passout file:"..path..".pwd 2>&1"
+ f = io.popen(cmd)
+ local newcmdresult = f:read("*a")
+ f:close()
+ cmdresult.value = cmdresult.value .. newcmdresult
+ end
+
+ -- Finally, remove the request
+ if fs.is_file(certname..".pfx") then
+ cmd = "rm "..path..".*"
+ f = io.popen(cmd)
+ f:close()
+ end
+ end
+ return cmdresult
+end
+
+deleterequest = function(request)
+ cmd = "rm "..requestdir..request..".*"
+ f = io.popen(cmd)
+ f:close()
+ return cfe({ value="Request deleted", label="Delete result" })
+end
+
+listcerts = function(user)
+ user = user or ""
+ local list={}
+ local fh = io.popen('find ' .. certdir .. ' -name "'..user..'*.pfx" -maxdepth 1')
+ for x in fh:lines() do
+ local name = basename(x,".pfx")
+ local a,b,c,d = string.match(name, "([^%.]*)%.([^%.]*)%.([^%.]*).([^%.]*)")
+ list[#list + 1] = {name=name, user=a, certtype=b, commonName=c, serial=d}
+ end
+ return cfe({ type="list", value=list, label="List of approved certificates" })
+end
+
+viewcert = function(cert)
+ local cmdresult = fs.read_file(certdir..cert..".crt")
+ local a,b,c,d = string.match(cert, "([^%.]*)%.([^%.]*)%.([^%.]*).([^%.]*)")
+ return cfe({ type="table", value={name=name, user=a, certtype=b, commonName=c, serial=d, value=cmdresult}, label="Certificate" })
+end
+
+getcert = function(cert)
+ local f = fs.read_file(certdir..cert..".pfx")
+ return cfe({ type="raw", value=f, label=cert..".pfx" })
+end
+
+revokecert = function(cert)
+end
+
+deletecert = function(cert)
+ -- The certificate will still be in the ca directories and index.txt, just not available for web interface
+ cmd = "rm "..certdir..cert..".*"
+ f = io.popen(cmd)
+ f:close()
+ return cfe({ value="Certificate deleted", label="Delete result" })
+end