Commit 6d1d86eb authored by Mark Karpilovskij's avatar Mark Karpilovskij Committed by Daniel Salzman

libdnssec: relax the fixed length condition for key ID

parent 3d1e98ed
......@@ -107,7 +107,8 @@ The salt is printed and expected in hexadecimal, or dash if empty.
.TP
\fBset\fP \fIkey_spec\fP [\fIarguments\fP\&...]
Changes a timing argument (or ksk/zsk) of an existing key to a new value. \fIKey_spec\fP is either the
key tag or a prefix of the key ID; \fIarguments\fP are like for \fBgenerate\fP, but just the related ones.
key tag or a prefix of the key ID, with an optional \fI[id=|keytag=]\fP prefix; \fIarguments\fP
are like for \fBgenerate\fP, but just the related ones.
.TP
\fBds\fP [\fIkey_spec\fP]
Generate DS record (all digest algorithms together) for specified key. \fIKey_spec\fP
......
......@@ -84,7 +84,8 @@ Commands
**set** *key_spec* [*arguments*...]
Changes a timing argument (or ksk/zsk) of an existing key to a new value. *Key_spec* is either the
key tag or a prefix of the key ID; *arguments* are like for **generate**, but just the related ones.
key tag or a prefix of the key ID, with an optional *[id=|keytag=]* prefix; *arguments*
are like for **generate**, but just the related ones.
**ds** [*key_spec*]
Generate DS record (all digest algorithms together) for specified key. *Key_spec*
......
/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2019 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
......@@ -33,11 +33,11 @@ bool dnssec_keyid_is_valid(const char *id)
return false;
}
if (strlen(id) != DNSSEC_KEYID_SIZE) {
if (strlen(id) % 2 != 0) {
return false;
}
for (int i = 0; i < DNSSEC_KEYID_SIZE; i++) {
for (int i = 0; id[i] != '\0'; i++) {
if (!is_xdigit(id[i])) {
return false;
}
......@@ -53,7 +53,7 @@ void dnssec_keyid_normalize(char *id)
return;
}
for (size_t i = 0; i < DNSSEC_KEYID_SIZE; i++) {
for (size_t i = 0; id[i] != '\0'; i++) {
assert(id[i] != '\0' && is_xdigit(id[i]));
id[i] = knot_tolower(id[i]);
}
......
......@@ -29,6 +29,7 @@
#include "contrib/tolower.h"
#include "contrib/wire_ctx.h"
#include "libdnssec/error.h"
#include "libdnssec/keyid.h"
#include "libdnssec/shared/shared.h"
#include "knot/dnssec/kasp/policy.h"
#include "knot/dnssec/key-events.h"
......@@ -556,8 +557,12 @@ int keymgr_import_pem(kdnssec_ctx_t *ctx, const char *import_file, int argc, cha
return import_key(ctx, KEYSTORE_BACKEND_PEM, import_file, argc, argv);
}
int keymgr_import_pkcs11(kdnssec_ctx_t *ctx, const char *key_id, int argc, char *argv[])
int keymgr_import_pkcs11(kdnssec_ctx_t *ctx, char *key_id, int argc, char *argv[])
{
if (!dnssec_keyid_is_valid(key_id)) {
return DNSSEC_INVALID_KEY_ID;
}
dnssec_keyid_normalize(key_id);
return import_key(ctx, KEYSTORE_BACKEND_PKCS11, key_id, argc, argv);
}
......@@ -688,10 +693,24 @@ static bool is_hex(const char *string)
int keymgr_get_key(kdnssec_ctx_t *ctx, const char *key_spec, knot_kasp_key_t **key)
{
// Check if type of key spec is prescribed.
bool is_keytag = false, is_id = false;
if (strncasecmp(key_spec, "keytag=", 7) == 0) {
key_spec += 7;
is_keytag = true;
} else if (strncasecmp(key_spec, "id=", 3) == 0) {
key_spec += 3;
is_id = true;
}
uint16_t keytag = 0;
bool has_keytag = (str_to_u16(key_spec, &keytag) == KNOT_EOK);
bool can_be_keytag = (str_to_u16(key_spec, &keytag) == KNOT_EOK);
long spec_len = strlen(key_spec);
if (!has_keytag && !is_hex(key_spec)) {
// Check if input is a valid key spec.
if ((is_keytag && !can_be_keytag) ||
(is_id && !is_hex(key_spec)) ||
(!can_be_keytag && !is_hex(key_spec))) {
printf("Error in key specification.\n");
return KNOT_EINVAL;
}
......@@ -699,14 +718,25 @@ int keymgr_get_key(kdnssec_ctx_t *ctx, const char *key_spec, knot_kasp_key_t **k
*key = NULL;
for (size_t i = 0; i < ctx->zone->num_keys; i++) {
knot_kasp_key_t *candidate = &ctx->zone->keys[i];
if ((has_keytag && dnssec_key_get_keytag(candidate->key) == keytag) ||
(!has_keytag && strncmp(candidate->id, key_spec, spec_len) == 0)) {
bool keyid_match = strncmp(candidate->id, key_spec, spec_len) == 0; // May be just a prefix.
bool keytag_match = can_be_keytag &&
dnssec_key_get_keytag(candidate->key) == keytag;
// Terminate if found exact key ID match.
if (keyid_match && !is_keytag && strlen(candidate->id) == spec_len) {
*key = candidate;
break;
}
// Check for key ID prefix or tag match.
if ((is_keytag && keytag_match) || // Tag is prescribed.
(is_id && keyid_match) || // Key ID is prescribed.
((!is_keytag && !is_id) && (keyid_match || keytag_match))) { // Nothing is prescribed.
if (*key == NULL) {
*key = candidate;
}
else {
printf("Key is not specified uniquely.\n");
return KNOT_ELIMIT;
} else {
printf("Key is not specified uniquely. Please use id=Full_Key_ID.\n");
return KNOT_EINVAL;
}
}
}
......
/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2019 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
......@@ -26,7 +26,7 @@ int keymgr_import_bind(kdnssec_ctx_t *ctx, const char *import_file, bool pub_onl
int keymgr_import_pem(kdnssec_ctx_t *ctx, const char *import_file, int argc, char *argv[]);
int keymgr_import_pkcs11(kdnssec_ctx_t *ctx, const char *key_id, int argc, char *argv[]);
int keymgr_import_pkcs11(kdnssec_ctx_t *ctx, char *key_id, int argc, char *argv[]);
int keymgr_nsec3_salt_print(kdnssec_ctx_t *ctx);
......
/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2019 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
......@@ -92,7 +92,8 @@ static void print_help(void)
" (syntax: import-skr <skr_file>)\n"
"\n"
"Key specification:\n"
" either the key tag (number) or [a prefix of] key ID.\n"
" either the key tag (number) or [a prefix of] key ID, with an optional\n"
" [id=|keytag=] prefix.\n"
"\n"
"Key attributes:\n"
" algorithm The key cryptographic algorithm: either name (e.g. RSASHA256) or\n"
......
/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2019 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
......@@ -30,6 +30,7 @@ static void test_keyid_is_valid_run(const char *param, bool should_ok)
static void test_keyid_is_valid(void)
{
test_keyid_is_valid_run(NULL, false);
test_keyid_is_valid_run("a1b1", true);
test_keyid_is_valid_run("3e90c5cb1fad5f8512da2028fda3808e749d3bf", false);
test_keyid_is_valid_run("9aa6dAAC706fb6fe4aceb327452a7b5FEA457544", true);
test_keyid_is_valid_run("eac45c184b7f476472c16d5b0c4f0c52389848001", false);
......
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