Commit 5ed4d625 authored by Libor Peltan's avatar Libor Peltan

libdnssec: moved kasp/policy to knot

parent bae88e1c
......@@ -77,7 +77,6 @@ src/dnssec/lib/dnssec/binary.h
src/dnssec/lib/dnssec/crypto.h
src/dnssec/lib/dnssec/dnssec.h
src/dnssec/lib/dnssec/error.h
src/dnssec/lib/dnssec/kasp.h
src/dnssec/lib/dnssec/key.h
src/dnssec/lib/dnssec/keyid.h
src/dnssec/lib/dnssec/keystore.h
......@@ -88,7 +87,6 @@ src/dnssec/lib/dnssec/random.h
src/dnssec/lib/dnssec/sign.h
src/dnssec/lib/dnssec/tsig.h
src/dnssec/lib/error.c
src/dnssec/lib/kasp/policy.c
src/dnssec/lib/key/algorithm.c
src/dnssec/lib/key/algorithm.h
src/dnssec/lib/key/convert.c
......@@ -145,7 +143,6 @@ src/dnssec/tests/binary.c
src/dnssec/tests/crypto.c
src/dnssec/tests/kasp_dir_escape.c
src/dnssec/tests/kasp_dir_file.c
src/dnssec/tests/kasp_policy.c
src/dnssec/tests/key.c
src/dnssec/tests/key_algorithm.c
src/dnssec/tests/key_ds.c
......@@ -207,6 +204,8 @@ src/knot/dnssec/kasp/keystate.c
src/knot/dnssec/kasp/keystate.h
src/knot/dnssec/kasp/keystore.c
src/knot/dnssec/kasp/keystore.h
src/knot/dnssec/kasp/policy.c
src/knot/dnssec/kasp/policy.h
src/knot/dnssec/key-events.c
src/knot/dnssec/key-events.h
src/knot/dnssec/nsec-chain.c
......
......@@ -255,6 +255,8 @@ libknotd_la_SOURCES = \
knot/dnssec/kasp/keystate.h \
knot/dnssec/kasp/keystore.c \
knot/dnssec/kasp/keystore.h \
knot/dnssec/kasp/policy.c \
knot/dnssec/kasp/policy.h \
knot/dnssec/key-events.c \
knot/dnssec/key-events.h \
knot/dnssec/nsec-chain.c \
......
......@@ -57,7 +57,6 @@ include_dnssec_HEADERS = \
lib/dnssec/crypto.h \
lib/dnssec/dnssec.h \
lib/dnssec/error.h \
lib/dnssec/kasp.h \
lib/dnssec/key.h \
lib/dnssec/keyid.h \
lib/dnssec/keystore.h \
......@@ -73,7 +72,6 @@ libdnssec_la_SOURCES = \
lib/binary.c \
lib/crypto.c \
lib/error.c \
lib/kasp/policy.c \
lib/key/algorithm.c \
lib/key/algorithm.h \
lib/key/convert.c \
......
......@@ -105,7 +105,6 @@
#include <dnssec/binary.h>
#include <dnssec/crypto.h>
#include <dnssec/error.h>
#include <dnssec/kasp.h>
#include <dnssec/key.h>
#include <dnssec/keyid.h>
#include <dnssec/keystore.h>
......
/* Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <stdlib.h>
#include "shared.h"
#include "error.h"
#include "kasp.h"
#define HOURS(x) (x * 60 * 60)
#define DAYS(x) (x * HOURS(24))
/*!
* Clear policy parameters, but keep references.
*/
static void clear_policy(dnssec_kasp_policy_t *policy)
{
assert(policy);
char *name = policy->name;
char *keystore = policy->keystore;
clear_struct(policy);
policy->name = name;
policy->keystore = keystore;
}
/* -- public API ----------------------------------------------------------- */
_public_
dnssec_kasp_policy_t *dnssec_kasp_policy_new(const char *name)
{
dnssec_kasp_policy_t *policy = malloc(sizeof(*policy));
clear_struct(policy);
if (name) {
policy->name = strdup(name);
if (!policy->name) {
free(policy);
return NULL;
}
}
return policy;
}
_public_
void dnssec_kasp_policy_defaults(dnssec_kasp_policy_t *policy)
{
if (!policy) {
return;
}
clear_policy(policy);
policy->algorithm = DNSSEC_KEY_ALGORITHM_ECDSA_P256_SHA256;
policy->zsk_size = dnssec_algorithm_key_size_default(policy->algorithm);
policy->ksk_size = dnssec_algorithm_key_size_default(policy->algorithm);
policy->dnskey_ttl = 1200;
policy->zsk_lifetime = DAYS(30);
policy->rrsig_lifetime = DAYS(14);
policy->rrsig_refresh_before = DAYS(7);
policy->propagation_delay = HOURS(1);
policy->nsec3_enabled = false;
policy->nsec3_iterations = 10;
policy->nsec3_salt_length = 8;
policy->nsec3_salt_lifetime = DAYS(30);
}
_public_
void dnssec_kasp_policy_free(dnssec_kasp_policy_t *policy)
{
if (!policy) {
return;
}
free(policy->name);
free(policy->keystore);
free(policy);
}
static bool valid_algorithm(const dnssec_kasp_policy_t *p)
{
return dnssec_algorithm_key_size_check(p->algorithm, p->ksk_size) &&
dnssec_algorithm_key_size_check(p->algorithm, p->zsk_size);
}
_public_
int dnssec_kasp_policy_validate(const dnssec_kasp_policy_t *policy)
{
if (!policy) {
return DNSSEC_EINVAL;
}
/*
* NOTES:
*
* - Don't check if key store is set.
* - Allow zero TTL for any record.
*
*/
// required parameters
if (policy->rrsig_lifetime == 0 ||
policy->rrsig_refresh_before == 0
) {
return DNSSEC_CONFIG_MALFORMED;
}
// signing algorithm constraints
if (!policy->manual && !valid_algorithm(policy)) {
return DNSSEC_INVALID_KEY_SIZE;
}
return DNSSEC_EOK;
}
......@@ -5,7 +5,6 @@
# test binaries
/binary
/crypto
/kasp_policy
/key
/key_algorithm
/key_ds
......
......@@ -20,7 +20,6 @@ EXTRA_DIST = sample_keys.h
check_PROGRAMS = \
binary \
crypto \
kasp_policy \
key \
key_algorithm \
key_ds \
......
/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <tap/basic.h>
#include <string.h>
#include "dnssec/error.h"
#include "dnssec/kasp.h"
static void test_new_policy(void)
{
diag("%s", __func__);
dnssec_kasp_policy_t *p = NULL;
p = dnssec_kasp_policy_new(NULL);
ok(p != NULL, "create policy without name");
if (!p) {
dnssec_kasp_policy_free(p);
}
dnssec_kasp_policy_free(p);
p = dnssec_kasp_policy_new("domestic");
ok(p != NULL, "create policy with name");
if (!p) {
return;
}
ok(strcmp(p->name, "domestic") == 0, "policy name is set");
ok(p->algorithm == DNSSEC_KEY_ALGORITHM_INVALID, "no algorithm set");
ok(dnssec_kasp_policy_validate(p) != DNSSEC_EOK, "validation fails");
dnssec_kasp_policy_free(p);
}
static void test_set_parameters(void)
{
diag("%s", __func__);
dnssec_kasp_policy_t *p = dnssec_kasp_policy_new("monetary");
ok(p != NULL, "create policy");
if (!p) {
return;
}
ok(dnssec_kasp_policy_validate(p) != DNSSEC_EOK, "validation fails with new policy");
p->algorithm = DNSSEC_KEY_ALGORITHM_RSA_SHA256;
p->ksk_size = 2048;
p->zsk_size = 1024;
p->rrsig_lifetime = 60;
p->rrsig_refresh_before = 50;
ok(dnssec_kasp_policy_validate(p) == DNSSEC_EOK, "validation succeeds with valid setting");
p->algorithm = DNSSEC_KEY_ALGORITHM_ECDSA_P256_SHA256;
ok(dnssec_kasp_policy_validate(p) != DNSSEC_EOK, "validation fails with incorrect key size");
p->manual = true;
ok(dnssec_kasp_policy_validate(p) == DNSSEC_EOK, "validation succeeds in manual mode");
dnssec_kasp_policy_free(p);
}
static void test_default_policy(void)
{
diag("%s", __func__);
dnssec_kasp_policy_t *p = dnssec_kasp_policy_new("environmental");
ok(p != NULL, "create policy");
if (!p) {
return;
}
ok(dnssec_kasp_policy_validate(p) != DNSSEC_EOK, "validation fails with new policy");
dnssec_kasp_policy_defaults(p);
ok(dnssec_kasp_policy_validate(p) == DNSSEC_EOK, "validation succeeds with defaults");
ok(p->manual == false, "manual mode disabled");
ok(p->algorithm == DNSSEC_KEY_ALGORITHM_ECDSA_P256_SHA256, "algorithm is ECDSAP256SHA256");
ok(p->nsec3_enabled == false, "NSEC3 is disabled");
ok(p->dnskey_ttl == 1200, "DNSKEY TTL is 1200");
ok(p->zsk_lifetime > 0, "ZSK lifetime is set");
ok(p->rrsig_lifetime > 0, "RRSIG lifetime is set");
ok(p->rrsig_lifetime == p->rrsig_refresh_before * 2, "RRSIG lifetime is double the refresh");
dnssec_kasp_policy_free(p);
}
int main(int argc, char *argv[])
{
plan_lazy();
test_new_policy();
test_set_parameters();
test_default_policy();
return 0;
}
......@@ -20,7 +20,6 @@
#include <time.h>
#include <dnssec/error.h>
#include <dnssec/kasp.h>
#include <dnssec/keystore.h>
#include "libknot/libknot.h"
......@@ -29,7 +28,7 @@
#include "knot/dnssec/kasp/keystore.h"
#include "contrib/files.h"
static int policy_load(dnssec_kasp_policy_t *policy)
static int policy_load(knot_kasp_policy_t *policy)
{
const uint8_t *id = (const uint8_t *)policy->name;
const size_t id_len = strlen(policy->name) + 1;
......@@ -111,7 +110,7 @@ int kdnssec_kasp_init(kdnssec_ctx_t *ctx, const char *kasp_path, size_t kasp_map
ctx->kasp_zone_path = strdup(kasp_path);
ctx->policy = dnssec_kasp_policy_new(policy_name);
ctx->policy = knot_kasp_policy_new(policy_name);
if (ctx->policy == NULL) {
return KNOT_ENOMEM;
}
......@@ -153,7 +152,7 @@ void kdnssec_ctx_deinit(kdnssec_ctx_t *ctx)
}
dnssec_keystore_deinit(ctx->keystore);
dnssec_kasp_policy_free(ctx->policy);
knot_kasp_policy_free(ctx->policy);
kasp_zone_free(&ctx->zone);
free(ctx->kasp_zone_path);
......
......@@ -18,11 +18,11 @@
#include <time.h>
#include <dnssec/kasp.h>
#include <dnssec/keystore.h>
#include "knot/conf/conf.h"
#include "knot/dnssec/kasp/kasp_zone.h"
#include "knot/dnssec/kasp/policy.h"
#include "libknot/dname.h"
/*!
......@@ -33,7 +33,7 @@ struct kdnssec_ctx {
kasp_db_t **kasp_db;
knot_kasp_zone_t *zone;
dnssec_kasp_policy_t *policy;
knot_kasp_policy_t *policy;
dnssec_keystore_t *keystore;
char *kasp_zone_path;
......
......@@ -19,8 +19,8 @@
#include <time.h>
#include "contrib/ucw/lists.h"
#include "dnssec/lib/dnssec/kasp.h"
#include "libknot/db/db_lmdb.h"
#include "knot/dnssec/kasp/policy.h"
#include "knot/zone/zone.h"
typedef struct kasp_db kasp_db_t;
......
......@@ -80,7 +80,7 @@ static int params2dnskey(const knot_dname_t *dname, key_params_t *params,
}
static int params2kaspkey(const knot_dname_t *dname, key_params_t *params,
dnssec_kasp_key_t *key)
knot_kasp_key_t *key)
{
int ret = params2dnskey(dname, params, &key->key);
if (ret != KNOT_EOK) {
......@@ -97,7 +97,7 @@ static int params2kaspkey(const knot_dname_t *dname, key_params_t *params,
return KNOT_EOK;
}
static void kaspkey2params(dnssec_kasp_key_t *key, key_params_t *params)
static void kaspkey2params(knot_kasp_key_t *key, key_params_t *params)
{
assert(key);
assert(params);
......@@ -123,7 +123,7 @@ int kasp_zone_load(knot_kasp_zone_t *zone,
const knot_dname_t *zone_name,
kasp_db_t *kdb)
{
dnssec_kasp_key_t *dkeys = NULL;
knot_kasp_key_t *dkeys = NULL;
size_t num_dkeys = 0;
dnssec_binary_t salt = { 0 };
time_t sc = 0;
......@@ -185,10 +185,10 @@ kzl_end:
return ret;
}
int kasp_zone_append(knot_kasp_zone_t *zone, const dnssec_kasp_key_t *appkey)
int kasp_zone_append(knot_kasp_zone_t *zone, const knot_kasp_key_t *appkey)
{
size_t new_num_keys = zone->num_keys + 1;
dnssec_kasp_key_t *new_keys = calloc(new_num_keys, sizeof(*new_keys));
knot_kasp_key_t *new_keys = calloc(new_num_keys, sizeof(*new_keys));
if (!new_keys) {
return KNOT_ENOMEM;
}
......
......@@ -16,14 +16,13 @@
#pragma once
#include "dnssec/lib/dnssec/kasp.h"
#include "knot/dnssec/kasp/kasp_db.h"
#include "knot/zone/zone.h"
typedef struct knot_kasp_zone {
knot_dname_t *dname;
dnssec_kasp_key_t *keys;
knot_kasp_key_t *keys;
size_t num_keys;
dnssec_binary_t nsec3_salt;
......@@ -39,7 +38,7 @@ int kasp_zone_save(const knot_kasp_zone_t *zone,
kasp_db_t *kdb);
int kasp_zone_append(knot_kasp_zone_t *zone,
const dnssec_kasp_key_t *appkey);
const knot_kasp_key_t *appkey);
void kasp_zone_clear(knot_kasp_zone_t *zone);
void kasp_zone_free(knot_kasp_zone_t **zone);
......@@ -18,10 +18,10 @@
#include <time.h>
#include <string.h>
#include "dnssec/kasp.h"
#include "knot/dnssec/kasp/policy.h"
#include "knot/dnssec/kasp/keystate.h"
key_state_t get_key_state(const dnssec_kasp_key_t *key, time_t moment)
key_state_t get_key_state(const knot_kasp_key_t *key, time_t moment)
{
if (!key || moment <= 0)
{
......@@ -38,7 +38,7 @@ key_state_t get_key_state(const dnssec_kasp_key_t *key, time_t moment)
* meaning of unset parameter when policy is used, etc.).
*/
const dnssec_kasp_key_timing_t *t = &key->timing;
const knot_kasp_key_timing_t *t = &key->timing;
bool removed = t->remove != 0 && t->remove <= moment;
bool retired = t->retire != 0 && t->retire <= moment;
......
......@@ -18,7 +18,7 @@
#include <time.h>
#include "dnssec/kasp.h"
#include "knot/dnssec/kasp/policy.h"
enum key_state {
DNSSEC_KEY_STATE_INVALID = 0,
......@@ -30,4 +30,4 @@ enum key_state {
typedef enum key_state key_state_t;
key_state_t get_key_state(const dnssec_kasp_key_t *key, time_t moment);
key_state_t get_key_state(const knot_kasp_key_t *key, time_t moment);
......@@ -16,7 +16,6 @@
#pragma once
#include <dnssec/kasp.h>
#include <dnssec/keystore.h>
#include "knot/dnssec/kasp/kasp_zone.h"
#include "libknot/dname.h"
......
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "knot/dnssec/kasp/policy.h"
knot_kasp_policy_t *knot_kasp_policy_new(const char *name)
{
knot_kasp_policy_t *policy = malloc(sizeof(*policy));
memset(policy, 0, sizeof(*policy));
if (name) {
policy->name = strdup(name);
if (!policy->name) {
free(policy);
return NULL;
}
}
return policy;
}
void knot_kasp_policy_free(knot_kasp_policy_t *policy)
{
if (!policy) {
return;
}
free(policy->name);
free(policy->keystore);
free(policy);
}
......@@ -13,94 +13,23 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
* \file
*
* Key and Signature Policy access.
*
* \defgroup kasp KASP
*
* Key and Signature Policy access.
*
* The module provides access to Key and Signature Policy (KASP), which
* keeps a signing state of a zone, zone signing policies, a reference
* to key stores.
*
* The functionality of the module is incomplete.
*
* Example use:
*
* ~~~~~ {.c}
*
* int result;
* dnssec_kasp_t *kasp = NULL;
* dnssec_kasp_zone_t *zone = NULL;
* dnssec_list_t *keys = NULL;
*
* // create API context
* dnssec_kasp_init_dir(&kasp);
*
* // open KASP
* result = dnssec_kasp_open_dir(kasp, "keydir");
* if (result != DNSSEC_EOK) {
* return result;
* }
*
* // get zone state of 'example.com.'
* result = dnssec_kasp_zone_load(kasp, "example.com", &zone);
* if (result != DNSSEC_EOK) {
* dnssec_kasp_close(kasp);
* return result;
* }
*
* // retrieve zone keys
* keys = dnssec_kasp_zone_get_keys(zone);
* if (keys == NULL) {
* dnssec_kasp_zone_free(zone);
* dnssec_kasp_close(kasp);
* return KNOT_ENOMEM;
* }
*
* // list key IDs and it they are active
* time_t now = time(NULL);
* dnssec_list_foreach(item, keys) {
* dnssec_kasp_key_t *key = dnssec_item_get(item);
* bool active = key->timing.active <= now && now < key->timing.retire;
* printf("key %s is %s\n", dnssec_key_get_id(key->key),
* active ? "active" : "inactive");
* }
*
* // cleanup
* dnssec_kasp_zone_free_keys(keys);
* dnssec_kasp_zone_free(zone);
* dnssec_kasp_close(kasp);
* dnssec_kasp_deinit(kasp);
*
* ~~~~~
*
* @{
*/
#pragma once
#include <dnssec/key.h>
#include <dnssec/list.h>
#include <dnssec/nsec.h>
#include "dnssec/lib/dnssec/key.h"
#include <stdbool.h>
#include <time.h>
struct dnssec_kasp_store_functions;
/*!
* KASP key timing information.
*/
typedef struct dnssec_kasp_key_timing {
typedef struct knot_kasp_key_timing {
time_t created; /*!< Time the key was generated/imported. */
time_t publish; /*!< Time of DNSKEY record publication. */
time_t active; /*!< Start of RRSIG records generating. */
time_t retire; /*!< End of RRSIG records generating. */
time_t remove; /*!< Time of DNSKEY record removal. */
} dnssec_kasp_key_timing_t;
} knot_kasp_key_timing_t;
/*!
* Key parameters as writing in zone config file.
......@@ -111,7 +40,7 @@ struct key_params {
uint8_t algorithm;
dnssec_binary_t public_key;
bool is_ksk;
struct dnssec_kasp_key_timing timing;
struct knot_kasp_key_timing timing;
};
typedef struct key_params key_params_t;
......@@ -119,18 +48,18 @@ typedef struct key_params key_params_t;
/*!
* Zone key.
*/
typedef struct dnssec_kasp_key {
char *id; /*!< Keystore unique key ID. */
dnssec_key_t *key; /*!< Instance of the key. */
dnssec_kasp_key_timing_t timing; /*!< Key timing information. */
} dnssec_kasp_key_t;
typedef struct knot_kasp_key {
char *id; /*!< Keystore unique key ID. */
dnssec_key_t *key; /*!< Instance of the key. */
knot_kasp_key_timing_t timing; /*!< Key timing information. */
} knot_kasp_key_t;
/*!
* Key and signature policy.
*
* \todo Move into internal API and add getters/setters (probably).
*/
typedef struct dnssec_kasp_policy {
typedef struct knot_kasp_policy {
char *name;
bool manual;
char *keystore;
......@@ -155,7 +84,7 @@ typedef struct dnssec_kasp_policy {
uint32_t zone_maximal_ttl;
// data propagation delay
uint32_t propagation_delay;
} dnssec_kasp_policy_t;
} knot_kasp_policy_t;
/*!
* Create new KASP policy.
......@@ -164,34 +93,11 @@ typedef struct dnssec_kasp_policy {
*
* \return Pointer to KASP policy.
*/
dnssec_kasp_policy_t *dnssec_kasp_policy_new(const char *name);
knot_kasp_policy_t *knot_kasp_policy_new(const char *name);
/*!
* Free a KASP policy.
*
* \param policy Policy to be freed.
*/
void dnssec_kasp_policy_free(dnssec_kasp_policy_t *policy);
/*!
* Validate a KASP policy.
*
* \param policy Policy to be validated.
*/
int dnssec_kasp_policy_validate(const dnssec_kasp_policy_t *policy);
/*!
* Set default policy.
*
* \param policy Policy to be set to defaults.
*/
void dnssec_kasp_policy_defaults(dnssec_kasp_policy_t *policy);
/*
* TODO: workaround, PKCS 8 dir keystore needs to know KASP base path
*/
#define DNSSEC_KASP_KEYSTORE_PKCS8 "pkcs8"
#define DNSSEC_KASP_KEYSTORE_PKCS11 "pkcs11"
/*! @} */
void knot_kasp_policy_free(knot_kasp_policy_t *policy);
......@@ -28,15 +28,15 @@
#include "knot/dnssec/zone-sign.h"
#include "knot/zone/serial.h"
static dnssec_kasp_key_t *last_key(kdnssec_ctx_t *ctx, key_state_t state)
static knot_kasp_key_t *last_key(kdnssec_ctx_t *ctx, key_state_t state)
{
assert(ctx);
assert(ctx->zone);
dnssec_kasp_key_t *match = NULL;
knot_kasp_key_t *match = NULL;
for (size_t i = 0; i < ctx->zone->num_keys; i++) {
dnssec_kasp_key_t *key = &ctx->zone->keys[i];