]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
prefill: allow to use system-wide CA store
authorPetr Špaček <petr.spacek@nic.cz>
Mon, 30 Dec 2019 11:16:52 +0000 (12:16 +0100)
committerLukáš Ježek <lukas.jezek@nic.cz>
Tue, 7 Jan 2020 10:02:31 +0000 (11:02 +0100)
It also improves error reporting from store:add() call.
Sometimes the error message from lua-ossl is incomplete. This is fixed
by https://github.com/wahern/luaossl/pull/176.

daemon/lua/kluautil.lua
daemon/lua/trust_anchors.lua.in
modules/prefill/README.rst
modules/prefill/prefill.lua

index 773738cf7027d8d9bc4a622615785630882ab585..d0cca438f3ef835fe4717854b56784efcc6334f9 100644 (file)
@@ -10,24 +10,31 @@ function kluautil.kr_table_len(t)
 end
 
 -- Fetch over HTTPS
-function kluautil.kr_https_fetch(url, ca_file, file)
+function kluautil.kr_https_fetch(url, out_file, ca_file)
        local http_ok, http_request = pcall(require, 'http.request')
+       local httptls_ok, http_tls = pcall(require, 'http.tls')
        local openssl_ok, openssl_ctx = pcall(require, 'openssl.ssl.context')
 
-       if not http_ok or not openssl_ok then
+       if not http_ok or not httptls_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.tls = true
+       if ca_file then
+               req.ctx = openssl_ctx.new()
+               local store = req.ctx:getStore()
+               local load_ok, errmsg = pcall(store.add, store, ca_file)
+               if not load_ok then
+                       return nil, errmsg
+               end
+       else  -- use defaults
+               req.ctx = http_tls.new_client_context()
+       end
 
        req.ctx:setVerify(openssl_ctx.VERIFY_PEER)
-       req.tls = true
 
        local headers, stream, errmsg = req:go()
        if not headers then
@@ -39,12 +46,12 @@ function kluautil.kr_https_fetch(url, ca_file, file)
        end
 
        local err
-       err, errmsg = stream:save_body_to_file(file)
+       err, errmsg = stream:save_body_to_file(out_file)
        if err == nil then
                return nil, errmsg
        end
 
-       file:seek ("set", 0)
+       out_file:seek("set", 0)
 
        return true
 end
index 1d4cc163908f245f236e4d1479f221da50eaf95e..7652cd75ccd19cb5451d9513ed87192897f54869 100644 (file)
@@ -124,7 +124,7 @@ local function bootstrap(url, ca)
        -- @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 rcode, errmsg = kluautil.kr_https_fetch(url, ca, file)
+       local rcode, errmsg = kluautil.kr_https_fetch(url, file, ca)
        if rcode == nil then
                file:close()
                return false, string.format('[ ta ] fetch of "%s" failed: %s', url, errmsg)
index 111378949462bb7924d4cef291c95ac8586a9848..1211d141e3f97c5a2f14707a0164d019b118bbec 100644 (file)
@@ -15,8 +15,8 @@ Example configuration is:
        prefill.config({
               ['.'] = {
                       url = 'https://www.internic.net/domain/root.zone',
-                      ca_file = '/etc/pki/tls/certs/ca-bundle.crt',
                       interval = 86400  -- seconds
+                      ca_file = '/etc/pki/tls/certs/ca-bundle.crt', -- optional
               }
         })
 
@@ -27,7 +27,7 @@ Root zone to import must be signed using DNSSEC and the resolver must have valid
 .. csv-table::
  :header: "Parameter", "Description"
 
- "ca_file", "path to CA certificate bundle used to authenticate the HTTPS connection"
+ "ca_file", "path to CA certificate bundle used to authenticate the HTTPS connection (optional, system-wide store will be used if not specified)"
  "interval", "number of seconds between zone data refresh attempts"
  "url", "URL of a file in :rfc:`1035` zone file format"
 
index 773162bd796ec4eb63f0db68f32f446d36884d41..32079f51941c2c6c80b6c961d1fe79c73436dcf1 100644 (file)
@@ -77,7 +77,7 @@ local function download(url, fname)
        end
 
        log("[prefill] downloading root zone to file %s ...", fname)
-       rcode, errmsg = kluautil.kr_https_fetch(url, rz_ca_file, file)
+       rcode, errmsg = kluautil.kr_https_fetch(url, file, rz_ca_file)
        if rcode == nil then
                error(string.format("[prefill] fetch of `%s` failed: %s", url, errmsg))
        end
@@ -156,10 +156,6 @@ local function config_zone(zone_cfg)
                rz_cur_interval = zone_cfg.interval
        end
 
-       if not zone_cfg.ca_file then
-               error('[prefill] option ca_file must point '
-                       .. 'to a file with CA certificate(s) in PEM format')
-       end
        rz_ca_file = zone_cfg.ca_file
 
        if not zone_cfg.url or not string.match(zone_cfg.url, '^https://') then