Commit df8276ae authored by Matthijs Mekking's avatar Matthijs Mekking 🏡

Add manual key rollover logic

Add to the keymgr a function that will schedule a rollover. This
basically means setting the time when the key needs to retire,
and updating the key lifetime, then update the state file. The next
time that named runs the keymgr the new lifetime will be taken into
account.
parent b7c9a80d
......@@ -77,6 +77,37 @@ dns_keymgr_checkds_id(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
*
*/
isc_result_t
dns_keymgr_rollover(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
const char *directory, isc_stdtime_t now,
isc_stdtime_t when, dns_keytag_t id,
unsigned int algorithm);
/*%<
* Rollover key with given 'id'. If the 'algorithm' is non-zero, it must
* match the key's algorithm. The changes are stored in the key state file.
*
* A rollover means adjusting the key metadata so that keymgr will start the
* actual rollover on the next run. Update the 'inactive' time and adjust
* key lifetime to match the 'when' to rollover time.
*
* The 'when' time may be in the past. In that case keymgr will roll the
* key as soon as possible.
*
* The 'when' time may be in the future. This may extend the lifetime,
* overriding the default lifetime from the policy.
*
* Requires:
*\li 'kasp' is not NULL.
*\li 'keyring' is not NULL.
*
* Returns:
*\li #ISC_R_SUCCESS (No error).
*\li #ISC_R_FAILURE (More than one matching keys found).
*\li #ISC_R_NOTFOUND (No matching keys found).
*\li #ISC_R_UNEXPECTED (Key is not active).
*
*/
void
dns_keymgr_status(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
isc_stdtime_t now, char *out, size_t out_len);
......
......@@ -2143,3 +2143,84 @@ dns_keymgr_status(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
"key rrsig: ", DST_KEY_KRRSIG);
}
}
isc_result_t
dns_keymgr_rollover(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
const char *directory, isc_stdtime_t now,
isc_stdtime_t when, dns_keytag_t id,
unsigned int algorithm) {
int options = (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC | DST_TYPE_STATE);
isc_dir_t dir;
isc_result_t result;
dns_dnsseckey_t *key = NULL;
isc_stdtime_t active, retire, prepub;
REQUIRE(DNS_KASP_VALID(kasp));
REQUIRE(keyring != NULL);
for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); dkey != NULL;
dkey = ISC_LIST_NEXT(dkey, link))
{
if (dst_key_id(dkey->key) != id) {
continue;
}
if (algorithm > 0 && dst_key_alg(dkey->key) != algorithm) {
continue;
}
if (key != NULL) {
/*
* Only rollover for one key at a time.
*/
return (ISC_R_FAILURE);
}
key = dkey;
}
if (key == NULL) {
return (ISC_R_NOTFOUND);
}
result = dst_key_gettime(key->key, DST_TIME_ACTIVATE, &active);
if (result != ISC_R_SUCCESS) {
return (ISC_R_UNEXPECTED);
}
result = dst_key_gettime(key->key, DST_TIME_INACTIVE, &retire);
if (result != ISC_R_SUCCESS) {
/**
* Default to as if this key was not scheduled to
* become retired, as if it had unlimited lifetime.
*/
retire = 0;
}
/**
* Usually when is set to now, which is before the scheduled
* prepublication time, meaning we reduce the lifetime of the
* key. But in some cases, the lifetime can also be extended.
* We accept it, but we can return an error here if that
* turns out to be unintuitive behavior.
*/
prepub = dst_key_getttl(key->key) + dns_kasp_publishsafety(kasp) +
dns_kasp_zonepropagationdelay(kasp);
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);
if (directory == NULL) {
directory = ".";
}
result = isc_dir_open(&dir, directory);
if (result != ISC_R_SUCCESS) {
return result;
}
dns_dnssec_get_hints(key, now);
result = dst_key_tofile(key->key, options, directory);
isc_dir_close(&dir);
return (result);
}
......@@ -470,6 +470,7 @@ dns_keydata_todnskey
dns_keyflags_fromtext
dns_keymgr_checkds
dns_keymgr_checkds_id
dns_keymgr_rollover
dns_keymgr_run
dns_keymgr_status
dns_keynode_dsset
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment