From 6c0380db8a5cc05a51198e9ba253f5db24c3754e Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Mon, 24 Jun 2024 10:01:37 +0200 Subject: [PATCH 1/5] Move dnssec-policy to kasp-fips.conf.in All dnssec-policy configurations are here, so why not this one? (cherry picked from commit 93326e3e180f4cb2d5fe0b01ba99941d5ec74355) --- bin/tests/system/kasp/ns6/named.conf.in | 6 ------ bin/tests/system/kasp/ns6/named2.conf.in | 6 ------ bin/tests/system/kasp/ns6/policies/kasp-fips.conf.in | 6 ++++++ 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/bin/tests/system/kasp/ns6/named.conf.in b/bin/tests/system/kasp/ns6/named.conf.in index 7b0cba8478..8215531f3e 100644 --- a/bin/tests/system/kasp/ns6/named.conf.in +++ b/bin/tests/system/kasp/ns6/named.conf.in @@ -89,12 +89,6 @@ zone "step1.csk-algorithm-roll.kasp" { dnssec-policy "csk-algoroll"; }; -dnssec-policy "modified" { - keys { - csk lifetime unlimited algorithm rsasha256 2048; - }; -}; - zone example { type primary; file "example.db"; diff --git a/bin/tests/system/kasp/ns6/named2.conf.in b/bin/tests/system/kasp/ns6/named2.conf.in index 087fa7716f..cd209e7a52 100644 --- a/bin/tests/system/kasp/ns6/named2.conf.in +++ b/bin/tests/system/kasp/ns6/named2.conf.in @@ -177,12 +177,6 @@ zone "step6.csk-algorithm-roll.kasp" { dnssec-policy "csk-algoroll"; }; -dnssec-policy "modified" { - keys { - csk lifetime unlimited algorithm rsasha256 2048; - }; -}; - zone example { type primary; file "example.db"; diff --git a/bin/tests/system/kasp/ns6/policies/kasp-fips.conf.in b/bin/tests/system/kasp/ns6/policies/kasp-fips.conf.in index 810b91d6ad..dc234d0c21 100644 --- a/bin/tests/system/kasp/ns6/policies/kasp-fips.conf.in +++ b/bin/tests/system/kasp/ns6/policies/kasp-fips.conf.in @@ -24,6 +24,12 @@ dnssec-policy "nsec3" { nsec3param iterations 0 optout no salt-length 0; }; +dnssec-policy "modified" { + keys { + csk lifetime unlimited algorithm rsasha256 2048; + }; +}; + dnssec-policy "rsasha256" { signatures-refresh P5D; signatures-validity 30d; From 55f79b34b6275e91d47b965fdeb47150fde58038 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Mon, 24 Jun 2024 11:18:40 +0200 Subject: [PATCH 2/5] Test updating dnssec-policy key lifetime Check if the key lifetime is updated in the key files. Make sure the inactive and removed timing metadata are adjusted accordingly. (cherry picked from commit 2237895bb4d06a1f9f127b11a320ae6ecf12053c) --- bin/tests/system/kasp/ns6/named.conf.in | 24 +++++++ bin/tests/system/kasp/ns6/named2.conf.in | 24 +++++++ .../kasp/ns6/policies/kasp-fips.conf.in | 17 +++++ bin/tests/system/kasp/ns6/setup.sh | 5 ++ bin/tests/system/kasp/tests.sh | 65 +++++++++++++++++++ 5 files changed, 135 insertions(+) diff --git a/bin/tests/system/kasp/ns6/named.conf.in b/bin/tests/system/kasp/ns6/named.conf.in index 8215531f3e..f30445ba27 100644 --- a/bin/tests/system/kasp/ns6/named.conf.in +++ b/bin/tests/system/kasp/ns6/named.conf.in @@ -95,3 +95,27 @@ zone example { inline-signing yes; dnssec-policy modified; }; + +zone longer-lifetime { + type primary; + file "longer-lifetime.db"; + dnssec-policy short-lifetime; +}; + +zone shorter-lifetime { + type primary; + file "shorter-lifetime.db"; + dnssec-policy long-lifetime; +}; + +zone limit-lifetime { + type primary; + file "limit-lifetime.db"; + dnssec-policy unlimited-lifetime; +}; + +zone unlimit-lifetime { + type primary; + file "unlimit-lifetime.db"; + dnssec-policy short-lifetime; +}; diff --git a/bin/tests/system/kasp/ns6/named2.conf.in b/bin/tests/system/kasp/ns6/named2.conf.in index cd209e7a52..fac2524e04 100644 --- a/bin/tests/system/kasp/ns6/named2.conf.in +++ b/bin/tests/system/kasp/ns6/named2.conf.in @@ -183,3 +183,27 @@ zone example { inline-signing yes; dnssec-policy modified; }; + +zone longer-lifetime { + type primary; + file "longer-lifetime.db"; + dnssec-policy long-lifetime; +}; + +zone shorter-lifetime { + type primary; + file "shorter-lifetime.db"; + dnssec-policy short-lifetime; +}; + +zone limit-lifetime { + type primary; + file "limit-lifetime.db"; + dnssec-policy short-lifetime; +}; + +zone unlimit-lifetime { + type primary; + file "unlimit-lifetime.db"; + dnssec-policy unlimited-lifetime; +}; diff --git a/bin/tests/system/kasp/ns6/policies/kasp-fips.conf.in b/bin/tests/system/kasp/ns6/policies/kasp-fips.conf.in index dc234d0c21..51c4d88488 100644 --- a/bin/tests/system/kasp/ns6/policies/kasp-fips.conf.in +++ b/bin/tests/system/kasp/ns6/policies/kasp-fips.conf.in @@ -30,6 +30,23 @@ dnssec-policy "modified" { }; }; +dnssec-policy "unlimited-lifetime" { + keys { + csk lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + }; +}; +dnssec-policy "short-lifetime" { + keys { + csk lifetime P6M algorithm @DEFAULT_ALGORITHM@; + }; +}; + +dnssec-policy "long-lifetime" { + keys { + csk lifetime P1Y algorithm @DEFAULT_ALGORITHM@; + }; +}; + dnssec-policy "rsasha256" { signatures-refresh P5D; signatures-validity 30d; diff --git a/bin/tests/system/kasp/ns6/setup.sh b/bin/tests/system/kasp/ns6/setup.sh index 1c2fd01610..dcca7290f0 100644 --- a/bin/tests/system/kasp/ns6/setup.sh +++ b/bin/tests/system/kasp/ns6/setup.sh @@ -29,6 +29,11 @@ R="RUMOURED" O="OMNIPRESENT" U="UNRETENTIVE" +for zn in shorter-lifetime longer-lifetime limit-lifetime unlimit-lifetime; do + setup $zn + cp template.db.in $zonefile +done + # The child zones (step1, step2) beneath these zones represent the various # steps of unsigning a zone. for zn in going-insecure.kasp going-insecure-dynamic.kasp; do diff --git a/bin/tests/system/kasp/tests.sh b/bin/tests/system/kasp/tests.sh index c16f3cd542..e0ea8d951a 100644 --- a/bin/tests/system/kasp/tests.sh +++ b/bin/tests/system/kasp/tests.sh @@ -3709,6 +3709,65 @@ check_apex check_subdomain dnssec_verify +# Test key lifetime changes +set_keytimes_lifetime_update() { + if [ $1 -eq 0 ]; then + set_keytime "KEY1" "RETIRED" "none" + set_keytime "KEY1" "REMOVED" "none" + else + active=$(key_get KEY1 ACTIVE) + set_addkeytime "KEY1" "RETIRED" "${active}" $1 + # The key is removed after the retire time plus max-zone-ttl (1d), + # sign delay (9d), zone propagation delay (5m), retire safety (1h) = + # 777600 + 86400 + 300 + 3600 = 867900 + retired=$(key_get KEY1 RETIRED) + set_addkeytime "KEY1" "REMOVED" "${retired}" 867900 + fi +} + +check_key_lifetime() { + zone=$1 + policy=$2 + lifetime=$3 + + set_zone "$zone" + set_policy "$policy" "1" "3600" + set_server "ns6" "10.53.0.6" + # Key properties. + key_clear "KEY1" + set_keyrole "KEY1" "csk" + set_keylifetime "KEY1" "$lifetime" + set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256" + set_keysigning "KEY1" "yes" + set_zonesigning "KEY1" "yes" + key_clear "KEY2" + key_clear "KEY3" + key_clear "KEY4" + + # The CSK is rumoured. + 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 + + # Key timings. + set_keytimes_csk_policy + set_keytimes_lifetime_update $lifetime + + # Variuous checks. + check_keytimes + check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" + check_apex + check_subdomain + dnssec_verify +} +check_key_lifetime "shorter-lifetime" "long-lifetime" "31536000" +check_key_lifetime "longer-lifetime" "short-lifetime" "16070400" +check_key_lifetime "limit-lifetime" "unlimited-lifetime" "0" +check_key_lifetime "unlimit-lifetime" "short-lifetime" "16070400" + # # Testing algorithm rollover. # @@ -4004,6 +4063,12 @@ check_apex check_subdomain dnssec_verify +# Test key lifetime updates. +check_key_lifetime "shorter-lifetime" "short-lifetime" "16070400" +check_key_lifetime "longer-lifetime" "long-lifetime" "31536000" +check_key_lifetime "limit-lifetime" "short-lifetime" "16070400" +check_key_lifetime "unlimit-lifetime" "unlimited-lifetime" "0" + # # Testing going insecure. # From 7ab4a358202c30cc34c55d234736cbb03cc950b6 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Mon, 24 Jun 2024 15:14:16 +0200 Subject: [PATCH 3/5] Update key lifetime and metadata after reconfig If dnssec-policy is reconfigured and the key lifetime has changed, update existing keys with the new lifetime and adjust the retire and removed timing metadata accordingly. If the key has no lifetime yet, just initialize the lifetime. It may be that the retire/removed timing metadata has already been set. Skip keys which goal is not set to omnipresent. These keys are already in the progress of retiring, or still unused. (cherry picked from commit 1cec0b04481567e814ee3388f84ecf2daf87f169) --- lib/dns/keymgr.c | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/lib/dns/keymgr.c b/lib/dns/keymgr.c index 023dee9e43..8d2f54eac8 100644 --- a/lib/dns/keymgr.c +++ b/lib/dns/keymgr.c @@ -413,6 +413,41 @@ keymgr_dnsseckey_kaspkey_match(dns_dnsseckey_t *dkey, dns_kasp_key_t *kkey) { return (true); } +/* Update lifetime and retire and remove time accordingly. */ +static void +keymgr_key_update_lifetime(dns_dnsseckey_t *key, dns_kasp_t *kasp, + isc_stdtime_t now, uint32_t lifetime) { + uint32_t l; + dst_key_state_t g = HIDDEN; + isc_result_t r; + + (void)dst_key_getstate(key->key, DST_KEY_GOAL, &g); + r = dst_key_getnum(key->key, DST_NUM_LIFETIME, &l); + /* Initialize lifetime. */ + if (r != ISC_R_SUCCESS) { + dst_key_setnum(key->key, DST_NUM_LIFETIME, lifetime); + return; + } + /* Skip keys that are still hidden or already retiring. */ + if (g != OMNIPRESENT) { + return; + } + /* Update lifetime and timing metadata. */ + if (l != lifetime) { + dst_key_setnum(key->key, DST_NUM_LIFETIME, lifetime); + if (lifetime > 0) { + uint32_t a = now; + (void)dst_key_gettime(key->key, DST_TIME_ACTIVATE, &a); + dst_key_settime(key->key, DST_TIME_INACTIVE, + (a + lifetime)); + keymgr_settime_remove(key, kasp); + } else { + dst_key_unsettime(key->key, DST_TIME_INACTIVE); + dst_key_unsettime(key->key, DST_TIME_DELETE); + } + } +} + static bool keymgr_keyid_conflict(dst_key_t *newkey, dns_dnsseckeylist_t *keys) { uint16_t id = dst_key_id(newkey); @@ -2122,15 +2157,9 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass, keystr, keymgr_keyrole(dkey->key), dns_kasp_getname(kasp)); - /* Initialize lifetime if not set. */ - uint32_t l; - if (dst_key_getnum(dkey->key, DST_NUM_LIFETIME, - &l) != ISC_R_SUCCESS) - { - dst_key_setnum(dkey->key, - DST_NUM_LIFETIME, - lifetime); - } + /* Update lifetime if changed. */ + keymgr_key_update_lifetime(dkey, kasp, now, + lifetime); if (active_key) { /* We already have an active key that From 8ec554e3def96dfda8839d7ef8a4b40b9383a2f6 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Mon, 24 Jun 2024 15:18:40 +0200 Subject: [PATCH 4/5] No longer update key lifetime if key is retired The key lifetime should no longer be adjusted if the key is being retired earlier, for example because a manual rollover was started. This would falsely be seen as a dnssec-policy lifetime reconfiguration, and would adjust the retire/removed time again. This also means we should update the status output, and the next rollover scheduled is now calculated using (retire-active) instead of key lifetime. (cherry picked from commit 129973ebb0deb20405da553f20b5e8cdfe9a0e80) --- bin/tests/system/kasp/tests.sh | 12 ------------ lib/dns/keymgr.c | 7 +++---- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/bin/tests/system/kasp/tests.sh b/bin/tests/system/kasp/tests.sh index e0ea8d951a..dbeabcf381 100644 --- a/bin/tests/system/kasp/tests.sh +++ b/bin/tests/system/kasp/tests.sh @@ -2153,9 +2153,6 @@ active=$(key_get KEY1 ACTIVE) set_addkeytime "KEY1" "RETIRED" "${active}" 15552000 retired=$(key_get KEY1 RETIRED) rndc_rollover "$SERVER" "$DIR" $(key_get KEY1 ID) "${retired}" "$ZONE" -# Rollover starts in six months, but lifetime is set to six months plus -# prepublication duration = 15552000 + 7500 = 15559500 seconds. -set_keylifetime "KEY1" "15559500" set_addkeytime "KEY1" "RETIRED" "${active}" 15559500 retired=$(key_get KEY1 RETIRED) # Retire interval of this policy is 26h (93600 seconds). @@ -2171,9 +2168,6 @@ dnssec_verify # Schedule KSK rollover now. set_policy "manual-rollover" "3" "3600" set_keystate "KEY1" "GOAL" "hidden" -# This key was activated one day ago, so lifetime is set to 1d plus -# prepublication duration (7500 seconds) = 93900 seconds. -set_keylifetime "KEY1" "93900" created=$(key_get KEY1 CREATED) set_keytime "KEY1" "RETIRED" "${created}" rndc_rollover "$SERVER" "$DIR" $(key_get KEY1 ID) "${created}" "$ZONE" @@ -2198,9 +2192,6 @@ dnssec_verify # Schedule ZSK rollover now. set_policy "manual-rollover" "4" "3600" set_keystate "KEY2" "GOAL" "hidden" -# This key was activated one day ago, so lifetime is set to 1d plus -# prepublication duration (7500 seconds) = 93900 seconds. -set_keylifetime "KEY2" "93900" created=$(key_get KEY2 CREATED) set_keytime "KEY2" "RETIRED" "${created}" rndc_rollover "$SERVER" "$DIR" $(key_get KEY2 ID) "${created}" "$ZONE" @@ -3655,9 +3646,6 @@ check_apex check_subdomain dnssec_verify # Roll over KEY2. -# Set expected key lifetime, which is DNSKEY TTL plus the zone propagation delay, -# plus the publish-safety: 7200s + 1h + 1d = 97200 seconds. -set_keylifetime "KEY2" "97200" created=$(key_get KEY2 CREATED) rndc_rollover "$SERVER" "$DIR" $(key_get KEY2 ID) "${created}" "$ZONE" # Update expected number of keys and key states. diff --git a/lib/dns/keymgr.c b/lib/dns/keymgr.c index 8d2f54eac8..4fbebbcb6d 100644 --- a/lib/dns/keymgr.c +++ b/lib/dns/keymgr.c @@ -2477,8 +2477,6 @@ rollover_status(dns_dnsseckey_t *dkey, dns_kasp_t *kasp, isc_stdtime_t now, } } else { isc_stdtime_t retire_time = 0; - uint32_t lifetime = 0; - (void)dst_key_getnum(key, DST_NUM_LIFETIME, &lifetime); ret = dst_key_gettime(key, retire, &retire_time); if (ret == ISC_R_SUCCESS) { if (now < retire_time) { @@ -2487,7 +2485,9 @@ rollover_status(dns_dnsseckey_t *dkey, dns_kasp_t *kasp, isc_stdtime_t now, " Next rollover " "scheduled on "); retire_time = keymgr_prepublication_time( - dkey, kasp, lifetime, now); + dkey, kasp, + (retire_time - active_time), + now); } else { isc_buffer_printf( buf, " Key will retire on "); @@ -2665,7 +2665,6 @@ dns_keymgr_rollover(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring, retire = when + prepub; dst_key_settime(key->key, DST_TIME_INACTIVE, retire); - dst_key_setnum(key->key, DST_NUM_LIFETIME, (retire - active)); /* Store key state and update hints. */ isc_dir_init(&dir); From d376d314af3ef6fc5e527836cea5c39b245daae5 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Tue, 30 Jul 2024 14:32:31 +0200 Subject: [PATCH 5/5] Fix kasp system test In 9.18, 'inline-signing yes;' must also be configured explicitly for zones using dnssec-policy without a configured 'allow-update' or 'update-policy'. --- bin/tests/system/kasp/ns6/named.conf.in | 4 ++++ bin/tests/system/kasp/ns6/named2.conf.in | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/bin/tests/system/kasp/ns6/named.conf.in b/bin/tests/system/kasp/ns6/named.conf.in index f30445ba27..019893c96e 100644 --- a/bin/tests/system/kasp/ns6/named.conf.in +++ b/bin/tests/system/kasp/ns6/named.conf.in @@ -99,23 +99,27 @@ zone example { zone longer-lifetime { type primary; file "longer-lifetime.db"; + inline-signing yes; dnssec-policy short-lifetime; }; zone shorter-lifetime { type primary; file "shorter-lifetime.db"; + inline-signing yes; dnssec-policy long-lifetime; }; zone limit-lifetime { type primary; file "limit-lifetime.db"; + inline-signing yes; dnssec-policy unlimited-lifetime; }; zone unlimit-lifetime { type primary; file "unlimit-lifetime.db"; + inline-signing yes; dnssec-policy short-lifetime; }; diff --git a/bin/tests/system/kasp/ns6/named2.conf.in b/bin/tests/system/kasp/ns6/named2.conf.in index fac2524e04..3762688bdd 100644 --- a/bin/tests/system/kasp/ns6/named2.conf.in +++ b/bin/tests/system/kasp/ns6/named2.conf.in @@ -187,23 +187,27 @@ zone example { zone longer-lifetime { type primary; file "longer-lifetime.db"; + inline-signing yes; dnssec-policy long-lifetime; }; zone shorter-lifetime { type primary; file "shorter-lifetime.db"; + inline-signing yes; dnssec-policy short-lifetime; }; zone limit-lifetime { type primary; file "limit-lifetime.db"; + inline-signing yes; dnssec-policy short-lifetime; }; zone unlimit-lifetime { type primary; file "unlimit-lifetime.db"; + inline-signing yes; dnssec-policy unlimited-lifetime; };