diff --git a/bin/tests/system/kasp/ns6/named.conf.in b/bin/tests/system/kasp/ns6/named.conf.in index 7b0cba8478..019893c96e 100644 --- a/bin/tests/system/kasp/ns6/named.conf.in +++ b/bin/tests/system/kasp/ns6/named.conf.in @@ -89,15 +89,37 @@ 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"; inline-signing yes; dnssec-policy modified; }; + +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 087fa7716f..3762688bdd 100644 --- a/bin/tests/system/kasp/ns6/named2.conf.in +++ b/bin/tests/system/kasp/ns6/named2.conf.in @@ -177,15 +177,37 @@ 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"; inline-signing yes; dnssec-policy modified; }; + +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; +}; 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..51c4d88488 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,29 @@ dnssec-policy "nsec3" { nsec3param iterations 0 optout no salt-length 0; }; +dnssec-policy "modified" { + keys { + csk lifetime unlimited algorithm rsasha256 2048; + }; +}; + +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..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. @@ -3709,6 +3697,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 +4051,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. # diff --git a/lib/dns/keymgr.c b/lib/dns/keymgr.c index 023dee9e43..4fbebbcb6d 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 @@ -2448,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) { @@ -2458,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 "); @@ -2636,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);