Commit 1cff09e6 authored by Libor Peltan's avatar Libor Peltan Committed by Daniel Salzman

dnssec: signing scheme rollover implemented

parent 34f7638e
...@@ -23,25 +23,25 @@ ...@@ -23,25 +23,25 @@
#include "knot/dnssec/policy.h" #include "knot/dnssec/policy.h"
#include "knot/dnssec/zone-keys.h" #include "knot/dnssec/zone-keys.h"
static bool key_present(kdnssec_ctx_t *ctx, uint16_t flag) static bool key_present(const kdnssec_ctx_t *ctx, bool ksk, bool zsk)
{ {
assert(ctx); assert(ctx);
assert(ctx->zone); assert(ctx->zone);
for (size_t i = 0; i < ctx->zone->num_keys; i++) { for (size_t i = 0; i < ctx->zone->num_keys; i++) {
knot_kasp_key_t *key = &ctx->zone->keys[i]; const knot_kasp_key_t *key = &ctx->zone->keys[i];
if (dnssec_key_get_flags(key->key) == flag) { if (key->is_ksk == ksk && key->is_zsk == zsk) {
return true; return true;
} }
} }
return false; return false;
} }
static bool key_id_present(kdnssec_ctx_t *ctx, const char *keyid, uint16_t flag) static bool key_id_present(const kdnssec_ctx_t *ctx, const char *keyid, uint16_t flag)
{ {
assert(ctx); assert(ctx);
assert(ctx->zone); assert(ctx->zone);
for (size_t i = 0; i < ctx->zone->num_keys; i++) { for (size_t i = 0; i < ctx->zone->num_keys; i++) {
knot_kasp_key_t *key = &ctx->zone->keys[i]; const knot_kasp_key_t *key = &ctx->zone->keys[i];
if (strcmp(keyid, key->id) == 0 && if (strcmp(keyid, key->id) == 0 &&
dnssec_key_get_flags(key->key) == flag) { dnssec_key_get_flags(key->key) == flag) {
return true; return true;
...@@ -50,19 +50,29 @@ static bool key_id_present(kdnssec_ctx_t *ctx, const char *keyid, uint16_t flag) ...@@ -50,19 +50,29 @@ static bool key_id_present(kdnssec_ctx_t *ctx, const char *keyid, uint16_t flag)
return false; return false;
} }
static bool algorithm_present(const kdnssec_ctx_t *ctx, uint8_t alg) static unsigned algorithm_present(const kdnssec_ctx_t *ctx, uint8_t alg)
{ {
assert(ctx); assert(ctx);
assert(ctx->zone); assert(ctx->zone);
unsigned ret = 0;
for (size_t i = 0; i < ctx->zone->num_keys; i++) { for (size_t i = 0; i < ctx->zone->num_keys; i++) {
knot_kasp_key_t *key = &ctx->zone->keys[i]; const knot_kasp_key_t *key = &ctx->zone->keys[i];
knot_time_t activated = knot_time_min(key->timing.pre_active, key->timing.ready); knot_time_t activated = knot_time_min(key->timing.pre_active, key->timing.ready);
if (knot_time_cmp(knot_time_min(activated, key->timing.active), ctx->now) <= 0 && if (knot_time_cmp(knot_time_min(activated, key->timing.active), ctx->now) <= 0 &&
dnssec_key_get_algorithm(key->key) == alg) { dnssec_key_get_algorithm(key->key) == alg) {
return true; ret++;
} }
} }
return false; return ret;
}
static bool signing_scheme_present(const kdnssec_ctx_t *ctx)
{
if (ctx->policy->singe_type_signing) {
return key_present(ctx, true, true);
} else {
return (key_present(ctx, true, false) && key_present(ctx, false, true));
}
} }
static knot_kasp_key_t *key_get_by_id(kdnssec_ctx_t *ctx, const char *keyid) static knot_kasp_key_t *key_get_by_id(kdnssec_ctx_t *ctx, const char *keyid)
...@@ -487,10 +497,11 @@ static int exec_ksk_retire(kdnssec_ctx_t *ctx, knot_kasp_key_t *key) ...@@ -487,10 +497,11 @@ static int exec_ksk_retire(kdnssec_ctx_t *ctx, knot_kasp_key_t *key)
knot_kasp_key_t *alg_rollover_friend = NULL; knot_kasp_key_t *alg_rollover_friend = NULL;
for (size_t i = 0; i < ctx->zone->num_keys; i++) { for (size_t i = 0; i < ctx->zone->num_keys; i++) {
knot_kasp_key_t *key = &ctx->zone->keys[i]; knot_kasp_key_t *k = &ctx->zone->keys[i];
if (key->is_zsk && get_key_state(key, ctx->now) == DNSSEC_KEY_STATE_RETIRE_ACTIVE) { if (k->is_zsk && get_key_state(k, ctx->now) == DNSSEC_KEY_STATE_RETIRE_ACTIVE &&
algorithm_present(ctx, dnssec_key_get_algorithm(k->key)) < 3) {
alg_rollover = true; alg_rollover = true;
alg_rollover_friend = key; alg_rollover_friend = k;
} }
} }
...@@ -526,7 +537,7 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *resched ...@@ -526,7 +537,7 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *resched
} }
int ret = KNOT_EOK; int ret = KNOT_EOK;
// generate initial keys if missing // generate initial keys if missing
if (!key_present(ctx, DNSKEY_FLAGS_KSK)) { if (!key_present(ctx, true, false) && !key_present(ctx, true, true)) {
if (ctx->policy->ksk_shared) { if (ctx->policy->ksk_shared) {
ret = share_or_generate_key(ctx, true, ctx->policy->singe_type_signing, ctx->now, false); ret = share_or_generate_key(ctx, true, ctx->policy->singe_type_signing, ctx->now, false);
} else { } else {
...@@ -536,13 +547,13 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *resched ...@@ -536,13 +547,13 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *resched
if (ret == KNOT_EOK) { if (ret == KNOT_EOK) {
reschedule->keys_changed = true; reschedule->keys_changed = true;
if (!ctx->policy->singe_type_signing && if (!ctx->policy->singe_type_signing &&
!key_present(ctx, DNSKEY_FLAGS_ZSK)) { !key_present(ctx, false, true)) {
ret = generate_key(ctx, false, true, ctx->now, false); ret = generate_key(ctx, false, true, ctx->now, false);
} }
} }
} }
// algorithm rollover // algorithm rollover
if (!algorithm_present(ctx,ctx->policy->algorithm) && if (algorithm_present(ctx, ctx->policy->algorithm) == 0 &&
!running_rollover(ctx) && ret == KNOT_EOK) { !running_rollover(ctx) && ret == KNOT_EOK) {
if (ctx->policy->ksk_shared) { if (ctx->policy->ksk_shared) {
ret = share_or_generate_key(ctx, true, ctx->policy->singe_type_signing, 0, true); ret = share_or_generate_key(ctx, true, ctx->policy->singe_type_signing, 0, true);
...@@ -557,6 +568,22 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *resched ...@@ -557,6 +568,22 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_reschedule_t *resched
reschedule->keys_changed = true; reschedule->keys_changed = true;
} }
} }
// scheme rollover
if (!signing_scheme_present(ctx) &&
!running_rollover(ctx) && ret == KNOT_EOK) {
if (ctx->policy->ksk_shared) {
ret = share_or_generate_key(ctx, true, ctx->policy->singe_type_signing, 0, false);
} else {
ret = generate_key(ctx, true, ctx->policy->singe_type_signing, 0, false);
}
if (!ctx->policy->singe_type_signing && ret == KNOT_EOK) {
ret = generate_key(ctx, false, true, 0, false);
}
log_zone_info(ctx->zone->dname, "DNSSEC, signing scheme rollover started");
if (ret == KNOT_EOK) {
reschedule->keys_changed = true;
}
}
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
return ret; return ret;
} }
......
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