]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Update the retire interval after full sign
authorMatthijs Mekking <matthijs@isc.org>
Tue, 19 Aug 2025 13:16:39 +0000 (15:16 +0200)
committerMatthijs Mekking <matthijs@isc.org>
Fri, 26 Sep 2025 11:24:46 +0000 (13:24 +0200)
After a full sign we no longer have to need to take the sign delay into
account. Update the timing checks in keymgr_transition_time to determine
the start of the interval: Either the last change, or if SigPublish/
SigDelete is set. The latter case indicates a full sign was done and
so we no longer have to take the sign delay into account.

lib/dns/dst_api.c
lib/dns/dst_parse.c
lib/dns/include/dns/keymgr.h
lib/dns/include/dst/dst.h
lib/dns/keymgr.c
lib/dns/zone.c

index a794c9d5bb88dd41f86f93e79509750aa6450af7..88a488772c04ed6e3f106f931520880befe695c8 100644 (file)
@@ -117,7 +117,7 @@ static const char *timingtags[TIMING_NTAGS] = {
 
        "DNSKEYChange:", "ZRRSIGChange:", "KRRSIGChange:", "DSChange:",
 
-       "DSRemoved:"
+       "DSRemoved:",    "ZRRSIGPublish", "ZRRSIGRemoved"
 };
 
 #define KEYSTATES_NTAGS (DST_MAX_KEYSTATES + 1)
@@ -1991,6 +1991,8 @@ write_key_state(const dst_key_t *key, int type, const char *directory) {
                printtime(key, DST_TIME_DELETE, "Removed", fp);
                printtime(key, DST_TIME_DSPUBLISH, "DSPublish", fp);
                printtime(key, DST_TIME_DSDELETE, "DSRemoved", fp);
+               printtime(key, DST_TIME_SIGPUBLISH, "SigPublish", fp);
+               printtime(key, DST_TIME_SIGDELETE, "SigRemoved", fp);
                printtime(key, DST_TIME_SYNCPUBLISH, "PublishCDS", fp);
                printtime(key, DST_TIME_SYNCDELETE, "DeleteCDS", fp);
 
index 5e53a19e4943990dfaff3d39949cda608ddbe9da..479d23c603b65ec7f07126fa5693d9e7a3b621eb 100644 (file)
 
 #define TIMING_NTAGS (DST_MAX_TIMES + 1)
 static const char *timetags[TIMING_NTAGS] = {
-       "Created:",    "Publish:", "Activate:",  "Revoke:",
-       "Inactive:",   "Delete:",  "DSPublish:", "SyncPublish:",
-       "SyncDelete:", NULL,       NULL,         NULL,
-       NULL
+       "Created:", "Publish:",   "Activate:",    "Revoke:",     "Inactive:",
+       "Delete:",  "DSPublish:", "SyncPublish:", "SyncDelete:", NULL,
+       NULL,       NULL,         NULL,           NULL,          NULL
 };
 
 #define NUMERIC_NTAGS (DST_MAX_NUMERIC + 1)
index 8fcc6dbfbbb1cb92daadd57daf633ae48ae3547c..8e1508304acee2b9dd41446b527a98a675079aca 100644 (file)
@@ -24,7 +24,8 @@
 #define DNS_KEYMGRATTR_NONE     0x00 /*%< No ordering. */
 #define DNS_KEYMGRATTR_S2I      0x01 /*%< Secure to insecure. */
 #define DNS_KEYMGRATTR_NOROLL   0x02 /*%< No rollover allowed. */
-#define DNS_KEYMGRATTR_FORCESTEP 0x04 /*%< Force next step in manual-mode */
+#define DNS_KEYMGRATTR_FORCESTEP 0x04 /*%< Force next step in manual-mode. */
+#define DNS_KEYMGRATTR_FULLSIGN         0x08 /*%< Full sign was issued. */
 
 void
 dns_keymgr_settime_syncpublish(dst_key_t *key, dns_kasp_t *kasp, bool first);
index f3eaa538346a4bf83b611c9ab35927e3f8519b32..ecd952e845c851a34f4d9d07ea1d2b3474809b2b 100644 (file)
@@ -152,7 +152,9 @@ typedef enum dst_algorithm {
 #define DST_TIME_KRRSIG             11
 #define DST_TIME_DS         12
 #define DST_TIME_DSDELETE    13
-#define DST_MAX_TIMES       13
+#define DST_TIME_SIGPUBLISH  14
+#define DST_TIME_SIGDELETE   15
+#define DST_MAX_TIMES       15
 
 /* Numeric metadata definitions */
 #define DST_NUM_PREDECESSOR 0
index bb1f831673a260dc1374f36a63e04c56144bf1c3..152c6016bb99e6d720c8df241a589d200a5812d8 100644 (file)
@@ -1296,9 +1296,9 @@ keymgr_transition_time(dns_dnsseckey_t *key, int type,
                       dst_key_state_t next_state, dns_kasp_t *kasp,
                       isc_stdtime_t now, isc_stdtime_t *when) {
        isc_result_t ret;
-       isc_stdtime_t lastchange, dstime, nexttime = now;
+       isc_stdtime_t lastchange, dstime, sigtime, nexttime = now;
        dns_ttl_t ttlsig = dns_kasp_zonemaxttl(kasp, true);
-       uint32_t dsstate;
+       uint32_t dsstate, sigstate, signdelay = 0;
 
        /*
         * No need to wait if we move things into an uncertain state.
@@ -1352,6 +1352,17 @@ keymgr_transition_time(dns_dnsseckey_t *key, int type,
                switch (next_state) {
                case OMNIPRESENT:
                case HIDDEN:
+                       /* Was there a full sign? */
+                       sigstate = (next_state == HIDDEN) ? DST_TIME_SIGDELETE
+                                                         : DST_TIME_SIGPUBLISH;
+                       ret = dst_key_gettime(key->key, sigstate, &sigtime);
+                       if (ret == ISC_R_SUCCESS && sigtime <= now) {
+                               signdelay = 0;
+                       } else {
+                               sigtime = lastchange;
+                               signdelay = dns_kasp_signdelay(kasp);
+                       }
+
                        /*
                         * RFC 7583: The retire interval (Iret) is the amount
                         * of time that must elapse after a DNSKEY or
@@ -1369,7 +1380,7 @@ keymgr_transition_time(dns_dnsseckey_t *key, int type,
                         *
                         *     Dsgn + zone-propagation-delay + max-zone-ttl.
                         */
-                       nexttime = lastchange + ttlsig +
+                       nexttime = sigtime + ttlsig +
                                   dns_kasp_zonepropagationdelay(kasp);
                        /*
                         * Only add the sign delay Dsgn and retire-safety if
@@ -1383,7 +1394,7 @@ keymgr_transition_time(dns_dnsseckey_t *key, int type,
                                                     DST_NUM_SUCCESSOR, &tag);
                        }
                        if (ret == ISC_R_SUCCESS) {
-                               nexttime += dns_kasp_signdelay(kasp) +
+                               nexttime += signdelay +
                                            dns_kasp_retiresafety(kasp);
                        }
                        break;
@@ -2106,6 +2117,32 @@ dst_key_doublematch(dns_dnsseckey_t *key, dns_kasp_t *kasp) {
        return matches > 1;
 }
 
+static void
+keymgr_zrrsig(dns_dnsseckeylist_t *keyring, isc_stdtime_t now) {
+       ISC_LIST_FOREACH(*keyring, dkey, link) {
+               isc_result_t ret;
+               bool zsk = false;
+
+               ret = dst_key_getbool(dkey->key, DST_BOOL_ZSK, &zsk);
+               if (ret == ISC_R_SUCCESS && zsk) {
+                       dst_key_state_t state;
+                       isc_result_t result = dst_key_getstate(
+                               dkey->key, DST_KEY_ZRRSIG, &state);
+                       if (result == ISC_R_SUCCESS) {
+                               if (state == RUMOURED) {
+                                       dst_key_settime(dkey->key,
+                                                       DST_TIME_SIGPUBLISH,
+                                                       now);
+                               } else if (state == UNRETENTIVE) {
+                                       dst_key_settime(dkey->key,
+                                                       DST_TIME_SIGDELETE,
+                                                       now);
+                               }
+                       }
+               }
+       }
+}
+
 /*
  * Examine 'keys' and match 'kasp' policy.
  *
@@ -2308,6 +2345,11 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
                opts |= DNS_KEYMGRATTR_S2I;
        }
 
+       /* In case of a full sign, store ZRRSIGPublish/ZRRSIGDelete. */
+       if ((opts & DNS_KEYMGRATTR_FULLSIGN) != 0) {
+               keymgr_zrrsig(keyring, now);
+       }
+
        /* Read to update key states. */
        isc_result_t retval = keymgr_update(keyring, kasp, now, nexttime, opts);
 
index fa151311063dac42860b60bc0ebfeb5521ad5c9d..901336780a19a3ce8938bdeb941a0ea472786ae8 100644 (file)
@@ -22460,6 +22460,9 @@ zone_rekey(dns_zone_t *zone) {
         * fully signed now.
         */
        fullsign = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FULLSIGN);
+       if (fullsign) {
+               options |= DNS_KEYMGRATTR_FULLSIGN;
+       }
 
        /*
         * True when called from "rndc dnssec -step". Indicates the zone