diff options
Diffstat (limited to 'openssl-model.lua')
-rw-r--r-- | openssl-model.lua | 106 |
1 files changed, 47 insertions, 59 deletions
diff --git a/openssl-model.lua b/openssl-model.lua index 575882a..ff30867 100644 --- a/openssl-model.lua +++ b/openssl-model.lua @@ -30,7 +30,7 @@ local distinguished_names = { {name="countryName", label="Country Name", short= local extensions = { "basicConstraints", "nsCertType", "nsComment", "keyUsage", "subjectKeyIdentifier", "authorityKeyIdentifier", "subjectAltName", "issuerAltName" } -- list of entries that must be found in ca section -local ca_mandatory_entries = { "new_certs_dir", "certificate", "private_key", "default_md", "database", "policy" } +local ca_mandatory_entries = { "new_certs_dir", "certificate", "private_key", "default_md", "database", "serial", "policy" } -- Create a cfe with the distinguished name defaults local getdefaults = function() @@ -98,6 +98,16 @@ local create_subject_string = function(values) return "/"..table.concat(outstr, "/") end +local getconfigentry = function(section, value) + config = config or getopts.getoptsfromfile(configfile) + local result = config[section][value] or config[""][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)] or "") + end + return result +end + -- Find the sections of the config file that define ca's (ca -name option) local find_ca_sections = function() config = config or getopts.getoptsfromfile(configfile) @@ -106,7 +116,7 @@ local find_ca_sections = function() for section in pairs(config) do local success = true for i,entry in ipairs(ca_mandatory_entries) do - if not config[section][entry] then + if getconfigentry(section,entry) == "" then success = false break end @@ -119,16 +129,7 @@ local find_ca_sections = function() return cert_types end -local handle_req_clientdata = function(clientdata, defaults) - - -- Next, put the user values into the table - for name,value in pairs(clientdata) do - if defaults.value[name] then - defaults.value[name].value = value - end - end - - -- Next, validate the values +local validate_request = function(defaults) local success success, defaults = validate_distinguished_names(defaults) @@ -149,23 +150,13 @@ local handle_req_clientdata = function(clientdata, defaults) return success, defaults end -local getconfigpath = function(section, value) - config = config or getopts.getoptsfromfile(configfile) - local 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)] or "") - end - return result -end - local copyca = function(cacert, cakey) config = config or getopts.getoptsfromfile(configfile) - local certpath = getconfigpath(config.ca.default_ca, "certificate") + local certpath = getconfigentry(config.ca.default_ca, "certificate") local cmd = "cp "..cacert.." "..certpath local f = io.popen(cmd) f:close() - local keypath = getconfigpath(config.ca.default_ca, "private_key") + local keypath = getconfigentry(config.ca.default_ca, "private_key") local cmd = "cp "..cakey.." "..keypath local f = io.popen(cmd) f:close() @@ -188,7 +179,11 @@ local checkfile = function(name, path, default) local filestats = posix.stat(path, "type") if not filestats or filestats == "" then errtxt = name.." does not exist" - cmdline = "echo "..default.." > "..path + if default then + cmdline = "echo "..default.." > "..path + else + cmdline = "touch "..path + end elseif filestats ~= "regular" then errtxt = "UNRECOVERABLE - "..name.." not a file" end @@ -218,7 +213,7 @@ getstatus = function() cacertcontents.errtxt="" cakey.errtxt="File not defined" else - cacert.value = getconfigpath(config.ca.default_ca, "certificate") + cacert.value = getconfigentry(config.ca.default_ca, "certificate") if not fs.is_file(cacert.value) then cacert.errtxt="File not found" else @@ -227,7 +222,7 @@ getstatus = function() cacertcontents.value = f:read("*a") f:close() end - cakey.value = getconfigpath(config.ca.default_ca, "private_key") + cakey.value = getconfigentry(config.ca.default_ca, "private_key") if not fs.is_file(cakey.value) then cakey.errtxt="File not found" end @@ -247,15 +242,10 @@ getreqdefaults = function() return defaults end -setreqdefaults = function(clientdata) - -- First, get the defaults - config = config or getopts.getoptsfromfile(configfile) - local defaults = getreqdefaults() - - -- Then, copy in user values and validate - local success, defaults = handle_req_clientdata(clientdata, defaults) +setreqdefaults = function(defaults) + local success, defaults = validate_request(defaults) - -- Finally, write the values to the config file + -- If success, write the values to the config file if success then getopts.setoptsinfile(configfile, "ca", "default_ca", defaults.value.certtype.value) config = nil @@ -277,12 +267,8 @@ getnewrequest = function() return values end -submitrequest = function(clientdata, user) - -- First, get the defaults - local defaults = getnewrequest() - - -- Then, copy in user values and validate - local success, defaults = handle_req_clientdata(clientdata, defaults) +submitrequest = function(defaults, user) + local success, defaults = validate_request(defaults) -- Must have a common name if #defaults.value.commonName.value == 0 then @@ -363,11 +349,11 @@ approverequest = function(request) local user,certtype,commonName = string.match(request, "([^%.]*)%.([^%.]*)%.([^%.]*)") -- Add the serial number to the end of the cert file name - local serialpath = getconfigpath(certtype, "serial") + local serialpath = getconfigentry(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 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" local f = io.popen(cmd) @@ -429,7 +415,7 @@ listcerts = function(user) local enddate = f:read("*a") enddate = string.match(enddate, "notAfter=(.*)") f:close() - local month, day, year = string.match(enddate, "(%a+) (%d+) %S+ (%d+)") + local month, day, year = string.match(enddate, "(%a+)%s+(%d+)%s+%S+%s+(%d+)") local reversemonth = {Jan=1,Feb=2,Mar=3,Apr=4,May=5,Jun=6,Jul=7,Aug=8,Sep=9,Oct=10,Nov=11,Dec=12} local time = os.time({year=year, month=reversemonth[month], day=day}) @@ -504,7 +490,6 @@ renewcert = function(cert, approve) -- Next, submit the request cmd = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin openssl req -new -config "..configfile.." -key "..reqname..".pem -out "..reqname..".csr -subj '"..subject.."' 2>&1" -APP.logevent(cmd) f = io.popen(cmd) cmdresult = f:read("*a") f:close() @@ -529,7 +514,7 @@ end listrevoked = function() config = config or getopts.getoptsfromfile(configfile) - local databasepath = getconfigpath(config.ca.default_ca, "database") + local databasepath = getconfigentry(config.ca.default_ca, "database") local revoked = {} local database = fs.read_file_as_array(databasepath) for x,line in ipairs(database) do @@ -626,12 +611,8 @@ getnewcarequest = function() return request end -generateca = function(clientdata) - -- First, get the defaults - local defaults = getnewcarequest() - - -- Then, copy in user values and validate - local success, defaults = handle_req_clientdata(clientdata, defaults) +generateca = function(defaults) + local success, defaults = validate_request(defaults) if not validator.is_integer(defaults.value.days.value) then defaults.value.days.errtxt = "Must be a number" @@ -698,29 +679,36 @@ end checkenvironment = function(set) local errtxt = {} 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", certdir) + errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("request directory", requestdir) + + -- Then check for the config file entries config = config or getopts.getoptsfromfile(configfile) - local path = getconfigpath(config.ca.default_ca, "new_certs_dir") + local path = getconfigentry(config.ca.default_ca, "new_certs_dir") errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("new_certs_dir", path) - local file = getconfigpath(config.ca.default_ca, "certificate") + local file = getconfigentry(config.ca.default_ca, "certificate") path = dirname(file) errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("certificate directory", path) - file = getconfigpath(config.ca.default_ca, "private_key") + file = getconfigentry(config.ca.default_ca, "private_key") path = dirname(file) errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("private_key directory", path) - file = getconfigpath(config.ca.default_ca, "database") + file = getconfigentry(config.ca.default_ca, "database") path = dirname(file) errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("database directory", path) - errtxt[#errtxt+1], cmdline[#cmdline+1] = checkfile("database", file, "") + errtxt[#errtxt+1], cmdline[#cmdline+1] = checkfile("database", file) - file = getconfigpath(config.ca.default_ca, "serial") + file = getconfigentry(config.ca.default_ca, "serial") path = dirname(file) errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("serial directory", path) errtxt[#errtxt+1], cmdline[#cmdline+1] = checkfile("serial", file, "01") - + if set then -- loop through the cmdline and execute for x,cmd in ipairs(cmdline) do |