mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-04 18:22:05 -04:00
add support for DS trust anchors in delv
This commit is contained in:
parent
edafbf1c0f
commit
342cc9b168
5 changed files with 158 additions and 44 deletions
127
bin/delv/delv.c
127
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;
|
||||
dns_rdata_dnskey_t dnskey;
|
||||
dns_rdata_ds_t ds;
|
||||
uint32_t n1, n2, n3;
|
||||
const char *keystr, *keynamestr;
|
||||
unsigned char keydata[4096];
|
||||
isc_buffer_t keydatabuf;
|
||||
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));
|
||||
|
|
@ -651,14 +661,26 @@ key_fromconfig(const cfg_obj_t *key, dns_client_t *client) {
|
|||
/* if DNSKEY, algorithm; if DS, digest type */
|
||||
n3 = cfg_obj_asuint32(cfg_tuple_get(key, "n3"));
|
||||
|
||||
keystruct.common.rdclass = dns_rdataclass_in;
|
||||
keystruct.common.rdtype = dns_rdatatype_dnskey;
|
||||
/*
|
||||
* The key data in keystruct is not dynamically allocated.
|
||||
*/
|
||||
keystruct.mctx = NULL;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
ISC_LINK_INIT(&keystruct.common, link);
|
||||
isc_buffer_init(&databuf, data, sizeof(data));
|
||||
isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
|
||||
|
||||
if (n1 > 0xffff) {
|
||||
CHECK(ISC_R_RANGE);
|
||||
|
|
@ -670,25 +692,78 @@ key_fromconfig(const cfg_obj_t *key, dns_client_t *client) {
|
|||
CHECK(ISC_R_RANGE);
|
||||
}
|
||||
|
||||
keystruct.flags = (uint16_t)n1;
|
||||
keystruct.protocol = (uint8_t)n2;
|
||||
keystruct.algorithm = (uint8_t)n3;
|
||||
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_buffer_init(&keydatabuf, keydata, sizeof(keydata));
|
||||
isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
|
||||
ISC_LINK_INIT(&dnskey.common, link);
|
||||
|
||||
keystr = cfg_obj_asstring(cfg_tuple_get(key, "data"));
|
||||
CHECK(isc_base64_decodestring(keystr, &keydatabuf));
|
||||
isc_buffer_usedregion(&keydatabuf, &r);
|
||||
keystruct.datalen = r.length;
|
||||
keystruct.data = r.base;
|
||||
dnskey.flags = (uint16_t)n1;
|
||||
dnskey.protocol = (uint8_t)n2;
|
||||
dnskey.algorithm = (uint8_t)n3;
|
||||
|
||||
CHECK(dns_rdata_fromstruct(NULL, keystruct.common.rdclass,
|
||||
keystruct.common.rdtype,
|
||||
&keystruct, &rrdatabuf));
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -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,28 +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,
|
||||
dst_key_name(dstkey), &dstkey, NULL);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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