2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 05:57:52 +00:00

Convert kasp checkds test cases to pytest

This converts the checkds test cases that deal with the 'rndc checkds'
command and setting the 'DSPublish' and 'DSRemoved' metadata.
This commit is contained in:
Matthijs Mekking 2025-03-17 16:39:52 +01:00
parent 1940aa1d0b
commit 44b4d5ebd6
2 changed files with 160 additions and 231 deletions

View File

@ -97,237 +97,6 @@ set_keytimes_csk_policy() {
# Key lifetime is unlimited, so not setting RETIRED and REMOVED.
}
# Key properties.
set_keyrole "KEY1" "csk"
set_keylifetime "KEY1" "0"
set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256"
set_keysigning "KEY1" "yes"
set_zonesigning "KEY1" "yes"
# DNSKEY, RRSIG (ksk), RRSIG (zsk) are published. DS needs to wait.
set_keystate "KEY1" "GOAL" "omnipresent"
set_keystate "KEY1" "STATE_DNSKEY" "rumoured"
set_keystate "KEY1" "STATE_KRRSIG" "rumoured"
set_keystate "KEY1" "STATE_ZRRSIG" "rumoured"
set_keystate "KEY1" "STATE_DS" "hidden"
#
# Zone: checkds-ksk.kasp.
#
key_clear "KEY1"
key_clear "KEY2"
key_clear "KEY3"
key_clear "KEY4"
set_zone "checkds-ksk.kasp"
set_policy "checkds-ksk" "2" "303"
set_server "ns3" "10.53.0.3"
# Key properties.
set_keyrole "KEY1" "ksk"
set_keylifetime "KEY1" "0"
set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256"
set_keysigning "KEY1" "yes"
set_zonesigning "KEY1" "no"
set_keyrole "KEY2" "zsk"
set_keylifetime "KEY2" "0"
set_keyalgorithm "KEY2" "13" "ECDSAP256SHA256" "256"
set_keysigning "KEY2" "no"
set_zonesigning "KEY2" "yes"
# DNSKEY, RRSIG (ksk), RRSIG (zsk) are published. DS needs to wait.
set_keystate "KEY1" "GOAL" "omnipresent"
set_keystate "KEY1" "STATE_DNSKEY" "rumoured"
set_keystate "KEY1" "STATE_KRRSIG" "rumoured"
set_keystate "KEY1" "STATE_DS" "hidden"
set_keystate "KEY2" "GOAL" "omnipresent"
set_keystate "KEY2" "STATE_DNSKEY" "rumoured"
set_keystate "KEY2" "STATE_ZRRSIG" "rumoured"
check_keys
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
check_apex
check_subdomain
dnssec_verify
basefile=$(key_get KEY1 BASEFILE)
_wait_for_metadata() {
_expr=$1
_file=$2
grep "$_expr" $_file >/dev/null || return 1
return 0
}
n=$((n + 1))
echo_i "checkds publish correctly sets DSPublish for zone $ZONE ($n)"
now=$(date +%Y%m%d%H%M%S)
rndc_checkds "$SERVER" "$DIR" "-" "$now" "published" "$ZONE"
retry_quiet 3 _wait_for_metadata "DSPublish: $now" "${basefile}.state" || log_error "bad DSPublish in ${basefile}.state"
# DS State should be forced into RUMOURED.
set_keystate "KEY1" "STATE_DS" "rumoured"
check_keys
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "checkds withdraw correctly sets DSRemoved for zone $ZONE ($n)"
now=$(date +%Y%m%d%H%M%S)
rndc_checkds "$SERVER" "$DIR" "-" "$now" "withdrawn" "$ZONE"
retry_quiet 3 _wait_for_metadata "DSRemoved: $now" "${basefile}.state" || log_error "bad DSRemoved in ${basefile}.state"
# DS State should be forced into UNRETENTIVE.
set_keystate "KEY1" "STATE_DS" "unretentive"
check_keys
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
#
# Zone: checkds-doubleksk.kasp.
#
key_clear "KEY1"
key_clear "KEY2"
key_clear "KEY3"
key_clear "KEY4"
set_zone "checkds-doubleksk.kasp"
set_policy "checkds-doubleksk" "3" "303"
set_server "ns3" "10.53.0.3"
# Key properties.
set_keyrole "KEY1" "ksk"
set_keylifetime "KEY1" "0"
set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256"
set_keysigning "KEY1" "yes"
set_zonesigning "KEY1" "no"
set_keyrole "KEY2" "ksk"
set_keylifetime "KEY2" "0"
set_keyalgorithm "KEY2" "13" "ECDSAP256SHA256" "256"
set_keysigning "KEY2" "yes"
set_zonesigning "KEY2" "no"
set_keyrole "KEY3" "zsk"
set_keylifetime "KEY3" "0"
set_keyalgorithm "KEY3" "13" "ECDSAP256SHA256" "256"
set_keysigning "KEY3" "no"
set_zonesigning "KEY3" "yes"
# DNSKEY, RRSIG (ksk), RRSIG (zsk) are published. DS needs to wait.
set_keystate "KEY1" "GOAL" "omnipresent"
set_keystate "KEY1" "STATE_DNSKEY" "rumoured"
set_keystate "KEY1" "STATE_KRRSIG" "rumoured"
set_keystate "KEY1" "STATE_DS" "hidden"
set_keystate "KEY2" "GOAL" "omnipresent"
set_keystate "KEY2" "STATE_DNSKEY" "rumoured"
set_keystate "KEY2" "STATE_KRRSIG" "rumoured"
set_keystate "KEY2" "STATE_DS" "hidden"
set_keystate "KEY3" "GOAL" "omnipresent"
set_keystate "KEY3" "STATE_DNSKEY" "rumoured"
set_keystate "KEY3" "STATE_ZRRSIG" "rumoured"
check_keys
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
check_apex
check_subdomain
dnssec_verify
basefile1=$(key_get KEY1 BASEFILE)
basefile2=$(key_get KEY2 BASEFILE)
n=$((n + 1))
echo_i "checkds published does not set DSPublish for zone $ZONE (multiple KSK) ($n)"
rndc_checkds "$SERVER" "$DIR" "-" "20200102121314" "published" "$ZONE"
grep "DSPublish:" "${basefile1}.state" >/dev/null && log_error "DSPublish incorrectly set in ${basefile1}"
grep "DSPublish:" "${basefile2}.state" >/dev/null && log_error "DSPublish incorrectly set in ${basefile2}"
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "checkds withdrawn does not set DSRemoved for zone $ZONE (multiple KSK) ($n)"
rndc_checkds "$SERVER" "$DIR" "-" "20190102121314" "withdrawn" "$ZONE"
grep "DSRemoved:" "${basefile1}.state" >/dev/null && log_error "DSRemoved incorrectly set in ${basefile1}"
grep "DSRemoved:" "${basefile2}.state" >/dev/null && log_error "DSRemoved incorrectly set in ${basefile2}"
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "checkds published does not set DSPublish for zone $ZONE (wrong algorithm) ($n)"
rndccmd "$SERVER" dnssec -checkds -key $(key_get KEY1 ID) -alg 8 "published" "$ZONE" >rndc.dnssec.checkds.out.$ZONE.$n
grep "DSPublish:" "${basefile1}.state" >/dev/null && log_error "DSPublish incorrectly set in ${basefile1}"
grep "DSPublish:" "${basefile2}.state" >/dev/null && log_error "DSPublish incorrectly set in ${basefile2}"
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "checkds withdrawn does not set DSRemoved for zone $ZONE (wrong algorithm) ($n)"
rndccmd "$SERVER" dnssec -checkds -key $(key_get KEY1 ID) -alg RSASHA256 "withdrawn" "$ZONE" >rndc.dnssec.checkds.out.$ZONE.$n
grep "DSRemoved:" "${basefile1}.state" >/dev/null && log_error "DSRemoved incorrectly set in ${basefile1}"
grep "DSRemoved:" "${basefile2}.state" >/dev/null && log_error "DSRemoved incorrectly set in ${basefile2}"
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "checkds published -key correctly sets DSPublish for key $(key_get KEY1 ID) zone $ZONE (multiple KSK) ($n)"
rndc_checkds "$SERVER" "$DIR" KEY1 "20190102121314" "published" "$ZONE"
retry_quiet 3 _wait_for_metadata "DSPublish: 20190102121314" "${basefile1}.state" || log_error "bad DSPublish in ${basefile1}.state"
grep "DSPublish:" "${basefile2}.state" >/dev/null && log_error "DSPublish incorrectly set in ${basefile2}"
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "checkds withdrawn -key correctly sets DSRemoved for key $(key_get KEY2 ID) zone $ZONE (multiple KSK) ($n)"
rndc_checkds "$SERVER" "$DIR" KEY2 "20200102121314" "withdrawn" "$ZONE"
grep "DSRemoved:" "${basefile1}.state" >/dev/null && log_error "DSPublish incorrectly set in ${basefile1}"
retry_quiet 3 _wait_for_metadata "DSRemoved: 20200102121314" "${basefile2}.state" || log_error "bad DSRemoved in ${basefile2}.state"
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
#
# Zone: checkds-csk.kasp.
#
key_clear "KEY1"
key_clear "KEY2"
key_clear "KEY3"
key_clear "KEY4"
set_zone "checkds-csk.kasp"
set_policy "checkds-csk" "1" "303"
set_server "ns3" "10.53.0.3"
# Key properties.
set_keyrole "KEY1" "csk"
set_keylifetime "KEY1" "0"
set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256"
set_keysigning "KEY1" "yes"
set_zonesigning "KEY1" "yes"
# DNSKEY, RRSIG (ksk), RRSIG (zsk) are published. DS needs to wait.
set_keystate "KEY1" "GOAL" "omnipresent"
set_keystate "KEY1" "STATE_DNSKEY" "rumoured"
set_keystate "KEY1" "STATE_KRRSIG" "rumoured"
set_keystate "KEY1" "STATE_ZRRSIG" "rumoured"
set_keystate "KEY1" "STATE_DS" "hidden"
check_keys
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
check_apex
check_subdomain
dnssec_verify
basefile=$(key_get KEY1 BASEFILE)
n=$((n + 1))
echo_i "checkds publish correctly sets DSPublish for zone $ZONE ($n)"
rndc_checkds "$SERVER" "$DIR" "-" "20190102121314" "published" "$ZONE"
retry_quiet 3 _wait_for_metadata "DSPublish: 20190102121314" "${basefile}.state" || log_error "bad DSPublish in ${basefile}.state"
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "checkds withdraw correctly sets DSRemoved for zone $ZONE ($n)"
rndc_checkds "$SERVER" "$DIR" "-" "20200102121314" "withdrawn" "$ZONE"
retry_quiet 3 _wait_for_metadata "DSRemoved: 20200102121314" "${basefile}.state" || log_error "bad DSRemoved in ${basefile}.state"
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# Set keytimes for dnssec-policy with various algorithms.
# These all use the same time values.
set_keytimes_algorithm_policy() {

View File

@ -921,6 +921,166 @@ def test_kasp_dynamic(servers):
assert f"zone_resigninc: zone {zone}/IN (unsigned): enter" not in "ns3/named.run"
def test_kasp_checkds(servers):
server = servers["ns3"]
def wait_for_metadata():
return isctest.util.file_contents_contain(ksk.statefile, metadata)
# Zone: checkds-ksk.kasp.
zone = "checkds-ksk.kasp"
policy = "checkds-ksk"
alg = os.environ["DEFAULT_ALGORITHM_NUMBER"]
size = os.environ["DEFAULT_BITS"]
policy_keys = [
f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden",
f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured",
]
expected = isctest.kasp.policy_to_properties(ttl=303, keys=policy_keys)
keys = isctest.kasp.keydir_to_keylist(zone, "ns3")
ksks = [k for k in keys if k.is_ksk()]
zsks = [k for k in keys if k.is_zsk()]
isctest.kasp.check_zone_is_signed(server, zone)
isctest.kasp.check_keys(zone, keys, expected)
check_all(server, zone, policy, ksks, zsks)
now = KeyTimingMetadata.now()
ksk = ksks[0]
isctest.log.info("check if checkds -publish correctly sets DSPublish")
server.rndc(f"dnssec -checkds -when {now} published {zone}", log=False)
metadata = f"DSPublish: {now}"
isctest.run.retry_with_timeout(wait_for_metadata, timeout=3)
expected[0].metadata["DSState"] = "rumoured"
expected[0].timing["DSPublish"] = now
isctest.kasp.check_keys(zone, keys, expected)
isctest.log.info("check if checkds -withdrawn correctly sets DSRemoved")
server.rndc(f"dnssec -checkds -when {now} withdrawn {zone}", log=False)
metadata = f"DSRemoved: {now}"
isctest.run.retry_with_timeout(wait_for_metadata, timeout=3)
expected[0].metadata["DSState"] = "unretentive"
expected[0].timing["DSRemoved"] = now
isctest.kasp.check_keys(zone, keys, expected)
def test_kasp_checkds_doubleksk(servers):
server = servers["ns3"]
def wait_for_metadata():
return isctest.util.file_contents_contain(ksk.statefile, metadata)
# Zone: checkds-doubleksk.kasp.
zone = "checkds-doubleksk.kasp"
policy = "checkds-doubleksk"
alg = os.environ["DEFAULT_ALGORITHM_NUMBER"]
size = os.environ["DEFAULT_BITS"]
policy_keys = [
f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden",
f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden",
f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured",
]
expected = isctest.kasp.policy_to_properties(ttl=303, keys=policy_keys)
keys = isctest.kasp.keydir_to_keylist(zone, "ns3")
ksks = [k for k in keys if k.is_ksk()]
zsks = [k for k in keys if k.is_zsk()]
isctest.kasp.check_zone_is_signed(server, zone)
isctest.kasp.check_keys(zone, keys, expected)
check_all(server, zone, policy, ksks, zsks)
now = KeyTimingMetadata.now()
ksk = ksks[0]
badalg = os.environ["ALTERNATIVE_ALGORITHM_NUMBER"]
isctest.log.info("check invalid checkds commands")
def check_error():
response = server.rndc(test["command"], log=False)
assert test["error"] in response
test_cases = [
{
"command": f"dnssec -checkds -when {now} published {zone}",
"error": "multiple possible keys found, retry command with -key id",
},
{
"command": f"dnssec -checkds -when {now} withdrawn {zone}",
"error": "multiple possible keys found, retry command with -key id",
},
{
"command": f"dnssec -checkds -when {now} -key {ksks[0].tag} -alg {badalg} published {zone}",
"error": "Error executing checkds command: no matching key found",
},
{
"command": f"dnssec -checkds -when {now} -key {ksks[0].tag} -alg {badalg} withdrawn {zone}",
"error": "Error executing checkds command: no matching key found",
},
]
for test in test_cases:
check_error()
isctest.log.info("check if checkds -publish -key correctly sets DSPublish")
server.rndc(
f"dnssec -checkds -when {now} -key {ksk.tag} published {zone}", log=False
)
metadata = f"DSPublish: {now}"
isctest.run.retry_with_timeout(wait_for_metadata, timeout=3)
expected[0].metadata["DSState"] = "rumoured"
expected[0].timing["DSPublish"] = now
isctest.kasp.check_keys(zone, keys, expected)
isctest.log.info("check if checkds -withdrawn -key correctly sets DSRemoved")
ksk = ksks[1]
server.rndc(
f"dnssec -checkds -when {now} -key {ksk.tag} withdrawn {zone}", log=False
)
metadata = f"DSRemoved: {now}"
isctest.run.retry_with_timeout(wait_for_metadata, timeout=3)
expected[1].metadata["DSState"] = "unretentive"
expected[1].timing["DSRemoved"] = now
isctest.kasp.check_keys(zone, keys, expected)
def test_kasp_checkds_csk(servers):
server = servers["ns3"]
def wait_for_metadata():
return isctest.util.file_contents_contain(ksk.statefile, metadata)
# Zone: checkds-csk.kasp.
zone = "checkds-csk.kasp"
policy = "checkds-csk"
alg = os.environ["DEFAULT_ALGORITHM_NUMBER"]
size = os.environ["DEFAULT_BITS"]
policy_keys = [
f"csk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden",
]
expected = isctest.kasp.policy_to_properties(ttl=303, keys=policy_keys)
keys = isctest.kasp.keydir_to_keylist(zone, "ns3")
isctest.kasp.check_zone_is_signed(server, zone)
isctest.kasp.check_keys(zone, keys, expected)
check_all(server, zone, policy, keys, [])
now = KeyTimingMetadata.now()
ksk = keys[0]
isctest.log.info("check if checkds -publish csk correctly sets DSPublish")
server.rndc(f"dnssec -checkds -when {now} published {zone}", log=False)
metadata = f"DSPublish: {now}"
isctest.run.retry_with_timeout(wait_for_metadata, timeout=3)
expected[0].metadata["DSState"] = "rumoured"
expected[0].timing["DSPublish"] = now
isctest.kasp.check_keys(zone, keys, expected)
isctest.log.info("check if checkds -withdrawn csk correctly sets DSRemoved")
server.rndc(f"dnssec -checkds -when {now} withdrawn {zone}", log=False)
metadata = f"DSRemoved: {now}"
isctest.run.retry_with_timeout(wait_for_metadata, timeout=3)
expected[0].metadata["DSState"] = "unretentive"
expected[0].timing["DSRemoved"] = now
isctest.kasp.check_keys(zone, keys, expected)
def test_kasp_special_characters(servers):
server = servers["ns3"]