Commit 6cea1fb0 authored by Libor Peltan's avatar Libor Peltan Committed by Daniel Salzman

dnssec: new timers for algorithm rollover; ksk rollover modified

new timers system:

created - ( pre_active ) - published - (ready) - active -
(retire_active) - [ retire | post_active ] - remove

ksk rollover:
 - now uses new retire_active for things to settle up after submission
 - CSK/CDNSKEY are always generated for the best active key (except for
imported keys)
parent d4d5c034
......@@ -215,7 +215,7 @@ static int serialize_key_params(const key_params_t *params, const knot_dname_t *
assert(val != NULL);
*key = make_key(KASPDBKEY_PARAMS, dname, params->id);
val->len = sizeof(uint16_t) + 2 * sizeof(uint8_t) + 8 * sizeof(uint64_t) +
val->len = sizeof(uint16_t) + 2 * sizeof(uint8_t) + 11 * sizeof(uint64_t) +
params->public_key.size;
val->data = malloc(val->len);
if (val->data == NULL) {
......@@ -230,12 +230,15 @@ static int serialize_key_params(const key_params_t *params, const knot_dname_t *
wire_ctx_write_u64(&wire, 0); // length of Unused-future block at the end
wire_ctx_write_u16(&wire, params->keytag);
wire_ctx_write_u8(&wire, params->algorithm);
wire_ctx_write_u8(&wire, (uint8_t)(params->is_ksk ? 0x01 : 0x00));
wire_ctx_write_u8(&wire, (uint8_t)(params->is_ksk ? 0x03 : 0x02));
wire_ctx_write_u64(&wire, (uint64_t)params->timing.created);
wire_ctx_write_u64(&wire, (uint64_t)params->timing.pre_active);
wire_ctx_write_u64(&wire, (uint64_t)params->timing.publish);
wire_ctx_write_u64(&wire, (uint64_t)params->timing.ready);
wire_ctx_write_u64(&wire, (uint64_t)params->timing.active);
wire_ctx_write_u64(&wire, (uint64_t)params->timing.retire_active);
wire_ctx_write_u64(&wire, (uint64_t)params->timing.retire);
wire_ctx_write_u64(&wire, (uint64_t)params->timing.post_active);
wire_ctx_write_u64(&wire, (uint64_t)params->timing.remove);
wire_ctx_write(&wire, params->public_key.data, params->public_key.size);
......@@ -265,13 +268,30 @@ static int deserialize_key_params(key_params_t *params, const knot_db_val_t *key
uint64_t unused_future_length = wire_ctx_read_u64(&wire);
params->keytag = wire_ctx_read_u16(&wire);
params->algorithm = wire_ctx_read_u8(&wire);
params->is_ksk = (wire_ctx_read_u8(&wire) != (uint8_t)0x00);
params->timing.created = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.publish = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.ready = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.active = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.retire = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.remove = (knot_time_t)wire_ctx_read_u64(&wire);
uint8_t isksk_plus_flags = wire_ctx_read_u8(&wire);
params->is_ksk = ((isksk_plus_flags & (uint8_t)0x01) != (uint8_t)0x00);
if ((isksk_plus_flags & (uint8_t)0x02) != (uint8_t)0x00) {
params->timing.created = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.pre_active = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.publish = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.ready = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.active = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.retire_active = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.retire = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.post_active = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.remove = (knot_time_t)wire_ctx_read_u64(&wire);
} else {
// import of old kasp db format missing some timers
params->timing.created = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.pre_active = 0;
params->timing.publish = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.ready = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.active = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.retire_active = 0;
params->timing.retire = (knot_time_t)wire_ctx_read_u64(&wire);
params->timing.post_active = 0;
params->timing.remove = (knot_time_t)wire_ctx_read_u64(&wire);
}
if (wire.error != KNOT_EOK) {
return KNOT_ERROR;
}
......
......@@ -28,48 +28,50 @@ key_state_t get_key_state(const knot_kasp_key_t *key, knot_time_t moment)
return DNSSEC_KEY_STATE_INVALID;
}
/*
* The meaning of unset timing parameter is different for key
* introduction and withdrawal. This is expected by the server.
* The keys can be used without timing metadata.
*
* However, it creates a lot of complications. It would be easier
* to find a different approach (persistent key states, different
* meaning of unset parameter when policy is used, etc.).
*/
const knot_kasp_key_timing_t *t = &key->timing;
bool removed = (knot_time_cmp(t->remove, moment) <= 0);
bool post_active = (knot_time_cmp(t->post_active, moment) <= 0);
bool retired = (knot_time_cmp(t->retire, moment) <= 0);
bool published = !removed && (knot_time_cmp(t->publish, moment) <= 0);
bool ready = !retired && (knot_time_cmp(t->ready, moment) <= 0);
bool activated = !retired && (knot_time_cmp(t->active, moment) <= 0);
/*
* Evaluate special transition states as invalid. E.g., when signatures
* are pre-published during algorithm rotation.
*/
if (retired && removed) {
bool retire_active = (knot_time_cmp(t->retire_active, moment) <= 0);
bool active = (knot_time_cmp(t->active, moment) <= 0);
bool ready = (knot_time_cmp(t->ready, moment) <= 0);
bool published = (knot_time_cmp(t->publish, moment) <= 0);
bool pre_active = (knot_time_cmp(t->pre_active, moment) <= 0);
bool created = (knot_time_cmp(t->created, moment) <= 0);
if (removed) {
return DNSSEC_KEY_STATE_REMOVED;
}
if (retired && !removed) {
if (post_active) {
if (retired) {
return DNSSEC_KEY_STATE_INVALID;
} else {
return DNSSEC_KEY_STATE_POST_ACTIVE;
}
}
if (retired) {
return DNSSEC_KEY_STATE_RETIRED;
}
if (published && activated) {
if (retire_active) {
return DNSSEC_KEY_STATE_RETIRE_ACTIVE;
}
if (active) {
return DNSSEC_KEY_STATE_ACTIVE;
}
if (published && !ready) {
if (ready) {
return DNSSEC_KEY_STATE_READY;
}
if (published) {
return DNSSEC_KEY_STATE_PUBLISHED;
}
if (ready && !activated) {
return DNSSEC_KEY_STATE_READY;
if (pre_active) {
return DNSSEC_KEY_STATE_PRE_ACTIVE;
}
if (created) {
// don't care
}
return DNSSEC_KEY_STATE_INVALID;
......
......@@ -23,10 +23,13 @@
enum key_state {
DNSSEC_KEY_STATE_INVALID = 0,
DNSSEC_KEY_STATE_PRE_ACTIVE,
DNSSEC_KEY_STATE_PUBLISHED,
DNSSEC_KEY_STATE_READY,
DNSSEC_KEY_STATE_ACTIVE,
DNSSEC_KEY_STATE_RETIRE_ACTIVE,
DNSSEC_KEY_STATE_RETIRED,
DNSSEC_KEY_STATE_POST_ACTIVE,
DNSSEC_KEY_STATE_REMOVED,
};
......
......@@ -27,10 +27,13 @@
*/
typedef struct {
knot_time_t created; /*!< Time the key was generated/imported. */
knot_time_t pre_active; /*!< Signing start with new algorithm. */
knot_time_t publish; /*!< Time of DNSKEY record publication. */
knot_time_t ready; /*!< Start of RRSIG generation, waiting for parent zone. */
knot_time_t active; /*!< RRSIG records generating, other keys can be retired */
knot_time_t retire_active; /*!< Still active, but obsoleted. */
knot_time_t retire; /*!< End of RRSIG records generating. */
knot_time_t post_active; /*!< Still signing with old algorithm, not published. */
knot_time_t remove; /*!< Time of DNSKEY record removal. */
} knot_kasp_key_timing_t;
......
......@@ -73,7 +73,7 @@ static int generate_key(kdnssec_ctx_t *ctx, bool ksk, knot_time_t when_active)
key->timing.remove = 0;
key->timing.retire = 0;
key->timing.active = (ksk ? 0 : when_active);
key->timing.ready = when_active;
key->timing.ready = (ksk ? when_active : 0);
key->timing.publish = ctx->now;
return KNOT_EOK;
......@@ -104,7 +104,7 @@ static int share_or_generate_key(kdnssec_ctx_t *ctx, bool ksk, knot_time_t when_
key->timing.remove = 0;
key->timing.retire = 0;
key->timing.active = (ksk ? 0 : when_active);
key->timing.ready = when_active;
key->timing.ready = (ksk ? when_active : 0);
key->timing.publish = ctx->now;
ret = kdnssec_ctx_commit(ctx);
......@@ -156,6 +156,7 @@ typedef enum {
GENERATE = 1,
SUBMIT,
REPLACE,
RETIRE,
REMOVE,
} roll_action_type;
......@@ -214,6 +215,14 @@ static knot_time_t ksk_sbm_max_time(knot_time_t ready_time, const kdnssec_ctx_t
return knot_time_add(ready_time, ctx->policy->ksk_sbm_timeout);
}
static knot_time_t ksk_retire_time(knot_time_t retire_active_time, const kdnssec_ctx_t *ctx)
{
if (retire_active_time <= 0) {
return 0;
}
return knot_time_add(retire_active_time, ctx->policy->propagation_delay + ctx->policy->dnskey_ttl);
}
static knot_time_t ksk_remove_time(knot_time_t retire_time, const kdnssec_ctx_t *ctx)
{
if (retire_time <= 0) {
......@@ -267,6 +276,10 @@ static roll_action next_action(kdnssec_ctx_t *ctx)
restype = GENERATE;
}
break;
case DNSSEC_KEY_STATE_RETIRE_ACTIVE:
keytime = ksk_retire_time(key->timing.retire_active, ctx);
restype = RETIRE;
break;
case DNSSEC_KEY_STATE_RETIRED:
case DNSSEC_KEY_STATE_REMOVED:
// ad REMOVED state: normally this wouldn't happen (key in removed state is instantly deleted)
......@@ -322,18 +335,16 @@ static int exec_new_signatures(kdnssec_ctx_t *ctx, knot_kasp_key_t *newkey)
{
uint16_t kskflag = dnssec_key_get_flags(newkey->key);
// A delay to avoid left-behind of behind-a-loadbalancer parent NSs
// for now we use (incorrectly) ksk_sbm_check_interval, to avoid too many conf options
knot_timediff_t delay = 0;
if (kskflag == DNSKEY_FLAGS_KSK && ctx->policy->ksk_sbm_check_interval != 0) {
delay = ctx->policy->ksk_sbm_check_interval;
}
for (size_t i = 0; i < ctx->zone->num_keys; i++) {
knot_kasp_key_t *key = &ctx->zone->keys[i];
if (dnssec_key_get_flags(key->key) == kskflag &&
uint16_t keyflags = dnssec_key_get_flags(key->key);
if (keyflags == kskflag &&
get_key_state(key, ctx->now) == DNSSEC_KEY_STATE_ACTIVE) {
key->timing.retire = knot_time_min(knot_time_add(ctx->now, delay), key->timing.retire);
if (keyflags == DNSKEY_FLAGS_KSK) {
key->timing.retire_active = knot_time_min(ctx->now, key->timing.retire_active);
} else {
key->timing.retire = knot_time_min(ctx->now, key->timing.retire);
}
}
}
......@@ -341,10 +352,16 @@ static int exec_new_signatures(kdnssec_ctx_t *ctx, knot_kasp_key_t *newkey)
assert(get_key_state(newkey, ctx->now) == DNSSEC_KEY_STATE_READY);
} else {
assert(get_key_state(newkey, ctx->now) == DNSSEC_KEY_STATE_PUBLISHED);
assert(delay == 0);
newkey->timing.ready = knot_time_min(knot_time_add(ctx->now, delay), newkey->timing.ready);
}
newkey->timing.active = knot_time_min(knot_time_add(ctx->now, delay), newkey->timing.active);
newkey->timing.active = knot_time_min(ctx->now, newkey->timing.active);
return KNOT_EOK;
}
static int exec_ksk_retire(kdnssec_ctx_t *ctx, knot_kasp_key_t *key)
{
assert(get_key_state(key, ctx->now) == DNSSEC_KEY_STATE_RETIRE_ACTIVE);
key->timing.retire = ctx->now;
return KNOT_EOK;
}
......@@ -412,6 +429,9 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *resched
case REPLACE:
ret = exec_new_signatures(ctx, next.key);
break;
case RETIRE:
ret = exec_ksk_retire(ctx, next.key);
break;
case REMOVE:
ret = exec_remove_old_key(ctx, next.key);
break;
......@@ -458,7 +478,8 @@ bool zone_has_key_sbm(const kdnssec_ctx_t *ctx)
for (size_t i = 0; i < ctx->zone->num_keys; i++) {
knot_kasp_key_t *key = &ctx->zone->keys[i];
if (dnssec_key_get_flags(key->key) == DNSKEY_FLAGS_KSK &&
get_key_state(key, ctx->now) == DNSSEC_KEY_STATE_READY) {
(get_key_state(key, ctx->now) == DNSSEC_KEY_STATE_READY ||
get_key_state(key, ctx->now) == DNSSEC_KEY_STATE_ACTIVE)) {
return true;
}
}
......
......@@ -199,15 +199,18 @@ static int set_key(knot_kasp_key_t *kasp_key, knot_time_t now, zone_key_t *zone_
// next event computation
knot_time_t next = 0;
knot_time_t timestamps[5] = {
timing->active,
timing->publish,
timing->remove,
timing->retire,
knot_time_t timestamps[] = {
timing->pre_active,
timing->publish,
timing->ready,
timing->active,
timing->retire_active,
timing->retire,
timing->post_active,
timing->remove,
};
for (int i = 0; i < 5; i++) {
for (int i = 0; i < sizeof(timestamps) / sizeof(knot_time_t); i++) {
knot_time_t ts = timestamps[i];
if (knot_time_cmp(now, ts) < 0 && knot_time_cmp(ts, next) < 0) {
next = ts;
......@@ -222,12 +225,22 @@ static int set_key(knot_kasp_key_t *kasp_key, knot_time_t now, zone_key_t *zone_
zone_key->is_ksk = flags & KNOT_RDATA_DNSKEY_FLAG_KSK;
zone_key->is_zsk = !zone_key->is_ksk;
zone_key->is_active = (knot_time_cmp(timing->active, now) <= 0 &&
knot_time_cmp(timing->retire, now) > 0);
zone_key->is_public = (knot_time_cmp(timing->publish, now) <= 0 &&
knot_time_cmp(timing->remove, now) > 0);
zone_key->is_ready = (knot_time_cmp(timing->ready, now) <= 0 &&
knot_time_cmp(timing->retire, now) > 0);
knot_time_cmp(timing->post_active, now) > 0 &&
knot_time_cmp(timing->remove, now) > 0);
zone_key->is_active = (((zone_key->is_zsk && knot_time_cmp(timing->pre_active, now) <= 0) ||
(knot_time_cmp(timing->pre_active, now) <= 0 && knot_time_cmp(timing->publish, now) <= 0) ||
knot_time_cmp(timing->ready, now) <= 0 ||
knot_time_cmp(timing->active, now) <= 0) &&
knot_time_cmp(timing->retire, now) > 0 &&
(zone_key->is_zsk || knot_time_cmp(timing->post_active, now) > 0) &&
knot_time_cmp(timing->remove, now) > 0);
zone_key->cds_priority = (knot_time_cmp(timing->ready, now) <= 0 ? (
(knot_time_cmp(timing->active, now) <= 0) ? (
(knot_time_cmp(timing->retire_active, now) <= 0 ||
knot_time_cmp(timing->retire, now) <= 0) ? 0 : 1) : 2) : 0);
return KNOT_EOK;
}
......@@ -294,7 +307,7 @@ static int prepare_and_check_keys(const knot_dname_t *zone_name, bool nsec3_enab
dnssec_key_get_keytag(key->key));
key->is_public = false;
key->is_active = false;
key->is_ready = false;
key->cds_priority = 0;
continue;
}
......@@ -327,11 +340,10 @@ static int prepare_and_check_keys(const knot_dname_t *zone_name, bool nsec3_enab
}
if (key->is_public) { u->is_public = true; }
if (key->is_ksk && (key->is_ready || key->is_active)) {
if (key->is_ksk && key->is_active) {
u->is_ksk_active = true;
}
if (key->is_zsk && (key->is_active ||
(key->is_ksk && key->is_ready))) {
if (key->is_zsk && key->is_active) {
u->is_zsk_active = true;
}
}
......@@ -366,7 +378,7 @@ static int load_private_keys(dnssec_keystore_t *keystore, zone_keyset_t *keyset)
assert(keyset);
for (size_t i = 0; i < keyset->count; i++) {
if (!keyset->keys[i].is_active && !keyset->keys[i].is_ready) {
if (!keyset->keys[i].is_active) {
continue;
}
......@@ -388,15 +400,15 @@ static void log_key_info(const zone_key_t *key, const knot_dname_t *zone_name)
assert(key);
assert(zone_name);
log_zone_info(zone_name, "DNSSEC, loaded key, tag %5d, "
"algorithm %d, KSK %s, ZSK %s, public %s, ready %s, active %s",
dnssec_key_get_keytag(key->key),
dnssec_key_get_algorithm(key->key),
key->is_ksk ? "yes" : "no",
key->is_zsk ? "yes" : "no",
key->is_public ? "yes" : "no",
key->is_ready ? "yes" : "no",
key->is_active ? "yes" : "no");
log_zone_info(zone_name, "DNSSEC, loaded key, tag %5d, algorithm %d, "
"KSK %s, ZSK %s, public %s, ready %s, active %s",
dnssec_key_get_keytag(key->key),
dnssec_key_get_algorithm(key->key),
key->is_ksk ? "yes" : "no",
key->is_zsk ? "yes" : "no",
key->is_public ? "yes" : "no",
key->cds_priority > 1 ? "yes" : "no",
key->is_active ? "yes" : "no");
}
/*!
......
......@@ -52,7 +52,7 @@ struct zone_key {
bool is_zsk;
bool is_active;
bool is_public;
bool is_ready;
int cds_priority;
};
typedef struct zone_key zone_key_t;
......
......@@ -153,7 +153,7 @@ static bool use_key(const zone_key_t *key, const knot_rrset_t *covered)
assert(key);
assert(covered);
if (!key->is_active && !key->is_ready) {
if (!key->is_active) {
return false;
}
......@@ -282,7 +282,7 @@ static int remove_expired_rrsigs(const knot_rrset_t *covered,
int endloop = 0; // 1 - continue; 2 - break
dynarray_foreach(keyptr, zone_key_t *, key, keys) {
if (!(*key)->is_active && !(*key)->is_ready) {
if (!(*key)->is_active) {
continue;
}
result = knot_check_signature(covered, &synth_rrsig, i,
......@@ -710,7 +710,7 @@ static bool is_from_keyset(zone_keyset_t *keyset,
struct keyptr_dynarray keys = get_zone_keys(keyset, tag);
for (size_t i = 0; i < keys.size; i++) {
bool usekey = (is_cds_cdnskey ? (keys.arr(&keys)[i]->is_ready && !keys.arr(&keys)[i]->is_active) : keys.arr(&keys)[i]->is_public);
bool usekey = (is_cds_cdnskey ? (keys.arr(&keys)[i]->cds_priority > 1) : keys.arr(&keys)[i]->is_public);
if (usekey && match_fce(keys.arr(&keys)[i], &rdata)) {
found = true;
if (matching_key != NULL) {
......@@ -1065,6 +1065,8 @@ int knot_zone_sign_update_dnskeys(zone_update_t *update,
if (add_dnskeys == NULL || add_cdnskeys == NULL || add_cdss == NULL) {
ret = KNOT_ENOMEM;
}
zone_key_t *ksk_for_cds = NULL;
int kfc_prio = 0;
for (int i = 0; i < zone_keys->count && ret == KNOT_EOK; i++) {
zone_key_t *key = &zone_keys->keys[i];
if (!key->is_public) {
......@@ -1072,19 +1074,48 @@ int knot_zone_sign_update_dnskeys(zone_update_t *update,
}
ret = rrset_add_zone_key(add_dnskeys, key, dnskey_ttl);
if (key->is_ready && !key->is_active && ret == KNOT_EOK) {
ret = rrset_add_zone_key(add_cdnskeys, key, 0);
if (ret == KNOT_EOK) {
ret = rrset_add_zone_ds(add_cdss, key, 0);
}
if (key->is_ksk && ret == KNOT_EOK && key->cds_priority > kfc_prio) {
ksk_for_cds = key;
kfc_prio = key->cds_priority;
}
}
if (ksk_for_cds != NULL) {
ret = rrset_add_zone_key(add_cdnskeys, ksk_for_cds, 0);
if (ret == KNOT_EOK) {
ret = rrset_add_zone_ds(add_cdss, ksk_for_cds, 0);
}
}
if (ret != KNOT_EOK) {
goto cleanup;
}
if (!knot_rrset_equal(&cdnskeys, add_cdnskeys, KNOT_RRSET_COMPARE_WHOLE)) {
if (!knot_rrset_empty(&cdnskeys)) {
ret = changeset_add_removal(&ch, &cdnskeys, 0);
}
if (ret == KNOT_EOK && !knot_rrset_empty(add_cdnskeys)) {
ret = changeset_add_addition(&ch, add_cdnskeys, 0);
}
}
if (ret != KNOT_EOK) {
goto cleanup;
}
knot_rrset_t *add_rrsets[3] = { add_dnskeys, add_cdnskeys, add_cdss };
for (int i = 0; i < 3 && ret == KNOT_EOK; i++) {
if (!knot_rrset_empty(add_rrsets[i])) {
ret = changeset_add_addition(&ch, add_rrsets[i], 0);
if (!knot_rrset_equal(&cdss, add_cdss, KNOT_RRSET_COMPARE_WHOLE)) {
if (!knot_rrset_empty(&cdss)) {
ret = changeset_add_removal(&ch, &cdss, 0);
}
if (ret == KNOT_EOK && !knot_rrset_empty(add_cdss)) {
ret = changeset_add_addition(&ch, add_cdss, 0);
}
}
if (ret != KNOT_EOK) {
goto cleanup;
}
if (!knot_rrset_empty(add_dnskeys)) {
ret = changeset_add_addition(&ch, add_dnskeys, 0);
}
if (ret == KNOT_EOK) {
......
......@@ -208,7 +208,7 @@ int event_parent_ds_q(conf_t *conf, zone_t *zone)
for (size_t i = 0; i < keyset.count; i++) {
zone_key_t *key = &keyset.keys[i];
if (dnssec_key_get_flags(key->key) == DNSKEY_FLAGS_KSK &&
key->is_ready && !key->is_active) {
key->cds_priority > 1) {
if (parents_have_ds(zone, conf, key)) {
ret = knot_dnssec_ksk_sbm_confirm(&ctx);
} else {
......
......@@ -345,7 +345,7 @@ void bind_privkey_to_timing(bind_privkey_t *params, knot_kasp_key_timing_t *timi
// unsupported: time_created, time_revoke
timing->publish = (knot_time_t)params->time_publish;
timing->ready = (knot_time_t)params->time_activate;
timing->ready = 0;
timing->active = (knot_time_t)params->time_activate;
timing->retire = (knot_time_t)params->time_inactive;
timing->remove = (knot_time_t)params->time_delete;
......
......@@ -110,6 +110,27 @@ static bool genkeyargs(int argc, char *argv[], bool just_timing,
timing->remove = stamp;
break;
}
} else if (strncasecmp(argv[i], "pre_active=", 11) == 0 ||
strncasecmp(argv[i], "retire_active=", 14) == 0 ||
strncasecmp(argv[i], "post_active=", 12) == 0) {
knot_time_t stamp;
int ret = knot_time_parse("YMDhms|'now'+-#u|'t'+-#u|+-#u|'t'+-#|+-#|#",
strchr(argv[i], '=') + 1, &stamp);
if (ret < 0) {
printf("Invalid timestamp: %s\n", argv[i]);
return false;
}
switch (argv[i][1]) {
case 'r':
timing->pre_active = stamp;
break;
case 'e':
timing->retire_active = stamp;
break;
case 'o':
timing->post_active = stamp;
break;
}
} else {
printf("Invalid parameter: %s\n", argv[i]);
return false;
......@@ -121,7 +142,7 @@ static bool genkeyargs(int argc, char *argv[], bool just_timing,
// modifies ctx->policy options, so don't do anything afterwards !
int keymgr_generate_key(kdnssec_ctx_t *ctx, int argc, char *argv[]) {
knot_time_t now = knot_time(), infty = 0;
knot_kasp_key_timing_t gen_timing = { now, now, now, now, infty, infty };
knot_kasp_key_timing_t gen_timing = { now, infty, now, infty, now, infty, infty, infty, infty };
bool isksk = false;
uint16_t keysize = 0;
if (!genkeyargs(argc, argv, false, &isksk, &ctx->policy->algorithm,
......@@ -582,12 +603,15 @@ int keymgr_list_keys(kdnssec_ctx_t *ctx, knot_time_print_t format)
printf("%s ksk=%s tag=%05d algorithm=%d ", key->id,
((dnssec_key_get_flags(key->key) == dnskey_flags(true)) ? "yes" : "no "),
dnssec_key_get_keytag(key->key), (int)dnssec_key_get_algorithm(key->key));
print_timer("created", key->timing.created, format, ' ');
print_timer("publish", key->timing.publish, format, ' ');
print_timer("ready", key->timing.ready, format, ' ');
print_timer("active", key->timing.active, format, ' ');
print_timer("retire", key->timing.retire, format, ' ');
print_timer("remove", key->timing.remove, format, '\n');
print_timer("created", key->timing.created, format, ' ');
print_timer("pre-active", key->timing.pre_active, format, ' ');
print_timer("publish", key->timing.publish, format, ' ');
print_timer("ready", key->timing.ready, format, ' ');
print_timer("active", key->timing.active, format, ' ');
print_timer("retire-active", key->timing.retire_active, format, ' ');
print_timer("retire", key->timing.retire, format, ' ');
print_timer("post-active", key->timing.post_active, format, ' ');
print_timer("remove", key->timing.remove, format, '\n');
}
return KNOT_EOK;
}
......
......@@ -79,9 +79,11 @@ ZSK2 = child.key_gen(ZONE, ksk="false", created="-2", publish="-2", ready="+14y"
t.start()
child.zone_wait(child_zone)
check_zone5(child, 4, 1, 0, "only first KSK")
check_zone5(child, 4, 1, 1, "only first KSK")
while child.dig(ZONE, "CDS").count("CDS") < 1:
CDS1 = str(child.dig(ZONE, "CDS").resp.answer[0].to_rdataset())
t.sleep(3)
while CDS1 == str(child.dig(ZONE, "CDS").resp.answer[0].to_rdataset()):
t.sleep(1)
check_zone5(child, 4, 2, 1, "new KSK ready")
......@@ -92,8 +94,8 @@ up = parent.update(parent_zone)
up.add(ZONE, 3600, "DS", cds_rdata)
up.send("NOERROR")
t.sleep(23)
t.sleep(40)
check_zone5(child, 2, 1, 0, "old KSK retired")
check_zone5(child, 2, 1, 1, "old KSK retired")
t.end()
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