mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Merge branch '622-ds-anchor' into 'master'
support "initial-ds" in managed-keys Closes #622 See merge request isc-projects/bind9!1762
This commit is contained in:
commit
ac65f56774
62 changed files with 1954 additions and 802 deletions
9
CHANGES
9
CHANGES
|
|
@ -1,3 +1,12 @@
|
|||
5319. [func] Trust anchors can now be configured using DS
|
||||
format to represent a key digest, by using the
|
||||
new "initial-ds" or "static-ds" keywords in
|
||||
the "dnssec-keys" statement.
|
||||
|
||||
Note: DNSKEY-format and DS-format trust anchors
|
||||
cannot both be used for the same domain name.
|
||||
[GL #622]
|
||||
|
||||
5318. [cleanup] The DNSSEC validation code has been refactored
|
||||
for clarity and to reduce code duplication.
|
||||
[GL #622]
|
||||
|
|
|
|||
156
bin/delv/delv.c
156
bin/delv/delv.c
|
|
@ -33,8 +33,10 @@
|
|||
#include <isc/app.h>
|
||||
#include <isc/base64.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/hex.h>
|
||||
#include <isc/lib.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/md.h>
|
||||
#include <isc/mem.h>
|
||||
#ifdef WIN32
|
||||
#include <isc/ntpaths.h>
|
||||
|
|
@ -608,11 +610,12 @@ convert_name(dns_fixedname_t *fn, dns_name_t **name, const char *text) {
|
|||
|
||||
static isc_result_t
|
||||
key_fromconfig(const cfg_obj_t *key, dns_client_t *client) {
|
||||
dns_rdata_dnskey_t keystruct;
|
||||
uint32_t flags, proto, alg;
|
||||
const char *keystr, *keynamestr;
|
||||
unsigned char keydata[4096];
|
||||
isc_buffer_t keydatabuf;
|
||||
dns_rdata_dnskey_t dnskey;
|
||||
dns_rdata_ds_t ds;
|
||||
uint32_t n1, n2, n3;
|
||||
const char *datastr = NULL, *keynamestr = NULL, *atstr = NULL;
|
||||
unsigned char data[4096];
|
||||
isc_buffer_t databuf;
|
||||
unsigned char rrdata[4096];
|
||||
isc_buffer_t rrdatabuf;
|
||||
isc_region_t r;
|
||||
|
|
@ -620,6 +623,13 @@ key_fromconfig(const cfg_obj_t *key, dns_client_t *client) {
|
|||
dns_name_t *keyname;
|
||||
isc_result_t result;
|
||||
bool match_root = false;
|
||||
enum {
|
||||
INITIAL_KEY,
|
||||
STATIC_KEY,
|
||||
INITIAL_DS,
|
||||
STATIC_DS,
|
||||
TRUSTED
|
||||
} anchortype;
|
||||
|
||||
keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name"));
|
||||
CHECK(convert_name(&fkeyname, &keyname, keynamestr));
|
||||
|
|
@ -642,46 +652,118 @@ key_fromconfig(const cfg_obj_t *key, dns_client_t *client) {
|
|||
|
||||
delv_log(ISC_LOG_DEBUG(3), "adding trust anchor %s", trust_anchor);
|
||||
|
||||
flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags"));
|
||||
proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol"));
|
||||
alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm"));
|
||||
/* if DNSKEY, flags; if DS, key tag */
|
||||
n1 = cfg_obj_asuint32(cfg_tuple_get(key, "n1"));
|
||||
|
||||
keystruct.common.rdclass = dns_rdataclass_in;
|
||||
keystruct.common.rdtype = dns_rdatatype_dnskey;
|
||||
/*
|
||||
* The key data in keystruct is not dynamically allocated.
|
||||
*/
|
||||
keystruct.mctx = NULL;
|
||||
/* if DNSKEY, protocol; if DS, algorithm */
|
||||
n2 = cfg_obj_asuint32(cfg_tuple_get(key, "n2"));
|
||||
|
||||
ISC_LINK_INIT(&keystruct.common, link);
|
||||
/* if DNSKEY, algorithm; if DS, digest type */
|
||||
n3 = cfg_obj_asuint32(cfg_tuple_get(key, "n3"));
|
||||
|
||||
if (flags > 0xffff)
|
||||
CHECK(ISC_R_RANGE);
|
||||
if (proto > 0xff)
|
||||
CHECK(ISC_R_RANGE);
|
||||
if (alg > 0xff)
|
||||
CHECK(ISC_R_RANGE);
|
||||
/* What type of trust anchor is this? */
|
||||
atstr = cfg_obj_asstring(cfg_tuple_get(key, "anchortype"));
|
||||
if (strcasecmp(atstr, "static-key") == 0) {
|
||||
anchortype = STATIC_KEY;
|
||||
} else if (strcasecmp(atstr, "static-ds") == 0) {
|
||||
anchortype = STATIC_DS;
|
||||
} else if (strcasecmp(atstr, "initial-key") == 0) {
|
||||
anchortype = INITIAL_KEY;
|
||||
} else if (strcasecmp(atstr, "initial-ds") == 0) {
|
||||
anchortype = INITIAL_DS;
|
||||
} else {
|
||||
delv_log(ISC_LOG_ERROR,
|
||||
"key '%s': invalid initialization method '%s'",
|
||||
keynamestr, atstr);
|
||||
result = ISC_R_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
keystruct.flags = (uint16_t)flags;
|
||||
keystruct.protocol = (uint8_t)proto;
|
||||
keystruct.algorithm = (uint8_t)alg;
|
||||
|
||||
isc_buffer_init(&keydatabuf, keydata, sizeof(keydata));
|
||||
isc_buffer_init(&databuf, data, sizeof(data));
|
||||
isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
|
||||
|
||||
keystr = cfg_obj_asstring(cfg_tuple_get(key, "key"));
|
||||
CHECK(isc_base64_decodestring(keystr, &keydatabuf));
|
||||
isc_buffer_usedregion(&keydatabuf, &r);
|
||||
keystruct.datalen = r.length;
|
||||
keystruct.data = r.base;
|
||||
if (n1 > 0xffff) {
|
||||
CHECK(ISC_R_RANGE);
|
||||
}
|
||||
if (n2 > 0xff) {
|
||||
CHECK(ISC_R_RANGE);
|
||||
}
|
||||
if (n3 > 0xff) {
|
||||
CHECK(ISC_R_RANGE);
|
||||
}
|
||||
|
||||
CHECK(dns_rdata_fromstruct(NULL,
|
||||
keystruct.common.rdclass,
|
||||
keystruct.common.rdtype,
|
||||
&keystruct, &rrdatabuf));
|
||||
switch (anchortype) {
|
||||
case STATIC_KEY:
|
||||
case INITIAL_KEY:
|
||||
case TRUSTED:
|
||||
dnskey.common.rdclass = dns_rdataclass_in;
|
||||
dnskey.common.rdtype = dns_rdatatype_dnskey;
|
||||
dnskey.mctx = NULL;
|
||||
|
||||
ISC_LINK_INIT(&dnskey.common, link);
|
||||
|
||||
dnskey.flags = (uint16_t)n1;
|
||||
dnskey.protocol = (uint8_t)n2;
|
||||
dnskey.algorithm = (uint8_t)n3;
|
||||
|
||||
datastr = cfg_obj_asstring(cfg_tuple_get(key, "data"));
|
||||
CHECK(isc_base64_decodestring(datastr, &databuf));
|
||||
isc_buffer_usedregion(&databuf, &r);
|
||||
dnskey.datalen = r.length;
|
||||
dnskey.data = r.base;
|
||||
|
||||
CHECK(dns_rdata_fromstruct(NULL, dnskey.common.rdclass,
|
||||
dnskey.common.rdtype,
|
||||
&dnskey, &rrdatabuf));
|
||||
CHECK(dns_client_addtrustedkey(client, dns_rdataclass_in,
|
||||
dns_rdatatype_dnskey,
|
||||
keyname, &rrdatabuf));
|
||||
break;
|
||||
case INITIAL_DS:
|
||||
case STATIC_DS:
|
||||
ds.common.rdclass = dns_rdataclass_in;
|
||||
ds.common.rdtype = dns_rdatatype_ds;
|
||||
ds.mctx = NULL;
|
||||
|
||||
ISC_LINK_INIT(&ds.common, link);
|
||||
|
||||
ds.key_tag = (uint16_t)n1;
|
||||
ds.algorithm = (uint8_t)n2;
|
||||
ds.digest_type = (uint8_t)n3;
|
||||
|
||||
datastr = cfg_obj_asstring(cfg_tuple_get(key, "data"));
|
||||
CHECK(isc_hex_decodestring(datastr, &databuf));
|
||||
isc_buffer_usedregion(&databuf, &r);
|
||||
|
||||
switch (ds.digest_type) {
|
||||
case DNS_DSDIGEST_SHA1:
|
||||
if (r.length != ISC_SHA1_DIGESTLENGTH) {
|
||||
CHECK(ISC_R_UNEXPECTEDEND);
|
||||
}
|
||||
break;
|
||||
case DNS_DSDIGEST_SHA256:
|
||||
if (r.length != ISC_SHA256_DIGESTLENGTH) {
|
||||
CHECK(ISC_R_UNEXPECTEDEND);
|
||||
}
|
||||
break;
|
||||
case DNS_DSDIGEST_SHA384:
|
||||
if (r.length != ISC_SHA384_DIGESTLENGTH) {
|
||||
CHECK(ISC_R_UNEXPECTEDEND);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ds.length = r.length;
|
||||
ds.digest = r.base;
|
||||
|
||||
CHECK(dns_rdata_fromstruct(NULL, ds.common.rdclass,
|
||||
ds.common.rdtype,
|
||||
&ds, &rrdatabuf));
|
||||
CHECK(dns_client_addtrustedkey(client, dns_rdataclass_in,
|
||||
dns_rdatatype_ds,
|
||||
keyname, &rrdatabuf));
|
||||
};
|
||||
|
||||
CHECK(dns_client_addtrustedkey(client, dns_rdataclass_in,
|
||||
keyname, &rrdatabuf));
|
||||
num_keys++;
|
||||
|
||||
cleanup:
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
<refentry xmlns:db="http://docbook.org/ns/docbook" version="5.0" xml:id="man.named.conf">
|
||||
<info>
|
||||
<date>2019-08-07</date>
|
||||
<date>2019-08-12</date>
|
||||
</info>
|
||||
<refentryinfo>
|
||||
<corpname>ISC</corpname>
|
||||
|
|
@ -113,7 +113,8 @@ dlz <replaceable>string</replaceable> {
|
|||
<refsection><info><title>DNSSEC-KEYS</title></info>
|
||||
<literallayout class="normal">
|
||||
dnssec-keys { <replaceable>string</replaceable> ( static-key |
|
||||
initial-key ) <replaceable>integer</replaceable> <replaceable>integer</replaceable> <replaceable>integer</replaceable>
|
||||
initial-key | static-ds | initial-ds )
|
||||
<replaceable>integer</replaceable> <replaceable>integer</replaceable> <replaceable>integer</replaceable>
|
||||
<replaceable>quoted_string</replaceable>; ... };
|
||||
</literallayout>
|
||||
</refsection>
|
||||
|
|
@ -158,9 +159,9 @@ logging {
|
|||
<para>Deprecated - see DNSSEC-KEYS.</para>
|
||||
<literallayout class="normal">
|
||||
managed-keys { <replaceable>string</replaceable> ( static-key
|
||||
| initial-key ) <replaceable>integer</replaceable>
|
||||
<replaceable>integer</replaceable> <replaceable>integer</replaceable>
|
||||
<replaceable>quoted_string</replaceable>; ... }; deprecated
|
||||
| initial-key | static-ds |
|
||||
initial-ds ) <replaceable>integer</replaceable> <replaceable>integer</replaceable>
|
||||
<replaceable>integer</replaceable> <replaceable>quoted_string</replaceable>; ... }; deprecated
|
||||
</literallayout>
|
||||
</refsection>
|
||||
|
||||
|
|
@ -607,8 +608,9 @@ view <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
|
|||
dnssec-accept-expired <replaceable>boolean</replaceable>;
|
||||
dnssec-dnskey-kskonly <replaceable>boolean</replaceable>;
|
||||
dnssec-keys { <replaceable>string</replaceable> ( static-key |
|
||||
initial-key ) <replaceable>integer</replaceable> <replaceable>integer</replaceable>
|
||||
<replaceable>integer</replaceable> <replaceable>quoted_string</replaceable>; ... };
|
||||
initial-key | static-ds | initial-ds
|
||||
) <replaceable>integer</replaceable> <replaceable>integer</replaceable> <replaceable>integer</replaceable>
|
||||
<replaceable>quoted_string</replaceable>; ... };
|
||||
dnssec-loadkeys-interval <replaceable>integer</replaceable>;
|
||||
dnssec-must-be-secure <replaceable>string</replaceable> <replaceable>boolean</replaceable>;
|
||||
dnssec-secure-to-insecure <replaceable>boolean</replaceable>;
|
||||
|
|
@ -646,6 +648,7 @@ view <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
|
|||
lmdb-mapsize <replaceable>sizeval</replaceable>;
|
||||
managed-keys { <replaceable>string</replaceable> (
|
||||
static-key | initial-key
|
||||
| static-ds | initial-ds
|
||||
) <replaceable>integer</replaceable> <replaceable>integer</replaceable>
|
||||
<replaceable>integer</replaceable>
|
||||
<replaceable>quoted_string</replaceable>; ... }; deprecated
|
||||
|
|
|
|||
|
|
@ -698,104 +698,190 @@ configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config,
|
|||
}
|
||||
|
||||
static isc_result_t
|
||||
dstkey_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **target,
|
||||
const char **keynamestrp, isc_mem_t *mctx)
|
||||
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)
|
||||
{
|
||||
dns_rdata_dnskey_t keystruct;
|
||||
uint32_t flags, proto, alg;
|
||||
const char *keystr, *keynamestr;
|
||||
unsigned char keydata[4096];
|
||||
isc_buffer_t keydatabuf;
|
||||
dns_rdata_ds_t *ds = NULL;
|
||||
uint32_t n1, n2, n3;
|
||||
const char *datastr = NULL, *namestr = NULL;
|
||||
unsigned char data[4096];
|
||||
isc_buffer_t databuf;
|
||||
unsigned char rrdata[4096];
|
||||
isc_buffer_t rrdatabuf;
|
||||
isc_region_t r;
|
||||
dns_fixedname_t fkeyname;
|
||||
dns_name_t *keyname;
|
||||
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,
|
||||
STATIC_DNSKEY,
|
||||
INIT_DS,
|
||||
STATIC_DS,
|
||||
TRUSTED
|
||||
} anchortype;
|
||||
|
||||
INSIST(target != NULL && *target == NULL);
|
||||
INSIST(keynamestrp != NULL && *keynamestrp == NULL);
|
||||
REQUIRE(keyp != NULL && *keyp == NULL);
|
||||
REQUIRE(dsp != NULL && *dsp == NULL);
|
||||
REQUIRE(namestrp != NULL && *namestrp == NULL);
|
||||
|
||||
flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags"));
|
||||
proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol"));
|
||||
alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm"));
|
||||
keyname = dns_fixedname_name(&fkeyname);
|
||||
keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name"));
|
||||
*keynamestrp = keynamestr;
|
||||
/* if DNSKEY, flags; if DS, key tag */
|
||||
n1 = cfg_obj_asuint32(cfg_tuple_get(key, "n1"));
|
||||
|
||||
/* if DNSKEY, protocol; if DS, algorithm */
|
||||
n2 = cfg_obj_asuint32(cfg_tuple_get(key, "n2"));
|
||||
|
||||
/* if DNSKEY, algorithm; if DS, digest type */
|
||||
n3 = cfg_obj_asuint32(cfg_tuple_get(key, "n3"));
|
||||
|
||||
namestr = cfg_obj_asstring(cfg_tuple_get(key, "name"));
|
||||
*namestrp = namestr;
|
||||
|
||||
name = dns_fixedname_initname(&fname);
|
||||
isc_buffer_constinit(&namebuf, namestr, strlen(namestr));
|
||||
isc_buffer_add(&namebuf, strlen(namestr));
|
||||
CHECK(dns_name_fromtext(name, &namebuf, dns_rootname, 0, NULL));
|
||||
|
||||
if (*initialp) {
|
||||
const char *initmethod;
|
||||
initmethod = cfg_obj_asstring(cfg_tuple_get(key, "init"));
|
||||
atstr = cfg_obj_asstring(cfg_tuple_get(key, "anchortype"));
|
||||
|
||||
if (strcasecmp(initmethod, "static-key") == 0) {
|
||||
if (strcasecmp(atstr, "static-key") == 0) {
|
||||
*initialp = false;
|
||||
} else if (strcasecmp(initmethod, "initial-key") != 0) {
|
||||
anchortype = STATIC_DNSKEY;
|
||||
} else if (strcasecmp(atstr, "static-ds") == 0) {
|
||||
*initialp = false;
|
||||
anchortype = STATIC_DS;
|
||||
} else if (strcasecmp(atstr, "initial-key") == 0) {
|
||||
anchortype = INIT_DNSKEY;
|
||||
} else if (strcasecmp(atstr, "initial-ds") == 0) {
|
||||
anchortype = INIT_DS;
|
||||
} else {
|
||||
cfg_obj_log(key, named_g_lctx, ISC_LOG_ERROR,
|
||||
"key '%s': "
|
||||
"invalid initialization method '%s'",
|
||||
keynamestr, initmethod);
|
||||
namestr, atstr);
|
||||
result = ISC_R_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
anchortype = TRUSTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function should never be reached for non-IN classes.
|
||||
*/
|
||||
keystruct.common.rdclass = dns_rdataclass_in;
|
||||
keystruct.common.rdtype = dns_rdatatype_dnskey;
|
||||
|
||||
/*
|
||||
* The key data in keystruct is not dynamically allocated.
|
||||
*/
|
||||
keystruct.mctx = NULL;
|
||||
|
||||
ISC_LINK_INIT(&keystruct.common, link);
|
||||
|
||||
if (flags > 0xffff)
|
||||
CHECKM(ISC_R_RANGE, "key flags");
|
||||
if (flags & DNS_KEYFLAG_REVOKE)
|
||||
CHECKM(DST_R_BADKEYTYPE, "key flags revoke bit set");
|
||||
if (proto > 0xff)
|
||||
CHECKM(ISC_R_RANGE, "key protocol");
|
||||
if (alg > 0xff)
|
||||
CHECKM(ISC_R_RANGE, "key algorithm");
|
||||
keystruct.flags = (uint16_t)flags;
|
||||
keystruct.protocol = (uint8_t)proto;
|
||||
keystruct.algorithm = (uint8_t)alg;
|
||||
|
||||
isc_buffer_init(&keydatabuf, keydata, sizeof(keydata));
|
||||
isc_buffer_init(&databuf, data, sizeof(data));
|
||||
isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
|
||||
|
||||
keystr = cfg_obj_asstring(cfg_tuple_get(key, "key"));
|
||||
CHECK(isc_base64_decodestring(keystr, &keydatabuf));
|
||||
isc_buffer_usedregion(&keydatabuf, &r);
|
||||
keystruct.datalen = r.length;
|
||||
keystruct.data = r.base;
|
||||
switch(anchortype) {
|
||||
case INIT_DNSKEY:
|
||||
case STATIC_DNSKEY:
|
||||
case TRUSTED:
|
||||
/*
|
||||
* This function should never be reached for view
|
||||
* class other than IN
|
||||
*/
|
||||
keystruct.common.rdclass = dns_rdataclass_in;
|
||||
keystruct.common.rdtype = dns_rdatatype_dnskey;
|
||||
|
||||
if ((keystruct.algorithm == DST_ALG_RSASHA1) &&
|
||||
r.length > 1 && r.base[0] == 1 && r.base[1] == 3)
|
||||
{
|
||||
cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING,
|
||||
"%s '%s' has a weak exponent",
|
||||
*initialp ? "initial-key" : "static-key",
|
||||
keynamestr);
|
||||
/*
|
||||
* The key data in keystruct is not dynamically allocated.
|
||||
*/
|
||||
keystruct.mctx = NULL;
|
||||
|
||||
ISC_LINK_INIT(&keystruct.common, link);
|
||||
|
||||
if (n1 > 0xffff) {
|
||||
CHECKM(ISC_R_RANGE, "key flags");
|
||||
}
|
||||
if (n1 & DNS_KEYFLAG_REVOKE) {
|
||||
CHECKM(DST_R_BADKEYTYPE, "key flags revoke bit set");
|
||||
}
|
||||
if (n2 > 0xff) {
|
||||
CHECKM(ISC_R_RANGE, "key protocol");
|
||||
}
|
||||
if (n3> 0xff) {
|
||||
CHECKM(ISC_R_RANGE, "key algorithm");
|
||||
}
|
||||
|
||||
keystruct.flags = (uint16_t)n1;
|
||||
keystruct.protocol = (uint8_t)n2;
|
||||
keystruct.algorithm = (uint8_t)n3;
|
||||
|
||||
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,
|
||||
keystruct.common.rdtype,
|
||||
&keystruct, &rrdatabuf));
|
||||
CHECK(dst_key_fromdns(name, dns_rdataclass_in,
|
||||
&rrdatabuf, mctx, &dstkey));
|
||||
|
||||
*keyp = dstkey;
|
||||
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 (n1 > 0xffff) {
|
||||
CHECKM(ISC_R_RANGE, "key tag");
|
||||
}
|
||||
if (n2 > 0xff) {
|
||||
CHECKM(ISC_R_RANGE, "key algorithm");
|
||||
}
|
||||
if (n3 > 0xff) {
|
||||
CHECKM(ISC_R_RANGE, "digest type");
|
||||
}
|
||||
|
||||
ds->key_tag = (uint16_t)n1;
|
||||
ds->algorithm = (uint8_t)n2;
|
||||
ds->digest_type = (uint8_t)n3;
|
||||
|
||||
datastr = cfg_obj_asstring(cfg_tuple_get(key, "data"));
|
||||
CHECK(isc_hex_decodestring(datastr, &databuf));
|
||||
isc_buffer_usedregion(&databuf, &r);
|
||||
|
||||
switch (ds->digest_type) {
|
||||
case DNS_DSDIGEST_SHA1:
|
||||
if (r.length != ISC_SHA1_DIGESTLENGTH) {
|
||||
CHECK(ISC_R_UNEXPECTEDEND);
|
||||
}
|
||||
break;
|
||||
case DNS_DSDIGEST_SHA256:
|
||||
if (r.length != ISC_SHA256_DIGESTLENGTH) {
|
||||
CHECK(ISC_R_UNEXPECTEDEND);
|
||||
}
|
||||
break;
|
||||
case DNS_DSDIGEST_SHA384:
|
||||
if (r.length != ISC_SHA384_DIGESTLENGTH) {
|
||||
CHECK(ISC_R_UNEXPECTEDEND);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ds->mctx = mctx;
|
||||
ds->length = r.length;
|
||||
ds->digest = isc_mem_allocate(mctx, r.length);
|
||||
memmove(ds->digest, r.base, r.length);
|
||||
|
||||
*dsp = ds;
|
||||
ds = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
INSIST(0);
|
||||
ISC_UNREACHABLE();
|
||||
}
|
||||
|
||||
CHECK(dns_rdata_fromstruct(NULL,
|
||||
keystruct.common.rdclass,
|
||||
keystruct.common.rdtype,
|
||||
&keystruct, &rrdatabuf));
|
||||
dns_fixedname_init(&fkeyname);
|
||||
isc_buffer_constinit(&namebuf, keynamestr, strlen(keynamestr));
|
||||
isc_buffer_add(&namebuf, strlen(keynamestr));
|
||||
CHECK(dns_name_fromtext(keyname, &namebuf, dns_rootname, 0, NULL));
|
||||
CHECK(dst_key_fromdns(keyname, dns_rdataclass_in, &rrdatabuf,
|
||||
mctx, &dstkey));
|
||||
|
||||
*target = dstkey;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
|
|
@ -803,6 +889,11 @@ dstkey_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **target,
|
|||
dst_key_free(&dstkey);
|
||||
}
|
||||
|
||||
if (ds != NULL) {
|
||||
dns_rdata_freestruct(ds);
|
||||
isc_mem_put(mctx, ds, sizeof(*ds));
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
|
@ -822,24 +913,45 @@ 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)
|
||||
{
|
||||
const dns_name_t *keyname = NULL;
|
||||
const char *keynamestr = NULL;
|
||||
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;
|
||||
isc_result_t result;
|
||||
bool initializing = managed;
|
||||
|
||||
result = dstkey_fromconfig(key, &initializing,
|
||||
&dstkey, &keynamestr, mctx);
|
||||
result = ta_fromconfig(key, &initializing, &dstkey, &ds,
|
||||
&namestr, mctx);
|
||||
|
||||
switch (result) {
|
||||
case ISC_R_SUCCESS:
|
||||
/*
|
||||
* Key was parsed correctly, its algorithm is supported by the
|
||||
* crypto library, and it is not revoked.
|
||||
* 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.
|
||||
*/
|
||||
keyname = dst_key_name(dstkey);
|
||||
keyalg = dst_key_alg(dstkey);
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case DST_R_UNSUPPORTEDALG:
|
||||
case DST_R_BADKEYTYPE:
|
||||
|
|
@ -851,7 +963,7 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
|
|||
cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING,
|
||||
"ignoring %s for '%s': %s",
|
||||
initializing ? "initial-key" : "static-key",
|
||||
keynamestr, isc_result_totext(result));
|
||||
namestr, isc_result_totext(result));
|
||||
return (ISC_R_SUCCESS);
|
||||
case DST_R_NOCRYPTO:
|
||||
/*
|
||||
|
|
@ -860,7 +972,7 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
|
|||
cfg_obj_log(key, named_g_lctx, ISC_LOG_ERROR,
|
||||
"ignoring %s for '%s': no crypto support",
|
||||
initializing ? "initial-key" : "static-key",
|
||||
keynamestr);
|
||||
namestr);
|
||||
return (result);
|
||||
default:
|
||||
/*
|
||||
|
|
@ -871,7 +983,7 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
|
|||
cfg_obj_log(key, named_g_lctx, ISC_LOG_ERROR,
|
||||
"configuring %s for '%s': %s",
|
||||
initializing ? "initial-key" : "static-key",
|
||||
keynamestr, isc_result_totext(result));
|
||||
namestr, isc_result_totext(result));
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
|
|
@ -893,7 +1005,7 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
|
|||
cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING,
|
||||
"ignoring %s for '%s': algorithm is disabled",
|
||||
initializing ? "initial-key" : "static-key",
|
||||
keynamestr);
|
||||
namestr);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
|
@ -905,7 +1017,9 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
|
|||
* 'managed' and 'initializing' arguments to dns_keytable_add().
|
||||
*/
|
||||
result = dns_keytable_add(secroots, initializing,
|
||||
initializing, &dstkey);
|
||||
initializing, keyname,
|
||||
dstkey != NULL ? &dstkey : NULL,
|
||||
ds);
|
||||
|
||||
done:
|
||||
/*
|
||||
|
|
@ -917,6 +1031,14 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
|
|||
dst_key_free(&dstkey);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free 'ds'.
|
||||
*/
|
||||
if (ds != NULL) {
|
||||
dns_rdata_freestruct(ds);
|
||||
isc_mem_put(mctx, ds, sizeof(*ds));
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
|
@ -1117,16 +1239,18 @@ configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig,
|
|||
}
|
||||
}
|
||||
|
||||
CHECK(load_view_keys(view_keys, view, false, NULL, mctx));
|
||||
CHECK(load_view_keys(view_managed_keys, view, true, NULL, mctx));
|
||||
CHECK(load_view_keys(view_dnssec_keys, view, true, NULL, mctx));
|
||||
|
||||
if (view->rdclass == dns_rdataclass_in) {
|
||||
CHECK(load_view_keys(view_keys, view, false, NULL, mctx));
|
||||
CHECK(load_view_keys(view_dnssec_keys, view, true, NULL,
|
||||
mctx));
|
||||
CHECK(load_view_keys(view_managed_keys, view, true, NULL,
|
||||
mctx));
|
||||
|
||||
CHECK(load_view_keys(global_keys, view, false, NULL, mctx));
|
||||
CHECK(load_view_keys(global_managed_keys, view, true,
|
||||
NULL, mctx));
|
||||
CHECK(load_view_keys(global_dnssec_keys, view, true,
|
||||
NULL, mctx));
|
||||
CHECK(load_view_keys(global_managed_keys, view, true,
|
||||
NULL, mctx));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -6700,35 +6824,55 @@ struct dotat_arg {
|
|||
* reported in the TAT query.
|
||||
*/
|
||||
static isc_result_t
|
||||
get_tat_qname(dns_name_t *dst, const dns_name_t **origin,
|
||||
get_tat_qname(dns_name_t *target, dns_name_t *keyname,
|
||||
dns_keytable_t *keytable, dns_keynode_t *keynode)
|
||||
{
|
||||
dns_keynode_t *firstnode = keynode;
|
||||
dns_keynode_t *nextnode;
|
||||
dns_keynode_t *nextnode = NULL;
|
||||
dns_rdataset_t *dsset = NULL;
|
||||
unsigned int i, n = 0;
|
||||
uint16_t ids[12];
|
||||
isc_textregion_t r;
|
||||
char label[64];
|
||||
int m;
|
||||
|
||||
REQUIRE(origin != NULL && *origin == NULL);
|
||||
if ((dsset = dns_keynode_dsset(keynode)) != NULL) {
|
||||
isc_result_t result;
|
||||
|
||||
do {
|
||||
dst_key_t *key = dns_keynode_key(keynode);
|
||||
if (key != NULL) {
|
||||
*origin = dst_key_name(key);
|
||||
for (result = dns_rdataset_first(dsset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(dsset))
|
||||
{
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_ds_t ds;
|
||||
|
||||
dns_rdata_reset(&rdata);
|
||||
dns_rdataset_current(dsset, &rdata);
|
||||
result = dns_rdata_tostruct(&rdata, &ds, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
if (n < (sizeof(ids)/sizeof(ids[0]))) {
|
||||
ids[n] = dst_key_id(key);
|
||||
ids[n] = ds.key_tag;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
nextnode = NULL;
|
||||
(void)dns_keytable_nextkeynode(keytable, keynode, &nextnode);
|
||||
if (keynode != firstnode) {
|
||||
dns_keytable_detachkeynode(keytable, &keynode);
|
||||
}
|
||||
keynode = nextnode;
|
||||
} while (keynode != NULL);
|
||||
} else {
|
||||
do {
|
||||
dst_key_t *key = dns_keynode_key(keynode);
|
||||
if (key != NULL) {
|
||||
if (n < (sizeof(ids)/sizeof(ids[0]))) {
|
||||
ids[n] = dst_key_id(key);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
nextnode = NULL;
|
||||
(void)dns_keytable_nextkeynode(keytable, keynode,
|
||||
&nextnode);
|
||||
if (keynode != firstnode) {
|
||||
dns_keytable_detachkeynode(keytable, &keynode);
|
||||
}
|
||||
keynode = nextnode;
|
||||
} while (keynode != NULL);
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
return (DNS_R_EMPTYNAME);
|
||||
|
|
@ -6758,14 +6902,15 @@ get_tat_qname(dns_name_t *dst, const dns_name_t **origin,
|
|||
isc_textregion_consume(&r, m);
|
||||
}
|
||||
|
||||
return (dns_name_fromstring2(dst, label, *origin, 0, NULL));
|
||||
return (dns_name_fromstring2(target, label, keyname, 0, NULL));
|
||||
}
|
||||
|
||||
static void
|
||||
dotat(dns_keytable_t *keytable, dns_keynode_t *keynode, void *arg) {
|
||||
dotat(dns_keytable_t *keytable, dns_keynode_t *keynode,
|
||||
dns_name_t *keyname, void *arg)
|
||||
{
|
||||
struct dotat_arg *dotat_arg = arg;
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
const dns_name_t *origin = NULL;
|
||||
dns_fixedname_t fixed, fdomain;
|
||||
dns_name_t *tatname, *domain;
|
||||
dns_rdataset_t nameservers;
|
||||
|
|
@ -6782,7 +6927,7 @@ dotat(dns_keytable_t *keytable, dns_keynode_t *keynode, void *arg) {
|
|||
task = dotat_arg->task;
|
||||
|
||||
tatname = dns_fixedname_initname(&fixed);
|
||||
result = get_tat_qname(tatname, &origin, keytable, keynode);
|
||||
result = get_tat_qname(tatname, keyname, keytable, keynode);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -6820,17 +6965,13 @@ dotat(dns_keytable_t *keytable, dns_keynode_t *keynode, void *arg) {
|
|||
* order to eventually find the destination host to send the TAT query
|
||||
* to.
|
||||
*
|
||||
* 'origin' holds the domain name at 'keynode', i.e. the domain name
|
||||
* for which the trust anchors to be reported by this TAT query are
|
||||
* defined.
|
||||
*
|
||||
* After the dns_view_findzonecut() call, 'domain' will hold the
|
||||
* deepest zone cut we can find for 'origin' while 'nameservers' will
|
||||
* deepest zone cut we can find for 'keyname' while 'nameservers' will
|
||||
* hold the NS RRset at that zone cut.
|
||||
*/
|
||||
domain = dns_fixedname_initname(&fdomain);
|
||||
dns_rdataset_init(&nameservers);
|
||||
result = dns_view_findzonecut(view, origin, domain, NULL, 0, 0,
|
||||
result = dns_view_findzonecut(view, keyname, domain, NULL, 0, 0,
|
||||
true, true, &nameservers, NULL);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = dns_resolver_createfetch(view->resolver, tatname,
|
||||
|
|
|
|||
|
|
@ -33,12 +33,12 @@ rm $zsknopriv.private
|
|||
ksksby=`$KEYGEN -3 -a RSASHA1 -q -P now -A now+15s -fk $zone`
|
||||
kskrev=`$KEYGEN -3 -a RSASHA1 -q -R now+15s -fk $zone`
|
||||
|
||||
keyfile_to_static_keys $ksksby > trusted.conf
|
||||
keyfile_to_static_ds $ksksby > trusted.conf
|
||||
cp trusted.conf ../ns2/trusted.conf
|
||||
cp trusted.conf ../ns3/trusted.conf
|
||||
cp trusted.conf ../ns4/trusted.conf
|
||||
|
||||
keyfile_to_static_keys $kskrev > trusted.conf
|
||||
keyfile_to_static_ds $kskrev > trusted.conf
|
||||
cp trusted.conf ../ns5/trusted.conf
|
||||
|
||||
echo $zskact > ../active.key
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ zonefile="${zone}.db"
|
|||
infile="${zonefile}.in"
|
||||
ksk=`$KEYGEN -a RSASHA1 -3 -q -fk $zone`
|
||||
$KEYGEN -a RSASHA1 -3 -q $zone > /dev/null
|
||||
keyfile_to_static_keys $ksk > private.conf
|
||||
keyfile_to_static_ds $ksk > private.conf
|
||||
cp private.conf ../ns4/private.conf
|
||||
$SIGNER -S -3 beef -A -o $zone -f $zonefile $infile > /dev/null
|
||||
|
||||
|
|
|
|||
15
bin/tests/system/checkconf/bad-ds-key-1.conf
Normal file
15
bin/tests/system/checkconf/bad-ds-key-1.conf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
dnssec-keys {
|
||||
example. initial-ds 60724 5 1 "D74CF845955A0DFE604AF215E948E67D2EA94FF3";
|
||||
example. initial-key 257 3 5 "AwEAAZtP9+RAA+W33A97e+HnnH8WTXzCWiEICyWj1B6rvZ9hd50ysbody0NLx7b3vZ1bzMLxLSRAr/n3Wi0TDZ1fvCKZhennfW8Wlc7ulCvHntSQYfKHUP0YWEo84sQAqIi850N1aiddj6CidwFo9JNW/HQ+8yarfrnGMFhX2STtkE0hNJ/R6JYKmD2EH7k1nyqJd08ibrEt55DuV4BiUjyyERdVbsuwE60jVqAwCKyVBYXb2sI+zv1yPNDBIANd6KTgnq6YWzx5ZodQP3W4K7Z/Bk3EKmVCvrTKZK/ADLAKaL0/6DD07+1jXA4BiNyoZTLTapkudkGad+Rn6zqCkwuMmrU=";
|
||||
};
|
||||
15
bin/tests/system/checkconf/bad-ds-key-2.conf
Normal file
15
bin/tests/system/checkconf/bad-ds-key-2.conf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
dnssec-keys {
|
||||
example. static-ds 60724 5 1 "D74CF845955A0DFE604AF215E948E67D2EA94FF3";
|
||||
example. static-key 257 3 5 "AwEAAZtP9+RAA+W33A97e+HnnH8WTXzCWiEICyWj1B6rvZ9hd50ysbody0NLx7b3vZ1bzMLxLSRAr/n3Wi0TDZ1fvCKZhennfW8Wlc7ulCvHntSQYfKHUP0YWEo84sQAqIi850N1aiddj6CidwFo9JNW/HQ+8yarfrnGMFhX2STtkE0hNJ/R6JYKmD2EH7k1nyqJd08ibrEt55DuV4BiUjyyERdVbsuwE60jVqAwCKyVBYXb2sI+zv1yPNDBIANd6KTgnq6YWzx5ZodQP3W4K7Z/Bk3EKmVCvrTKZK/ADLAKaL0/6DD07+1jXA4BiNyoZTLTapkudkGad+Rn6zqCkwuMmrU=";
|
||||
};
|
||||
15
bin/tests/system/checkconf/bad-static-initial-1.conf
Normal file
15
bin/tests/system/checkconf/bad-static-initial-1.conf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
dnssec-keys {
|
||||
example. initial-ds 60724 5 1 "D74CF845955A0DFE604AF215E948E67D2EA94FF3";
|
||||
example. static-ds 60724 5 2 "29E79B9064EE1A11DF3BFF19581DDFED7952C22CC204ACE17B6007EB1437E9E6";
|
||||
};
|
||||
15
bin/tests/system/checkconf/bad-static-initial-2.conf
Normal file
15
bin/tests/system/checkconf/bad-static-initial-2.conf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
dnssec-keys {
|
||||
example. initial-ds 60724 5 1 "D74CF845955A0DFE604AF215E948E67D2EA94FF3";
|
||||
example. static-key 257 3 5 "AwEAAZtP9+RAA+W33A97e+HnnH8WTXzCWiEICyWj1B6rvZ9hd50ysbody0NLx7b3vZ1bzMLxLSRAr/n3Wi0TDZ1fvCKZhennfW8Wlc7ulCvHntSQYfKHUP0YWEo84sQAqIi850N1aiddj6CidwFo9JNW/HQ+8yarfrnGMFhX2STtkE0hNJ/R6JYKmD2EH7k1nyqJd08ibrEt55DuV4BiUjyyERdVbsuwE60jVqAwCKyVBYXb2sI+zv1yPNDBIANd6KTgnq6YWzx5ZodQP3W4K7Z/Bk3EKmVCvrTKZK/ADLAKaL0/6DD07+1jXA4BiNyoZTLTapkudkGad+Rn6zqCkwuMmrU=";
|
||||
};
|
||||
15
bin/tests/system/checkconf/bad-static-initial-3.conf
Normal file
15
bin/tests/system/checkconf/bad-static-initial-3.conf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
dnssec-keys {
|
||||
example. static-ds 60724 5 1 "D74CF845955A0DFE604AF215E948E67D2EA94FF3";
|
||||
example. initial-key 257 3 5 "AwEAAZtP9+RAA+W33A97e+HnnH8WTXzCWiEICyWj1B6rvZ9hd50ysbody0NLx7b3vZ1bzMLxLSRAr/n3Wi0TDZ1fvCKZhennfW8Wlc7ulCvHntSQYfKHUP0YWEo84sQAqIi850N1aiddj6CidwFo9JNW/HQ+8yarfrnGMFhX2STtkE0hNJ/R6JYKmD2EH7k1nyqJd08ibrEt55DuV4BiUjyyERdVbsuwE60jVqAwCKyVBYXb2sI+zv1yPNDBIANd6KTgnq6YWzx5ZodQP3W4K7Z/Bk3EKmVCvrTKZK/ADLAKaL0/6DD07+1jXA4BiNyoZTLTapkudkGad+Rn6zqCkwuMmrU=";
|
||||
};
|
||||
15
bin/tests/system/checkconf/bad-static-initial-4.conf
Normal file
15
bin/tests/system/checkconf/bad-static-initial-4.conf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
dnssec-keys {
|
||||
example. initial-key 257 3 5 "AwEAAawvFp8GlBx8Qt6yaIqXkDe+nMkSk2HkTAG7qlVBo++AQwZ1j3Xl25IN4jsw0VTMbKUbafw9DYsVzztIwx1sNkKRLo6qP9SSkBL8RicQaafGtURtsYI3oqte5qqLve1CUpRD8J06Pg1xkOxsDlz9sQAyiQrOyvMbykJYkYrFYGLzYAgl/JtMyVVYlBl9pqxQuAPKYPOuO1axaad/wLN3+wTy/hcJfpvJpqzXlDF9bI5RmpoX/7geZ06vpcYJEoT0xkkmPlEl0ZjEDrm/WIaSWG0/CEDpHcOXFz4OEczMVpY+lnuFfKybwF1WHFn2BwVEOS6cMM6ukIjINQyrszHhWUU=";
|
||||
example. static-key 257 3 5 "AwEAAZtP9+RAA+W33A97e+HnnH8WTXzCWiEICyWj1B6rvZ9hd50ysbody0NLx7b3vZ1bzMLxLSRAr/n3Wi0TDZ1fvCKZhennfW8Wlc7ulCvHntSQYfKHUP0YWEo84sQAqIi850N1aiddj6CidwFo9JNW/HQ+8yarfrnGMFhX2STtkE0hNJ/R6JYKmD2EH7k1nyqJd08ibrEt55DuV4BiUjyyERdVbsuwE60jVqAwCKyVBYXb2sI+zv1yPNDBIANd6KTgnq6YWzx5ZodQP3W4K7Z/Bk3EKmVCvrTKZK/ADLAKaL0/6DD07+1jXA4BiNyoZTLTapkudkGad+Rn6zqCkwuMmrU=";
|
||||
};
|
||||
14
bin/tests/system/checkconf/check-root-static-ds.conf
Normal file
14
bin/tests/system/checkconf/check-root-static-ds.conf
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
dnssec-keys {
|
||||
. static-ds 20326 8 2 "E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D";
|
||||
};
|
||||
14
bin/tests/system/checkconf/good-initial-ds.conf
Normal file
14
bin/tests/system/checkconf/good-initial-ds.conf
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
dnssec-keys {
|
||||
example. initial-ds 60724 5 2 "29E79B9064EE1A11DF3BFF19581DDFED7952C22CC204ACE17B6007EB1437E9E6";
|
||||
};
|
||||
14
bin/tests/system/checkconf/good-static-ds.conf
Normal file
14
bin/tests/system/checkconf/good-static-ds.conf
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
dnssec-keys {
|
||||
example. static-ds 60724 5 2 "29E79B9064EE1A11DF3BFF19581DDFED7952C22CC204ACE17B6007EB1437E9E6";
|
||||
};
|
||||
|
|
@ -437,7 +437,15 @@ n=`expr $n + 1`
|
|||
echo_i "check that a static root key generates a warning ($n)"
|
||||
ret=0
|
||||
$CHECKCONF check-root-static-key.conf > checkconf.out$n 2>/dev/null || ret=1
|
||||
grep "static-key entry for the root zone WILL FAIL" checkconf.out$n > /dev/null || ret=1
|
||||
grep "static entry for the root zone WILL FAIL" checkconf.out$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; ret=1; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "check that a static root DS trust anchor generates a warning ($n)"
|
||||
ret=0
|
||||
$CHECKCONF check-root-static-ds.conf > checkconf.out$n 2>/dev/null || ret=1
|
||||
grep "static entry for the root zone WILL FAIL" checkconf.out$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; ret=1; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
|
|
|
|||
|
|
@ -221,9 +221,9 @@ assert_int_equal() {
|
|||
}
|
||||
|
||||
# keyfile_to_keys_section: helper function for keyfile_to_*_keys() which
|
||||
# converts keyfile data into a configuration section using the supplied
|
||||
# parameters
|
||||
keyfile_to_keys_section() {
|
||||
# converts keyfile data into a key-style trust anchor configuration
|
||||
# section using the supplied parameters
|
||||
keyfile_to_keys() {
|
||||
section_name=$1
|
||||
key_prefix=$2
|
||||
shift
|
||||
|
|
@ -241,18 +241,54 @@ keyfile_to_keys_section() {
|
|||
echo "};"
|
||||
}
|
||||
|
||||
# keyfile_to_dskeys_section: helper function for keyfile_to_*_dskeys()
|
||||
# converts keyfile data into a DS-style trust anchor configuration
|
||||
# section using the supplied parameters
|
||||
keyfile_to_dskeys() {
|
||||
section_name=$1
|
||||
key_prefix=$2
|
||||
shift
|
||||
shift
|
||||
echo "$section_name {"
|
||||
for keyname in $*; do
|
||||
$DSFROMKEY $keyname.key | \
|
||||
awk '!/^; /{
|
||||
printf "\t\""$1"\" "
|
||||
printf "'"$key_prefix "'"
|
||||
printf $4 " " $5 " " $6 " \""
|
||||
for (i=7; i<=NF; i++) printf $i
|
||||
printf "\";\n"
|
||||
}'
|
||||
done
|
||||
echo "};"
|
||||
}
|
||||
|
||||
# keyfile_to_static_keys: convert key data contained in the keyfile(s)
|
||||
# provided to a *static* "dnssec-keys" section suitable for including in a
|
||||
# provided to a *static-key* "dnssec-keys" section suitable for including in a
|
||||
# resolver's configuration file
|
||||
keyfile_to_static_keys() {
|
||||
keyfile_to_keys_section "dnssec-keys" "static-key" $*
|
||||
keyfile_to_keys "dnssec-keys" "static-key" $*
|
||||
}
|
||||
|
||||
# keyfile_to_initial_keys: convert key data contained in the keyfile(s)
|
||||
# provided to an *initialzing* "dnssec-keys" section suitable for including
|
||||
# provided to an *initial-key* "dnssec-keys" section suitable for including
|
||||
# in a resolver's configuration file
|
||||
keyfile_to_initial_keys() {
|
||||
keyfile_to_keys_section "dnssec-keys" "initial-key" $*
|
||||
keyfile_to_keys "dnssec-keys" "initial-key" $*
|
||||
}
|
||||
|
||||
# keyfile_to_static_ds_keys: convert key data contained in the keyfile(s)
|
||||
# provided to a *static-ds* "dnssec-keys" section suitable for including in a
|
||||
# resolver's configuration file
|
||||
keyfile_to_static_ds() {
|
||||
keyfile_to_dskeys "dnssec-keys" "static-ds" $*
|
||||
}
|
||||
|
||||
# keyfile_to_initial_ds_keys: convert key data contained in the keyfile(s)
|
||||
# provided to an *initial-ds* "dnssec-keys" section suitable for including
|
||||
# in a resolver's configuration file
|
||||
keyfile_to_initial_ds() {
|
||||
keyfile_to_dskeys "dnssec-keys" "initial-ds" $*
|
||||
}
|
||||
|
||||
# keyfile_to_key_id: convert a key file name to a key ID
|
||||
|
|
|
|||
|
|
@ -30,14 +30,15 @@ cp "../ns2/dsset-in-addr.arpa$TP" .
|
|||
grep "$DEFAULT_ALGORITHM_NUMBER [12] " "../ns2/dsset-algroll$TP" > "dsset-algroll$TP"
|
||||
cp "../ns6/dsset-optout-tld$TP" .
|
||||
|
||||
keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone")
|
||||
ksk=$("$KEYGEN" -q -fk -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone")
|
||||
zsk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone")
|
||||
|
||||
cat "$infile" "$keyname.key" > "$zonefile"
|
||||
cat "$infile" "$ksk.key" "$zsk.key" > "$zonefile"
|
||||
|
||||
"$SIGNER" -P -g -o "$zone" "$zonefile" > /dev/null 2>&1
|
||||
|
||||
# Configure the resolving server with a staitc key.
|
||||
keyfile_to_static_keys "$keyname" > trusted.conf
|
||||
keyfile_to_static_ds "$ksk" > trusted.conf
|
||||
cp trusted.conf ../ns2/trusted.conf
|
||||
cp trusted.conf ../ns3/trusted.conf
|
||||
cp trusted.conf ../ns4/trusted.conf
|
||||
|
|
@ -46,11 +47,11 @@ cp trusted.conf ../ns7/trusted.conf
|
|||
cp trusted.conf ../ns9/trusted.conf
|
||||
|
||||
# ...or with an initializing key.
|
||||
keyfile_to_initial_keys "$keyname" > managed.conf
|
||||
keyfile_to_initial_ds "$ksk" > managed.conf
|
||||
cp managed.conf ../ns4/managed.conf
|
||||
|
||||
#
|
||||
# Save keyid for managed key id test.
|
||||
#
|
||||
|
||||
keyfile_to_key_id "$keyname" > managed.key.id
|
||||
keyfile_to_key_id "$ksk" > managed.key.id
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ zonefile=root.db.signed
|
|||
keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK "$zone")
|
||||
|
||||
# copy the KSK out first, then revoke it
|
||||
keyfile_to_initial_keys "$keyname" > revoked.conf
|
||||
keyfile_to_initial_ds "$keyname" > revoked.conf
|
||||
|
||||
"$SETTIME" -R now "${keyname}.key" > /dev/null
|
||||
|
||||
|
|
@ -34,4 +34,4 @@ keyfile_to_initial_keys "$keyname" > revoked.conf
|
|||
|
||||
keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone ".")
|
||||
|
||||
keyfile_to_static_keys "$keyname" > trusted.conf
|
||||
keyfile_to_static_ds "$keyname" > trusted.conf
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ options {
|
|||
listen-on { 10.53.0.8; };
|
||||
listen-on-v6 { none; };
|
||||
recursion yes;
|
||||
dnssec-enable yes;
|
||||
dnssec-validation yes;
|
||||
minimal-responses no;
|
||||
disable-algorithms "disabled.managed." { @DISABLED_ALGORITHM@; };
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ options {
|
|||
listen-on { 10.53.0.9; };
|
||||
listen-on-v6 { none; };
|
||||
recursion yes;
|
||||
dnssec-enable yes;
|
||||
dnssec-validation yes;
|
||||
forward only;
|
||||
forwarders { 10.53.0.4; };
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ cat $infile $key1.key $key2.key > $zonefile
|
|||
$SIGNER -P -g -o $zone $zonefile > /dev/null
|
||||
|
||||
# Configure the resolving server with a static key.
|
||||
keyfile_to_static_keys $key2 > trusted.conf
|
||||
keyfile_to_static_ds $key2 > trusted.conf
|
||||
cp trusted.conf ../ns2/trusted.conf
|
||||
cp trusted.conf ../ns3/trusted.conf
|
||||
cp trusted.conf ../ns4/trusted.conf
|
||||
|
|
|
|||
|
|
@ -25,5 +25,5 @@ cat $infile $key1.key $key2.key > $zonefile
|
|||
$SIGNER -P -g -o $zone $zonefile > /dev/null 2> signer.err || cat signer.err
|
||||
|
||||
# Configure the resolving server with a static key.
|
||||
keyfile_to_static_keys $key1 > trusted.conf
|
||||
keyfile_to_static_ds $key1 > trusted.conf
|
||||
cp trusted.conf ../ns2/trusted.conf
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ cat $infile $key1.key $key2.key > $zonefile
|
|||
$SIGNER -P -g -o $zone $zonefile > /dev/null 2> signer.err || cat signer.err
|
||||
|
||||
# Configure the resolving server with a static key.
|
||||
keyfile_to_static_keys $key1 > trusted.conf
|
||||
keyfile_to_static_ds $key1 > trusted.conf
|
||||
cp trusted.conf ../ns2/trusted.conf
|
||||
|
||||
cd ../ns2 && $SHELL sign.sh
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ $KEYGEN -f KSK -a $DEFAULT_ALGORITHM $zone 2>&1 > keygen.out | cat_i
|
|||
keyname=`cat keygen.out`
|
||||
rm -f keygen.out
|
||||
|
||||
keyfile_to_static_keys $keyname > trusted.conf
|
||||
keyfile_to_static_ds $keyname > trusted.conf
|
||||
cp trusted.conf ../ns2/trusted.conf
|
||||
cp trusted.conf ../ns3/trusted.conf
|
||||
cp trusted.conf ../ns5/trusted.conf
|
||||
|
|
|
|||
|
|
@ -20,5 +20,5 @@ keyname=`$KEYGEN -q -a RSASHA1 -b 1024 -n zone -f KSK $zone`
|
|||
$SIGNER -S -x -T 1200 -o ${zone} root.db > signer.out
|
||||
[ $? = 0 ] || cat signer.out
|
||||
|
||||
keyfile_to_static_keys $keyname > trusted.conf
|
||||
keyfile_to_static_ds $keyname > trusted.conf
|
||||
cp trusted.conf ../ns6/trusted.conf
|
||||
|
|
|
|||
|
|
@ -28,5 +28,5 @@ cat $infile $keyname1.key $keyname2.key >$zonefile
|
|||
|
||||
$SIGNER -g -o $zone -f $outfile -e +30y $zonefile > /dev/null 2> signer.err || cat signer.err
|
||||
|
||||
keyfile_to_static_keys $keyname2 > trusted.conf
|
||||
keyfile_to_static_ds $keyname2 > trusted.conf
|
||||
cp trusted.conf ../ns1
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ zskkeyname=`$KEYGEN -a rsasha256 -q $zone`
|
|||
$SIGNER -Sg -o $zone $zonefile > /dev/null 2>/dev/null
|
||||
|
||||
# Configure the resolving server with an initializing key.
|
||||
keyfile_to_initial_keys $keyname > managed.conf
|
||||
keyfile_to_initial_ds $keyname > managed.conf
|
||||
cp managed.conf ../ns2/managed.conf
|
||||
cp managed.conf ../ns4/managed.conf
|
||||
cp managed.conf ../ns5/managed.conf
|
||||
|
||||
# Configure a static key to be used by delv.
|
||||
keyfile_to_static_keys $keyname > trusted.conf
|
||||
keyfile_to_static_ds $keyname > trusted.conf
|
||||
|
||||
# Prepare an unsupported algorithm key.
|
||||
unsupportedkey=Kunknown.+255+00000
|
||||
|
|
|
|||
|
|
@ -27,4 +27,6 @@ rootkey=`cat ../ns1/managed.key`
|
|||
cp "../ns1/${rootkey}.key" .
|
||||
|
||||
# Configure the resolving server with an initializing key.
|
||||
# (We use key-format trust anchors here because otherwise the
|
||||
# unsupported algorithm test won't work.)
|
||||
keyfile_to_initial_keys $unsupportedkey $rsakey $rootkey > managed.conf
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ status=`expr $status + $ret`
|
|||
echo_i "reinitialize trust anchors, add second key to bind.keys"
|
||||
$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} mkeys ns2
|
||||
rm -f ns2/managed-keys.bind*
|
||||
keyfile_to_initial_keys ns1/$original ns1/$standby1 > ns2/managed.conf
|
||||
keyfile_to_initial_ds ns1/$original ns1/$standby1 > ns2/managed.conf
|
||||
nextpart ns2/named.run > /dev/null
|
||||
$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} mkeys ns2
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ cat $infile $keyname1.key $keyname2.key > $zonefile
|
|||
$SIGNER -g -o $zone $zonefile > /dev/null
|
||||
|
||||
# Configure the resolving server with a static key.
|
||||
keyfile_to_static_keys $keyname2 > trusted.conf
|
||||
keyfile_to_static_ds $keyname2 > trusted.conf
|
||||
cp trusted.conf ../ns2/trusted.conf
|
||||
cp trusted.conf ../ns3/trusted.conf
|
||||
cp trusted.conf ../ns4/trusted.conf
|
||||
|
|
|
|||
|
|
@ -31,4 +31,4 @@ cat $ksk.key $zsk.key dsset-ds.example.net$TP >> $zonefile
|
|||
$SIGNER -P -o $zone $zonefile > /dev/null
|
||||
|
||||
# Configure a static key to be used by delv
|
||||
keyfile_to_static_keys $ksk > ../ns5/trusted.conf
|
||||
keyfile_to_static_ds $ksk > ../ns5/trusted.conf
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ cat $infile $keyname.key > $zonefile
|
|||
$SIGNER -P -g -o $zone $zonefile > /dev/null
|
||||
|
||||
# Configure the resolving server with a static key.
|
||||
keyfile_to_static_keys $keyname > trusted.conf
|
||||
keyfile_to_static_ds $keyname > trusted.conf
|
||||
cp trusted.conf ../ns2/trusted.conf
|
||||
cp trusted.conf ../ns3/trusted.conf
|
||||
cp trusted.conf ../ns4/trusted.conf
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ cat $infile $keyname.key > $zonefile
|
|||
$SIGNER -P -g -o $zone $zonefile > /dev/null
|
||||
|
||||
# Configure the resolving server with a static key.
|
||||
keyfile_to_static_keys $keyname > trusted.conf
|
||||
keyfile_to_static_ds $keyname > trusted.conf
|
||||
cp trusted.conf ../ns2/trusted.conf
|
||||
cp trusted.conf ../ns3/trusted.conf
|
||||
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ cat "$infile" "$keyname.key" > "$zonefile"
|
|||
$SIGNER -P -g -o $zone $zonefile > /dev/null
|
||||
|
||||
# Configure the resolving server with a static key.
|
||||
keyfile_to_static_keys "$keyname" > trusted.conf
|
||||
keyfile_to_static_ds "$keyname" > trusted.conf
|
||||
cp trusted.conf ../ns2/trusted.conf
|
||||
|
||||
# ...or with an initializing key.
|
||||
keyfile_to_initial_keys "$keyname" > managed.conf
|
||||
keyfile_to_initial_ds "$keyname" > managed.conf
|
||||
|
|
|
|||
|
|
@ -16,4 +16,4 @@ set -e
|
|||
|
||||
keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone ".")
|
||||
|
||||
keyfile_to_static_keys "$keyname" > trusted.conf
|
||||
keyfile_to_static_ds "$keyname" > trusted.conf
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ cat $infile $keyname1.key $keyname2.key > $zonefile
|
|||
$SIGNER -g -o $zone $zonefile > /dev/null
|
||||
|
||||
# Configure the resolving server with a trusted key.
|
||||
keyfile_to_static_keys $keyname2 > trusted.conf
|
||||
keyfile_to_static_ds $keyname2 > trusted.conf
|
||||
|
||||
zone=undelegated
|
||||
infile=undelegated.db.in
|
||||
|
|
@ -38,5 +38,5 @@ cat $infile $keyname1.key $keyname2.key > $zonefile
|
|||
|
||||
$SIGNER -g -o $zone $zonefile > /dev/null
|
||||
|
||||
keyfile_to_static_keys $keyname2 >> trusted.conf
|
||||
keyfile_to_static_ds $keyname2 >> trusted.conf
|
||||
cp trusted.conf ../ns2/trusted.conf
|
||||
|
|
|
|||
|
|
@ -40,4 +40,4 @@ cat "$infile" "$keyname.key" > "$zonefile"
|
|||
$SIGNER -P -g -o $zone $zonefile > /dev/null
|
||||
|
||||
# Configure the resolving server with a static key.
|
||||
keyfile_to_static_keys "$keyname" > trusted.conf
|
||||
keyfile_to_static_ds "$keyname" > trusted.conf
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ cat $infile $keyname1.key $keyname2.key > $zonefile
|
|||
$SIGNER -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err
|
||||
echo_i "signed $zone"
|
||||
|
||||
keyfile_to_static_keys $keyname2 > private.nsec.conf
|
||||
keyfile_to_static_ds $keyname2 > private.nsec.conf
|
||||
|
||||
zone=nsec3
|
||||
infile=nsec3.db.in
|
||||
|
|
@ -72,7 +72,7 @@ cat $infile $keyname1.key $keyname2.key > $zonefile
|
|||
$SIGNER -3 - -H 10 -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err
|
||||
echo_i "signed $zone"
|
||||
|
||||
keyfile_to_static_keys $keyname2 > private.nsec3.conf
|
||||
keyfile_to_static_ds $keyname2 > private.nsec3.conf
|
||||
|
||||
zone=.
|
||||
infile=root.db.in
|
||||
|
|
@ -87,4 +87,4 @@ cat $infile $keyname1.key $keyname2.key $dssets >$zonefile
|
|||
$SIGNER -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err
|
||||
echo_i "signed $zone"
|
||||
|
||||
keyfile_to_static_keys $keyname2 > trusted.conf
|
||||
keyfile_to_static_ds $keyname2 > trusted.conf
|
||||
|
|
|
|||
|
|
@ -2230,13 +2230,14 @@ allow-update { !{ !localnets; any; }; key host1-host2. ;};
|
|||
The keys specified in <command>dnssec-keys</command>
|
||||
copies of DNSKEY RRs for zones that are used to form the
|
||||
first link in the cryptographic chain of trust. Keys configured
|
||||
with the keyword <command>static-key</command> are loaded directly
|
||||
with the keyword <command>static-key</command> or
|
||||
<command>static-ds</command> are loaded directly
|
||||
into the table of trust anchors, and can only be changed by
|
||||
altering the configuration. Keys configured with
|
||||
<command>initial-key</command> are used to initialize
|
||||
RFC 5011 trust anchor maintenance, and will be kept up to
|
||||
date automatically after the first time <command>named</command>
|
||||
runs.
|
||||
<command>initial-key</command> or <command>initial-ds</command>
|
||||
are used to initialize RFC 5011 trust anchor maintenance, and
|
||||
will be kept up to date automatically after the first time
|
||||
<command>named</command> runs.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
|
@ -2276,17 +2277,7 @@ dnssec-keys {
|
|||
97S+LKUTpQcq27R7AT3/V5hRQxScINqwcz4jYqZD2fQ
|
||||
dgxbcDTClU0CRBdiieyLMNzXG3";
|
||||
/* Key for our organization's forward zone */
|
||||
example.com. static-key 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM6
|
||||
5KbhTjrW1ZaARmPhEZZe3Y9ifgEuq7vZ/z
|
||||
GZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb
|
||||
4JKUbbOTcM8pwXlj0EiX3oDFVmjHO444gL
|
||||
kBOUKUf/mC7HvfwYH/Be22GnClrinKJp1O
|
||||
g4ywzO9WglMk7jbfW33gUKvirTHr25GL7S
|
||||
TQUzBb5Usxt8lgnyTUHs1t3JwCY5hKZ6Cq
|
||||
FxmAVZP20igTixin/1LcrgX/KMEGd/biuv
|
||||
F4qJCyduieHukuY3H4XMAcR+xia2nIUPvm
|
||||
/oyWR8BW/hWdzOvnSCThlHf3xiYleDbt/o
|
||||
1OTQ09A0=";
|
||||
example.com. static-ds 54135 5 2 "8EF922C97F1D07B23134440F19682E7519ADDAE180E20B1B1EC52E7F58B2831D"
|
||||
|
||||
/* Key for our reverse zone. */
|
||||
2.0.192.IN-ADDRPA.NET. static-key 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwc
|
||||
|
|
@ -3215,11 +3206,14 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
|
|||
</entry>
|
||||
<entry colname="2">
|
||||
<para>
|
||||
defines DNSSEC keys: if used with the
|
||||
<command>initial-key</command> keyword,
|
||||
keys are kept up to date using RFC 5011
|
||||
trust anchor maintenance, and if used with
|
||||
<command>static-key</command>, keys are permanent.
|
||||
defines DNSSEC trust anchors: if used with
|
||||
the <command>initial-key</command> or
|
||||
<command>initial-ds</command> keyword,
|
||||
trust anchors are kept up to date using RFC
|
||||
5011 trust anchor maintenance, and if used with
|
||||
<command>static-key</command> or
|
||||
<command>static-ds</command>, trust anchors
|
||||
are permanent.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
|
|
@ -4628,7 +4622,8 @@ badresp:1,adberr:0,findfail:0,valfail:0]
|
|||
<para>
|
||||
Specifies the directory in which to store the files that
|
||||
track managed DNSSEC keys (i.e., those configured using
|
||||
the <command>initial-key</command> keyword in a
|
||||
the <command>initial-key</command> or
|
||||
<command>initial-ds</command> keywords in a
|
||||
<command>dnssec-keys</command> statement). By default,
|
||||
this is the working directory. The directory
|
||||
<emphasis>must</emphasis> be writable by the effective
|
||||
|
|
@ -10864,12 +10859,12 @@ example.com CNAME rpz-tcp-only.
|
|||
trust anchors. DNSSEC is described in <xref linkend="DNSSEC"/>.
|
||||
</para>
|
||||
<para>
|
||||
A trust anchor is defined when the public key for
|
||||
a non-authoritative zone is known, but cannot be securely
|
||||
obtained through DNS, either because it is the DNS root zone
|
||||
or because its parent zone is unsigned. Once a key has been
|
||||
configured as a trust anchor, it is treated as if it had
|
||||
been validated and proven secure.
|
||||
A trust anchor is defined when the public key or public key
|
||||
digest for a non-authoritative zone is known, but cannot be
|
||||
securely obtained through DNS, either because it is the DNS
|
||||
root zone or because its parent zone is unsigned. Once a key
|
||||
or digest has been configured as a trust anchor, it is treated
|
||||
as if it had been validated and proven secure.
|
||||
</para>
|
||||
<para>
|
||||
The resolver attempts DNSSEC validation on all DNS data
|
||||
|
|
@ -10881,19 +10876,9 @@ example.com CNAME rpz-tcp-only.
|
|||
<para>
|
||||
All keys listed in <command>dnssec-keys</command>, and
|
||||
their corresponding zones, are deemed to exist regardless
|
||||
of what parent zones say. Only keys configured as trust anchors
|
||||
of what parent zones say. Only keys configured as trust anchors
|
||||
are used to validate the DNSKEY RRset for the corresponding
|
||||
name. The parent's DS RRset will not be used.
|
||||
</para>
|
||||
<para>
|
||||
The <command>dnssec-keys</command> statement can contain
|
||||
multiple key entries, each consisting of the key's
|
||||
domain name, followed by the <command>static-key</command> or
|
||||
<command>initial-key</command> keyword, then the key's flags,
|
||||
protocol, algorithm, and the Base64 representation of the key
|
||||
data. Spaces, tabs, newlines and carriage returns are ignored
|
||||
in the key data, so the configuration may be split up into
|
||||
multiple lines.
|
||||
name. The parent's DS RRset will not be used.
|
||||
</para>
|
||||
<para>
|
||||
<command>dnssec-keys</command> may be set at the top level
|
||||
|
|
@ -10903,11 +10888,33 @@ example.com CNAME rpz-tcp-only.
|
|||
defined in a view are only used within that view.
|
||||
</para>
|
||||
<para>
|
||||
<command>dnssec-keys</command> entries can be configured with
|
||||
two keywords: <command>static-key</command> or
|
||||
<command>initial-key</command>. Keys configured with
|
||||
<command>static-key</command> are immutable,
|
||||
while keys configured with <command>initial-key</command>
|
||||
The <command>dnssec-keys</command> statement can contain
|
||||
multiple trust anchor entries, each consisting of a
|
||||
domain name, followed by an "anchor type" keyword indicating
|
||||
the trust anchor's format, followed by the key or digest data.
|
||||
</para>
|
||||
<para>
|
||||
If the anchor type is <command>static-key</command> or
|
||||
<command>initial-key</command>, then it is followed with the
|
||||
key's flags, protocol, algorithm, and the Base64 representation
|
||||
of the public key data. This is identical to the text
|
||||
representation of a DNSKEY record. Spaces, tabs, newlines and
|
||||
carriage returns are ignored in the key data, so the
|
||||
configuration may be split up into multiple lines.
|
||||
</para>
|
||||
<para>
|
||||
If the anchor type is <command>static-ds</command> or
|
||||
<command>initial-ds</command>, then it is followed with the
|
||||
key tag, algorithm, digest type, and the hexidecimal
|
||||
representation of the key digest. This is identical to the
|
||||
text representation of a DS record. Spaces, tabs, newlines
|
||||
and carriage returns are ignored.
|
||||
</para>
|
||||
<para>
|
||||
Trust anchors configured with the
|
||||
<command>static-key</command> or <command>static-ds</command>
|
||||
anchor types are immutable, while keys configured with
|
||||
<command>initial-key</command> or <command>initial-ds</command>
|
||||
can be kept up to date automatically, without intervention
|
||||
from the resolver operator. (<command>static-key</command>
|
||||
keys are identical to keys configured using the deprecated
|
||||
|
|
@ -10917,45 +10924,55 @@ example.com CNAME rpz-tcp-only.
|
|||
Suppose, for example, that a zone's key-signing
|
||||
key was compromised, and the zone owner had to revoke and
|
||||
replace the key. A resolver which had the original key
|
||||
configured as a <command>static-key</command> would be
|
||||
unable to validate this zone any longer; it would
|
||||
reply with a SERVFAIL response code. This would
|
||||
continue until the resolver operator had updated the
|
||||
<command>dnssec-keys</command> statement with the new key.
|
||||
configured using <command>static-key</command> or
|
||||
<command>static-ds</command> would be unable to validate
|
||||
this zone any longer; it would reply with a SERVFAIL response
|
||||
code. This would continue until the resolver operator had
|
||||
updated the <command>dnssec-keys</command> statement with
|
||||
the new key.
|
||||
</para>
|
||||
<para>
|
||||
If, however, the trust anchor had been configured with
|
||||
<command>initial-key</command> instead, then the
|
||||
zone owner could add a "stand-by" key to their zone in advance.
|
||||
<command>named</command> would store the stand-by key, and
|
||||
when the original key was revoked, <command>named</command>
|
||||
would be able to transition smoothly to the new key. It would
|
||||
also recognize that the old key had been revoked, and cease
|
||||
using that key to validate answers, minimizing the damage that
|
||||
the compromised key could do. This is the process used to
|
||||
keep the ICANN root DNSSEC key up to date.
|
||||
<command>initial-key</command> or <command>initial-ds</command>
|
||||
instead, then the zone owner could add a "stand-by" key to
|
||||
their zone in advance. <command>named</command> would store
|
||||
the stand-by key, and when the original key was revoked,
|
||||
<command>named</command> would be able to transition smoothly
|
||||
to the new key. It would also recognize that the old key had
|
||||
been revoked, and cease using that key to validate answers,
|
||||
minimizing the damage that the compromised key could do.
|
||||
This is the process used to keep the ICANN root DNSSEC key
|
||||
up to date.
|
||||
</para>
|
||||
<para>
|
||||
Whereas <command>static-key</command>
|
||||
keys continue to be trusted until they are removed from
|
||||
Whereas <command>static-key</command> and
|
||||
<command>static-ds</command> trust anchors continue
|
||||
to be trusted until they are removed from
|
||||
<filename>named.conf</filename>, an
|
||||
<command>initial-key</command> is only trusted
|
||||
<emphasis>once</emphasis>: for as long as it
|
||||
<command>initial-key</command> or <command>initial-ds</command>
|
||||
is only trusted <emphasis>once</emphasis>: for as long as it
|
||||
takes to load the managed key database and start the RFC 5011
|
||||
key maintenance process.
|
||||
</para>
|
||||
<para>
|
||||
It is not possible to mix static with initial trust anchors
|
||||
for the same domain name. It is also not possible to mix
|
||||
<command>key</command> with <command>ds</command> trust anchors.
|
||||
</para>
|
||||
<para>
|
||||
The first time <command>named</command> runs with an
|
||||
<command>initial-key</command> configured in
|
||||
<filename>named.conf</filename>, it fetches the
|
||||
<command>initial-key</command> or <command>initial-ds</command>
|
||||
configured in <filename>named.conf</filename>, it fetches the
|
||||
DNSKEY RRset directly from the zone apex, and validates it
|
||||
using the key specified in <command>dnssec-keys</command>.
|
||||
If the DNSKEY RRset is validly signed, then it is
|
||||
used as the basis for a new managed keys database.
|
||||
using the trust anchor specified in <command>dnssec-keys</command>.
|
||||
If the DNSKEY RRset is validly signed by a key matching
|
||||
the trust anchor, then it is used as the basis for a new
|
||||
managed keys database.
|
||||
</para>
|
||||
<para>
|
||||
From that point on, whenever <command>named</command> runs, it
|
||||
sees the <command>initial-key</command> listed in
|
||||
sees the <command>initial-key</command> or
|
||||
<command>initial-ds</command> listed in
|
||||
<command>dnssec-keys</command>, checks to
|
||||
make sure RFC 5011 key maintenance has already been initialized
|
||||
for the specified domain, and if so, it simply moves on. The
|
||||
|
|
@ -10966,13 +10983,13 @@ example.com CNAME rpz-tcp-only.
|
|||
</para>
|
||||
<para>
|
||||
The next time <command>named</command> runs after an
|
||||
<command>initial-key</command> has been
|
||||
<emphasis>removed</emphasis> from the
|
||||
<command>initial-key</command> or <command>initial-ds</command>
|
||||
trust anchor has been <emphasis>removed</emphasis> from the
|
||||
<command>dnssec-keys</command> statement (or changed to
|
||||
a <command>static-key</command>), the corresponding
|
||||
zone will be removed from the managed keys database,
|
||||
and RFC 5011 key maintenance will no longer be used for that
|
||||
domain.
|
||||
a <command>static-key</command> or <command>static-ds</command>),
|
||||
the corresponding keys will be removed from the managed keys
|
||||
database, and RFC 5011 key maintenance will no longer be used
|
||||
for that domain.
|
||||
</para>
|
||||
<para>
|
||||
In the current implementation, the managed keys database
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
<programlisting>
|
||||
<command>dnssec-keys</command> { <replaceable>string</replaceable> ( static-key |
|
||||
<command>initial-key</command> ) <replaceable>integer</replaceable> <replaceable>integer</replaceable> <replaceable>integer</replaceable>
|
||||
<command>initial-key</command> | static-ds | initial-ds )
|
||||
<replaceable>integer</replaceable> <replaceable>integer</replaceable> <replaceable>integer</replaceable>
|
||||
<replaceable>quoted_string</replaceable>; ... };
|
||||
</programlisting>
|
||||
|
|
|
|||
|
|
@ -138,7 +138,8 @@ $ <userinput>make</userinput>
|
|||
<filename>named.conf</filename>, except that all
|
||||
<command>managed-keys</command> entries will be treated as
|
||||
if they were configured with the <command>static-key</command>
|
||||
keyword, even if they are configured with <command>initial-key</command>.
|
||||
or <command>static-ds</command> keywords, even if they are configured
|
||||
with <command>initial-key</command> or <command>iniital-ds</command>.
|
||||
(See <xref linkend="managed-keys"/> for syntax details.)
|
||||
</para>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
<programlisting>
|
||||
<command>managed-keys</command> { <replaceable>string</replaceable> ( static-key
|
||||
| initial-key ) <replaceable>integer</replaceable>
|
||||
<replaceable>integer</replaceable> <replaceable>integer</replaceable>
|
||||
<replaceable>quoted_string</replaceable>; ... }; deprecated
|
||||
| initial-key | static-ds |
|
||||
<command>initial-ds</command> ) <replaceable>integer</replaceable> <replaceable>integer</replaceable>
|
||||
<replaceable>integer</replaceable> <replaceable>quoted_string</replaceable>; ... }; deprecated
|
||||
</programlisting>
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@
|
|||
<para>To configure a validating resolver to use RFC 5011 to
|
||||
maintain a trust anchor, configure the trust anchor using a
|
||||
<command>dnssec-keys</command> statement and the
|
||||
<command>initial-key</command> keyword. Information about
|
||||
this can be found in
|
||||
<command>initial-key</command> or <command>initial-ds</command>
|
||||
keyword. Information about this can be found in
|
||||
<xref linkend="dnssec-keys"/>.</para>
|
||||
</section>
|
||||
<section><info><title>Authoritative Server</title></info>
|
||||
|
|
|
|||
|
|
@ -33,6 +33,27 @@
|
|||
policy used by <command>dnssec-keymgr</command>.) [GL #1134]
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Two new keywords have been added to the
|
||||
<command>dnssec-keys</command> statement:
|
||||
<command>initial-ds</command> and <command>static-ds</command>.
|
||||
These allow the use of trust anchors in DS format instead of
|
||||
DNSKEY format. DS format allows trust anchors to be configured
|
||||
for keys that have not yet been published; this is the format
|
||||
used by IANA when announcing future root keys.
|
||||
</para>
|
||||
<para>
|
||||
As with the <command>initial-key</command> and
|
||||
<command>static-key</command> keywords, <command>initial-ds</command>
|
||||
configures a dynamic trust anchor to be maintained via RFC 5011, and
|
||||
<command>static-ds</command> configures a permanent trust anchor.
|
||||
</para>
|
||||
<para>
|
||||
(Note: Currently, DNSKEY-format and DS-format trust anchors
|
||||
cannot both be used for the same domain name.) [GL #6] [GL #622]
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ dlz <string> {
|
|||
}; // may occur multiple times
|
||||
|
||||
dnssec-keys { <string> ( static-key |
|
||||
initial-key ) <integer> <integer> <integer>
|
||||
initial-key | static-ds | initial-ds )
|
||||
<integer> <integer> <integer>
|
||||
<quoted_string>; ... }; // may occur multiple times
|
||||
|
||||
dnssec-policy <string> {
|
||||
|
|
@ -68,9 +69,9 @@ logging {
|
|||
lwres { <unspecified-text> }; // obsolete, may occur multiple times
|
||||
|
||||
managed-keys { <string> ( static-key
|
||||
| initial-key ) <integer>
|
||||
<integer> <integer>
|
||||
<quoted_string>; ... }; // may occur multiple times, deprecated
|
||||
| initial-key | static-ds |
|
||||
initial-ds ) <integer> <integer>
|
||||
<integer> <quoted_string>; ... }; // may occur multiple times, deprecated
|
||||
|
||||
masters <string> [ port <integer> ] [ dscp
|
||||
<integer> ] { ( <masters> | <ipv4_address> [
|
||||
|
|
@ -209,7 +210,7 @@ options {
|
|||
fstrm-set-output-queue-model ( mpsc | spsc ); // not configured
|
||||
fstrm-set-output-queue-size <integer>; // not configured
|
||||
fstrm-set-reopen-interval <ttlval>; // not configured
|
||||
geoip-directory ( <quoted_string> | none ); // not configured
|
||||
geoip-directory ( <quoted_string> | none );
|
||||
geoip-use-ecs <boolean>; // obsolete
|
||||
glue-cache <boolean>;
|
||||
has-old-clients <boolean>; // ancient
|
||||
|
|
@ -230,7 +231,7 @@ options {
|
|||
listen-on-v6 [ port <integer> ] [ dscp
|
||||
<integer> ] {
|
||||
<address_match_element>; ... }; // may occur multiple times
|
||||
lmdb-mapsize <sizeval>; // non-operational
|
||||
lmdb-mapsize <sizeval>;
|
||||
lock-file ( <quoted_string> | none );
|
||||
maintain-ixfr-base <boolean>; // ancient
|
||||
managed-keys-directory <quoted_string>;
|
||||
|
|
@ -538,8 +539,9 @@ view <string> [ <class> ] {
|
|||
dnssec-dnskey-kskonly <boolean>;
|
||||
dnssec-enable <boolean>; // obsolete
|
||||
dnssec-keys { <string> ( static-key |
|
||||
initial-key ) <integer> <integer>
|
||||
<integer> <quoted_string>; ... }; // may occur multiple times
|
||||
initial-key | static-ds | initial-ds
|
||||
) <integer> <integer> <integer>
|
||||
<quoted_string>; ... }; // may occur multiple times
|
||||
dnssec-loadkeys-interval <integer>;
|
||||
dnssec-lookaside ( <string>
|
||||
trust-anchor <string> |
|
||||
|
|
@ -581,10 +583,11 @@ view <string> [ <class> ] {
|
|||
}; // may occur multiple times
|
||||
key-directory <quoted_string>;
|
||||
lame-ttl <ttlval>;
|
||||
lmdb-mapsize <sizeval>; // non-operational
|
||||
lmdb-mapsize <sizeval>;
|
||||
maintain-ixfr-base <boolean>; // ancient
|
||||
managed-keys { <string> (
|
||||
static-key | initial-key
|
||||
| static-ds | initial-ds
|
||||
) <integer> <integer>
|
||||
<integer>
|
||||
<quoted_string>; ... }; // may occur multiple times, deprecated
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ dlz <string> {
|
|||
}; // may occur multiple times
|
||||
|
||||
dnssec-keys { <string> ( static-key |
|
||||
initial-key ) <integer> <integer> <integer>
|
||||
initial-key | static-ds | initial-ds )
|
||||
<integer> <integer> <integer>
|
||||
<quoted_string>; ... }; // may occur multiple times
|
||||
|
||||
dyndb <string> <quoted_string> {
|
||||
|
|
@ -50,9 +51,9 @@ logging {
|
|||
};
|
||||
|
||||
managed-keys { <string> ( static-key
|
||||
| initial-key ) <integer>
|
||||
<integer> <integer>
|
||||
<quoted_string>; ... }; // may occur multiple times, deprecated
|
||||
| initial-key | static-ds |
|
||||
initial-ds ) <integer> <integer>
|
||||
<integer> <quoted_string>; ... }; // may occur multiple times, deprecated
|
||||
|
||||
masters <string> [ port <integer> ] [ dscp
|
||||
<integer> ] { ( <masters> | <ipv4_address> [
|
||||
|
|
@ -175,7 +176,7 @@ options {
|
|||
fstrm-set-output-queue-model ( mpsc | spsc ); // not configured
|
||||
fstrm-set-output-queue-size <integer>; // not configured
|
||||
fstrm-set-reopen-interval <ttlval>; // not configured
|
||||
geoip-directory ( <quoted_string> | none ); // not configured
|
||||
geoip-directory ( <quoted_string> | none );
|
||||
glue-cache <boolean>;
|
||||
heartbeat-interval <integer>;
|
||||
hostname ( <quoted_string> | none );
|
||||
|
|
@ -192,7 +193,7 @@ options {
|
|||
listen-on-v6 [ port <integer> ] [ dscp
|
||||
<integer> ] {
|
||||
<address_match_element>; ... }; // may occur multiple times
|
||||
lmdb-mapsize <sizeval>; // non-operational
|
||||
lmdb-mapsize <sizeval>;
|
||||
lock-file ( <quoted_string> | none );
|
||||
managed-keys-directory <quoted_string>;
|
||||
masterfile-format ( map | raw | text );
|
||||
|
|
@ -470,8 +471,9 @@ view <string> [ <class> ] {
|
|||
dnssec-accept-expired <boolean>;
|
||||
dnssec-dnskey-kskonly <boolean>;
|
||||
dnssec-keys { <string> ( static-key |
|
||||
initial-key ) <integer> <integer>
|
||||
<integer> <quoted_string>; ... }; // may occur multiple times
|
||||
initial-key | static-ds | initial-ds
|
||||
) <integer> <integer> <integer>
|
||||
<quoted_string>; ... }; // may occur multiple times
|
||||
dnssec-loadkeys-interval <integer>;
|
||||
dnssec-must-be-secure <string> <boolean>; // may occur multiple times
|
||||
dnssec-secure-to-insecure <boolean>;
|
||||
|
|
@ -506,9 +508,10 @@ view <string> [ <class> ] {
|
|||
}; // may occur multiple times
|
||||
key-directory <quoted_string>;
|
||||
lame-ttl <ttlval>;
|
||||
lmdb-mapsize <sizeval>; // non-operational
|
||||
lmdb-mapsize <sizeval>;
|
||||
managed-keys { <string> (
|
||||
static-key | initial-key
|
||||
| static-ds | initial-ds
|
||||
) <integer> <integer>
|
||||
<integer>
|
||||
<quoted_string>; ... }; // may occur multiple times, deprecated
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include <dns/acl.h>
|
||||
#include <dns/dnstap.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/keyvalues.h>
|
||||
#include <dns/rbt.h>
|
||||
#include <dns/rdataclass.h>
|
||||
#include <dns/rdatatype.h>
|
||||
|
|
@ -48,6 +49,7 @@
|
|||
#include <dns/ssu.h>
|
||||
|
||||
#include <dst/dst.h>
|
||||
#include <dst/result.h>
|
||||
|
||||
#include <isccfg/aclconf.h>
|
||||
#include <isccfg/cfg.h>
|
||||
|
|
@ -3117,28 +3119,128 @@ check_servers(const cfg_obj_t *config, const cfg_obj_t *voptions,
|
|||
#define ROOT_KSK_2017 0x08
|
||||
|
||||
static isc_result_t
|
||||
check_trusted_key(const cfg_obj_t *key, bool managed,
|
||||
unsigned int *keyflags, isc_log_t *logctx)
|
||||
check_trust_anchor(const cfg_obj_t *key, bool managed,
|
||||
unsigned int *flagsp, isc_log_t *logctx)
|
||||
{
|
||||
const char *keystr, *keynamestr;
|
||||
const char *str = NULL, *namestr = NULL;
|
||||
dns_fixedname_t fkeyname;
|
||||
dns_name_t *keyname;
|
||||
dns_name_t *keyname = NULL;
|
||||
isc_buffer_t b;
|
||||
isc_region_t r;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_result_t tresult;
|
||||
uint32_t flags, proto, alg;
|
||||
unsigned char keydata[4096];
|
||||
uint32_t n1, n2, n3;
|
||||
unsigned char data[4096];
|
||||
const char *atstr = NULL;
|
||||
enum {
|
||||
INIT_DNSKEY,
|
||||
STATIC_DNSKEY,
|
||||
INIT_DS,
|
||||
STATIC_DS,
|
||||
TRUSTED
|
||||
} anchortype;
|
||||
|
||||
flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags"));
|
||||
proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol"));
|
||||
alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm"));
|
||||
/*
|
||||
* The 2010 and 2017 IANA root keys - these are used below
|
||||
* to check the contents of trusted, initial and
|
||||
* static trust anchor configurations.
|
||||
*/
|
||||
static const unsigned char root_ksk_2010[] = {
|
||||
0x03, 0x01, 0x00, 0x01, 0xa8, 0x00, 0x20, 0xa9,
|
||||
0x55, 0x66, 0xba, 0x42, 0xe8, 0x86, 0xbb, 0x80,
|
||||
0x4c, 0xda, 0x84, 0xe4, 0x7e, 0xf5, 0x6d, 0xbd,
|
||||
0x7a, 0xec, 0x61, 0x26, 0x15, 0x55, 0x2c, 0xec,
|
||||
0x90, 0x6d, 0x21, 0x16, 0xd0, 0xef, 0x20, 0x70,
|
||||
0x28, 0xc5, 0x15, 0x54, 0x14, 0x4d, 0xfe, 0xaf,
|
||||
0xe7, 0xc7, 0xcb, 0x8f, 0x00, 0x5d, 0xd1, 0x82,
|
||||
0x34, 0x13, 0x3a, 0xc0, 0x71, 0x0a, 0x81, 0x18,
|
||||
0x2c, 0xe1, 0xfd, 0x14, 0xad, 0x22, 0x83, 0xbc,
|
||||
0x83, 0x43, 0x5f, 0x9d, 0xf2, 0xf6, 0x31, 0x32,
|
||||
0x51, 0x93, 0x1a, 0x17, 0x6d, 0xf0, 0xda, 0x51,
|
||||
0xe5, 0x4f, 0x42, 0xe6, 0x04, 0x86, 0x0d, 0xfb,
|
||||
0x35, 0x95, 0x80, 0x25, 0x0f, 0x55, 0x9c, 0xc5,
|
||||
0x43, 0xc4, 0xff, 0xd5, 0x1c, 0xbe, 0x3d, 0xe8,
|
||||
0xcf, 0xd0, 0x67, 0x19, 0x23, 0x7f, 0x9f, 0xc4,
|
||||
0x7e, 0xe7, 0x29, 0xda, 0x06, 0x83, 0x5f, 0xa4,
|
||||
0x52, 0xe8, 0x25, 0xe9, 0xa1, 0x8e, 0xbc, 0x2e,
|
||||
0xcb, 0xcf, 0x56, 0x34, 0x74, 0x65, 0x2c, 0x33,
|
||||
0xcf, 0x56, 0xa9, 0x03, 0x3b, 0xcd, 0xf5, 0xd9,
|
||||
0x73, 0x12, 0x17, 0x97, 0xec, 0x80, 0x89, 0x04,
|
||||
0x1b, 0x6e, 0x03, 0xa1, 0xb7, 0x2d, 0x0a, 0x73,
|
||||
0x5b, 0x98, 0x4e, 0x03, 0x68, 0x73, 0x09, 0x33,
|
||||
0x23, 0x24, 0xf2, 0x7c, 0x2d, 0xba, 0x85, 0xe9,
|
||||
0xdb, 0x15, 0xe8, 0x3a, 0x01, 0x43, 0x38, 0x2e,
|
||||
0x97, 0x4b, 0x06, 0x21, 0xc1, 0x8e, 0x62, 0x5e,
|
||||
0xce, 0xc9, 0x07, 0x57, 0x7d, 0x9e, 0x7b, 0xad,
|
||||
0xe9, 0x52, 0x41, 0xa8, 0x1e, 0xbb, 0xe8, 0xa9,
|
||||
0x01, 0xd4, 0xd3, 0x27, 0x6e, 0x40, 0xb1, 0x14,
|
||||
0xc0, 0xa2, 0xe6, 0xfc, 0x38, 0xd1, 0x9c, 0x2e,
|
||||
0x6a, 0xab, 0x02, 0x64, 0x4b, 0x28, 0x13, 0xf5,
|
||||
0x75, 0xfc, 0x21, 0x60, 0x1e, 0x0d, 0xee, 0x49,
|
||||
0xcd, 0x9e, 0xe9, 0x6a, 0x43, 0x10, 0x3e, 0x52,
|
||||
0x4d, 0x62, 0x87, 0x3d
|
||||
};
|
||||
static const unsigned char root_ksk_2017[] = {
|
||||
0x03, 0x01, 0x00, 0x01, 0xac, 0xff, 0xb4, 0x09,
|
||||
0xbc, 0xc9, 0x39, 0xf8, 0x31, 0xf7, 0xa1, 0xe5,
|
||||
0xec, 0x88, 0xf7, 0xa5, 0x92, 0x55, 0xec, 0x53,
|
||||
0x04, 0x0b, 0xe4, 0x32, 0x02, 0x73, 0x90, 0xa4,
|
||||
0xce, 0x89, 0x6d, 0x6f, 0x90, 0x86, 0xf3, 0xc5,
|
||||
0xe1, 0x77, 0xfb, 0xfe, 0x11, 0x81, 0x63, 0xaa,
|
||||
0xec, 0x7a, 0xf1, 0x46, 0x2c, 0x47, 0x94, 0x59,
|
||||
0x44, 0xc4, 0xe2, 0xc0, 0x26, 0xbe, 0x5e, 0x98,
|
||||
0xbb, 0xcd, 0xed, 0x25, 0x97, 0x82, 0x72, 0xe1,
|
||||
0xe3, 0xe0, 0x79, 0xc5, 0x09, 0x4d, 0x57, 0x3f,
|
||||
0x0e, 0x83, 0xc9, 0x2f, 0x02, 0xb3, 0x2d, 0x35,
|
||||
0x13, 0xb1, 0x55, 0x0b, 0x82, 0x69, 0x29, 0xc8,
|
||||
0x0d, 0xd0, 0xf9, 0x2c, 0xac, 0x96, 0x6d, 0x17,
|
||||
0x76, 0x9f, 0xd5, 0x86, 0x7b, 0x64, 0x7c, 0x3f,
|
||||
0x38, 0x02, 0x9a, 0xbd, 0xc4, 0x81, 0x52, 0xeb,
|
||||
0x8f, 0x20, 0x71, 0x59, 0xec, 0xc5, 0xd2, 0x32,
|
||||
0xc7, 0xc1, 0x53, 0x7c, 0x79, 0xf4, 0xb7, 0xac,
|
||||
0x28, 0xff, 0x11, 0x68, 0x2f, 0x21, 0x68, 0x1b,
|
||||
0xf6, 0xd6, 0xab, 0xa5, 0x55, 0x03, 0x2b, 0xf6,
|
||||
0xf9, 0xf0, 0x36, 0xbe, 0xb2, 0xaa, 0xa5, 0xb3,
|
||||
0x77, 0x8d, 0x6e, 0xeb, 0xfb, 0xa6, 0xbf, 0x9e,
|
||||
0xa1, 0x91, 0xbe, 0x4a, 0xb0, 0xca, 0xea, 0x75,
|
||||
0x9e, 0x2f, 0x77, 0x3a, 0x1f, 0x90, 0x29, 0xc7,
|
||||
0x3e, 0xcb, 0x8d, 0x57, 0x35, 0xb9, 0x32, 0x1d,
|
||||
0xb0, 0x85, 0xf1, 0xb8, 0xe2, 0xd8, 0x03, 0x8f,
|
||||
0xe2, 0x94, 0x19, 0x92, 0x54, 0x8c, 0xee, 0x0d,
|
||||
0x67, 0xdd, 0x45, 0x47, 0xe1, 0x1d, 0xd6, 0x3a,
|
||||
0xf9, 0xc9, 0xfc, 0x1c, 0x54, 0x66, 0xfb, 0x68,
|
||||
0x4c, 0xf0, 0x09, 0xd7, 0x19, 0x7c, 0x2c, 0xf7,
|
||||
0x9e, 0x79, 0x2a, 0xb5, 0x01, 0xe6, 0xa8, 0xa1,
|
||||
0xca, 0x51, 0x9a, 0xf2, 0xcb, 0x9b, 0x5f, 0x63,
|
||||
0x67, 0xe9, 0x4c, 0x0d, 0x47, 0x50, 0x24, 0x51,
|
||||
0x35, 0x7b, 0xe1, 0xb5
|
||||
};
|
||||
static const unsigned char root_ds_1_2017[] = {
|
||||
0xae, 0x1e, 0xa5, 0xb9, 0x74, 0xd4, 0xc8, 0x58,
|
||||
0xb7, 0x40, 0xbd, 0x03, 0xe3, 0xce, 0xd7, 0xeb,
|
||||
0xfc, 0xbd, 0x17, 0x24
|
||||
};
|
||||
static const unsigned char root_ds_2_2017[] = {
|
||||
0xe0, 0x6d, 0x44, 0xb8, 0x0b, 0x8f, 0x1d, 0x39,
|
||||
0xa9, 0x5c, 0x0b, 0x0d, 0x7c, 0x65, 0xd0, 0x84,
|
||||
0x58, 0xe8, 0x80, 0x40, 0x9b, 0xbc, 0x68, 0x34,
|
||||
0x57, 0x10, 0x42, 0x37, 0xc7, 0xf8, 0xec, 0x8D
|
||||
};
|
||||
|
||||
/* if DNSKEY, flags; if DS, key tag */
|
||||
n1 = cfg_obj_asuint32(cfg_tuple_get(key, "n1"));
|
||||
|
||||
/* if DNSKEY, protocol; if DS, algorithm */
|
||||
n2 = cfg_obj_asuint32(cfg_tuple_get(key, "n2"));
|
||||
|
||||
/* if DNSKEY, algorithm; if DS, digest type */
|
||||
n3 = cfg_obj_asuint32(cfg_tuple_get(key, "n3"));
|
||||
|
||||
namestr = cfg_obj_asstring(cfg_tuple_get(key, "name"));
|
||||
|
||||
keyname = dns_fixedname_initname(&fkeyname);
|
||||
keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name"));
|
||||
|
||||
isc_buffer_constinit(&b, keynamestr, strlen(keynamestr));
|
||||
isc_buffer_add(&b, strlen(keynamestr));
|
||||
isc_buffer_constinit(&b, namestr, strlen(namestr));
|
||||
isc_buffer_add(&b, strlen(namestr));
|
||||
result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_WARNING, "bad key name: %s\n",
|
||||
|
|
@ -3146,151 +3248,169 @@ check_trusted_key(const cfg_obj_t *key, bool managed,
|
|||
result = ISC_R_FAILURE;
|
||||
}
|
||||
|
||||
if (flags > 0xffff) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_WARNING,
|
||||
"flags too big: %u\n", flags);
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
if (proto > 0xff) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_WARNING,
|
||||
"protocol too big: %u\n", proto);
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
if (alg > 0xff) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_WARNING,
|
||||
"algorithm too big: %u\n", alg);
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
|
||||
if (managed) {
|
||||
const char *initmethod;
|
||||
initmethod = cfg_obj_asstring(cfg_tuple_get(key, "init"));
|
||||
atstr = cfg_obj_asstring(cfg_tuple_get(key, "anchortype"));
|
||||
|
||||
if (strcasecmp(initmethod, "static-key") == 0) {
|
||||
if (strcasecmp(atstr, "static-key") == 0) {
|
||||
managed = false;
|
||||
} else if (strcasecmp(initmethod, "initial-key") != 0) {
|
||||
anchortype = STATIC_DNSKEY;
|
||||
} else if (strcasecmp(atstr, "static-ds") == 0) {
|
||||
managed = false;
|
||||
anchortype = STATIC_DS;
|
||||
} else if (strcasecmp(atstr, "initial-key") == 0) {
|
||||
anchortype = INIT_DNSKEY;
|
||||
} else if (strcasecmp(atstr, "initial-ds") == 0) {
|
||||
anchortype = INIT_DS;
|
||||
} else {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
|
||||
"managed key '%s': "
|
||||
"key '%s': "
|
||||
"invalid initialization method '%s'",
|
||||
keynamestr, initmethod);
|
||||
namestr, atstr);
|
||||
result = ISC_R_FAILURE;
|
||||
|
||||
/*
|
||||
* We can't interpret the trust anchor, so
|
||||
* we skip all other checks.
|
||||
*/
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
atstr = "trusted-key";
|
||||
anchortype = TRUSTED;
|
||||
}
|
||||
|
||||
switch(anchortype) {
|
||||
case INIT_DNSKEY:
|
||||
case STATIC_DNSKEY:
|
||||
case TRUSTED:
|
||||
if (n1 > 0xffff) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
|
||||
"flags too big: %u", n1);
|
||||
result = ISC_R_RANGE;
|
||||
}
|
||||
if (n1 & DNS_KEYFLAG_REVOKE) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_WARNING,
|
||||
"key flags revoke bit set");
|
||||
}
|
||||
if (n2 > 0xff) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
|
||||
"protocol too big: %u", n2);
|
||||
result = ISC_R_RANGE;
|
||||
}
|
||||
if (n3 > 0xff) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
|
||||
"algorithm too big: %u\n", n3);
|
||||
result = ISC_R_RANGE;
|
||||
}
|
||||
|
||||
isc_buffer_init(&b, data, sizeof(data));
|
||||
|
||||
str = cfg_obj_asstring(cfg_tuple_get(key, "data"));
|
||||
tresult = isc_base64_decodestring(str, &b);
|
||||
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
|
||||
"%s", isc_result_totext(tresult));
|
||||
result = ISC_R_FAILURE;
|
||||
} else {
|
||||
isc_buffer_usedregion(&b, &r);
|
||||
|
||||
if ((n3 == DST_ALG_RSASHA1) &&
|
||||
r.length > 1 && r.base[0] == 1 && r.base[1] == 3)
|
||||
{
|
||||
cfg_obj_log(key, logctx, ISC_LOG_WARNING,
|
||||
"%s '%s' has a weak exponent",
|
||||
atstr, namestr);
|
||||
}
|
||||
}
|
||||
|
||||
if (result == ISC_R_SUCCESS &&
|
||||
dns_name_equal(keyname, dns_rootname)) {
|
||||
/*
|
||||
* Flag any use of a root key, regardless of content.
|
||||
*/
|
||||
*flagsp |=
|
||||
(managed ? ROOT_KSK_MANAGED : ROOT_KSK_STATIC);
|
||||
|
||||
|
||||
if (n1 == 257 && n2 == 3 && n3 == 8 &&
|
||||
(isc_buffer_usedlength(&b) ==
|
||||
sizeof(root_ksk_2010)) &&
|
||||
memcmp(data, root_ksk_2010,
|
||||
sizeof(root_ksk_2010)) == 0)
|
||||
{
|
||||
*flagsp |= ROOT_KSK_2010;
|
||||
}
|
||||
|
||||
if (n1 == 257 && n2 == 3 && n3 == 8 &&
|
||||
(isc_buffer_usedlength(&b) ==
|
||||
sizeof(root_ksk_2017)) &&
|
||||
memcmp(data, root_ksk_2017,
|
||||
sizeof(root_ksk_2017)) == 0)
|
||||
{
|
||||
*flagsp |= ROOT_KSK_2017;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case INIT_DS:
|
||||
case STATIC_DS:
|
||||
if (n1 > 0xffff) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
|
||||
"key tag too big: %u", n1);
|
||||
result = ISC_R_RANGE;
|
||||
}
|
||||
if (n2 > 0xff) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
|
||||
"algorithm too big: %u\n", n2);
|
||||
result = ISC_R_RANGE;
|
||||
}
|
||||
if (n3 > 0xff) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
|
||||
"digest type too big: %u", 32);
|
||||
result = ISC_R_RANGE;
|
||||
}
|
||||
|
||||
isc_buffer_init(&b, data, sizeof(data));
|
||||
|
||||
str = cfg_obj_asstring(cfg_tuple_get(key, "data"));
|
||||
tresult = isc_hex_decodestring(str, &b);
|
||||
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
|
||||
"%s", isc_result_totext(tresult));
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
if (result == ISC_R_SUCCESS &&
|
||||
dns_name_equal(keyname, dns_rootname)) {
|
||||
/*
|
||||
* Flag any use of a root key, regardless of content.
|
||||
*/
|
||||
*flagsp |=
|
||||
(managed ? ROOT_KSK_MANAGED : ROOT_KSK_STATIC);
|
||||
|
||||
if (n1 == 20326 && n2 == 8 && n3 == 1 &&
|
||||
(isc_buffer_usedlength(&b) ==
|
||||
sizeof(root_ds_1_2017)) &&
|
||||
memcmp(data, root_ds_1_2017,
|
||||
sizeof(root_ds_1_2017)) == 0)
|
||||
{
|
||||
*flagsp |= ROOT_KSK_2017;
|
||||
}
|
||||
|
||||
if (n1 == 20326 && n2 == 8 && n3 == 2 &&
|
||||
(isc_buffer_usedlength(&b) ==
|
||||
sizeof(root_ds_2_2017)) &&
|
||||
memcmp(data, root_ds_2_2017,
|
||||
sizeof(root_ds_2_2017)) == 0)
|
||||
{
|
||||
*flagsp |= ROOT_KSK_2017;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
isc_buffer_init(&b, keydata, sizeof(keydata));
|
||||
|
||||
keystr = cfg_obj_asstring(cfg_tuple_get(key, "key"));
|
||||
tresult = isc_base64_decodestring(keystr, &b);
|
||||
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
|
||||
"%s", isc_result_totext(tresult));
|
||||
result = ISC_R_FAILURE;
|
||||
} else {
|
||||
isc_buffer_usedregion(&b, &r);
|
||||
|
||||
if ((alg == DST_ALG_RSASHA1) &&
|
||||
r.length > 1 && r.base[0] == 1 && r.base[1] == 3)
|
||||
{
|
||||
cfg_obj_log(key, logctx, ISC_LOG_WARNING,
|
||||
"%s key '%s' has a weak exponent",
|
||||
managed ? "initializing" : "static",
|
||||
keynamestr);
|
||||
}
|
||||
}
|
||||
|
||||
if (result == ISC_R_SUCCESS && dns_name_equal(keyname, dns_rootname)) {
|
||||
static const unsigned char root_ksk_2010[] = {
|
||||
0x03, 0x01, 0x00, 0x01, 0xa8, 0x00, 0x20, 0xa9,
|
||||
0x55, 0x66, 0xba, 0x42, 0xe8, 0x86, 0xbb, 0x80,
|
||||
0x4c, 0xda, 0x84, 0xe4, 0x7e, 0xf5, 0x6d, 0xbd,
|
||||
0x7a, 0xec, 0x61, 0x26, 0x15, 0x55, 0x2c, 0xec,
|
||||
0x90, 0x6d, 0x21, 0x16, 0xd0, 0xef, 0x20, 0x70,
|
||||
0x28, 0xc5, 0x15, 0x54, 0x14, 0x4d, 0xfe, 0xaf,
|
||||
0xe7, 0xc7, 0xcb, 0x8f, 0x00, 0x5d, 0xd1, 0x82,
|
||||
0x34, 0x13, 0x3a, 0xc0, 0x71, 0x0a, 0x81, 0x18,
|
||||
0x2c, 0xe1, 0xfd, 0x14, 0xad, 0x22, 0x83, 0xbc,
|
||||
0x83, 0x43, 0x5f, 0x9d, 0xf2, 0xf6, 0x31, 0x32,
|
||||
0x51, 0x93, 0x1a, 0x17, 0x6d, 0xf0, 0xda, 0x51,
|
||||
0xe5, 0x4f, 0x42, 0xe6, 0x04, 0x86, 0x0d, 0xfb,
|
||||
0x35, 0x95, 0x80, 0x25, 0x0f, 0x55, 0x9c, 0xc5,
|
||||
0x43, 0xc4, 0xff, 0xd5, 0x1c, 0xbe, 0x3d, 0xe8,
|
||||
0xcf, 0xd0, 0x67, 0x19, 0x23, 0x7f, 0x9f, 0xc4,
|
||||
0x7e, 0xe7, 0x29, 0xda, 0x06, 0x83, 0x5f, 0xa4,
|
||||
0x52, 0xe8, 0x25, 0xe9, 0xa1, 0x8e, 0xbc, 0x2e,
|
||||
0xcb, 0xcf, 0x56, 0x34, 0x74, 0x65, 0x2c, 0x33,
|
||||
0xcf, 0x56, 0xa9, 0x03, 0x3b, 0xcd, 0xf5, 0xd9,
|
||||
0x73, 0x12, 0x17, 0x97, 0xec, 0x80, 0x89, 0x04,
|
||||
0x1b, 0x6e, 0x03, 0xa1, 0xb7, 0x2d, 0x0a, 0x73,
|
||||
0x5b, 0x98, 0x4e, 0x03, 0x68, 0x73, 0x09, 0x33,
|
||||
0x23, 0x24, 0xf2, 0x7c, 0x2d, 0xba, 0x85, 0xe9,
|
||||
0xdb, 0x15, 0xe8, 0x3a, 0x01, 0x43, 0x38, 0x2e,
|
||||
0x97, 0x4b, 0x06, 0x21, 0xc1, 0x8e, 0x62, 0x5e,
|
||||
0xce, 0xc9, 0x07, 0x57, 0x7d, 0x9e, 0x7b, 0xad,
|
||||
0xe9, 0x52, 0x41, 0xa8, 0x1e, 0xbb, 0xe8, 0xa9,
|
||||
0x01, 0xd4, 0xd3, 0x27, 0x6e, 0x40, 0xb1, 0x14,
|
||||
0xc0, 0xa2, 0xe6, 0xfc, 0x38, 0xd1, 0x9c, 0x2e,
|
||||
0x6a, 0xab, 0x02, 0x64, 0x4b, 0x28, 0x13, 0xf5,
|
||||
0x75, 0xfc, 0x21, 0x60, 0x1e, 0x0d, 0xee, 0x49,
|
||||
0xcd, 0x9e, 0xe9, 0x6a, 0x43, 0x10, 0x3e, 0x52,
|
||||
0x4d, 0x62, 0x87, 0x3d
|
||||
};
|
||||
static const unsigned char root_ksk_2017[] = {
|
||||
0x03, 0x01, 0x00, 0x01, 0xac, 0xff, 0xb4, 0x09,
|
||||
0xbc, 0xc9, 0x39, 0xf8, 0x31, 0xf7, 0xa1, 0xe5,
|
||||
0xec, 0x88, 0xf7, 0xa5, 0x92, 0x55, 0xec, 0x53,
|
||||
0x04, 0x0b, 0xe4, 0x32, 0x02, 0x73, 0x90, 0xa4,
|
||||
0xce, 0x89, 0x6d, 0x6f, 0x90, 0x86, 0xf3, 0xc5,
|
||||
0xe1, 0x77, 0xfb, 0xfe, 0x11, 0x81, 0x63, 0xaa,
|
||||
0xec, 0x7a, 0xf1, 0x46, 0x2c, 0x47, 0x94, 0x59,
|
||||
0x44, 0xc4, 0xe2, 0xc0, 0x26, 0xbe, 0x5e, 0x98,
|
||||
0xbb, 0xcd, 0xed, 0x25, 0x97, 0x82, 0x72, 0xe1,
|
||||
0xe3, 0xe0, 0x79, 0xc5, 0x09, 0x4d, 0x57, 0x3f,
|
||||
0x0e, 0x83, 0xc9, 0x2f, 0x02, 0xb3, 0x2d, 0x35,
|
||||
0x13, 0xb1, 0x55, 0x0b, 0x82, 0x69, 0x29, 0xc8,
|
||||
0x0d, 0xd0, 0xf9, 0x2c, 0xac, 0x96, 0x6d, 0x17,
|
||||
0x76, 0x9f, 0xd5, 0x86, 0x7b, 0x64, 0x7c, 0x3f,
|
||||
0x38, 0x02, 0x9a, 0xbd, 0xc4, 0x81, 0x52, 0xeb,
|
||||
0x8f, 0x20, 0x71, 0x59, 0xec, 0xc5, 0xd2, 0x32,
|
||||
0xc7, 0xc1, 0x53, 0x7c, 0x79, 0xf4, 0xb7, 0xac,
|
||||
0x28, 0xff, 0x11, 0x68, 0x2f, 0x21, 0x68, 0x1b,
|
||||
0xf6, 0xd6, 0xab, 0xa5, 0x55, 0x03, 0x2b, 0xf6,
|
||||
0xf9, 0xf0, 0x36, 0xbe, 0xb2, 0xaa, 0xa5, 0xb3,
|
||||
0x77, 0x8d, 0x6e, 0xeb, 0xfb, 0xa6, 0xbf, 0x9e,
|
||||
0xa1, 0x91, 0xbe, 0x4a, 0xb0, 0xca, 0xea, 0x75,
|
||||
0x9e, 0x2f, 0x77, 0x3a, 0x1f, 0x90, 0x29, 0xc7,
|
||||
0x3e, 0xcb, 0x8d, 0x57, 0x35, 0xb9, 0x32, 0x1d,
|
||||
0xb0, 0x85, 0xf1, 0xb8, 0xe2, 0xd8, 0x03, 0x8f,
|
||||
0xe2, 0x94, 0x19, 0x92, 0x54, 0x8c, 0xee, 0x0d,
|
||||
0x67, 0xdd, 0x45, 0x47, 0xe1, 0x1d, 0xd6, 0x3a,
|
||||
0xf9, 0xc9, 0xfc, 0x1c, 0x54, 0x66, 0xfb, 0x68,
|
||||
0x4c, 0xf0, 0x09, 0xd7, 0x19, 0x7c, 0x2c, 0xf7,
|
||||
0x9e, 0x79, 0x2a, 0xb5, 0x01, 0xe6, 0xa8, 0xa1,
|
||||
0xca, 0x51, 0x9a, 0xf2, 0xcb, 0x9b, 0x5f, 0x63,
|
||||
0x67, 0xe9, 0x4c, 0x0d, 0x47, 0x50, 0x24, 0x51,
|
||||
0x35, 0x7b, 0xe1, 0xb5
|
||||
};
|
||||
|
||||
/*
|
||||
* Flag any use of a root key, regardless of content.
|
||||
*/
|
||||
*keyflags |= (managed ? ROOT_KSK_MANAGED : ROOT_KSK_STATIC);
|
||||
|
||||
if (flags == 257 && proto == 3 && alg == 8 &&
|
||||
isc_buffer_usedlength(&b) == sizeof(root_ksk_2010) &&
|
||||
!memcmp(keydata, root_ksk_2010, sizeof(root_ksk_2010)))
|
||||
{
|
||||
*keyflags |= ROOT_KSK_2010;
|
||||
}
|
||||
|
||||
if (flags == 257 && proto == 3 && alg == 8 &&
|
||||
isc_buffer_usedlength(&b) == sizeof(root_ksk_2017) &&
|
||||
!memcmp(keydata, root_ksk_2017, sizeof(root_ksk_2017)))
|
||||
{
|
||||
*keyflags |= ROOT_KSK_2017;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
|
@ -3322,13 +3442,17 @@ record_static_keys(isc_symtab_t *symtab, isc_mem_t *mctx,
|
|||
continue;
|
||||
}
|
||||
|
||||
init = cfg_tuple_get(obj, "init");
|
||||
init = cfg_tuple_get(obj, "anchortype");
|
||||
if (!cfg_obj_isvoid(init)) {
|
||||
initmethod = cfg_obj_asstring(init);
|
||||
if (strcasecmp(initmethod, "initial-key") == 0) {
|
||||
/* initializing key, skip it */
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp(initmethod, "initial-ds") == 0) {
|
||||
/* initializing key, skip it */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
dns_name_format(name, namebuf, sizeof(namebuf));
|
||||
|
|
@ -3346,7 +3470,7 @@ record_static_keys(isc_symtab_t *symtab, isc_mem_t *mctx,
|
|||
|
||||
if (autovalidation && dns_name_equal(name, dns_rootname)) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"static key for root zone "
|
||||
"static trust anchor for root zone "
|
||||
"cannot be used with "
|
||||
"'dnssec-validation auto'.");
|
||||
ret = ISC_R_FAILURE;
|
||||
|
|
@ -3378,9 +3502,10 @@ check_initializing_keys(isc_symtab_t *symtab, const cfg_obj_t *keylist,
|
|||
const char *str;
|
||||
isc_symvalue_t symvalue;
|
||||
|
||||
init = cfg_tuple_get(obj, "init");
|
||||
init = cfg_tuple_get(obj, "anchortype");
|
||||
if (cfg_obj_isvoid(init) ||
|
||||
strcasecmp(cfg_obj_asstring(init), "static-key") == 0)
|
||||
strcasecmp(cfg_obj_asstring(init), "static-key") == 0 ||
|
||||
strcasecmp(cfg_obj_asstring(init), "static-ds") == 0)
|
||||
{
|
||||
/* static key, skip it */
|
||||
continue;
|
||||
|
|
@ -3414,6 +3539,118 @@ check_initializing_keys(isc_symtab_t *symtab, const cfg_obj_t *keylist,
|
|||
return (ret);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
record_ds_keys(isc_symtab_t *symtab, isc_mem_t *mctx, const cfg_obj_t *keylist)
|
||||
{
|
||||
isc_result_t result, ret = ISC_R_SUCCESS;
|
||||
const cfg_listelt_t *elt;
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *name;
|
||||
char namebuf[DNS_NAME_FORMATSIZE], *p = NULL;
|
||||
|
||||
name = dns_fixedname_initname(&fixed);
|
||||
|
||||
for (elt = cfg_list_first(keylist);
|
||||
elt != NULL;
|
||||
elt = cfg_list_next(elt))
|
||||
{
|
||||
const char *initmethod;
|
||||
const cfg_obj_t *init = NULL;
|
||||
const cfg_obj_t *obj = cfg_listelt_value(elt);
|
||||
const char *str = cfg_obj_asstring(cfg_tuple_get(obj, "name"));
|
||||
isc_symvalue_t symvalue;
|
||||
|
||||
result = dns_name_fromstring(name, str, 0, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
init = cfg_tuple_get(obj, "anchortype");
|
||||
if (!cfg_obj_isvoid(init)) {
|
||||
initmethod = cfg_obj_asstring(init);
|
||||
if (strcasecmp(initmethod, "initial-key") == 0 ||
|
||||
strcasecmp(initmethod, "static-key") == 0)
|
||||
{
|
||||
/* Key-style key, skip it */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
dns_name_format(name, namebuf, sizeof(namebuf));
|
||||
symvalue.as_cpointer = obj;
|
||||
p = isc_mem_strdup(mctx, namebuf);
|
||||
result = isc_symtab_define(symtab, p, 1, symvalue,
|
||||
isc_symexists_reject);
|
||||
if (result == ISC_R_EXISTS) {
|
||||
isc_mem_free(mctx, p);
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
isc_mem_free(mctx, p);
|
||||
ret = result;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
check_non_ds_keys(isc_symtab_t *symtab, const cfg_obj_t *keylist,
|
||||
isc_log_t *logctx)
|
||||
{
|
||||
isc_result_t result, ret = ISC_R_SUCCESS;
|
||||
const cfg_listelt_t *elt;
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *name;
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
|
||||
name = dns_fixedname_initname(&fixed);
|
||||
|
||||
for (elt = cfg_list_first(keylist);
|
||||
elt != NULL;
|
||||
elt = cfg_list_next(elt))
|
||||
{
|
||||
const cfg_obj_t *obj = cfg_listelt_value(elt);
|
||||
const cfg_obj_t *init = NULL;
|
||||
const char *str;
|
||||
isc_symvalue_t symvalue;
|
||||
|
||||
init = cfg_tuple_get(obj, "anchortype");
|
||||
if (cfg_obj_isvoid(init) ||
|
||||
strcasecmp(cfg_obj_asstring(init), "static-ds") == 0 ||
|
||||
strcasecmp(cfg_obj_asstring(init), "initial-ds") == 0)
|
||||
{
|
||||
/* DS-style entry, skip it */
|
||||
continue;
|
||||
}
|
||||
|
||||
str = cfg_obj_asstring(cfg_tuple_get(obj, "name"));
|
||||
result = dns_name_fromstring(name, str, 0, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dns_name_format(name, namebuf, sizeof(namebuf));
|
||||
result = isc_symtab_lookup(symtab, namebuf, 1, &symvalue);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
const char *file = cfg_obj_file(symvalue.as_cpointer);
|
||||
unsigned int line = cfg_obj_line(symvalue.as_cpointer);
|
||||
if (file == NULL) {
|
||||
file = "<unknown file>";
|
||||
}
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"ds-style and key-style keys "
|
||||
"cannot be used for the "
|
||||
"same domain. "
|
||||
"ds-style defined at "
|
||||
"%s:%u", file, line);
|
||||
|
||||
ret = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for conflicts between static and initialiizing keys.
|
||||
*/
|
||||
|
|
@ -3425,27 +3662,38 @@ check_ta_conflicts(const cfg_obj_t *global_dkeys, const cfg_obj_t *view_dkeys,
|
|||
isc_result_t result, tresult;
|
||||
const cfg_listelt_t *elt = NULL;
|
||||
const cfg_obj_t *keylist = NULL;
|
||||
isc_symtab_t *symtab = NULL;
|
||||
isc_symtab_t *statictab = NULL, *dstab = NULL;
|
||||
|
||||
result = isc_symtab_create(mctx, 100, freekey, mctx, false, &symtab);
|
||||
result = isc_symtab_create(mctx, 100, freekey, mctx, false, &statictab);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = isc_symtab_create(mctx, 100, freekey, mctx, false, &dstab);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* First we record all the static keys (i.e., old-style
|
||||
* trusted-keys and dnssec-keys configured with "static-key")
|
||||
* trusted-keys and dnssec-keys configured with "static-key"),
|
||||
* and all the DS-style trust anchors.
|
||||
*/
|
||||
for (elt = cfg_list_first(global_dkeys);
|
||||
elt != NULL;
|
||||
elt = cfg_list_next(elt))
|
||||
{
|
||||
keylist = cfg_listelt_value(elt);
|
||||
tresult = record_static_keys(symtab, mctx, keylist,
|
||||
tresult = record_static_keys(statictab, mctx, keylist,
|
||||
logctx, autovalidation);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = tresult;
|
||||
}
|
||||
|
||||
tresult = record_ds_keys(dstab, mctx, keylist);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = tresult;
|
||||
}
|
||||
}
|
||||
|
||||
for (elt = cfg_list_first(view_dkeys);
|
||||
|
|
@ -3453,11 +3701,16 @@ check_ta_conflicts(const cfg_obj_t *global_dkeys, const cfg_obj_t *view_dkeys,
|
|||
elt = cfg_list_next(elt))
|
||||
{
|
||||
keylist = cfg_listelt_value(elt);
|
||||
tresult = record_static_keys(symtab, mctx, keylist,
|
||||
tresult = record_static_keys(statictab, mctx, keylist,
|
||||
logctx, autovalidation);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = tresult;
|
||||
}
|
||||
|
||||
tresult = record_ds_keys(dstab, mctx, keylist);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = tresult;
|
||||
}
|
||||
}
|
||||
|
||||
for (elt = cfg_list_first(global_tkeys);
|
||||
|
|
@ -3465,7 +3718,7 @@ check_ta_conflicts(const cfg_obj_t *global_dkeys, const cfg_obj_t *view_dkeys,
|
|||
elt = cfg_list_next(elt))
|
||||
{
|
||||
keylist = cfg_listelt_value(elt);
|
||||
tresult = record_static_keys(symtab, mctx, keylist,
|
||||
tresult = record_static_keys(statictab, mctx, keylist,
|
||||
logctx, autovalidation);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = tresult;
|
||||
|
|
@ -3477,24 +3730,29 @@ check_ta_conflicts(const cfg_obj_t *global_dkeys, const cfg_obj_t *view_dkeys,
|
|||
elt = cfg_list_next(elt))
|
||||
{
|
||||
keylist = cfg_listelt_value(elt);
|
||||
tresult = record_static_keys(symtab, mctx, keylist,
|
||||
tresult = record_static_keys(statictab, mctx, keylist,
|
||||
logctx, autovalidation);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = tresult;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Next, ensure that there's no conflict between the
|
||||
* static keys and the dnssec-keys configured with "initial-key"
|
||||
* static keys and the dnssec-keys configured with "initial-key",
|
||||
* or between DS-style and DNSKEY-style dnssec-keys.
|
||||
*/
|
||||
for (elt = cfg_list_first(global_dkeys);
|
||||
elt != NULL;
|
||||
elt = cfg_list_next(elt))
|
||||
{
|
||||
keylist = cfg_listelt_value(elt);
|
||||
tresult = check_initializing_keys(symtab, keylist, logctx);
|
||||
tresult = check_initializing_keys(statictab, keylist, logctx);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = tresult;
|
||||
}
|
||||
|
||||
tresult = check_non_ds_keys(dstab, keylist, logctx);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = tresult;
|
||||
}
|
||||
|
|
@ -3505,15 +3763,23 @@ check_ta_conflicts(const cfg_obj_t *global_dkeys, const cfg_obj_t *view_dkeys,
|
|||
elt = cfg_list_next(elt))
|
||||
{
|
||||
keylist = cfg_listelt_value(elt);
|
||||
tresult = check_initializing_keys(symtab, keylist, logctx);
|
||||
tresult = check_initializing_keys(statictab, keylist, logctx);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = tresult;
|
||||
}
|
||||
|
||||
tresult = check_non_ds_keys(dstab, keylist, logctx);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = tresult;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (symtab != NULL) {
|
||||
isc_symtab_destroy(&symtab);
|
||||
if (statictab != NULL) {
|
||||
isc_symtab_destroy(&statictab);
|
||||
}
|
||||
if (dstab != NULL) {
|
||||
isc_symtab_destroy(&dstab);
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -3898,8 +4164,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
|
|||
element2 = cfg_list_next(element2))
|
||||
{
|
||||
obj = cfg_listelt_value(element2);
|
||||
tresult = check_trusted_key(obj,
|
||||
false,
|
||||
tresult = check_trust_anchor(obj, false,
|
||||
&flags,
|
||||
logctx);
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
|
|
@ -3914,7 +4179,8 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
|
|||
"trusted-keys entry for the root "
|
||||
"zone WILL FAIL after key "
|
||||
"rollover - use dnssec-keys "
|
||||
"with initial-key instead.");
|
||||
"with initial-key "
|
||||
"or initial-ds instead.");
|
||||
}
|
||||
|
||||
tflags |= flags;
|
||||
|
|
@ -3958,8 +4224,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
|
|||
element2 = cfg_list_next(element2))
|
||||
{
|
||||
obj = cfg_listelt_value(element2);
|
||||
tresult = check_trusted_key(obj,
|
||||
true,
|
||||
tresult = check_trust_anchor(obj, true,
|
||||
&flags,
|
||||
logctx);
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
|
|
@ -3971,10 +4236,11 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
|
|||
if ((flags & ROOT_KSK_STATIC) != 0) {
|
||||
cfg_obj_log(check_keys[i], logctx,
|
||||
ISC_LOG_WARNING,
|
||||
"static-key entry for the root "
|
||||
"static entry for the root "
|
||||
"zone WILL FAIL after key "
|
||||
"rollover - use dnssec-keys "
|
||||
"with initial-key instead.");
|
||||
"with initial-key "
|
||||
"or initial-ds instead.");
|
||||
}
|
||||
|
||||
if ((flags & ROOT_KSK_2010) != 0 &&
|
||||
|
|
@ -4001,7 +4267,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
|
|||
if ((dflags & ROOT_KSK_ANY) == ROOT_KSK_ANY) {
|
||||
keys = (view_dkeys != NULL) ? view_dkeys : global_dkeys;
|
||||
cfg_obj_log(keys, logctx, ISC_LOG_WARNING,
|
||||
"both initial-key and static-key entries for the "
|
||||
"both initial and static entries for the "
|
||||
"root zone are present");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,13 @@
|
|||
#define RESOLVER_NTASKS 31
|
||||
#endif /* TUNE_LARGE */
|
||||
|
||||
#define CHECK(r) \
|
||||
do { \
|
||||
result = (r); \
|
||||
if (result != ISC_R_SUCCESS) \
|
||||
goto cleanup; \
|
||||
} while (0)
|
||||
|
||||
/*%
|
||||
* DNS client object
|
||||
*/
|
||||
|
|
@ -1482,12 +1489,19 @@ dns_client_destroyrestrans(dns_clientrestrans_t **transp) {
|
|||
|
||||
isc_result_t
|
||||
dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
|
||||
const dns_name_t *keyname, isc_buffer_t *keydatabuf)
|
||||
dns_rdatatype_t rdtype, const dns_name_t *keyname,
|
||||
isc_buffer_t *databuf)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_view_t *view = NULL;
|
||||
dst_key_t *dstkey = NULL;
|
||||
dns_keytable_t *secroots = NULL;
|
||||
dns_name_t *name = NULL;
|
||||
char dsbuf[DNS_DS_BUFFERSIZE];
|
||||
dns_rdata_ds_t ds;
|
||||
dns_decompress_t dctx;
|
||||
dns_rdata_t rdata;
|
||||
isc_buffer_t b;
|
||||
|
||||
REQUIRE(DNS_CLIENT_VALID(client));
|
||||
|
||||
|
|
@ -1495,27 +1509,49 @@ dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
|
|||
result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME,
|
||||
rdclass, &view);
|
||||
UNLOCK(&client->lock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
CHECK(result);
|
||||
|
||||
result = dns_view_getsecroots(view, &secroots);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
CHECK(dns_view_getsecroots(view, &secroots));
|
||||
|
||||
result = dst_key_fromdns(keyname, rdclass, keydatabuf, client->mctx,
|
||||
&dstkey);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
DE_CONST(keyname, name);
|
||||
|
||||
result = dns_keytable_add(secroots, false, false, &dstkey);
|
||||
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:
|
||||
result = ISC_R_NOTIMPLEMENTED;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (dstkey != NULL)
|
||||
if (dstkey != NULL) {
|
||||
dst_key_free(&dstkey);
|
||||
if (view != NULL)
|
||||
}
|
||||
if (view != NULL) {
|
||||
dns_view_detach(&view);
|
||||
if (secroots != NULL)
|
||||
}
|
||||
if (secroots != NULL) {
|
||||
dns_keytable_detach(&secroots);
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2270,3 +2270,53 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||
failure:
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_dnssec_matchdskey(dns_name_t *name, dns_rdata_t *dsrdata,
|
||||
dns_rdataset_t *keyset, dns_rdata_t *keyrdata)
|
||||
{
|
||||
isc_result_t result;
|
||||
unsigned char buf[DNS_DS_BUFFERSIZE];
|
||||
dns_keytag_t keytag;
|
||||
dns_rdata_dnskey_t key;
|
||||
dns_rdata_ds_t ds;
|
||||
isc_region_t r;
|
||||
|
||||
result = dns_rdata_tostruct(dsrdata, &ds, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
for (result = dns_rdataset_first(keyset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(keyset))
|
||||
{
|
||||
dns_rdata_t newdsrdata = DNS_RDATA_INIT;
|
||||
|
||||
dns_rdata_reset(keyrdata);
|
||||
dns_rdataset_current(keyset, keyrdata);
|
||||
|
||||
result = dns_rdata_tostruct(keyrdata, &key, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
dns_rdata_toregion(keyrdata, &r);
|
||||
keytag = dst_region_computeid(&r);
|
||||
|
||||
if (ds.key_tag != keytag || ds.algorithm != key.algorithm) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result = dns_ds_buildrdata(name, keyrdata, ds.digest_type,
|
||||
buf, &newdsrdata);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dns_rdata_compare(dsrdata, &newdsrdata) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result == ISC_R_NOMORE) {
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -385,11 +385,13 @@ dns_client_freeresanswer(dns_client_t *client, dns_namelist_t *namelist);
|
|||
|
||||
isc_result_t
|
||||
dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
|
||||
const dns_name_t *keyname, isc_buffer_t *keydatabuf);
|
||||
dns_rdatatype_t rdtype, const dns_name_t *keyname,
|
||||
isc_buffer_t *keydatabuf);
|
||||
/*%<
|
||||
* Add a DNSSEC trusted key for the 'rdclass' class. A view for the 'rdclass'
|
||||
* class must be created beforehand. 'keyname' is the DNS name of the key,
|
||||
* and 'keydatabuf' stores the resource data of the key.
|
||||
* class must be created beforehand. 'rdtype' is the type of the RR data
|
||||
* for the key, either DNSKEY or DS. 'keyname' is the DNS name of the key,
|
||||
* and 'keydatabuf' stores the RR data.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -360,6 +360,18 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys,
|
|||
* Update the CDS and CDNSKEY RRsets, adding and removing keys as needed.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_dnssec_matchdskey(dns_name_t *name, dns_rdata_t *dsrdata,
|
||||
dns_rdataset_t *keyset, dns_rdata_t *keyrdata);
|
||||
/*%<
|
||||
* Given a DS rdata and a DNSKEY RRset, find the DNSKEY rdata that matches
|
||||
* the DS, and place it in 'keyrdata'.
|
||||
*
|
||||
* Returns:
|
||||
*\li ISC_R_SUCCESS
|
||||
*\li ISC_R_NOTFOUND
|
||||
*\li Other values indicate error
|
||||
*/
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_DNSSEC_H */
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include <isc/rwlock.h>
|
||||
#include <isc/stdtime.h>
|
||||
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
#include <dst/dst.h>
|
||||
|
|
@ -105,10 +106,14 @@ dns_keytable_detach(dns_keytable_t **keytablep);
|
|||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_keytable_add(dns_keytable_t *keytable, bool managed,
|
||||
bool initial, dst_key_t **keyp);
|
||||
dns_keytable_add(dns_keytable_t *keytable,
|
||||
bool managed, bool initial,
|
||||
dns_name_t *name, dst_key_t **keyp, dns_rdata_ds_t *ds);
|
||||
/*%<
|
||||
* Add '*keyp' to 'keytable' (using the name in '*keyp').
|
||||
* 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'.
|
||||
*
|
||||
* The value of keynode->managed is set to 'managed', and the
|
||||
* value of keynode->initial is set to 'initial'. (Note: 'initial'
|
||||
* should only be used when adding managed-keys from configuration.
|
||||
|
|
@ -119,6 +124,12 @@ dns_keytable_add(dns_keytable_t *keytable, bool managed,
|
|||
* 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.
|
||||
*
|
||||
|
|
@ -407,6 +418,19 @@ dns_keynode_key(dns_keynode_t *keynode);
|
|||
* Get the DST key associated with keynode.
|
||||
*/
|
||||
|
||||
dns_rdataset_t *
|
||||
dns_keynode_dsset(dns_keynode_t *keynode);
|
||||
/*%<
|
||||
* Return a pointer to the DS RRset associated with 'keynode'.
|
||||
*
|
||||
* Returns:
|
||||
*\li ISC_R_SUCCESS
|
||||
*\li ISC_R_FAILURE if the keynode does not contain a DS trust anchor.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'keynode' is valid.
|
||||
*/
|
||||
|
||||
bool
|
||||
dns_keynode_managed(dns_keynode_t *keynode);
|
||||
/*%<
|
||||
|
|
@ -453,7 +477,8 @@ dns_keynode_detachall(isc_mem_t *mctx, dns_keynode_t **target);
|
|||
|
||||
isc_result_t
|
||||
dns_keytable_forall(dns_keytable_t *keytable,
|
||||
void (*func)(dns_keytable_t *, dns_keynode_t *, void *),
|
||||
void (*func)(dns_keytable_t *, dns_keynode_t *,
|
||||
dns_name_t *, void *),
|
||||
void *arg);
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@
|
|||
#include <dns/keytable.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/rbt.h>
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdatalist.h>
|
||||
#include <dns/rdataset.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/result.h>
|
||||
|
||||
#define KEYTABLE_MAGIC ISC_MAGIC('K', 'T', 'b', 'l')
|
||||
|
|
@ -46,10 +50,12 @@ struct dns_keytable {
|
|||
struct dns_keynode {
|
||||
unsigned int magic;
|
||||
isc_refcount_t refcount;
|
||||
dst_key_t * key;
|
||||
dst_key_t *key;
|
||||
dns_rdatalist_t *dslist;
|
||||
dns_rdataset_t dsset;
|
||||
bool managed;
|
||||
bool initial;
|
||||
struct dns_keynode * next;
|
||||
struct dns_keynode *next;
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
@ -135,12 +141,32 @@ dns_keytable_detach(dns_keytable_t **keytablep) {
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_dslist(isc_mem_t *mctx, dns_keynode_t *knode) {
|
||||
dns_rdata_t *rdata = NULL;
|
||||
|
||||
for (rdata = ISC_LIST_HEAD(knode->dslist->rdata);
|
||||
rdata != NULL;
|
||||
rdata = ISC_LIST_HEAD(knode->dslist->rdata))
|
||||
{
|
||||
ISC_LIST_UNLINK(knode->dslist->rdata, rdata, link);
|
||||
isc_mem_put(mctx, rdata->data, DNS_DS_BUFFERSIZE);
|
||||
isc_mem_put(mctx, rdata, sizeof(*rdata));
|
||||
}
|
||||
|
||||
isc_mem_put(mctx, knode->dslist, sizeof(*knode->dslist));
|
||||
knode->dslist = NULL;
|
||||
}
|
||||
|
||||
/*%
|
||||
* Search "node" for either a null key node or a key node for the exact same
|
||||
* key as the one supplied in "keyp" and, if found, update it accordingly.
|
||||
* Search "node" for an empty or DS-style keynode, or a keynode for the
|
||||
* exact same key as the one supplied in "keyp" and, if found, update it
|
||||
* accordingly.
|
||||
*/
|
||||
static isc_result_t
|
||||
update_keynode(dst_key_t **keyp, dns_rbtnode_t *node, bool initial) {
|
||||
update_keynode(dns_keytable_t *keytable, dns_rbtnode_t *node,
|
||||
dst_key_t **keyp, bool initial)
|
||||
{
|
||||
dns_keynode_t *knode;
|
||||
|
||||
REQUIRE(keyp != NULL && *keyp != NULL);
|
||||
|
|
@ -149,13 +175,17 @@ update_keynode(dst_key_t **keyp, dns_rbtnode_t *node, bool initial) {
|
|||
for (knode = node->data; knode != NULL; knode = knode->next) {
|
||||
if (knode->key == NULL) {
|
||||
/*
|
||||
* Null key node found. Attach the supplied key to it,
|
||||
* making it a non-null key node and transferring key
|
||||
* Null or DS-style keynode found. Detach
|
||||
* the DS rdatalist if present. Attach the
|
||||
* supplied key to it, transferring key
|
||||
* ownership to the keytable.
|
||||
*/
|
||||
if (knode->dslist != NULL) {
|
||||
free_dslist(keytable->mctx, knode);
|
||||
}
|
||||
|
||||
knode->key = *keyp;
|
||||
*keyp = NULL;
|
||||
return (ISC_R_SUCCESS);
|
||||
} else if (dst_key_compare(knode->key, *keyp)) {
|
||||
/*
|
||||
* Key node found for the supplied key. Free the
|
||||
|
|
@ -163,11 +193,15 @@ update_keynode(dst_key_t **keyp, dns_rbtnode_t *node, bool initial) {
|
|||
* node's flags if necessary.
|
||||
*/
|
||||
dst_key_free(keyp);
|
||||
if (!initial) {
|
||||
dns_keynode_trust(knode);
|
||||
}
|
||||
return (ISC_R_SUCCESS);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!initial) {
|
||||
dns_keynode_trust(knode);
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
return (ISC_R_NOTFOUND);
|
||||
|
|
@ -179,9 +213,9 @@ update_keynode(dst_key_t **keyp, dns_rbtnode_t *node, bool initial) {
|
|||
* one attached to "node" in "keytable".
|
||||
*/
|
||||
static isc_result_t
|
||||
prepend_keynode(dst_key_t **keyp, dns_rbtnode_t *node,
|
||||
dns_keytable_t *keytable, bool managed,
|
||||
bool initial)
|
||||
prepend_keynode(dst_key_t **keyp, dns_rdata_ds_t *ds,
|
||||
dns_rbtnode_t *node, dns_keytable_t *keytable,
|
||||
bool managed, bool initial)
|
||||
{
|
||||
dns_keynode_t *knode = NULL;
|
||||
isc_result_t result;
|
||||
|
|
@ -196,15 +230,60 @@ prepend_keynode(dst_key_t **keyp, dns_rbtnode_t *node,
|
|||
}
|
||||
|
||||
/*
|
||||
* If a key was supplied, transfer its ownership to the keytable.
|
||||
* If a dst_key was supplied, transfer its ownership to the keytable.
|
||||
* Otherwise, if a DS was supplied, append it to the rdatalist
|
||||
* (initializing if necessary).
|
||||
*/
|
||||
if (keyp) {
|
||||
if (keyp != NULL) {
|
||||
if (knode->dslist != NULL) {
|
||||
free_dslist(keytable->mctx, knode);
|
||||
}
|
||||
knode->key = *keyp;
|
||||
*keyp = NULL;
|
||||
} else if (ds != NULL) {
|
||||
dns_rdata_t *rdata = NULL;
|
||||
void *data = NULL;
|
||||
isc_buffer_t b;
|
||||
|
||||
if (knode->dslist == NULL) {
|
||||
knode->dslist = isc_mem_get(keytable->mctx,
|
||||
sizeof(*knode->dslist));
|
||||
dns_rdatalist_init(knode->dslist);
|
||||
knode->dslist->rdclass = dns_rdataclass_in;
|
||||
knode->dslist->type = dns_rdatatype_ds;
|
||||
knode->dslist->ttl = 0;
|
||||
}
|
||||
|
||||
rdata = isc_mem_get(keytable->mctx, sizeof(*rdata));
|
||||
dns_rdata_init(rdata);
|
||||
|
||||
data = isc_mem_get(keytable->mctx, DNS_DS_BUFFERSIZE);
|
||||
isc_buffer_init(&b, data, DNS_DS_BUFFERSIZE);
|
||||
|
||||
result = dns_rdata_fromstruct(rdata, dns_rdataclass_in,
|
||||
dns_rdatatype_ds, ds, &b);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
ISC_LIST_APPEND(knode->dslist->rdata, rdata, link);
|
||||
|
||||
if (dns_rdataset_isassociated(&knode->dsset)) {
|
||||
dns_rdataset_disassociate(&knode->dsset);
|
||||
}
|
||||
|
||||
result = dns_rdatalist_tordataset(knode->dslist,
|
||||
&knode->dsset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
knode->dsset.trust = dns_trust_ultimate;
|
||||
}
|
||||
|
||||
knode->managed = managed;
|
||||
knode->initial = initial;
|
||||
|
||||
knode->next = node->data;
|
||||
node->data = knode;
|
||||
|
||||
|
|
@ -219,7 +298,7 @@ prepend_keynode(dst_key_t **keyp, dns_rbtnode_t *node,
|
|||
*/
|
||||
static isc_result_t
|
||||
insert(dns_keytable_t *keytable, bool managed, bool initial,
|
||||
const dns_name_t *keyname, dst_key_t **keyp)
|
||||
const dns_name_t *keyname, dst_key_t **keyp, dns_rdata_ds_t *ds)
|
||||
{
|
||||
dns_rbtnode_t *node = NULL;
|
||||
isc_result_t result;
|
||||
|
|
@ -232,17 +311,17 @@ insert(dns_keytable_t *keytable, bool managed, bool initial,
|
|||
if (result == ISC_R_SUCCESS) {
|
||||
/*
|
||||
* There was no node for "keyname" in "keytable" yet, so one
|
||||
* was created. Create a new key node for the supplied key (or
|
||||
* a null key node if "keyp" is NULL) and attach it to the
|
||||
* created node.
|
||||
* was created. Create a new key node for the supplied
|
||||
* trust anchor (or a null key node if both "keyp" and
|
||||
* "ds" are NULL) and attach it to the created node.
|
||||
*/
|
||||
result = prepend_keynode(keyp, node, keytable, managed,
|
||||
initial);
|
||||
result = prepend_keynode(keyp, ds, node, keytable,
|
||||
managed, initial);
|
||||
} else if (result == ISC_R_EXISTS) {
|
||||
/*
|
||||
* A node already exists for "keyname" in "keytable".
|
||||
*/
|
||||
if (keyp == NULL) {
|
||||
if (keyp == NULL && ds == NULL) {
|
||||
/*
|
||||
* We were told to add a null key at "keyname", which
|
||||
* means there is nothing left to do as there is either
|
||||
|
|
@ -252,7 +331,7 @@ insert(dns_keytable_t *keytable, bool managed, bool initial,
|
|||
* "keyname" is already marked as secure.
|
||||
*/
|
||||
result = ISC_R_SUCCESS;
|
||||
} else {
|
||||
} else if (keyp != NULL) {
|
||||
/*
|
||||
* We were told to add the key supplied in "keyp" at
|
||||
* "keyname". Try to find an already existing key node
|
||||
|
|
@ -260,7 +339,7 @@ insert(dns_keytable_t *keytable, bool managed, bool initial,
|
|||
* node or a key node for the exact same key) and, if
|
||||
* found, update it accordingly.
|
||||
*/
|
||||
result = update_keynode(keyp, node, initial);
|
||||
result = update_keynode(keytable, node, keyp, initial);
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
/*
|
||||
* The node for "keyname" only contains key
|
||||
|
|
@ -268,9 +347,13 @@ insert(dns_keytable_t *keytable, bool managed, bool initial,
|
|||
* one. Create a new key node for the supplied
|
||||
* key and prepend it before the others.
|
||||
*/
|
||||
result = prepend_keynode(keyp, node, keytable,
|
||||
result = prepend_keynode(keyp, NULL,
|
||||
node, keytable,
|
||||
managed, initial);
|
||||
}
|
||||
} else if (ds != NULL) {
|
||||
result = prepend_keynode(NULL, ds, node, keytable,
|
||||
managed, initial);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -280,17 +363,19 @@ insert(dns_keytable_t *keytable, bool managed, bool initial,
|
|||
}
|
||||
|
||||
isc_result_t
|
||||
dns_keytable_add(dns_keytable_t *keytable, bool managed,
|
||||
bool initial, dst_key_t **keyp)
|
||||
dns_keytable_add(dns_keytable_t *keytable,
|
||||
bool managed, bool initial,
|
||||
dns_name_t *name, dst_key_t **keyp, dns_rdata_ds_t *ds)
|
||||
{
|
||||
REQUIRE(keyp != NULL && *keyp != NULL);
|
||||
REQUIRE(keyp == NULL || *keyp != NULL);
|
||||
REQUIRE(keyp != NULL || ds != NULL);
|
||||
REQUIRE(!initial || managed);
|
||||
return (insert(keytable, managed, initial, dst_key_name(*keyp), keyp));
|
||||
return (insert(keytable, managed, initial, name, keyp, ds));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_keytable_marksecure(dns_keytable_t *keytable, const dns_name_t *name) {
|
||||
return (insert(keytable, true, false, name, NULL));
|
||||
return (insert(keytable, true, false, name, NULL, NULL));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
|
@ -420,8 +505,9 @@ dns_keytable_nextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
|
|||
REQUIRE(VALID_KEYNODE(keynode));
|
||||
REQUIRE(nextnodep != NULL && *nextnodep == NULL);
|
||||
|
||||
if (keynode->next == NULL)
|
||||
if (keynode->next == NULL) {
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
|
||||
dns_keynode_attach(keynode->next, nextnodep);
|
||||
isc_refcount_increment(&keytable->active_nodes);
|
||||
|
|
@ -459,25 +545,29 @@ dns_keytable_findkeynode(dns_keytable_t *keytable, const dns_name_t *name,
|
|||
knode = NULL;
|
||||
data = NULL;
|
||||
result = dns_rbt_findname(keytable->table, name, 0, NULL, &data);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
INSIST(data != NULL);
|
||||
|
||||
for (knode = data; knode != NULL; knode = knode->next) {
|
||||
if (knode->key == NULL) {
|
||||
knode = NULL;
|
||||
break;
|
||||
}
|
||||
if (algorithm == dst_key_alg(knode->key)
|
||||
&& tag == dst_key_id(knode->key))
|
||||
if (algorithm == dst_key_alg(knode->key) &&
|
||||
tag == dst_key_id(knode->key))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (knode != NULL) {
|
||||
isc_refcount_increment0(&keytable->active_nodes);
|
||||
dns_keynode_attach(knode, keynodep);
|
||||
} else
|
||||
} else {
|
||||
result = DNS_R_PARTIALMATCH;
|
||||
} else if (result == DNS_R_PARTIALMATCH)
|
||||
}
|
||||
} else if (result == DNS_R_PARTIALMATCH) {
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
|
||||
RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
|
||||
|
||||
|
|
@ -507,14 +597,17 @@ dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
|
|||
}
|
||||
if (dst_key_alg(keynode->key) == dst_key_alg(knode->key) &&
|
||||
dst_key_id(keynode->key) == dst_key_id(knode->key))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (knode != NULL) {
|
||||
isc_refcount_increment(&keytable->active_nodes);
|
||||
result = ISC_R_SUCCESS;
|
||||
dns_keynode_attach(knode, nextnodep);
|
||||
} else
|
||||
} else {
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -539,8 +632,9 @@ dns_keytable_finddeepestmatch(dns_keytable_t *keytable, const dns_name_t *name,
|
|||
data = NULL;
|
||||
result = dns_rbt_findname(keytable->table, name, 0, foundname, &data);
|
||||
|
||||
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
|
||||
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
|
||||
|
||||
|
|
@ -616,8 +710,9 @@ putstr(isc_buffer_t **b, const char *str) {
|
|||
isc_result_t result;
|
||||
|
||||
result = isc_buffer_reserve(b, strlen(str));
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_buffer_putstr(*b, str);
|
||||
return (ISC_R_SUCCESS);
|
||||
|
|
@ -639,9 +734,9 @@ dns_keytable_dump(dns_keytable_t *keytable, FILE *fp) {
|
|||
|
||||
if (isc_buffer_usedlength(text) != 0) {
|
||||
(void) putstr(&text, "\n");
|
||||
} else if (result == ISC_R_SUCCESS)
|
||||
} else if (result == ISC_R_SUCCESS) {
|
||||
(void) putstr(&text, "none");
|
||||
else {
|
||||
} else {
|
||||
(void) putstr(&text, "could not dump key table: ");
|
||||
(void) putstr(&text, isc_result_totext(result));
|
||||
}
|
||||
|
|
@ -653,44 +748,112 @@ dns_keytable_dump(dns_keytable_t *keytable, FILE *fp) {
|
|||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
keynode_dslist_totext(dns_name_t *name, dns_keynode_t *keynode,
|
||||
isc_buffer_t **text)
|
||||
{
|
||||
isc_result_t result;
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
char obuf[DNS_NAME_FORMATSIZE + 200];
|
||||
dns_rdataset_t *dsset = NULL;
|
||||
|
||||
dns_name_format(name, namebuf, sizeof(namebuf));
|
||||
|
||||
dsset = dns_keynode_dsset(keynode);
|
||||
|
||||
for (result = dns_rdataset_first(dsset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(dsset))
|
||||
{
|
||||
char algbuf[DNS_SECALG_FORMATSIZE];
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_ds_t ds;
|
||||
|
||||
dns_rdataset_current(dsset, &rdata);
|
||||
result = dns_rdata_tostruct(&rdata, &ds, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
dns_secalg_format(ds.algorithm, algbuf, sizeof(algbuf));
|
||||
|
||||
snprintf(obuf, sizeof(obuf), "%s/%s/%d ; %s%s (DS)\n",
|
||||
namebuf, algbuf, ds.key_tag,
|
||||
keynode->initial ? "initializing " : "",
|
||||
keynode->managed ? "managed" : "static");
|
||||
|
||||
result = putstr(text, obuf);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **text) {
|
||||
isc_result_t result;
|
||||
dns_keynode_t *knode;
|
||||
dns_rbtnode_t *node;
|
||||
dns_rbtnodechain_t chain;
|
||||
dns_name_t *foundname, *origin, *fullname;
|
||||
dns_fixedname_t fixedfoundname, fixedorigin, fixedfullname;
|
||||
|
||||
REQUIRE(VALID_KEYTABLE(keytable));
|
||||
REQUIRE(text != NULL && *text != NULL);
|
||||
|
||||
origin = dns_fixedname_initname(&fixedorigin);
|
||||
fullname = dns_fixedname_initname(&fixedfullname);
|
||||
foundname = dns_fixedname_initname(&fixedfoundname);
|
||||
|
||||
RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
|
||||
dns_rbtnodechain_init(&chain);
|
||||
result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL);
|
||||
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
|
||||
if (result == ISC_R_NOTFOUND)
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
for (;;) {
|
||||
char pbuf[DST_KEY_FORMATSIZE];
|
||||
|
||||
dns_rbtnodechain_current(&chain, NULL, NULL, &node);
|
||||
for (knode = node->data; knode != NULL; knode = knode->next) {
|
||||
dns_rbtnodechain_current(&chain, foundname, origin, &node);
|
||||
|
||||
knode = node->data;
|
||||
if (knode != NULL && knode->dslist != NULL) {
|
||||
result = dns_name_concatenate(foundname, origin,
|
||||
fullname, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = keynode_dslist_totext(fullname, knode, text);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (; knode != NULL; knode = knode->next) {
|
||||
char obuf[DNS_NAME_FORMATSIZE + 200];
|
||||
if (knode->key == NULL)
|
||||
|
||||
if (knode->key == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dst_key_format(knode->key, pbuf, sizeof(pbuf));
|
||||
snprintf(obuf, sizeof(obuf), "%s ; %s%s\n", pbuf,
|
||||
knode->initial ? "initializing " : "",
|
||||
knode->managed ? "managed" : "static");
|
||||
|
||||
result = putstr(text, obuf);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result = dns_rbtnodechain_next(&chain, NULL, NULL);
|
||||
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
|
||||
if (result == ISC_R_NOMORE)
|
||||
if (result == ISC_R_NOMORE) {
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -703,32 +866,45 @@ dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **text) {
|
|||
|
||||
isc_result_t
|
||||
dns_keytable_forall(dns_keytable_t *keytable,
|
||||
void (*func)(dns_keytable_t *, dns_keynode_t *, void *),
|
||||
void (*func)(dns_keytable_t *, dns_keynode_t *,
|
||||
dns_name_t *, void *),
|
||||
void *arg)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_rbtnode_t *node;
|
||||
dns_rbtnodechain_t chain;
|
||||
dns_fixedname_t fixedfoundname, fixedorigin, fixedfullname;
|
||||
dns_name_t *foundname, *origin, *fullname;
|
||||
|
||||
REQUIRE(VALID_KEYTABLE(keytable));
|
||||
|
||||
origin = dns_fixedname_initname(&fixedorigin);
|
||||
fullname = dns_fixedname_initname(&fixedfullname);
|
||||
foundname = dns_fixedname_initname(&fixedfoundname);
|
||||
|
||||
RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
|
||||
dns_rbtnodechain_init(&chain);
|
||||
result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL);
|
||||
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
|
||||
if (result == ISC_R_NOTFOUND)
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
isc_refcount_increment0(&keytable->active_nodes);
|
||||
for (;;) {
|
||||
dns_rbtnodechain_current(&chain, NULL, NULL, &node);
|
||||
if (node->data != NULL)
|
||||
(*func)(keytable, node->data, arg);
|
||||
dns_rbtnodechain_current(&chain, foundname, origin, &node);
|
||||
if (node->data != NULL) {
|
||||
result = dns_name_concatenate(foundname, origin,
|
||||
fullname, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
(*func)(keytable, node->data, fullname, arg);
|
||||
}
|
||||
result = dns_rbtnodechain_next(&chain, NULL, NULL);
|
||||
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
|
||||
if (result == ISC_R_NOMORE)
|
||||
if (result == ISC_R_NOMORE) {
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -747,6 +923,17 @@ dns_keynode_key(dns_keynode_t *keynode) {
|
|||
return (keynode->key);
|
||||
}
|
||||
|
||||
dns_rdataset_t *
|
||||
dns_keynode_dsset(dns_keynode_t *keynode) {
|
||||
REQUIRE(VALID_KEYNODE(keynode));
|
||||
|
||||
if (keynode->dslist != NULL) {
|
||||
return (&keynode->dsset);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
dns_keynode_managed(dns_keynode_t *keynode) {
|
||||
REQUIRE(VALID_KEYNODE(keynode));
|
||||
|
|
@ -780,6 +967,8 @@ dns_keynode_create(isc_mem_t *mctx, dns_keynode_t **target) {
|
|||
knode->managed = false;
|
||||
knode->initial = false;
|
||||
knode->key = NULL;
|
||||
knode->dslist = NULL;
|
||||
dns_rdataset_init(&knode->dsset);
|
||||
knode->next = NULL;
|
||||
|
||||
isc_refcount_init(&knode->refcount, 1);
|
||||
|
|
@ -796,17 +985,23 @@ dns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target) {
|
|||
}
|
||||
|
||||
void
|
||||
dns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **keynode) {
|
||||
REQUIRE(keynode != NULL && VALID_KEYNODE(*keynode));
|
||||
dns_keynode_t *node = *keynode;
|
||||
*keynode = NULL;
|
||||
dns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **keynodep) {
|
||||
REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep));
|
||||
dns_keynode_t *knode = *keynodep;
|
||||
*keynodep = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&node->refcount) == 1) {
|
||||
isc_refcount_destroy(&node->refcount);
|
||||
if (node->key != NULL) {
|
||||
dst_key_free(&node->key);
|
||||
if (isc_refcount_decrement(&knode->refcount) == 1) {
|
||||
isc_refcount_destroy(&knode->refcount);
|
||||
if (knode->key != NULL) {
|
||||
dst_key_free(&knode->key);
|
||||
}
|
||||
isc_mem_put(mctx, node, sizeof(dns_keynode_t));
|
||||
if (knode->dslist != NULL) {
|
||||
if (dns_rdataset_isassociated(&knode->dsset)) {
|
||||
dns_rdataset_disassociate(&knode->dsset);
|
||||
}
|
||||
free_dslist(mctx, knode);
|
||||
}
|
||||
isc_mem_put(mctx, knode, sizeof(dns_keynode_t));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -155,12 +155,14 @@ create_tables() {
|
|||
|
||||
/* Add a normal key */
|
||||
create_key(257, 3, 5, "example.com", keystr1, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false, &key),
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
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, &key),
|
||||
assert_int_equal(dns_keytable_add(keytable, true, true,
|
||||
dst_key_name(key), &key, NULL),
|
||||
ISC_R_SUCCESS);
|
||||
|
||||
/* Add a null key */
|
||||
|
|
@ -216,7 +218,8 @@ add_test(void **state) {
|
|||
* nextkeynode() should still return NOTFOUND.
|
||||
*/
|
||||
create_key(257, 3, 5, "example.com", keystr1, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false, &key),
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_nextkeynode(keytable, keynode,
|
||||
&next_keynode),
|
||||
|
|
@ -225,7 +228,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, &key),
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("example.com"),
|
||||
&keynode),
|
||||
|
|
@ -259,7 +263,8 @@ add_test(void **state) {
|
|||
* ISC_R_NOTFOUND and that the added key is an initializing key.
|
||||
*/
|
||||
create_key(257, 3, 5, "managed.com", keystr2, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, true, true, &key),
|
||||
assert_int_equal(dns_keytable_add(keytable, true, true,
|
||||
dst_key_name(key), &key, NULL),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("managed.com"),
|
||||
&keynode),
|
||||
|
|
@ -278,7 +283,8 @@ add_test(void **state) {
|
|||
* 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, &key),
|
||||
assert_int_equal(dns_keytable_add(keytable, true, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("managed.com"),
|
||||
&keynode),
|
||||
|
|
@ -302,7 +308,8 @@ add_test(void **state) {
|
|||
* that the added key is an initializing key.
|
||||
*/
|
||||
create_key(257, 3, 5, "two.com", keystr1, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, true, true, &key),
|
||||
assert_int_equal(dns_keytable_add(keytable, true, true,
|
||||
dst_key_name(key), &key, NULL),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("two.com"),
|
||||
&keynode),
|
||||
|
|
@ -319,7 +326,8 @@ add_test(void **state) {
|
|||
* ISC_R_NOTFOUND and that the added key is not an initializing key.
|
||||
*/
|
||||
create_key(257, 3, 5, "two.com", keystr2, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, true, false, &key),
|
||||
assert_int_equal(dns_keytable_add(keytable, true, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("two.com"),
|
||||
&keynode),
|
||||
|
|
@ -337,7 +345,8 @@ add_test(void **state) {
|
|||
* 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, &key),
|
||||
assert_int_equal(dns_keytable_add(keytable, true, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("two.com"),
|
||||
&keynode),
|
||||
|
|
@ -363,7 +372,8 @@ add_test(void **state) {
|
|||
&null_keynode),
|
||||
ISC_R_SUCCESS);
|
||||
create_key(257, 3, 5, "null.example", keystr2, &key);
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false, &key),
|
||||
assert_int_equal(dns_keytable_add(keytable, false, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_keytable_find(keytable, str2name("null.example"),
|
||||
&keynode),
|
||||
|
|
@ -663,7 +673,8 @@ nta_test(void **state) {
|
|||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
create_key(257, 3, 5, "example", keystr1, &key);
|
||||
result = dns_keytable_add(keytable, false, false, &key);
|
||||
result = dns_keytable_add(keytable, false, false,
|
||||
dst_key_name(key), &key, NULL),
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_stdtime_get(&now);
|
||||
|
|
|
|||
|
|
@ -1684,49 +1684,6 @@ check_signer(dns_validator_t *val, dns_rdata_t *keyrdata,
|
|||
return (result);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Find the DNSKEY that corresponds to the DS.
|
||||
*/
|
||||
static isc_result_t
|
||||
dnskey_for_ds(dns_validator_t *val, dns_rdataset_t *rdataset,
|
||||
dns_rdata_t *dsrdata, dns_rdata_ds_t *ds, dns_rdata_t *keyrdata)
|
||||
{
|
||||
dns_keytag_t keytag;
|
||||
dns_rdata_dnskey_t key;
|
||||
isc_result_t result;
|
||||
unsigned char dsbuf[DNS_DS_BUFFERSIZE];
|
||||
|
||||
for (result = dns_rdataset_first(rdataset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(rdataset))
|
||||
{
|
||||
dns_rdata_t newdsrdata = DNS_RDATA_INIT;
|
||||
|
||||
dns_rdata_reset(keyrdata);
|
||||
dns_rdataset_current(rdataset, keyrdata);
|
||||
result = dns_rdata_tostruct(keyrdata, &key, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
keytag = compute_keytag(keyrdata);
|
||||
if (ds->key_tag != keytag || ds->algorithm != key.algorithm) {
|
||||
continue;
|
||||
}
|
||||
dns_rdata_reset(&newdsrdata);
|
||||
result = dns_ds_buildrdata(val->event->name, keyrdata,
|
||||
ds->digest_type,
|
||||
dsbuf, &newdsrdata);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"dns_ds_buildrdata() -> %s",
|
||||
dns_result_totext(result));
|
||||
continue;
|
||||
}
|
||||
if (dns_rdata_compare(dsrdata, &newdsrdata) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
anchor_signed(dns_validator_t *val, isc_result_t *resp) {
|
||||
isc_result_t result;
|
||||
|
|
@ -1926,6 +1883,8 @@ get_dsset(dns_validator_t *val, dns_name_t *tname, isc_result_t *resp) {
|
|||
* Attempts positive response validation of an RRset containing zone keys
|
||||
* (i.e. a DNSKEY rrset).
|
||||
*
|
||||
* Caller must be holding the validator lock.
|
||||
*
|
||||
* Returns:
|
||||
* \li ISC_R_SUCCESS Validation completed successfully
|
||||
* \li DNS_R_WAIT Validation has started but is waiting
|
||||
|
|
@ -1935,17 +1894,33 @@ get_dsset(dns_validator_t *val, dns_name_t *tname, isc_result_t *resp) {
|
|||
static isc_result_t
|
||||
validate_dnskey(dns_validator_t *val) {
|
||||
isc_result_t result;
|
||||
dns_rdataset_t trdataset;
|
||||
dns_rdata_t dsrdata = DNS_RDATA_INIT;
|
||||
dns_rdata_t keyrdata = DNS_RDATA_INIT;
|
||||
dns_keynode_t *keynode = NULL;
|
||||
dns_rdata_ds_t ds;
|
||||
bool supported_algorithm;
|
||||
char digest_types[256];
|
||||
|
||||
/*
|
||||
* Caller must be holding the validator lock.
|
||||
* If we don't already have a DS RRset, check to see if there's
|
||||
* a DS style trust anchor configured for this key.
|
||||
*/
|
||||
if (val->dsset == NULL) {
|
||||
result = dns_keytable_find(val->keytable,
|
||||
val->event->name, &keynode);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
val->dsset = dns_keynode_dsset(keynode);
|
||||
if (val->dsset == NULL) {
|
||||
dns_keytable_detachkeynode(val->keytable,
|
||||
&keynode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If that didn't work, see if there's a key-style trust anchor we
|
||||
* can validate against. If not, look up the DS at the parent.
|
||||
*/
|
||||
if (val->dsset == NULL) {
|
||||
isc_result_t tresult = ISC_R_SUCCESS;
|
||||
|
||||
|
|
@ -1989,6 +1964,7 @@ validate_dnskey(dns_validator_t *val) {
|
|||
INSIST(val->dsset != NULL);
|
||||
|
||||
if (val->dsset->trust < dns_trust_secure) {
|
||||
INSIST(keynode == NULL);
|
||||
return (markanswer(val, "validate_dnskey (2)", "insecure DS"));
|
||||
}
|
||||
|
||||
|
|
@ -2069,16 +2045,14 @@ validate_dnskey(dns_validator_t *val) {
|
|||
|
||||
supported_algorithm = true;
|
||||
|
||||
dns_rdataset_init(&trdataset);
|
||||
dns_rdataset_clone(val->event->rdataset, &trdataset);
|
||||
|
||||
/*
|
||||
* Find the DNSKEY matching the DS...
|
||||
*/
|
||||
result = dnskey_for_ds(val, &trdataset, &dsrdata,
|
||||
&ds, &keyrdata);
|
||||
result = dns_dnssec_matchdskey(val->event->name,
|
||||
&dsrdata,
|
||||
val->event->rdataset,
|
||||
&keyrdata);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_rdataset_disassociate(&trdataset);
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"no DNSKEY matching DS");
|
||||
continue;
|
||||
|
|
@ -2088,13 +2062,18 @@ validate_dnskey(dns_validator_t *val) {
|
|||
* ... and check that it signed the DNSKEY RRset.
|
||||
*/
|
||||
result = check_signer(val, &keyrdata, ds.key_tag, ds.algorithm);
|
||||
dns_rdataset_disassociate(&trdataset);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
validator_log(val, ISC_LOG_DEBUG(3),
|
||||
"no RRSIG matching DS key");
|
||||
}
|
||||
|
||||
if (keynode != NULL) {
|
||||
val->dsset = NULL;
|
||||
dns_keytable_detachkeynode(val->keytable, &keynode);
|
||||
}
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
marksecure(val->event);
|
||||
validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (DS)");
|
||||
|
|
|
|||
|
|
@ -320,6 +320,7 @@ dns_dnssec_get_hints
|
|||
dns_dnssec_keyactive
|
||||
dns_dnssec_keyfromrdata
|
||||
dns_dnssec_keylistfromrdataset
|
||||
dns_dnssec_matchdskey
|
||||
dns_dnssec_selfsigns
|
||||
dns_dnssec_sign
|
||||
dns_dnssec_signmessage
|
||||
|
|
@ -462,6 +463,7 @@ dns_keynode_attach
|
|||
dns_keynode_create
|
||||
dns_keynode_detach
|
||||
dns_keynode_detachall
|
||||
dns_keynode_dsset
|
||||
dns_keynode_initial
|
||||
dns_keynode_key
|
||||
dns_keynode_managed
|
||||
|
|
|
|||
397
lib/dns/zone.c
397
lib/dns/zone.c
|
|
@ -3828,81 +3828,59 @@ set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
|
|||
}
|
||||
|
||||
/*
|
||||
* Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
|
||||
* If keynode references a key or a DS rdataset, and if the key
|
||||
* zone does not contain a KEYDATA record for the corresponding name,
|
||||
* then create an empty KEYDATA and push it into the zone as a placeholder,
|
||||
* then schedule a key refresh immediately. This new KEYDATA record will be
|
||||
* updated during the refresh.
|
||||
*
|
||||
* If the key zone is changed, set '*changed' to true.
|
||||
*/
|
||||
static isc_result_t
|
||||
create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
|
||||
dns_diff_t *diff, dns_keytable_t *keytable,
|
||||
dns_keynode_t **keynodep, bool *changed)
|
||||
dns_diff_t *diff, dns_keynode_t *keynode,
|
||||
dns_name_t *keyname, bool *changed)
|
||||
{
|
||||
const char me[] = "create_keydata";
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_buffer_t keyb, dstb;
|
||||
unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
|
||||
dns_rdata_keydata_t keydata;
|
||||
dns_rdata_dnskey_t dnskey;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_keynode_t *keynode;
|
||||
dns_rdata_keydata_t kd;
|
||||
unsigned char rrdata[4096];
|
||||
isc_buffer_t rrdatabuf;
|
||||
isc_stdtime_t now;
|
||||
isc_region_t r;
|
||||
dst_key_t *key;
|
||||
|
||||
REQUIRE(keynodep != NULL);
|
||||
keynode = *keynodep;
|
||||
REQUIRE(keynode != NULL);
|
||||
|
||||
ENTER;
|
||||
isc_stdtime_get(&now);
|
||||
|
||||
/* Loop in case there's more than one key. */
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_keynode_t *nextnode = NULL;
|
||||
|
||||
key = dns_keynode_key(keynode);
|
||||
if (key == NULL)
|
||||
goto skip;
|
||||
|
||||
isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
|
||||
CHECK(dst_key_todns(key, &dstb));
|
||||
|
||||
/* Convert DST key to DNSKEY. */
|
||||
dns_rdata_reset(&rdata);
|
||||
isc_buffer_usedregion(&dstb, &r);
|
||||
dns_rdata_fromregion(&rdata, dst_key_class(key),
|
||||
dns_rdatatype_dnskey, &r);
|
||||
|
||||
/* DSTKEY to KEYDATA. */
|
||||
CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
|
||||
CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
|
||||
NULL));
|
||||
|
||||
/* KEYDATA to rdata. */
|
||||
dns_rdata_reset(&rdata);
|
||||
isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
|
||||
CHECK(dns_rdata_fromstruct(&rdata,
|
||||
zone->rdclass, dns_rdatatype_keydata,
|
||||
&keydata, &keyb));
|
||||
|
||||
/* Add rdata to zone. */
|
||||
CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
|
||||
dst_key_name(key), 0, &rdata));
|
||||
*changed = true;
|
||||
|
||||
/* Refresh new keys from the zone apex as soon as possible. */
|
||||
set_refreshkeytimer(zone, &keydata, now, true);
|
||||
|
||||
skip:
|
||||
result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
|
||||
if (result != ISC_R_NOTFOUND) {
|
||||
dns_keytable_detachkeynode(keytable, &keynode);
|
||||
keynode = nextnode;
|
||||
}
|
||||
/*
|
||||
* If the keynode has neither a key nor a DS RRset,
|
||||
* we shouldn't be here.
|
||||
*/
|
||||
if (dns_keynode_key(keynode) == NULL &&
|
||||
dns_keynode_dsset(keynode) == NULL)
|
||||
{
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
if (keynode != NULL)
|
||||
dns_keytable_detachkeynode(keytable, &keynode);
|
||||
*keynodep = NULL;
|
||||
memset(&kd, 0, sizeof(kd));
|
||||
kd.common.rdclass = zone->rdclass;
|
||||
kd.common.rdtype = dns_rdatatype_keydata;
|
||||
ISC_LINK_INIT(&kd.common, link);
|
||||
|
||||
isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
|
||||
|
||||
CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass,
|
||||
dns_rdatatype_keydata,
|
||||
&kd, &rrdatabuf));
|
||||
/* Add rdata to zone. */
|
||||
CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
|
||||
keyname, 0, &rdata));
|
||||
*changed = true;
|
||||
|
||||
/* Refresh new keys from the zone apex as soon as possible. */
|
||||
set_refreshkeytimer(zone, &kd, now, true);
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
failure:
|
||||
|
|
@ -3985,7 +3963,8 @@ trust_key(dns_zone_t *zone, dns_name_t *keyname,
|
|||
goto failure;
|
||||
|
||||
CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
|
||||
CHECK(dns_keytable_add(sr, true, initial, &dstkey));
|
||||
CHECK(dns_keytable_add(sr, true, initial,
|
||||
dst_key_name(dstkey), &dstkey, NULL));
|
||||
dns_keytable_detach(&sr);
|
||||
|
||||
failure:
|
||||
|
|
@ -4262,51 +4241,69 @@ struct addifmissing_arg {
|
|||
};
|
||||
|
||||
static void
|
||||
addifmissing(dns_keytable_t *keytable, dns_keynode_t *keynode, void *arg) {
|
||||
addifmissing(dns_keytable_t *keytable, dns_keynode_t *keynode,
|
||||
dns_name_t *keyname, void *arg)
|
||||
{
|
||||
dns_db_t *db = ((struct addifmissing_arg *)arg)->db;
|
||||
dns_dbversion_t *ver = ((struct addifmissing_arg *)arg)->ver;
|
||||
dns_diff_t *diff = ((struct addifmissing_arg *)arg)->diff;
|
||||
dns_zone_t *zone = ((struct addifmissing_arg *)arg)->zone;
|
||||
bool *changed = ((struct addifmissing_arg *)arg)->changed;
|
||||
isc_result_t result;
|
||||
dns_keynode_t *dummy = NULL;
|
||||
dns_fixedname_t fname;
|
||||
|
||||
if (((struct addifmissing_arg *)arg)->result != ISC_R_SUCCESS)
|
||||
UNUSED(keytable);
|
||||
|
||||
if (((struct addifmissing_arg *)arg)->result != ISC_R_SUCCESS) {
|
||||
return;
|
||||
|
||||
if (dns_keynode_managed(keynode)) {
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *keyname;
|
||||
dst_key_t *key;
|
||||
|
||||
key = dns_keynode_key(keynode);
|
||||
if (key == NULL)
|
||||
return;
|
||||
dns_fixedname_init(&fname);
|
||||
|
||||
keyname = dst_key_name(key);
|
||||
result = dns_db_find(db, keyname, ver,
|
||||
dns_rdatatype_keydata,
|
||||
DNS_DBFIND_NOWILD, 0, NULL,
|
||||
dns_fixedname_name(&fname),
|
||||
NULL, NULL);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
return;
|
||||
dns_keytable_attachkeynode(keytable, keynode, &dummy);
|
||||
result = create_keydata(zone, db, ver, diff, keytable,
|
||||
&dummy, changed);
|
||||
if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE)
|
||||
((struct addifmissing_arg *)arg)->result = result;
|
||||
}
|
||||
};
|
||||
|
||||
if (!dns_keynode_managed(keynode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the keynode has neither a key-style nor a DS-style
|
||||
* trust anchor, return.
|
||||
*/
|
||||
if (dns_keynode_dsset(keynode) == NULL &&
|
||||
dns_keynode_key(keynode) == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether there's already a KEYDATA entry for this name;
|
||||
* if so, we don't need to add another.
|
||||
*/
|
||||
dns_fixedname_init(&fname);
|
||||
result = dns_db_find(db, keyname, ver, dns_rdatatype_keydata,
|
||||
DNS_DBFIND_NOWILD, 0, NULL,
|
||||
dns_fixedname_name(&fname),
|
||||
NULL, NULL);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the keydata.
|
||||
*/
|
||||
result = create_keydata(zone, db, ver, diff, keynode, keyname, changed);
|
||||
if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) {
|
||||
((struct addifmissing_arg *)arg)->result = result;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Synchronize the set of initializing keys found in managed-keys {}
|
||||
* statements with the set of trust anchors found in the managed-keys.bind
|
||||
* zone. If a domain is no longer named in managed-keys, delete all keys
|
||||
* from that domain from the key zone. If a domain is mentioned in in
|
||||
* managed-keys but there are no references to it in the key zone, load
|
||||
* the key zone with the initializing key(s) for that domain.
|
||||
* from that domain from the key zone. If a domain is configured as an
|
||||
* initial-key in dnssec-keys, but there are no references to it in the
|
||||
* key zone, load the key zone with the initializing key(s) for that
|
||||
* domain and schedule a key refresh. If a domain is configured as
|
||||
* an initial-ds in dnssec-keys, fetch the DNSKEY RRset, load the key
|
||||
* zone with the matching key, and schedule a key refresh.
|
||||
*/
|
||||
static isc_result_t
|
||||
sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
|
||||
|
|
@ -4337,9 +4334,9 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
|
|||
|
||||
/*
|
||||
* Walk the zone DB. If we find any keys whose names are no longer
|
||||
* in managed-keys as initial-keys (or which are now configured as
|
||||
* static keys, meaning they are permanent and not RFC5011-maintained),
|
||||
* delete them from the zone. Otherwise call load_secroots(), which
|
||||
* in dnssec-keys, or which have been changed from initial to static,
|
||||
* (meaning they are permanent and not RFC5011-maintained), delete
|
||||
* them from the zone. Otherwise call load_secroots(), which
|
||||
* loads keys into secroots as appropriate.
|
||||
*/
|
||||
dns_rriterator_init(&rrit, db, ver, 0);
|
||||
|
|
@ -4362,12 +4359,8 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
|
|||
}
|
||||
|
||||
result = dns_keytable_find(sr, rrname, &keynode);
|
||||
if ((result != ISC_R_SUCCESS &&
|
||||
result != DNS_R_PARTIALMATCH) ||
|
||||
dns_keynode_managed(keynode) == false)
|
||||
{
|
||||
CHECK(delete_keydata(db, ver, &diff,
|
||||
rrname, rdataset));
|
||||
if (result != ISC_R_SUCCESS || !dns_keynode_managed(keynode)) {
|
||||
CHECK(delete_keydata(db, ver, &diff, rrname, rdataset));
|
||||
changed = true;
|
||||
} else {
|
||||
load_secroots(zone, rrname, rdataset);
|
||||
|
|
@ -4380,8 +4373,10 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
|
|||
dns_rriterator_destroy(&rrit);
|
||||
|
||||
/*
|
||||
* Now walk secroots to find any managed keys that aren't
|
||||
* in the zone. If we find any, we add them to the zone.
|
||||
* Walk secroots to find any initial keys that aren't in
|
||||
* the zone. If we find any, add them to the zone directly.
|
||||
* If any DS-style initial keys are found, refresh the key
|
||||
* zone so that they'll be looked up.
|
||||
*/
|
||||
arg.db = db;
|
||||
arg.ver = ver;
|
||||
|
|
@ -9740,7 +9735,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
dns_diff_t diff;
|
||||
bool alldone = false;
|
||||
bool commit = false;
|
||||
dns_name_t *keyname;
|
||||
dns_name_t *keyname = NULL;
|
||||
dns_rdata_t sigrr = DNS_RDATA_INIT;
|
||||
dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
|
||||
dns_rdata_t keydatarr = DNS_RDATA_INIT;
|
||||
|
|
@ -9751,11 +9746,14 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
unsigned char key_buf[4096];
|
||||
isc_buffer_t keyb;
|
||||
dst_key_t *dstkey;
|
||||
dst_key_t *dstkey = NULL;
|
||||
isc_stdtime_t now;
|
||||
int pending = 0;
|
||||
bool secure = false, initial = false;
|
||||
bool free_needed;
|
||||
dns_keynode_t *keynode = NULL;
|
||||
dns_rdataset_t *dnskeys = NULL, *dnskeysigs = NULL;
|
||||
dns_rdataset_t *keydataset = NULL, *dsset = NULL;
|
||||
|
||||
UNUSED(task);
|
||||
INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
|
||||
|
|
@ -9765,6 +9763,9 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
zone = kfetch->zone;
|
||||
isc_mem_attach(zone->mctx, &mctx);
|
||||
keyname = dns_fixedname_name(&kfetch->name);
|
||||
dnskeys = &kfetch->dnskeyset;
|
||||
dnskeysigs = &kfetch->dnskeysigset;
|
||||
keydataset = &kfetch->keydataset;
|
||||
|
||||
devent = (dns_fetchevent_t *) event;
|
||||
eresult = devent->result;
|
||||
|
|
@ -9806,9 +9807,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
namebuf, dns_result_totext(eresult));
|
||||
|
||||
/* Fetch failed */
|
||||
if (eresult != ISC_R_SUCCESS ||
|
||||
!dns_rdataset_isassociated(&kfetch->dnskeyset))
|
||||
{
|
||||
if (eresult != ISC_R_SUCCESS || !dns_rdataset_isassociated(dnskeys)) {
|
||||
dnssec_log(zone, ISC_LOG_WARNING,
|
||||
"Unable to fetch DNSKEY set '%s': %s",
|
||||
namebuf, dns_result_totext(eresult));
|
||||
|
|
@ -9817,7 +9816,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
}
|
||||
|
||||
/* No RRSIGs found */
|
||||
if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
|
||||
if (!dns_rdataset_isassociated(dnskeysigs)) {
|
||||
dnssec_log(zone, ISC_LOG_WARNING,
|
||||
"No DNSKEY RRSIGs found for '%s': %s",
|
||||
namebuf, dns_result_totext(eresult));
|
||||
|
|
@ -9829,27 +9828,110 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
* Clear any cached trust level, as we need to run validation
|
||||
* over again; trusted keys might have changed.
|
||||
*/
|
||||
kfetch->dnskeyset.trust = kfetch->dnskeysigset.trust = dns_trust_none;
|
||||
dnskeys->trust = dnskeysigs->trust = dns_trust_none;
|
||||
|
||||
/* Look up the trust anchor */
|
||||
result = dns_keytable_find(secroots, keyname, &keynode);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto anchors_done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate the dnskeyset against the current trusted keys.
|
||||
* If the first keynode has a DS trust anchor, use that for
|
||||
* verification.
|
||||
*/
|
||||
for (result = dns_rdataset_first(&kfetch->dnskeysigset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(&kfetch->dnskeysigset))
|
||||
{
|
||||
dns_keynode_t *keynode = NULL;
|
||||
if ((dsset = dns_keynode_dsset(keynode)) != NULL) {
|
||||
for (result = dns_rdataset_first(dnskeysigs);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(dnskeysigs))
|
||||
{
|
||||
isc_result_t tresult;
|
||||
dns_rdata_t keyrdata = DNS_RDATA_INIT;
|
||||
|
||||
dns_rdata_reset(&sigrr);
|
||||
dns_rdataset_current(dnskeysigs, &sigrr);
|
||||
result = dns_rdata_tostruct(&sigrr, &sig, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
for (tresult = dns_rdataset_first(dsset);
|
||||
tresult == ISC_R_SUCCESS;
|
||||
tresult = dns_rdataset_next(dsset))
|
||||
{
|
||||
dns_rdata_t dsrdata = DNS_RDATA_INIT;
|
||||
dns_rdata_ds_t ds;
|
||||
|
||||
dns_rdata_reset(&dsrdata);
|
||||
dns_rdataset_current(dsset, &dsrdata);
|
||||
tresult = dns_rdata_tostruct(&dsrdata, &ds,
|
||||
NULL);
|
||||
RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
|
||||
|
||||
if (ds.key_tag != sig.keyid ||
|
||||
ds.algorithm != sig.algorithm)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result = dns_dnssec_matchdskey(keyname,
|
||||
&dsrdata,
|
||||
dnskeys,
|
||||
&keyrdata);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tresult == ISC_R_NOMORE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result = dns_dnssec_keyfromrdata(keyname, &keyrdata,
|
||||
mctx, &dstkey);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result = dns_dnssec_verify(keyname, dnskeys,
|
||||
dstkey, false, 0,
|
||||
mctx, &sigrr, NULL);
|
||||
dst_key_free(&dstkey);
|
||||
|
||||
dnssec_log(zone, ISC_LOG_DEBUG(3),
|
||||
"Verifying DNSKEY set for zone "
|
||||
"'%s' using DS %d/%d: %s",
|
||||
namebuf, sig.keyid, sig.algorithm,
|
||||
dns_result_totext(result));
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
dnskeys->trust = dns_trust_secure;
|
||||
dnskeysigs->trust = dns_trust_secure;
|
||||
initial = dns_keynode_initial(keynode);
|
||||
dns_keynode_trust(keynode);
|
||||
secure = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dns_keytable_detachkeynode(secroots, &keynode);
|
||||
goto anchors_done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate the DNSKEY set against using the key-style
|
||||
* trust anchor(s).
|
||||
*/
|
||||
for (result = dns_rdataset_first(dnskeysigs);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(dnskeysigs))
|
||||
{
|
||||
dns_rdata_reset(&sigrr);
|
||||
dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
|
||||
dns_rdataset_current(dnskeysigs, &sigrr);
|
||||
result = dns_rdata_tostruct(&sigrr, &sig, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
result = dns_keytable_find(secroots, keyname, &keynode);
|
||||
result = ISC_R_SUCCESS;
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_keynode_t *nextnode = NULL;
|
||||
dns_fixedname_t fixed;
|
||||
dns_fixedname_init(&fixed);
|
||||
|
||||
dstkey = dns_keynode_key(keynode);
|
||||
if (dstkey == NULL) {
|
||||
|
|
@ -9860,26 +9942,21 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
if (dst_key_alg(dstkey) == sig.algorithm &&
|
||||
dst_key_id(dstkey) == sig.keyid)
|
||||
{
|
||||
result = dns_dnssec_verify(keyname,
|
||||
&kfetch->dnskeyset,
|
||||
dstkey, false,
|
||||
0,
|
||||
zone->view->mctx,
|
||||
&sigrr,
|
||||
dns_fixedname_name(
|
||||
&fixed));
|
||||
result = dns_dnssec_verify(keyname, dnskeys,
|
||||
dstkey, false, 0,
|
||||
mctx, &sigrr, NULL);
|
||||
|
||||
dnssec_log(zone, ISC_LOG_DEBUG(3),
|
||||
"Verifying DNSKEY set for zone "
|
||||
"'%s' using key %d/%d: %s",
|
||||
namebuf, sig.keyid, sig.algorithm,
|
||||
"Verifying DNSKEY set "
|
||||
"for zone '%s' "
|
||||
"using key %d/%d: %s",
|
||||
namebuf, sig.keyid,
|
||||
sig.algorithm,
|
||||
dns_result_totext(result));
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
kfetch->dnskeyset.trust =
|
||||
dns_trust_secure;
|
||||
kfetch->dnskeysigset.trust =
|
||||
dns_trust_secure;
|
||||
dnskeys->trust = dns_trust_secure;
|
||||
dnskeysigs->trust = dns_trust_secure;
|
||||
secure = true;
|
||||
initial = dns_keynode_initial(keynode);
|
||||
dns_keynode_trust(keynode);
|
||||
|
|
@ -9887,14 +9964,12 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
}
|
||||
}
|
||||
|
||||
result = dns_keytable_nextkeynode(secroots,
|
||||
keynode, &nextnode);
|
||||
dns_keytable_detachkeynode(secroots, &keynode);
|
||||
keynode = nextnode;
|
||||
}
|
||||
|
||||
if (keynode != NULL) {
|
||||
dns_keytable_detachkeynode(secroots, &keynode);
|
||||
result = dns_keytable_nextkeynode(secroots, keynode,
|
||||
&nextnode);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
dns_keytable_detachkeynode(secroots, &keynode);
|
||||
keynode = nextnode;
|
||||
}
|
||||
}
|
||||
|
||||
if (secure) {
|
||||
|
|
@ -9902,6 +9977,12 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
}
|
||||
}
|
||||
|
||||
anchors_done:
|
||||
if (keynode != NULL) {
|
||||
dns_keytable_detachkeynode(secroots, &keynode);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If we were not able to verify the answer using the current
|
||||
* trusted keys then all we can do is look at any revoked keys.
|
||||
|
|
@ -9926,14 +10007,14 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
* updated
|
||||
*/
|
||||
initializing = true;
|
||||
for (result = dns_rdataset_first(&kfetch->keydataset);
|
||||
for (result = dns_rdataset_first(keydataset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(&kfetch->keydataset))
|
||||
result = dns_rdataset_next(keydataset))
|
||||
{
|
||||
dns_keytag_t keytag;
|
||||
|
||||
dns_rdata_reset(&keydatarr);
|
||||
dns_rdataset_current(&kfetch->keydataset, &keydatarr);
|
||||
dns_rdataset_current(keydataset, &keydatarr);
|
||||
result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
|
|
@ -9960,7 +10041,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
*/
|
||||
initializing = initializing && (keydata.addhd == 0);
|
||||
|
||||
if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
|
||||
if (! matchkey(dnskeys, &keydatarr)) {
|
||||
bool deletekey = false;
|
||||
|
||||
if (!secure) {
|
||||
|
|
@ -10041,9 +10122,9 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
* - All keys not being removed have their refresh
|
||||
* timers updated
|
||||
*/
|
||||
for (result = dns_rdataset_first(&kfetch->dnskeyset);
|
||||
for (result = dns_rdataset_first(dnskeys);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(&kfetch->dnskeyset))
|
||||
result = dns_rdataset_next(dnskeys))
|
||||
{
|
||||
bool revoked = false;
|
||||
bool newkey = false;
|
||||
|
|
@ -10053,7 +10134,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
dns_keytag_t keytag;
|
||||
|
||||
dns_rdata_reset(&dnskeyrr);
|
||||
dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
|
||||
dns_rdataset_current(dnskeys, &dnskeyrr);
|
||||
result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
|
|
@ -10078,9 +10159,9 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
revoked = ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0);
|
||||
|
||||
if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
|
||||
if (matchkey(keydataset, &dnskeyrr)) {
|
||||
dns_rdata_reset(&keydatarr);
|
||||
dns_rdataset_current(&kfetch->keydataset, &keydatarr);
|
||||
dns_rdataset_current(keydataset, &keydatarr);
|
||||
result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
|
|
@ -10339,14 +10420,14 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
zone->irefs--;
|
||||
kfetch->zone = NULL;
|
||||
|
||||
if (dns_rdataset_isassociated(&kfetch->keydataset)) {
|
||||
dns_rdataset_disassociate(&kfetch->keydataset);
|
||||
if (dns_rdataset_isassociated(keydataset)) {
|
||||
dns_rdataset_disassociate(keydataset);
|
||||
}
|
||||
if (dns_rdataset_isassociated(&kfetch->dnskeyset)) {
|
||||
dns_rdataset_disassociate(&kfetch->dnskeyset);
|
||||
if (dns_rdataset_isassociated(dnskeys)) {
|
||||
dns_rdataset_disassociate(dnskeys);
|
||||
}
|
||||
if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
|
||||
dns_rdataset_disassociate(&kfetch->dnskeysigset);
|
||||
if (dns_rdataset_isassociated(dnskeysigs)) {
|
||||
dns_rdataset_disassociate(dnskeysigs);
|
||||
}
|
||||
|
||||
dns_name_free(keyname, mctx);
|
||||
|
|
@ -10366,8 +10447,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
}
|
||||
|
||||
/*
|
||||
* Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
|
||||
* records from the zone apex.
|
||||
* Refresh the data in the key zone. Initiate a fetch to look up
|
||||
* DNSKEY records at the trust anchor name.
|
||||
*/
|
||||
static void
|
||||
zone_refreshkeys(dns_zone_t *zone) {
|
||||
|
|
|
|||
|
|
@ -255,6 +255,7 @@ irs_context_create(irs_context_t **contextp) {
|
|||
trustedkey != NULL;
|
||||
trustedkey = ISC_LIST_NEXT(trustedkey, link)) {
|
||||
result = dns_client_addtrustedkey(client, dns_rdataclass_in,
|
||||
dns_rdatatype_dnskey,
|
||||
trustedkey->keyname,
|
||||
trustedkey->keydatabuf);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
|
|
|
|||
|
|
@ -445,11 +445,11 @@ static cfg_type_t cfg_type_category = {
|
|||
*/
|
||||
static cfg_tuplefielddef_t dnsseckey_fields[] = {
|
||||
{ "name", &cfg_type_astring, 0 },
|
||||
{ "init", &cfg_type_void, 0 },
|
||||
{ "flags", &cfg_type_uint32, 0 },
|
||||
{ "protocol", &cfg_type_uint32, 0 },
|
||||
{ "algorithm", &cfg_type_uint32, 0 },
|
||||
{ "key", &cfg_type_qstring, 0 },
|
||||
{ "anchortype", &cfg_type_void, 0 },
|
||||
{ "n1", &cfg_type_uint32, 0 },
|
||||
{ "n2", &cfg_type_uint32, 0 },
|
||||
{ "n3", &cfg_type_uint32, 0 },
|
||||
{ "data", &cfg_type_qstring, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
static cfg_type_t cfg_type_dnsseckey = {
|
||||
|
|
@ -461,19 +461,20 @@ static cfg_type_t cfg_type_dnsseckey = {
|
|||
* A key initialization specifier, as used in the
|
||||
* "dnssec-keys" (or synonymous "managed-keys") statement.
|
||||
*/
|
||||
static const char *init_enums[] = { "static-key", "initial-key", NULL };
|
||||
static cfg_type_t cfg_type_keyinit = {
|
||||
"keyinit", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
|
||||
&cfg_rep_string, &init_enums
|
||||
static const char *anchortype_enums[] = {
|
||||
"static-key", "initial-key", "static-ds", "initial-ds", NULL
|
||||
};
|
||||
static cfg_type_t cfg_type_anchortype = {
|
||||
"anchortype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
|
||||
&cfg_rep_string, anchortype_enums
|
||||
};
|
||||
|
||||
static cfg_tuplefielddef_t managedkey_fields[] = {
|
||||
{ "name", &cfg_type_astring, 0 },
|
||||
{ "init", &cfg_type_keyinit, 0 },
|
||||
{ "flags", &cfg_type_uint32, 0 },
|
||||
{ "protocol", &cfg_type_uint32, 0 },
|
||||
{ "algorithm", &cfg_type_uint32, 0 },
|
||||
{ "key", &cfg_type_qstring, 0 },
|
||||
{ "anchortype", &cfg_type_anchortype, 0 },
|
||||
{ "n1", &cfg_type_uint32, 0 },
|
||||
{ "n2", &cfg_type_uint32, 0 },
|
||||
{ "n3", &cfg_type_uint32, 0 },
|
||||
{ "data", &cfg_type_qstring, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
static cfg_type_t cfg_type_managedkey = {
|
||||
|
|
@ -692,10 +693,9 @@ static cfg_type_t cfg_type_trustedkeys = {
|
|||
};
|
||||
|
||||
/*%
|
||||
* A list of key entries, as in "trusted-keys". This has a format similar
|
||||
* to dnssec keys, except the keyname is followed by keyword, either
|
||||
* "initial-key" or "static-key". If "initial-key", then the key is
|
||||
* RFC 5011 managed; if "static-key", then the key never changes.
|
||||
* A list of managed trust anchors. Each entry contains a name, a keyword
|
||||
* ("static-key", initial-key", "static-ds" or "initial-ds"), and the
|
||||
* fields associated with either a DNSKEY or a DS record.
|
||||
*/
|
||||
static cfg_type_t cfg_type_dnsseckeys = {
|
||||
"dnsseckeys", cfg_parse_bracketed_list, cfg_print_bracketed_list,
|
||||
|
|
|
|||
|
|
@ -6596,6 +6596,8 @@ static bool
|
|||
has_ta(query_ctx_t *qctx) {
|
||||
dns_keytable_t *keytable = NULL;
|
||||
dns_keynode_t *keynode = NULL;
|
||||
dns_rdataset_t *dsset = NULL;
|
||||
dns_keytag_t sentinel = qctx->client->query.root_key_sentinel_keyid;
|
||||
isc_result_t result;
|
||||
|
||||
result = dns_view_getsecroots(qctx->view, &keytable);
|
||||
|
|
@ -6604,10 +6606,38 @@ has_ta(query_ctx_t *qctx) {
|
|||
}
|
||||
|
||||
result = dns_keytable_find(keytable, dns_rootname, &keynode);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (keynode != NULL) {
|
||||
dns_keytable_detachkeynode(keytable, &keynode);
|
||||
}
|
||||
dns_keytable_detach(&keytable);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if ((dsset = dns_keynode_dsset(keynode)) != NULL) {
|
||||
for (result = dns_rdataset_first(dsset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(dsset))
|
||||
{
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_ds_t ds;
|
||||
|
||||
dns_rdata_reset(&rdata);
|
||||
dns_rdataset_current(dsset, &rdata);
|
||||
result = dns_rdata_tostruct(&rdata, &ds, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
if (ds.key_tag == sentinel) {
|
||||
dns_keytable_detachkeynode(keytable, &keynode);
|
||||
dns_keytable_detach(&keytable);
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_keynode_t *nextnode = NULL;
|
||||
dns_keytag_t keyid = dst_key_id(dns_keynode_key(keynode));
|
||||
if (keyid == qctx->client->query.root_key_sentinel_keyid) {
|
||||
if (keyid == sentinel) {
|
||||
dns_keytable_detachkeynode(keytable, &keynode);
|
||||
dns_keytable_detach(&keytable);
|
||||
return (true);
|
||||
|
|
@ -6616,8 +6646,11 @@ has_ta(query_ctx_t *qctx) {
|
|||
dns_keytable_detachkeynode(keytable, &keynode);
|
||||
keynode = nextnode;
|
||||
}
|
||||
dns_keytable_detach(&keytable);
|
||||
|
||||
if (keynode != NULL) {
|
||||
dns_keytable_detachkeynode(keytable, &keynode);
|
||||
}
|
||||
dns_keytable_detach(&keytable);
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ set_key(dns_client_t *client, char *keynamestr, char *keystr,
|
|||
exit(1);
|
||||
}
|
||||
result = dns_client_addtrustedkey(client, dns_rdataclass_in,
|
||||
dns_rdatatype_dnskey,
|
||||
keyname, &rrdatabuf);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fprintf(stderr, "failed to add key for %s\n",
|
||||
|
|
|
|||
Loading…
Reference in a new issue