]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Convert kasp checkds test cases to pytest
authorMatthijs Mekking <matthijs@isc.org>
Mon, 17 Mar 2025 15:39:52 +0000 (16:39 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Fri, 25 Apr 2025 08:20:46 +0000 (10:20 +0200)
This converts the checkds test cases that deal with the 'rndc checkds'
command and setting the 'DSPublish' and 'DSRemoved' metadata.

bin/tests/system/kasp/tests.sh
bin/tests/system/kasp/tests_kasp.py

index d71c16eef4cacb7394def22b55d1582e956c74f4..5254ede76bdb53226959d98255f249198018820c 100644 (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() {
index 5fe82fa4037a21c2f1d2528f3cb9bead23cfeffc..d3406b746a4c5641e82768103aa5d756cc273581 100644 (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"]