Add a template for TA and generate it from isctest.kasp.Key

Add isctest.kasp.Key.into_ta() method which convert the key into DS /
DNSKEY trust anchor for BIND config. Add a shared template
trusted.conf.j2 which can be linked to in tests to create the trust
anchor configuration from trust anchor data returned from bootstrap()
function.

This is basically a python replacement for the keyfile_to_static_ds (and
friends) from the conf.sh shell framework.
This commit is contained in:
Nicki Křížek 2025-11-03 14:59:00 +01:00
parent 0bf20f8d68
commit f6cb154b65
3 changed files with 42 additions and 0 deletions

View file

@ -0,0 +1,18 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
trust-anchors {
{% for ta in trust_anchors %}
"@ta.domain@" @ta.type@ @ta.contents@;
{% endfor %}
};

View file

@ -20,6 +20,8 @@ import time
from typing import Dict, List, Optional, Tuple, Union
import dns
import dns.dnssec
from dns.dnssectypes import DSDigest
import dns.rdatatype
import dns.rrset
import dns.tsig
@ -30,6 +32,7 @@ import isctest.log
import isctest.query
import isctest.util
from isctest.instance import NamedInstance
from isctest.template import TrustAnchor
from isctest.vars.algorithms import Algorithm, ALL_ALGORITHMS_BY_NUM
DEFAULT_TTL = 300
@ -464,6 +467,19 @@ class Key:
), f"DNSKEY not found in {self.keyfile}"
return dnskey_rr
def into_ta(self, ta_type: str, dsdigest=DSDigest.SHA256) -> TrustAnchor:
dnskey = self.dnskey
if ta_type in ["static-ds", "initial-ds"]:
ds = dns.dnssec.make_ds(dnskey.name, dnskey[0], dsdigest)
parts = str(ds).split()
contents = " ".join(parts[:3]) + f' "{parts[3]}"'
elif ta_type in ["static-key", "initial-key"]:
parts = str(dnskey).split()
contents = " ".join(parts[4:7]) + f' "{"".join(parts[7:])}"'
else:
raise ValueError(f"invalid trust anchor type: {ta_type}")
return TrustAnchor(str(dnskey.name), ta_type, contents)
def is_ksk(self) -> bool:
return self.get_metadata("KSK") == "yes"

View file

@ -11,6 +11,7 @@
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Dict, Optional, Union
@ -79,3 +80,10 @@ class TemplateEngine:
]
for template in templates:
self.render(template[:-3], data)
@dataclass
class TrustAnchor:
domain: str
type: str
contents: str