diff --git a/daemon/engine.c b/daemon/engine.c index 21cf159040ea8221db9fca3d570412da704795d2..23d03986381b060015e8a49f6a3371dd1aa65e8a 100644 --- a/daemon/engine.c +++ b/daemon/engine.c @@ -232,6 +232,15 @@ static int l_option(lua_State *L) return 1; } +/** @internal for l_trustanchor: */ +static void ta_add(zs_scanner_t *zs) +{ + map_t *ta = zs->process.data; + if (!ta) + return; + if (kr_ta_add(ta, zs->r_owner, zs->r_type, zs->r_ttl, zs->r_data, zs->r_data_length)) + zs->process.data = NULL; /* error signalling */ +} /** Enable/disable trust anchor. */ static int l_trustanchor(lua_State *L) { @@ -260,13 +269,11 @@ static int l_trustanchor(lua_State *L) lua_pushstring(L, "not enough memory"); lua_error(L); } - int ok = zs_set_input_string(zs, anchor, strlen(anchor)) == 0 && - zs_parse_all(zs) == 0; - /* Add it to TA set and cleanup */ - if (ok) { - ok = kr_ta_add(&engine->resolver.trust_anchors, - zs->r_owner, zs->r_type, zs->r_ttl, zs->r_data, zs->r_data_length) == 0; - } + zs_set_processing(zs, ta_add, NULL, &engine->resolver.trust_anchors); + bool ok = zs_set_input_string(zs, anchor, strlen(anchor)) == 0 + && zs_parse_all(zs) == 0; + ok = ok && zs->process.data; /* reset to NULL on error in ta_add */ + zs_deinit(zs); free(zs); /* Report errors */ diff --git a/daemon/lua/trust_anchors.lua b/daemon/lua/trust_anchors.lua index 52eb0d546f2b2b651547fb05ae7e9b48baf4a305..b219e6a007ba68c2c35055adb16d02940e8fc4af 100644 --- a/daemon/lua/trust_anchors.lua +++ b/daemon/lua/trust_anchors.lua @@ -17,7 +17,7 @@ local function https_fetch(url, ca) return resp[1] end --- Fetch root anchors in XML over HTTPS +-- Fetch root anchors in XML over HTTPS, returning a zone-file-style string. 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 @@ -28,11 +28,14 @@ local function bootstrap(url, ca) if not xml then return false, string.format('[ ta ] fetch of "%s" failed: %s', url, err) end - -- Parse root trust anchor - local fields = {} - string.gsub(xml, "<([%w]+).->([^<]+)</[%w]+>", function (k, v) fields[k] = v end) - local rrdata = string.format('%s %s %s %s', fields.KeyDigest, fields.Algorithm, fields.DigestType, fields.Digest) - local rr = string.format('%s 0 IN DS %s', fields.TrustAnchor, rrdata) + local rr = '' + -- Parse root trust anchor, one digest at a time, converting to a zone-file-style string. + string.gsub(xml, "<KeyDigest[^>]*>(.-)</KeyDigest>", function (xml1) + local fields = {} + string.gsub(xml1, "<([%w]+).->([^<]+)</[%w]+>", function (k, v) fields[k] = v end) + rr = rr .. '\n' .. string.format('. 0 IN DS %s %s %s %s', + fields.KeyTag, fields.Algorithm, fields.DigestType, fields.Digest) + end) -- Add to key set, create an empty keyset file to be filled print('[ ta ] warning: root anchor bootstrapped, you SHOULD check the key manually, see: '.. 'https://data.iana.org/root-anchors/draft-icann-dnssec-trust-anchor.html#sigs')