diff --git a/daemon/lua/kluautil.lua b/daemon/lua/kluautil.lua
index 1ab6d5356979d6751a9ecd72d00a1b268a5b23d2..158927914d96c5f30d5f94642265e88842ed352b 100644
--- a/daemon/lua/kluautil.lua
+++ b/daemon/lua/kluautil.lua
@@ -8,3 +8,39 @@ function kr_table_len (t)
 	return len
 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
+
diff --git a/daemon/lua/trust_anchors.lua.in b/daemon/lua/trust_anchors.lua.in
index 87135c81aa46358a57d015b22949236089aa93a0..2676a6a3398f3d5eb018c48247ecbf9ac2558128 100644
--- a/daemon/lua/trust_anchors.lua.in
+++ b/daemon/lua/trust_anchors.lua.in
@@ -22,32 +22,6 @@ local function upgrade_required(msg)
 end
 
 -- 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
 local function time2utc(orig_timespec)
 	local patterns = {'[+-]00:00$', 'Z$'}
@@ -144,15 +118,21 @@ end
 -- Fetch root anchors in XML over HTTPS, returning a zone-file-style string
 -- or false in case of error, and a message.
 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.
 	-- @todo ICANN certificate is verified against current CA
 	--       this is not ideal, as it should rather verify .xml signature which
 	--       is signed by ICANN long-lived cert, but luasec has no PKCS7
-	local xml, err = https_fetch(url, ca)
-	if not xml then
-		return false, string.format('[ ta ] fetch of "%s" failed: %s', url, err)
+	local rcode, errmsg = kluautil.kr_https_fetch(url, ca, file)
+	if rcode == nil then
+		file:close()
+		return false, string.format('[ ta ] fetch of "%s" failed: %s', url, errmsg)
 	end
 
+	local xml = file:read("*a")
+	file:close()
+
 	-- 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, '<TrustAnchor ', 1)
diff --git a/modules/policy/policy.lua b/modules/policy/policy.lua
index c5775aae72635ac64a0698f6f439333a3ce6108a..d9da4d80031d8c7e4ca01003e7cb0ae442ac66d2 100644
--- a/modules/policy/policy.lua
+++ b/modules/policy/policy.lua
@@ -13,7 +13,7 @@ end
 
 -- Support for client sockets from inside policy actions
 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
 local has_socket, socket = pcall(require, 'cqueues.socket')
 if has_socket then
diff --git a/modules/prefill/prefill.lua b/modules/prefill/prefill.lua
index 821e8bb8f4149525db75fb51459bb63b7d250cdf..aa2246eea89746e795bf9d3336d0202ee8a84cd5 100644
--- a/modules/prefill/prefill.lua
+++ b/modules/prefill/prefill.lua
@@ -16,50 +16,6 @@ local rz_interval_min = 3600
 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 days = math.floor(time / 86400)
 	local hours = math.floor((time % 86400) / 3600)
@@ -93,11 +49,21 @@ local function get_file_ttl(fname)
 end
 
 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)
-	local rzone, err = https_fetch(url, rz_ca_file, fname)
-	if rzone == nil then
-		error(string.format("[prefill] fetch of `%s` failed: %s", url, err))
+	rcode, errmsg = kluautil.kr_https_fetch(url, rz_ca_file, file)
+	if rcode == nil then
+		error(string.format("[prefill] fetch of `%s` failed: %s", url, errmsg))
 	end
+
+	file:close()
 end
 
 local function import(fname)