Skip to content
Snippets Groups Projects
Verified Commit cff435f6 authored by Lukas Jezek's avatar Lukas Jezek Committed by Petr Špaček
Browse files

modules/prefill and TA: Move https_fetch to daemon/lua/kluautil.lua

parent 0bea81d9
Branches
Tags
1 merge request!894replace lua-socket depedency with lua-http
...@@ -8,3 +8,39 @@ function kr_table_len (t) ...@@ -8,3 +8,39 @@ function kr_table_len (t)
return len return len
end end
-- Fetch over HTTPS
function kr_https_fetch (url, ca_file, file)
local http_ok, http_request = pcall(require, 'http.request')
local openssl_ok, openssl_ctx = pcall(require, 'openssl.ssl.context')
if not http_ok or not openssl_ok then
return nil, 'error: lua-http and luaossl libraries are missing (but required)'
end
assert(string.match(url, '^https://'))
assert(ca_file)
local req = http_request.new_from_uri(url)
req.ctx = openssl_ctx.new()
local store = req.ctx:getStore()
store:add(ca_file)
req.ctx:setVerify(openssl_ctx.VERIFY_PEER)
req.tls = true
local headers, stream = req:go()
assert(headers, 'HTTP client library error')
if headers:get(':status') ~= "200" then
return nil, headers:get(':status')
end
local err, errmsg = stream:save_body_to_file(file)
if err == nil then
return err, errmsg
end
file:seek ("set", 0)
return true
end
...@@ -22,32 +22,6 @@ local function upgrade_required(msg) ...@@ -22,32 +22,6 @@ local function upgrade_required(msg)
end end
-- TODO: Move bootstrap to a separate module or even its own binary -- TODO: Move bootstrap to a separate module or even its own binary
-- Fetch over HTTPS with peert cert checked
local function https_fetch(url, ca)
local http_ok, http_request = pcall(require, 'http.request')
local openssl_ok, openssl_ctx = pcall(require, 'openssl.ssl.context')
if not http_ok or not openssl_ok then
return nil, 'error: lua-http and luaossl libraries are missing (but required) for root TA bootstrap'
end
local request = http_request.new_from_uri(url)
request.ctx = openssl_ctx.new('TLSv1_2')
local store = request.ctx:getStore()
store:add(ca)
request.ctx:setVerify(openssl_ctx.VERIFY_PEER)
request.tls = true
local headers, stream = request:go()
if headers == nil then return nil, 'HTTP client library error' end
if headers:get(':status') ~= "200" then return nil, headers:get(':status') end
local resp, err = stream:get_body_as_string()
return resp, err or ""
end
-- remove UTC timezone specification if present or throw error -- remove UTC timezone specification if present or throw error
local function time2utc(orig_timespec) local function time2utc(orig_timespec)
local patterns = {'[+-]00:00$', 'Z$'} local patterns = {'[+-]00:00$', 'Z$'}
...@@ -144,15 +118,21 @@ end ...@@ -144,15 +118,21 @@ end
-- Fetch root anchors in XML over HTTPS, returning a zone-file-style string -- Fetch root anchors in XML over HTTPS, returning a zone-file-style string
-- or false in case of error, and a message. -- or false in case of error, and a message.
local function bootstrap(url, ca) local function bootstrap(url, ca)
local kluautil = pcall(require, 'kluautil')
local file = io.tmpfile()
-- RFC 7958, sec. 2, but we don't do precise XML parsing. -- RFC 7958, sec. 2, but we don't do precise XML parsing.
-- @todo ICANN certificate is verified against current CA -- @todo ICANN certificate is verified against current CA
-- this is not ideal, as it should rather verify .xml signature which -- this is not ideal, as it should rather verify .xml signature which
-- is signed by ICANN long-lived cert, but luasec has no PKCS7 -- is signed by ICANN long-lived cert, but luasec has no PKCS7
local xml, err = https_fetch(url, ca) local rcode, errmsg = kluautil.kr_https_fetch(url, ca, file)
if not xml then if rcode == nil then
return false, string.format('[ ta ] fetch of "%s" failed: %s', url, err) file:close()
return false, string.format('[ ta ] fetch of "%s" failed: %s', url, errmsg)
end end
local xml = file:read("*a")
file:close()
-- we support only minimal subset of https://tools.ietf.org/html/rfc7958 -- we support only minimal subset of https://tools.ietf.org/html/rfc7958
assert_str_match(xml, '<?xml version="1%.0" encoding="UTF%-8"%?>', 1) assert_str_match(xml, '<?xml version="1%.0" encoding="UTF%-8"%?>', 1)
assert_str_match(xml, '<TrustAnchor ', 1) assert_str_match(xml, '<TrustAnchor ', 1)
......
...@@ -13,7 +13,7 @@ end ...@@ -13,7 +13,7 @@ end
-- Support for client sockets from inside policy actions -- Support for client sockets from inside policy actions
local socket_client = function () local socket_client = function ()
return error("missing lua-cqueues library, can't create socket client") return error("missing lua-cqueues library, can't create socket client")
end end
local has_socket, socket = pcall(require, 'cqueues.socket') local has_socket, socket = pcall(require, 'cqueues.socket')
if has_socket then if has_socket then
......
...@@ -16,50 +16,6 @@ local rz_interval_min = 3600 ...@@ -16,50 +16,6 @@ local rz_interval_min = 3600
local prefill = { local prefill = {
} }
-- Fetch over HTTPS
local function https_fetch(url, ca_file, fname)
local http_ok, http_request = pcall(require, 'http.request')
local openssl_ok, openssl_ctx = pcall(require, 'openssl.ssl.context')
if not http_ok or not openssl_ok then
return nil, 'lua-http and luaossl needed for root TA bootstrap'
end
assert(string.match(url, '^https://'))
assert(ca_file)
local req = http_request.new_from_uri(url)
req.ctx = openssl_ctx.new()
local store = req.ctx:getStore()
store:add(ca_file)
req.ctx:setVerify(openssl_ctx.VERIFY_PEER)
req.tls = true
local headers, stream = req:go()
assert(headers, 'HTTP client library error')
if headers:get(':status') ~= "200" then
return nil, headers:get(':status')
end
local file, errmsg = io.open(fname, 'w')
if not file then
error(string.format("[prefill] unable to open file %s (%s)",
fname, errmsg))
end
local err
err, errmsg = stream:save_body_to_file(file)
if err == nil then
return err, errmsg
end
file:close()
return file
end
local function display_delay(time) local function display_delay(time)
local days = math.floor(time / 86400) local days = math.floor(time / 86400)
local hours = math.floor((time % 86400) / 3600) local hours = math.floor((time % 86400) / 3600)
...@@ -93,11 +49,21 @@ local function get_file_ttl(fname) ...@@ -93,11 +49,21 @@ local function get_file_ttl(fname)
end end
local function download(url, fname) local function download(url, fname)
local kluautil = pcall(require, 'kluautil')
local file, rcode, errmsg
file, errmsg = io.open(fname, 'w')
if not file then
error(string.format("[prefill] unable to open file %s (%s)",
fname, errmsg))
end
log("[prefill] downloading root zone to file %s ...", fname) log("[prefill] downloading root zone to file %s ...", fname)
local rzone, err = https_fetch(url, rz_ca_file, fname) rcode, errmsg = kluautil.kr_https_fetch(url, rz_ca_file, file)
if rzone == nil then if rcode == nil then
error(string.format("[prefill] fetch of `%s` failed: %s", url, err)) error(string.format("[prefill] fetch of `%s` failed: %s", url, errmsg))
end end
file:close()
end end
local function import(fname) local function import(fname)
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment