mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 03:50:00 -04:00
disable adding keys to keytable; only DS trust anchors can now be added
the internal keytable structure has not yet been changed, but insertion of DS anchors is the only method now available. NOTE: the keytable unit test is currently failing because of tests that expect individual keynode objects to contain single DST key objects.
This commit is contained in:
parent
7fdf40770f
commit
b984a4b647
10 changed files with 218 additions and 255 deletions
|
|
@ -700,11 +700,12 @@ configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config,
|
|||
}
|
||||
|
||||
static isc_result_t
|
||||
ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
|
||||
dns_rdata_ds_t **dsp, const char **namestrp, isc_mem_t *mctx)
|
||||
ta_fromconfig(const cfg_obj_t *key, bool *initialp, const char **namestrp,
|
||||
unsigned char *digest, dns_rdata_ds_t *ds)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_rdata_dnskey_t keystruct;
|
||||
dns_rdata_ds_t *ds = NULL;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
uint32_t rdata1, rdata2, rdata3;
|
||||
const char *datastr = NULL, *namestr = NULL;
|
||||
unsigned char data[4096];
|
||||
|
|
@ -715,8 +716,6 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
|
|||
dns_fixedname_t fname;
|
||||
dns_name_t *name = NULL;
|
||||
isc_buffer_t namebuf;
|
||||
isc_result_t result;
|
||||
dst_key_t *dstkey = NULL;
|
||||
const char *atstr = NULL;
|
||||
enum {
|
||||
INIT_DNSKEY,
|
||||
|
|
@ -726,9 +725,8 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
|
|||
TRUSTED
|
||||
} anchortype;
|
||||
|
||||
REQUIRE(keyp != NULL && *keyp == NULL);
|
||||
REQUIRE(dsp != NULL && *dsp == NULL);
|
||||
REQUIRE(namestrp != NULL && *namestrp == NULL);
|
||||
REQUIRE(ds != NULL);
|
||||
|
||||
/* if DNSKEY, flags; if DS, key tag */
|
||||
rdata1 = cfg_obj_asuint32(cfg_tuple_get(key, "rdata1"));
|
||||
|
|
@ -775,6 +773,13 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
|
|||
isc_buffer_init(&databuf, data, sizeof(data));
|
||||
isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
|
||||
|
||||
*ds = (dns_rdata_ds_t){
|
||||
.common.rdclass = dns_rdataclass_in,
|
||||
.common.rdtype = dns_rdatatype_ds
|
||||
};
|
||||
|
||||
ISC_LINK_INIT(&ds->common, link);
|
||||
|
||||
switch(anchortype) {
|
||||
case INIT_DNSKEY:
|
||||
case STATIC_DNSKEY:
|
||||
|
|
@ -802,7 +807,7 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
|
|||
if (rdata2 > 0xff) {
|
||||
CHECKM(ISC_R_RANGE, "key protocol");
|
||||
}
|
||||
if (rdata3> 0xff) {
|
||||
if (rdata3 > 0xff) {
|
||||
CHECKM(ISC_R_RANGE, "key algorithm");
|
||||
}
|
||||
|
||||
|
|
@ -810,30 +815,25 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
|
|||
keystruct.protocol = (uint8_t)rdata2;
|
||||
keystruct.algorithm = (uint8_t)rdata3;
|
||||
|
||||
if (!dst_algorithm_supported(keystruct.algorithm)) {
|
||||
CHECK(DST_R_UNSUPPORTEDALG);
|
||||
}
|
||||
|
||||
datastr = cfg_obj_asstring(cfg_tuple_get(key, "data"));
|
||||
CHECK(isc_base64_decodestring(datastr, &databuf));
|
||||
isc_buffer_usedregion(&databuf, &r);
|
||||
keystruct.datalen = r.length;
|
||||
keystruct.data = r.base;
|
||||
|
||||
CHECK(dns_rdata_fromstruct(NULL, keystruct.common.rdclass,
|
||||
CHECK(dns_rdata_fromstruct(&rdata, keystruct.common.rdclass,
|
||||
keystruct.common.rdtype,
|
||||
&keystruct, &rrdatabuf));
|
||||
CHECK(dst_key_fromdns(name, dns_rdataclass_in,
|
||||
&rrdatabuf, mctx, &dstkey));
|
||||
|
||||
*keyp = dstkey;
|
||||
CHECK(dns_ds_fromkeyrdata(name, &rdata, DNS_DSDIGEST_SHA256,
|
||||
digest, ds));
|
||||
break;
|
||||
|
||||
case INIT_DS:
|
||||
case STATIC_DS:
|
||||
ds = isc_mem_get(mctx, sizeof(*ds));
|
||||
ds->common.rdclass = dns_rdataclass_in;
|
||||
ds->common.rdtype = dns_rdatatype_ds;
|
||||
ds->mctx = NULL;
|
||||
|
||||
ISC_LINK_INIT(&ds->common, link);
|
||||
|
||||
if (rdata1 > 0xffff) {
|
||||
CHECKM(ISC_R_RANGE, "key tag");
|
||||
}
|
||||
|
|
@ -878,13 +878,10 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
|
|||
break;
|
||||
}
|
||||
|
||||
ds->mctx = mctx;
|
||||
ds->length = r.length;
|
||||
ds->digest = isc_mem_allocate(mctx, r.length);
|
||||
ds->digest = digest;
|
||||
memmove(ds->digest, r.base, r.length);
|
||||
|
||||
*dsp = ds;
|
||||
ds = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -895,15 +892,6 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
|
|||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
if (dstkey != NULL) {
|
||||
dst_key_free(&dstkey);
|
||||
}
|
||||
|
||||
if (ds != NULL) {
|
||||
dns_rdata_freestruct(ds);
|
||||
isc_mem_put(mctx, ds, sizeof(*ds));
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
|
@ -921,46 +909,30 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
|
|||
static isc_result_t
|
||||
process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
|
||||
const dns_name_t *keyname_match, dns_resolver_t *resolver,
|
||||
bool managed, isc_mem_t *mctx)
|
||||
bool managed)
|
||||
{
|
||||
dns_fixedname_t fkeyname;
|
||||
dns_name_t *keyname = NULL;
|
||||
const char *namestr = NULL;
|
||||
dst_key_t *dstkey = NULL;
|
||||
dns_rdata_ds_t *ds = NULL;
|
||||
unsigned int keyalg;
|
||||
dns_rdata_ds_t ds;
|
||||
isc_result_t result;
|
||||
bool initializing = managed;
|
||||
unsigned char digest[ISC_MAX_MD_SIZE];
|
||||
isc_buffer_t b;
|
||||
|
||||
result = ta_fromconfig(key, &initializing, &dstkey, &ds,
|
||||
&namestr, mctx);
|
||||
result = ta_fromconfig(key, &initializing, &namestr, digest, &ds);
|
||||
|
||||
switch (result) {
|
||||
case ISC_R_SUCCESS:
|
||||
/*
|
||||
* Trust anchor was parsed correctly. If dstkey is
|
||||
* not NULL, then it was a key anchor, its algorithm
|
||||
* is supported by the crypto library, and it is not
|
||||
* revoked. If dstkey is NULL, then it was a DS
|
||||
* trust anchor instead.
|
||||
* Trust anchor was parsed correctly.
|
||||
*/
|
||||
if (dstkey != NULL) {
|
||||
keyname = dst_key_name(dstkey);
|
||||
keyalg = dst_key_alg(dstkey);
|
||||
} else {
|
||||
isc_buffer_t b;
|
||||
|
||||
INSIST(ds != NULL);
|
||||
|
||||
isc_buffer_constinit(&b, namestr, strlen(namestr));
|
||||
isc_buffer_add(&b, strlen(namestr));
|
||||
keyname = dns_fixedname_initname(&fkeyname);
|
||||
result = dns_name_fromtext(keyname, &b,
|
||||
dns_rootname, 0, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
keyalg = ds->algorithm;
|
||||
isc_buffer_constinit(&b, namestr, strlen(namestr));
|
||||
isc_buffer_add(&b, strlen(namestr));
|
||||
keyname = dns_fixedname_initname(&fkeyname);
|
||||
result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
break;
|
||||
case DST_R_UNSUPPORTEDALG:
|
||||
|
|
@ -1011,7 +983,8 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
|
|||
* its owner name. If it does not, do not load the key and log a
|
||||
* warning, but do not prevent further keys from being processed.
|
||||
*/
|
||||
if (!dns_resolver_algorithm_supported(resolver, keyname, keyalg)) {
|
||||
if (!dns_resolver_algorithm_supported(resolver, keyname, ds.algorithm))
|
||||
{
|
||||
cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING,
|
||||
"ignoring %s for '%s': algorithm is disabled",
|
||||
initializing ? "initial-key" : "static-key",
|
||||
|
|
@ -1026,29 +999,10 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
|
|||
* managed, so we use 'initializing' twice here, for both the
|
||||
* 'managed' and 'initializing' arguments to dns_keytable_add().
|
||||
*/
|
||||
result = dns_keytable_add(secroots, initializing,
|
||||
initializing, keyname,
|
||||
dstkey != NULL ? &dstkey : NULL,
|
||||
ds);
|
||||
result = dns_keytable_add(secroots, initializing, initializing,
|
||||
keyname, &ds);
|
||||
|
||||
done:
|
||||
/*
|
||||
* Ensure 'dstkey' does not leak. Note that if dns_keytable_add()
|
||||
* succeeds, ownership of the key structure is transferred to the key
|
||||
* table, i.e. 'dstkey' is set to NULL.
|
||||
*/
|
||||
if (dstkey != NULL) {
|
||||
dst_key_free(&dstkey);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free 'ds'.
|
||||
*/
|
||||
if (ds != NULL) {
|
||||
dns_rdata_freestruct(ds);
|
||||
isc_mem_put(mctx, ds, sizeof(*ds));
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
|
@ -1059,7 +1013,7 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
|
|||
*/
|
||||
static isc_result_t
|
||||
load_view_keys(const cfg_obj_t *keys, dns_view_t *view, bool managed,
|
||||
const dns_name_t *keyname, isc_mem_t *mctx)
|
||||
const dns_name_t *keyname)
|
||||
{
|
||||
const cfg_listelt_t *elt, *elt2;
|
||||
const cfg_obj_t *keylist;
|
||||
|
|
@ -1078,9 +1032,8 @@ load_view_keys(const cfg_obj_t *keys, dns_view_t *view, bool managed,
|
|||
elt2 != NULL;
|
||||
elt2 = cfg_list_next(elt2))
|
||||
{
|
||||
CHECK(process_key(cfg_listelt_value(elt2),
|
||||
secroots, keyname, view->resolver,
|
||||
managed, mctx));
|
||||
CHECK(process_key(cfg_listelt_value(elt2), secroots,
|
||||
keyname, view->resolver, managed));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1238,7 +1191,7 @@ configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig,
|
|||
|
||||
if (builtin_keys != NULL) {
|
||||
CHECK(load_view_keys(builtin_keys, view, true,
|
||||
dns_rootname, mctx));
|
||||
dns_rootname));
|
||||
}
|
||||
|
||||
if (!keyloaded(view, dns_rootname)) {
|
||||
|
|
@ -1251,17 +1204,13 @@ configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig,
|
|||
}
|
||||
|
||||
if (view->rdclass == dns_rdataclass_in) {
|
||||
CHECK(load_view_keys(view_keys, view, false, NULL, mctx));
|
||||
CHECK(load_view_keys(view_trust_anchors, view, true, NULL,
|
||||
mctx));
|
||||
CHECK(load_view_keys(view_managed_keys, view, true, NULL,
|
||||
mctx));
|
||||
CHECK(load_view_keys(view_keys, view, false, NULL));
|
||||
CHECK(load_view_keys(view_trust_anchors, view, true, NULL));
|
||||
CHECK(load_view_keys(view_managed_keys, view, true, NULL));
|
||||
|
||||
CHECK(load_view_keys(global_keys, view, false, NULL, mctx));
|
||||
CHECK(load_view_keys(global_trust_anchors, view, true,
|
||||
NULL, mctx));
|
||||
CHECK(load_view_keys(global_managed_keys, view, true,
|
||||
NULL, mctx));
|
||||
CHECK(load_view_keys(global_keys, view, false, NULL));
|
||||
CHECK(load_view_keys(global_trust_anchors, view, true, NULL));
|
||||
CHECK(load_view_keys(global_managed_keys, view, true, NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -3700,12 +3700,12 @@ status=$((status+ret))
|
|||
# DNSSEC tests related to unsupported, disabled and revoked trust anchors.
|
||||
#
|
||||
|
||||
# This nameserver (ns8) is loaded with a bunch of trust anchors. Some of them
|
||||
# are good (enabled.managed, enabled.trusted, secure.managed, secure.trusted),
|
||||
# and some of them are bad (disabled.managed, revoked.managed, unsupported.managed,
|
||||
# disabled.trusted, revoked.trusted, unsupported.trusted). Make sure that the bad
|
||||
# trust anchors are ignored. This is tested by looking for the corresponding
|
||||
# lines in the logfile.
|
||||
# This nameserver (ns8) is loaded with a bunch of trust anchors. Some of
|
||||
# them are good (enabled.managed, enabled.trusted, secure.managed,
|
||||
# secure.trusted), and some of them are bad (disabled.managed,
|
||||
# revoked.managed, unsupported.managed, disabled.trusted, revoked.trusted,
|
||||
# unsupported.trusted). Make sure that the bad trust anchors are ignored.
|
||||
# This is tested by looking for the corresponding lines in the logfile.
|
||||
echo_i "checking that keys with unsupported algorithms and disabled algorithms are ignored ($n)"
|
||||
ret=0
|
||||
grep -q "ignoring static-key for 'disabled\.trusted\.': algorithm is disabled" ns8/named.run || ret=1
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <isc/app.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/md.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/mutex.h>
|
||||
#include <isc/portset.h>
|
||||
|
|
@ -1498,6 +1499,7 @@ dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
|
|||
dns_keytable_t *secroots = NULL;
|
||||
dns_name_t *name = NULL;
|
||||
char dsbuf[DNS_DS_BUFFERSIZE];
|
||||
unsigned char digest[ISC_MAX_MD_SIZE];
|
||||
dns_rdata_ds_t ds;
|
||||
dns_decompress_t dctx;
|
||||
dns_rdata_t rdata;
|
||||
|
|
@ -1515,33 +1517,28 @@ dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
|
|||
|
||||
DE_CONST(keyname, name);
|
||||
|
||||
switch (rdtype) {
|
||||
case dns_rdatatype_dnskey:
|
||||
result = dst_key_fromdns(keyname, rdclass, databuf,
|
||||
client->mctx, &dstkey);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
CHECK(dns_keytable_add(secroots, false, false,
|
||||
name, &dstkey, NULL));
|
||||
break;
|
||||
case dns_rdatatype_ds:
|
||||
isc_buffer_init(&b, dsbuf, sizeof(dsbuf));
|
||||
dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
|
||||
dns_rdata_init(&rdata);
|
||||
isc_buffer_setactive(databuf, isc_buffer_usedlength(databuf));
|
||||
CHECK(dns_rdata_fromwire(&rdata, rdclass, rdtype,
|
||||
databuf, &dctx, 0, &b));
|
||||
dns_decompress_invalidate(&dctx);
|
||||
CHECK(dns_rdata_tostruct(&rdata, &ds, NULL));
|
||||
CHECK(dns_keytable_add(secroots, false, false,
|
||||
name, NULL, &ds));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (rdtype != dns_rdatatype_dnskey && rdtype != dns_rdatatype_ds) {
|
||||
result = ISC_R_NOTIMPLEMENTED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
isc_buffer_init(&b, dsbuf, sizeof(dsbuf));
|
||||
dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
|
||||
dns_rdata_init(&rdata);
|
||||
isc_buffer_setactive(databuf, isc_buffer_usedlength(databuf));
|
||||
CHECK(dns_rdata_fromwire(&rdata, rdclass, rdtype,
|
||||
databuf, &dctx, 0, &b));
|
||||
dns_decompress_invalidate(&dctx);
|
||||
|
||||
if (rdtype == dns_rdatatype_ds) {
|
||||
CHECK(dns_rdata_tostruct(&rdata, &ds, NULL));
|
||||
} else {
|
||||
CHECK(dns_ds_fromkeyrdata(name, &rdata, DNS_DSDIGEST_SHA256,
|
||||
digest, &ds));
|
||||
}
|
||||
|
||||
CHECK(dns_keytable_add(secroots, false, false, name, &ds));
|
||||
|
||||
cleanup:
|
||||
if (dstkey != NULL) {
|
||||
dst_key_free(&dstkey);
|
||||
|
|
|
|||
72
lib/dns/ds.c
72
lib/dns/ds.c
|
|
@ -29,20 +29,17 @@
|
|||
#include <dst/dst.h>
|
||||
|
||||
isc_result_t
|
||||
dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
|
||||
dns_dsdigest_t digest_type, unsigned char *buffer,
|
||||
dns_rdata_t *rdata)
|
||||
dns_ds_fromkeyrdata(dns_name_t *owner, dns_rdata_t *key,
|
||||
dns_dsdigest_t digest_type, unsigned char *digest,
|
||||
dns_rdata_ds_t *dsrdata)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name;
|
||||
unsigned char digest[ISC_MAX_MD_SIZE];
|
||||
unsigned int digestlen;
|
||||
isc_region_t r;
|
||||
isc_buffer_t b;
|
||||
dns_rdata_ds_t ds;
|
||||
isc_md_t *md;
|
||||
isc_md_type_t md_type = 0;
|
||||
isc_result_t ret;
|
||||
|
||||
REQUIRE(key != NULL);
|
||||
REQUIRE(key->type == dns_rdatatype_dnskey ||
|
||||
|
|
@ -73,51 +70,68 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
|
|||
name = dns_fixedname_initname(&fname);
|
||||
(void)dns_name_downcase(owner, name, NULL);
|
||||
|
||||
memset(buffer, 0, DNS_DS_BUFFERSIZE);
|
||||
isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE);
|
||||
|
||||
md = isc_md_new();
|
||||
if (md == NULL) {
|
||||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
|
||||
ret = isc_md_init(md, md_type);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
result = isc_md_init(md, md_type);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
dns_name_toregion(name, &r);
|
||||
|
||||
ret = isc_md_update(md, r.base, r.length);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
result = isc_md_update(md, r.base, r.length);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
dns_rdata_toregion(key, &r);
|
||||
INSIST(r.length >= 4);
|
||||
|
||||
ret = isc_md_update(md, r.base, r.length);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
result = isc_md_update(md, r.base, r.length);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = isc_md_final(md, digest, &digestlen);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
result = isc_md_final(md, digest, &digestlen);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
ds.mctx = NULL;
|
||||
ds.common.rdclass = key->rdclass;
|
||||
ds.common.rdtype = dns_rdatatype_ds;
|
||||
ds.algorithm = r.base[3];
|
||||
ds.key_tag = dst_region_computeid(&r);
|
||||
ds.digest_type = digest_type;
|
||||
ds.digest = digest;
|
||||
ds.length = digestlen;
|
||||
dsrdata->mctx = NULL;
|
||||
dsrdata->common.rdclass = key->rdclass;
|
||||
dsrdata->common.rdtype = dns_rdatatype_ds;
|
||||
dsrdata->algorithm = r.base[3];
|
||||
dsrdata->key_tag = dst_region_computeid(&r);
|
||||
dsrdata->digest_type = digest_type;
|
||||
dsrdata->digest = digest;
|
||||
dsrdata->length = digestlen;
|
||||
|
||||
ret = dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds,
|
||||
&ds, &b);
|
||||
end:
|
||||
isc_md_free(md);
|
||||
return (ret);
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
|
||||
dns_dsdigest_t digest_type, unsigned char *buffer,
|
||||
dns_rdata_t *rdata)
|
||||
{
|
||||
isc_result_t result;
|
||||
unsigned char digest[ISC_MAX_MD_SIZE];
|
||||
dns_rdata_ds_t ds;
|
||||
isc_buffer_t b;
|
||||
|
||||
result = dns_ds_fromkeyrdata(owner, key, digest_type, digest, &ds);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
memset(buffer, 0, DNS_DS_BUFFERSIZE);
|
||||
isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE);
|
||||
result = dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds,
|
||||
&ds, &b);
|
||||
return (result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <isc/lang.h>
|
||||
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
#define DNS_DSDIGEST_SHA1 (1)
|
||||
|
|
@ -29,16 +30,30 @@
|
|||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
isc_result_t
|
||||
dns_ds_fromkeyrdata(dns_name_t *owner, dns_rdata_t *key,
|
||||
dns_dsdigest_t digest_type, unsigned char *digest,
|
||||
dns_rdata_ds_t *dsrdata);
|
||||
/*%<
|
||||
* Build a DS rdata structure from a key.
|
||||
*
|
||||
* Requires:
|
||||
*\li key Points to a valid DNSKEY or CDNSKEY record.
|
||||
*\li buffer Points to a buffer of at least
|
||||
* #ISC_MAX_MD_SIZE bytes.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
|
||||
dns_dsdigest_t digest_type, unsigned char *buffer,
|
||||
dns_rdata_t *rdata);
|
||||
/*%<
|
||||
* Build the rdata of a DS record.
|
||||
* Similar to dns_ds_fromkeyrdata(), but copies the DS into a
|
||||
* dns_rdata object.
|
||||
*
|
||||
* Requires:
|
||||
*\li key Points to a valid DNSKEY or CDNSKEY record.
|
||||
*\li buffer Points to a temporary buffer of at least
|
||||
*\li buffer Points to a buffer of at least
|
||||
* #DNS_DS_BUFFERSIZE bytes.
|
||||
*\li rdata Points to an initialized dns_rdata_t.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -106,13 +106,11 @@ dns_keytable_detach(dns_keytable_t **keytablep);
|
|||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_keytable_add(dns_keytable_t *keytable,
|
||||
bool managed, bool initial,
|
||||
dns_name_t *name, dst_key_t **keyp, dns_rdata_ds_t *ds);
|
||||
dns_keytable_add(dns_keytable_t *keytable, bool managed, bool initial,
|
||||
dns_name_t *name, dns_rdata_ds_t *ds);
|
||||
/*%<
|
||||
* Add a key to 'keytable'. The keynode associated with 'name'
|
||||
* is updated with either the key referenced in '*keyp'
|
||||
* or with the DS specified in 'ds'.
|
||||
* is updated with the DS specified in 'ds'.
|
||||
*
|
||||
* The value of keynode->managed is set to 'managed', and the
|
||||
* value of keynode->initial is set to 'initial'. (Note: 'initial'
|
||||
|
|
@ -123,28 +121,15 @@ dns_keytable_add(dns_keytable_t *keytable,
|
|||
*
|
||||
* Notes:
|
||||
*
|
||||
*\li Ownership of *keyp is transferred to the keytable.
|
||||
*\li If 'keyp' is not NULL and DS-style keys already exist
|
||||
* in the table for this name, they are freed before adding
|
||||
* the new key.
|
||||
*\li If 'ds' is not NULL and key-style keys already exist
|
||||
* in the table for this name, return ISC_R_EXISTS. DS keys
|
||||
* can be updated to key-style, but not vice versa.
|
||||
*\li If the key already exists in the table, ISC_R_EXISTS is
|
||||
* returned and the new key is freed.
|
||||
*\li If the key already exists in the table, adding it again
|
||||
* has no effect and ISC_R_SUCCESS is returned.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'keytable' points to a valid keytable.
|
||||
*
|
||||
*\li 'ds' is not NULL.
|
||||
*\li if 'initial' is true then 'managed' must also be true.
|
||||
*
|
||||
*\li keyp != NULL && *keyp is a valid dst_key_t *.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li On success, *keyp == NULL
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li ISC_R_SUCCESS
|
||||
|
|
|
|||
|
|
@ -364,14 +364,12 @@ insert(dns_keytable_t *keytable, bool managed, bool initial,
|
|||
}
|
||||
|
||||
isc_result_t
|
||||
dns_keytable_add(dns_keytable_t *keytable,
|
||||
bool managed, bool initial,
|
||||
dns_name_t *name, dst_key_t **keyp, dns_rdata_ds_t *ds)
|
||||
dns_keytable_add(dns_keytable_t *keytable, bool managed, bool initial,
|
||||
dns_name_t *name, dns_rdata_ds_t *ds)
|
||||
{
|
||||
REQUIRE(keyp == NULL || *keyp != NULL);
|
||||
REQUIRE(keyp != NULL || ds != NULL);
|
||||
REQUIRE(ds != NULL);
|
||||
REQUIRE(!initial || managed);
|
||||
return (insert(keytable, managed, initial, name, keyp, ds));
|
||||
return (insert(keytable, managed, initial, name, NULL, ds));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
|
|
|||
|
|
@ -27,11 +27,12 @@
|
|||
|
||||
#include <isc/base64.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/md.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/name.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/keytable.h>
|
||||
#include <dns/name.h>
|
||||
#include <dns/nta.h>
|
||||
#include <dns/rdataclass.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
|
|
@ -129,44 +130,48 @@ create_keystruct(uint16_t flags, uint8_t proto, uint8_t alg,
|
|||
}
|
||||
|
||||
static void
|
||||
create_key(uint16_t flags, uint8_t proto, uint8_t alg,
|
||||
const char *keynamestr, const char *keystr, dst_key_t **target)
|
||||
create_dsstruct(dns_name_t *name, uint16_t flags,
|
||||
uint8_t proto, uint8_t alg, const char *keystr,
|
||||
unsigned char *digest, dns_rdata_ds_t *dsstruct)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_rdata_dnskey_t keystruct;
|
||||
unsigned char rrdata[4096];
|
||||
isc_buffer_t rrdatabuf;
|
||||
const dns_rdataclass_t rdclass = dns_rdataclass_in;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_dnskey_t dnskey;
|
||||
|
||||
/*
|
||||
* Populate DNSKEY rdata structure.
|
||||
*/
|
||||
create_keystruct(flags, proto, alg, keystr, &keystruct);
|
||||
create_keystruct(flags, proto, alg, keystr, &dnskey);
|
||||
|
||||
/*
|
||||
* Convert to wire format.
|
||||
*/
|
||||
isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
|
||||
result = dns_rdata_fromstruct(NULL, keystruct.common.rdclass,
|
||||
keystruct.common.rdtype,
|
||||
&keystruct, &rrdatabuf),
|
||||
result = dns_rdata_fromstruct(&rdata, dnskey.common.rdclass,
|
||||
dnskey.common.rdtype,
|
||||
&dnskey, &rrdatabuf);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Convert wire format to DST key.
|
||||
* Build DS rdata struct.
|
||||
*/
|
||||
result = dst_key_fromdns(str2name(keynamestr), rdclass,
|
||||
&rrdatabuf, dt_mctx, target),
|
||||
result = dns_ds_fromkeyrdata(name, &rdata, DNS_DSDIGEST_SHA256,
|
||||
digest, dsstruct);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
dns_rdata_freestruct(&keystruct);
|
||||
dns_rdata_freestruct(&dnskey);
|
||||
}
|
||||
|
||||
/* Common setup: create a keytable and ntatable to test with a few keys */
|
||||
static void
|
||||
create_tables() {
|
||||
isc_result_t result;
|
||||
dst_key_t *key = NULL;
|
||||
unsigned char digest[ISC_MAX_MD_SIZE];
|
||||
dns_rdata_ds_t ds;
|
||||
dns_fixedname_t fn;
|
||||
dns_name_t *keyname = dns_fixedname_name(&fn);
|
||||
isc_stdtime_t now;
|
||||
|
||||
result = dns_test_makeview("view", &view);
|
||||
|
|
@ -178,15 +183,15 @@ create_tables() {
|
|||
&ntatable), ISC_R_SUCCESS);
|
||||
|
||||
/* Add a normal key */
|
||||
create_key(257, 3, 5, "example.com", keystr1, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
dns_test_namefromstring("example.com", &fn);
|
||||
create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds),
|
||||
ISC_R_SUCCESS);
|
||||
|
||||
/* Add an initializing managed key */
|
||||
create_key(257, 3, 5, "managed.com", keystr1, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, true, true,
|
||||
dst_key_name(key), &key, NULL),
|
||||
dns_test_namefromstring("managed.com", &fn);
|
||||
create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds),
|
||||
ISC_R_SUCCESS);
|
||||
|
||||
/* Add a null key */
|
||||
|
|
@ -217,9 +222,12 @@ destroy_tables() {
|
|||
/* add keys to the keytable */
|
||||
static void
|
||||
add_test(void **state) {
|
||||
dst_key_t *key = NULL;
|
||||
dns_keynode_t *keynode = NULL;
|
||||
dns_keynode_t *null_keynode = NULL;
|
||||
unsigned char digest[ISC_MAX_MD_SIZE];
|
||||
dns_rdata_ds_t ds;
|
||||
dns_fixedname_t fn;
|
||||
dns_name_t *keyname = dns_fixedname_name(&fn);
|
||||
|
||||
UNUSED(state);
|
||||
|
||||
|
|
@ -236,9 +244,9 @@ add_test(void **state) {
|
|||
* Try to add the same key. This should have no effect but
|
||||
* report success.
|
||||
*/
|
||||
create_key(257, 3, 5, "example.com", keystr1, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
dns_test_namefromstring("example.com", &fn);
|
||||
create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds),
|
||||
ISC_R_SUCCESS);
|
||||
dns_keytable_detachkeynode(keytable, &keynode);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("example.com"),
|
||||
|
|
@ -247,9 +255,8 @@ add_test(void **state) {
|
|||
|
||||
/* Add another key (different keydata) */
|
||||
dns_keytable_detachkeynode(keytable, &keynode);
|
||||
create_key(257, 3, 5, "example.com", keystr2, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("example.com"),
|
||||
&keynode),
|
||||
|
|
@ -273,9 +280,9 @@ add_test(void **state) {
|
|||
* Add a different managed key for managed.com, marking it as an
|
||||
* initializing key.
|
||||
*/
|
||||
create_key(257, 3, 5, "managed.com", keystr2, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, true, true,
|
||||
dst_key_name(key), &key, NULL),
|
||||
dns_test_namefromstring("managed.com", &fn);
|
||||
create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
|
||||
assert_int_equal(dns_keytable_add(keytable, true, true, keyname, &ds),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("managed.com"),
|
||||
&keynode),
|
||||
|
|
@ -289,9 +296,7 @@ add_test(void **state) {
|
|||
* to a non-initializing key and make sure there are still two key
|
||||
* nodes for managed.com, both containing non-initializing keys.
|
||||
*/
|
||||
create_key(257, 3, 5, "managed.com", keystr2, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, true, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
assert_int_equal(dns_keytable_add(keytable, true, false, keyname, &ds),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("managed.com"),
|
||||
&keynode),
|
||||
|
|
@ -303,9 +308,9 @@ add_test(void **state) {
|
|||
* Add a managed key at a new node, two.com, marking it as an
|
||||
* initializing key.
|
||||
*/
|
||||
create_key(257, 3, 5, "two.com", keystr1, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, true, true,
|
||||
dst_key_name(key), &key, NULL),
|
||||
dns_test_namefromstring("two.com", &fn);
|
||||
create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
|
||||
assert_int_equal(dns_keytable_add(keytable, true, true, keyname, &ds),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("two.com"),
|
||||
&keynode),
|
||||
|
|
@ -317,9 +322,8 @@ add_test(void **state) {
|
|||
* Add a different managed key for two.com, marking it as a
|
||||
* non-initializing key.
|
||||
*/
|
||||
create_key(257, 3, 5, "two.com", keystr2, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, true, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
|
||||
assert_int_equal(dns_keytable_add(keytable, true, false, keyname, &ds),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("two.com"),
|
||||
&keynode),
|
||||
|
|
@ -333,9 +337,8 @@ add_test(void **state) {
|
|||
* to a non-initializing key and make sure there are still two key
|
||||
* nodes for two.com, both containing non-initializing keys.
|
||||
*/
|
||||
create_key(257, 3, 5, "two.com", keystr1, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, true, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
|
||||
assert_int_equal(dns_keytable_add(keytable, true, false, keyname, &ds),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("two.com"),
|
||||
&keynode),
|
||||
|
|
@ -350,9 +353,9 @@ add_test(void **state) {
|
|||
assert_int_equal(dns_keytable_find(keytable, str2name("null.example"),
|
||||
&null_keynode),
|
||||
ISC_R_SUCCESS);
|
||||
create_key(257, 3, 5, "null.example", keystr2, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
dns_test_namefromstring("null.example", &fn);
|
||||
create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("null.example"),
|
||||
&keynode),
|
||||
|
|
@ -595,8 +598,11 @@ dump_test(void **state) {
|
|||
static void
|
||||
nta_test(void **state) {
|
||||
isc_result_t result;
|
||||
dst_key_t *key = NULL;
|
||||
bool issecure, covered;
|
||||
dns_fixedname_t fn;
|
||||
dns_name_t *keyname = dns_fixedname_name(&fn);
|
||||
unsigned char digest[ISC_MAX_MD_SIZE];
|
||||
dns_rdata_ds_t ds;
|
||||
dns_view_t *myview = NULL;
|
||||
isc_stdtime_t now;
|
||||
|
||||
|
|
@ -618,14 +624,13 @@ nta_test(void **state) {
|
|||
result = dns_view_getntatable(myview, &ntatable);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
create_key(257, 3, 5, "example", keystr1, &key);
|
||||
result = dns_keytable_add(keytable, false, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
dns_test_namefromstring("example", &fn);
|
||||
create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
|
||||
result = dns_keytable_add(keytable, false, false, keyname, &ds),
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_stdtime_get(&now);
|
||||
result = dns_ntatable_add(ntatable,
|
||||
str2name("insecure.example"),
|
||||
result = dns_ntatable_add(ntatable, str2name("insecure.example"),
|
||||
false, now, 1);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
|
|
|
|||
|
|
@ -336,6 +336,7 @@ dns_dnssecsignstats_create
|
|||
dns_dnssecsignstats_dump
|
||||
dns_dnssecsignstats_increment
|
||||
dns_ds_buildrdata
|
||||
dns_ds_fromkeyrdata
|
||||
dns_dsdigest_format
|
||||
dns_dsdigest_fromtext
|
||||
dns_dsdigest_totext
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <isc/atomic.h>
|
||||
#include <isc/file.h>
|
||||
#include <isc/hex.h>
|
||||
#include <isc/md.h>
|
||||
#include <isc/mutex.h>
|
||||
#include <isc/pool.h>
|
||||
#include <isc/print.h>
|
||||
|
|
@ -3942,35 +3943,34 @@ compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
|
|||
*/
|
||||
static void
|
||||
trust_key(dns_zone_t *zone, dns_name_t *keyname,
|
||||
dns_rdata_dnskey_t *dnskey, bool initial,
|
||||
isc_mem_t *mctx)
|
||||
dns_rdata_dnskey_t *dnskey, bool initial)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
unsigned char data[4096];
|
||||
unsigned char data[4096], digest[ISC_MAX_MD_SIZE];
|
||||
isc_buffer_t buffer;
|
||||
dns_keytable_t *sr = NULL;
|
||||
dst_key_t *dstkey = NULL;
|
||||
dns_rdata_ds_t ds;
|
||||
|
||||
/* Convert dnskey to DST key. */
|
||||
result = dns_view_getsecroots(zone->view, &sr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Build DS record for key. */
|
||||
isc_buffer_init(&buffer, data, sizeof(data));
|
||||
dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
|
||||
dns_rdatatype_dnskey, dnskey, &buffer);
|
||||
CHECK(dns_ds_fromkeyrdata(keyname, &rdata, DNS_DSDIGEST_SHA256,
|
||||
digest, &ds));
|
||||
CHECK(dns_keytable_add(sr, true, initial, keyname, &ds));
|
||||
|
||||
result = dns_view_getsecroots(zone->view, &sr);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto failure;
|
||||
|
||||
CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
|
||||
CHECK(dns_keytable_add(sr, true, initial,
|
||||
dst_key_name(dstkey), &dstkey, NULL));
|
||||
dns_keytable_detach(&sr);
|
||||
|
||||
failure:
|
||||
if (dstkey != NULL)
|
||||
dst_key_free(&dstkey);
|
||||
if (sr != NULL)
|
||||
if (sr != NULL) {
|
||||
dns_keytable_detach(&sr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4000,7 +4000,6 @@ load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
|
|||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_keydata_t keydata;
|
||||
dns_rdata_dnskey_t dnskey;
|
||||
isc_mem_t *mctx = zone->mctx;
|
||||
int trusted = 0, revoked = 0, pending = 0;
|
||||
isc_stdtime_t now;
|
||||
dns_keytable_t *sr = NULL;
|
||||
|
|
@ -4051,7 +4050,7 @@ load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
|
|||
|
||||
/* Add to keytables. */
|
||||
trusted++;
|
||||
trust_key(zone, name, &dnskey, (keydata.addhd == 0), mctx);
|
||||
trust_key(zone, name, &dnskey, (keydata.addhd == 0));
|
||||
}
|
||||
|
||||
if (trusted == 0 && pending != 0) {
|
||||
|
|
@ -10271,7 +10270,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
/* Trust this key. */
|
||||
result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
trust_key(zone, keyname, &dnskey, false, mctx);
|
||||
trust_key(zone, keyname, &dnskey, false);
|
||||
}
|
||||
|
||||
if (secure && !deletekey) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue