mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 23:15:18 +00:00
Optimise dnssec-verify
dns_dnssec_keyfromrdata() only needs to be called once per DNSKEY rather than once per verification attempt.
This commit is contained in:
@@ -161,37 +161,22 @@ has_dname(const vctx_t *vctx, dns_dbnode_t *node) {
|
|||||||
|
|
||||||
static bool
|
static bool
|
||||||
goodsig(const vctx_t *vctx, dns_rdata_t *sigrdata, const dns_name_t *name,
|
goodsig(const vctx_t *vctx, dns_rdata_t *sigrdata, const dns_name_t *name,
|
||||||
dns_rdataset_t *keyrdataset, dns_rdataset_t *rdataset) {
|
dst_key_t **dstkeys, size_t nkeys, dns_rdataset_t *rdataset) {
|
||||||
dns_rdata_dnskey_t key;
|
|
||||||
dns_rdata_rrsig_t sig;
|
dns_rdata_rrsig_t sig;
|
||||||
dst_key_t *dstkey = NULL;
|
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
result = dns_rdata_tostruct(sigrdata, &sig, NULL);
|
result = dns_rdata_tostruct(sigrdata, &sig, NULL);
|
||||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||||
|
|
||||||
for (result = dns_rdataset_first(keyrdataset); result == ISC_R_SUCCESS;
|
for (size_t key = 0; key < nkeys; key++) {
|
||||||
result = dns_rdataset_next(keyrdataset))
|
if (sig.algorithm != dst_key_alg(dstkeys[key]) ||
|
||||||
{
|
sig.keyid != dst_key_id(dstkeys[key]) ||
|
||||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
|
||||||
dns_rdataset_current(keyrdataset, &rdata);
|
|
||||||
result = dns_rdata_tostruct(&rdata, &key, NULL);
|
|
||||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
|
||||||
result = dns_dnssec_keyfromrdata(vctx->origin, &rdata,
|
|
||||||
vctx->mctx, &dstkey);
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
if (sig.algorithm != key.algorithm ||
|
|
||||||
sig.keyid != dst_key_id(dstkey) ||
|
|
||||||
!dns_name_equal(&sig.signer, vctx->origin))
|
!dns_name_equal(&sig.signer, vctx->origin))
|
||||||
{
|
{
|
||||||
dst_key_free(&dstkey);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
result = dns_dnssec_verify(name, rdataset, dstkey, false, 0,
|
result = dns_dnssec_verify(name, rdataset, dstkeys[key], false,
|
||||||
vctx->mctx, sigrdata, NULL);
|
0, vctx->mctx, sigrdata, NULL);
|
||||||
dst_key_free(&dstkey);
|
|
||||||
if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) {
|
if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) {
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
@@ -816,7 +801,7 @@ verifynsec3s(const vctx_t *vctx, const dns_name_t *name,
|
|||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
verifyset(vctx_t *vctx, dns_rdataset_t *rdataset, const dns_name_t *name,
|
verifyset(vctx_t *vctx, dns_rdataset_t *rdataset, const dns_name_t *name,
|
||||||
dns_dbnode_t *node, dns_rdataset_t *keyrdataset) {
|
dns_dbnode_t *node, dst_key_t **dstkeys, size_t nkeys) {
|
||||||
unsigned char set_algorithms[256];
|
unsigned char set_algorithms[256];
|
||||||
char namebuf[DNS_NAME_FORMATSIZE];
|
char namebuf[DNS_NAME_FORMATSIZE];
|
||||||
char algbuf[DNS_SECALG_FORMATSIZE];
|
char algbuf[DNS_SECALG_FORMATSIZE];
|
||||||
@@ -883,7 +868,7 @@ verifyset(vctx_t *vctx, dns_rdataset_t *rdataset, const dns_name_t *name,
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (goodsig(vctx, &rdata, name, keyrdataset, rdataset)) {
|
if (goodsig(vctx, &rdata, name, dstkeys, nkeys, rdataset)) {
|
||||||
dns_rdataset_settrust(rdataset, dns_trust_secure);
|
dns_rdataset_settrust(rdataset, dns_trust_secure);
|
||||||
dns_rdataset_settrust(&sigrdataset, dns_trust_secure);
|
dns_rdataset_settrust(&sigrdataset, dns_trust_secure);
|
||||||
set_algorithms[sig.algorithm] = 1;
|
set_algorithms[sig.algorithm] = 1;
|
||||||
@@ -919,7 +904,7 @@ done:
|
|||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
verifynode(vctx_t *vctx, const dns_name_t *name, dns_dbnode_t *node,
|
verifynode(vctx_t *vctx, const dns_name_t *name, dns_dbnode_t *node,
|
||||||
bool delegation, dns_rdataset_t *keyrdataset,
|
bool delegation, dst_key_t **dstkeys, size_t nkeys,
|
||||||
dns_rdataset_t *nsecset, dns_rdataset_t *nsec3paramset,
|
dns_rdataset_t *nsecset, dns_rdataset_t *nsec3paramset,
|
||||||
const dns_name_t *nextname, isc_result_t *vresult) {
|
const dns_name_t *nextname, isc_result_t *vresult) {
|
||||||
unsigned char types[8192];
|
unsigned char types[8192];
|
||||||
@@ -953,8 +938,8 @@ verifynode(vctx_t *vctx, const dns_name_t *name, dns_dbnode_t *node,
|
|||||||
(!delegation || rdataset.type == dns_rdatatype_ds ||
|
(!delegation || rdataset.type == dns_rdatatype_ds ||
|
||||||
rdataset.type == dns_rdatatype_nsec))
|
rdataset.type == dns_rdatatype_nsec))
|
||||||
{
|
{
|
||||||
result = verifyset(vctx, &rdataset, name, node,
|
result = verifyset(vctx, &rdataset, name, node, dstkeys,
|
||||||
keyrdataset);
|
nkeys);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
dns_rdataset_disassociate(&rdataset);
|
dns_rdataset_disassociate(&rdataset);
|
||||||
dns_rdatasetiter_destroy(&rdsiter);
|
dns_rdatasetiter_destroy(&rdsiter);
|
||||||
@@ -1724,6 +1709,8 @@ verify_nodes(vctx_t *vctx, isc_result_t *vresult) {
|
|||||||
dns_name_t *name, *nextname, *prevname, *zonecut;
|
dns_name_t *name, *nextname, *prevname, *zonecut;
|
||||||
dns_dbnode_t *node = NULL, *nextnode;
|
dns_dbnode_t *node = NULL, *nextnode;
|
||||||
dns_dbiterator_t *dbiter = NULL;
|
dns_dbiterator_t *dbiter = NULL;
|
||||||
|
dst_key_t **dstkeys;
|
||||||
|
size_t count, nkeys = 0;
|
||||||
bool done = false;
|
bool done = false;
|
||||||
isc_result_t tvresult = ISC_R_UNSET;
|
isc_result_t tvresult = ISC_R_UNSET;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
@@ -1735,11 +1722,27 @@ verify_nodes(vctx_t *vctx, isc_result_t *vresult) {
|
|||||||
dns_fixedname_init(&fzonecut);
|
dns_fixedname_init(&fzonecut);
|
||||||
zonecut = NULL;
|
zonecut = NULL;
|
||||||
|
|
||||||
|
count = dns_rdataset_count(&vctx->keyset);
|
||||||
|
dstkeys = isc_mem_get(vctx->mctx, sizeof(*dstkeys) * count);
|
||||||
|
|
||||||
|
for (result = dns_rdataset_first(&vctx->keyset);
|
||||||
|
result == ISC_R_SUCCESS; result = dns_rdataset_next(&vctx->keyset))
|
||||||
|
{
|
||||||
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||||
|
dns_rdataset_current(&vctx->keyset, &rdata);
|
||||||
|
dstkeys[nkeys] = NULL;
|
||||||
|
result = dns_dnssec_keyfromrdata(vctx->origin, &rdata,
|
||||||
|
vctx->mctx, &dstkeys[nkeys]);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
nkeys++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result = dns_db_createiterator(vctx->db, DNS_DB_NONSEC3, &dbiter);
|
result = dns_db_createiterator(vctx->db, DNS_DB_NONSEC3, &dbiter);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
zoneverify_log_error(vctx, "dns_db_createiterator(): %s",
|
zoneverify_log_error(vctx, "dns_db_createiterator(): %s",
|
||||||
isc_result_totext(result));
|
isc_result_totext(result));
|
||||||
return (result);
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = dns_dbiterator_first(dbiter);
|
result = dns_dbiterator_first(dbiter);
|
||||||
@@ -1839,9 +1842,9 @@ verify_nodes(vctx_t *vctx, isc_result_t *vresult) {
|
|||||||
dns_db_detachnode(vctx->db, &node);
|
dns_db_detachnode(vctx->db, &node);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
result = verifynode(vctx, name, node, isdelegation,
|
result = verifynode(vctx, name, node, isdelegation, dstkeys,
|
||||||
&vctx->keyset, &vctx->nsecset,
|
nkeys, &vctx->nsecset, &vctx->nsec3paramset,
|
||||||
&vctx->nsec3paramset, nextname, &tvresult);
|
nextname, &tvresult);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
dns_db_detachnode(vctx->db, &node);
|
dns_db_detachnode(vctx->db, &node);
|
||||||
goto done;
|
goto done;
|
||||||
@@ -1889,7 +1892,7 @@ verify_nodes(vctx_t *vctx, isc_result_t *vresult) {
|
|||||||
isc_result_totext(result));
|
isc_result_totext(result));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
result = verifynode(vctx, name, node, false, &vctx->keyset,
|
result = verifynode(vctx, name, node, false, dstkeys, nkeys,
|
||||||
NULL, NULL, NULL, NULL);
|
NULL, NULL, NULL, NULL);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
zoneverify_log_error(vctx, "verifynode: %s",
|
zoneverify_log_error(vctx, "verifynode: %s",
|
||||||
@@ -1907,7 +1910,13 @@ verify_nodes(vctx_t *vctx, isc_result_t *vresult) {
|
|||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
dns_dbiterator_destroy(&dbiter);
|
while (nkeys-- > 0U) {
|
||||||
|
dst_key_free(&dstkeys[nkeys]);
|
||||||
|
}
|
||||||
|
isc_mem_put(vctx->mctx, dstkeys, sizeof(*dstkeys) * count);
|
||||||
|
if (dbiter != NULL) {
|
||||||
|
dns_dbiterator_destroy(&dbiter);
|
||||||
|
}
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user