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 from typing import Dict, List, Optional, Tuple, Union
import dns import dns
import dns.dnssec
from dns.dnssectypes import DSDigest
import dns.rdatatype import dns.rdatatype
import dns.rrset import dns.rrset
import dns.tsig import dns.tsig
@ -30,6 +32,7 @@ import isctest.log
import isctest.query import isctest.query
import isctest.util import isctest.util
from isctest.instance import NamedInstance from isctest.instance import NamedInstance
from isctest.template import TrustAnchor
from isctest.vars.algorithms import Algorithm, ALL_ALGORITHMS_BY_NUM from isctest.vars.algorithms import Algorithm, ALL_ALGORITHMS_BY_NUM
DEFAULT_TTL = 300 DEFAULT_TTL = 300
@ -464,6 +467,19 @@ class Key:
), f"DNSKEY not found in {self.keyfile}" ), f"DNSKEY not found in {self.keyfile}"
return dnskey_rr 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: def is_ksk(self) -> bool:
return self.get_metadata("KSK") == "yes" return self.get_metadata("KSK") == "yes"

View file

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