2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 15:05:23 +00:00

Reduce nsec3 max iterations to 150

This commit is contained in:
Mark Andrews
2021-04-19 16:32:54 +10:00
parent 51f94b8c7c
commit 29126500d2
6 changed files with 17 additions and 100 deletions

View File

@@ -3857,7 +3857,6 @@ main(int argc, char *argv[]) {
warnifallksk(gdb); warnifallksk(gdb);
if (IS_NSEC3) { if (IS_NSEC3) {
unsigned int max;
bool answer; bool answer;
hash_length = dns_nsec3_hashlength(dns_hash_sha1); hash_length = dns_nsec3_hashlength(dns_hash_sha1);
@@ -3876,12 +3875,10 @@ main(int argc, char *argv[]) {
"NSEC-only DNSKEY"); "NSEC-only DNSKEY");
} }
result = dns_nsec3_maxiterations(gdb, NULL, mctx, &max); if (nsec3iter > dns_nsec3_maxiterations()) {
check_result(result, "dns_nsec3_maxiterations()");
if (nsec3iter > max) {
fatal("NSEC3 iterations too big for weakest DNSKEY " fatal("NSEC3 iterations too big for weakest DNSKEY "
"strength. Maximum iterations allowed %u.", "strength. Maximum iterations allowed %u.",
max); dns_nsec3_maxiterations());
} }
} else { } else {
hashlist_init(&hashlist, 0, 0); /* silence clang */ hashlist_init(&hashlist, 0, 0); /* silence clang */

View File

@@ -14786,7 +14786,8 @@ named_server_signing(named_server_t *server, isc_lex_t *lex,
return (ISC_R_BADNUMBER); return (ISC_R_BADNUMBER);
} }
if (hash > 0xffU || flags > 0xffU) { if (hash > 0xffU || flags > 0xffU ||
iter > dns_nsec3_maxiterations()) {
return (ISC_R_RANGE); return (ISC_R_RANGE);
} }

View File

@@ -208,18 +208,10 @@ dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version, bool complete,
* 'answer' to be non NULL. * 'answer' to be non NULL.
*/ */
isc_result_t unsigned int
dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version, isc_mem_t *mctx, dns_nsec3_maxiterations(void);
unsigned int *iterationsp);
/*%< /*%<
* Find the maximum permissible number of iterations allowed based on * Return the maximum permissible number of NSEC3 iterations.
* the key strength.
*
* Requires:
* 'db' to be valid.
* 'version' to be valid or NULL.
* 'mctx' to be valid.
* 'iterationsp' to be non NULL.
*/ */
bool bool

View File

@@ -1878,78 +1878,9 @@ try_private:
return (result); return (result);
} }
isc_result_t unsigned int
dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version, isc_mem_t *mctx, dns_nsec3_maxiterations(void) {
unsigned int *iterationsp) { return (150);
dns_dbnode_t *node = NULL;
dns_rdataset_t rdataset;
dst_key_t *key = NULL;
isc_buffer_t buffer;
isc_result_t result;
unsigned int bits, minbits = 4096;
result = dns_db_getoriginnode(db, &node);
if (result != ISC_R_SUCCESS) {
return (result);
}
dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 0,
0, &rdataset, NULL);
dns_db_detachnode(db, &node);
if (result == ISC_R_NOTFOUND) {
*iterationsp = 0;
return (ISC_R_SUCCESS);
}
if (result != ISC_R_SUCCESS) {
goto failure;
}
for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset))
{
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_current(&rdataset, &rdata);
REQUIRE(rdata.type == dns_rdatatype_key ||
rdata.type == dns_rdatatype_dnskey);
REQUIRE(rdata.length > 3);
/* Skip unsupported algorithms when
* calculating the maximum iterations.
*/
if (!dst_algorithm_supported(rdata.data[3])) {
continue;
}
isc_buffer_init(&buffer, rdata.data, rdata.length);
isc_buffer_add(&buffer, rdata.length);
CHECK(dst_key_fromdns(dns_db_origin(db), rdataset.rdclass,
&buffer, mctx, &key));
bits = dst_key_size(key);
dst_key_free(&key);
if (minbits > bits) {
minbits = bits;
}
}
if (result != ISC_R_NOMORE) {
goto failure;
}
if (minbits <= 1024) {
*iterationsp = 150;
} else if (minbits <= 2048) {
*iterationsp = 500;
} else {
*iterationsp = 2500;
}
result = ISC_R_SUCCESS;
failure:
if (dns_rdataset_isassociated(&rdataset)) {
dns_rdataset_disassociate(&rdataset);
}
return (result);
} }
isc_result_t isc_result_t

View File

@@ -60,8 +60,7 @@ iteration_test(const char *file, unsigned int expected) {
result = dns_test_loaddb(&db, dns_dbtype_zone, "test", file); result = dns_test_loaddb(&db, dns_dbtype_zone, "test", file);
assert_int_equal(result, ISC_R_SUCCESS); assert_int_equal(result, ISC_R_SUCCESS);
result = dns_nsec3_maxiterations(db, NULL, dt_mctx, &iterations); iterations = dns_nsec3_maxiterations();
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(iterations, expected); assert_int_equal(iterations, expected);
@@ -138,10 +137,10 @@ max_iterations(void **state) {
UNUSED(state); UNUSED(state);
iteration_test("testdata/nsec3/1024.db", 150); iteration_test("testdata/nsec3/1024.db", 150);
iteration_test("testdata/nsec3/2048.db", 500); iteration_test("testdata/nsec3/2048.db", 150);
iteration_test("testdata/nsec3/4096.db", 2500); iteration_test("testdata/nsec3/4096.db", 150);
iteration_test("testdata/nsec3/min-1024.db", 150); iteration_test("testdata/nsec3/min-1024.db", 150);
iteration_test("testdata/nsec3/min-2048.db", 500); iteration_test("testdata/nsec3/min-2048.db", 150);
} }
/* check dns_nsec3param_salttotext() */ /* check dns_nsec3param_salttotext() */

View File

@@ -2007,7 +2007,7 @@ check_dnssec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_difftuple_t *tuple; dns_difftuple_t *tuple;
bool nseconly = false, nsec3 = false; bool nseconly = false, nsec3 = false;
isc_result_t result; isc_result_t result;
unsigned int iterations = 0, max; unsigned int iterations = 0;
dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
/* Scan the tuples for an NSEC-only DNSKEY or an NSEC3PARAM */ /* Scan the tuples for an NSEC-only DNSKEY or an NSEC3PARAM */
@@ -2062,12 +2062,9 @@ check_dnssec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
/* Verify NSEC3 params */ /* Verify NSEC3 params */
CHECK(get_iterations(db, ver, privatetype, &iterations)); CHECK(get_iterations(db, ver, privatetype, &iterations));
CHECK(dns_nsec3_maxiterations(db, ver, client->mctx, &max)); if (iterations > dns_nsec3_maxiterations()) {
if (max != 0 && iterations > max) {
update_log(client, zone, ISC_LOG_ERROR, update_log(client, zone, ISC_LOG_ERROR,
"too many NSEC3 iterations (%u) for " "too many NSEC3 iterations (%u)", iterations);
"weakest DNSKEY (%u)",
iterations, max);
result = DNS_R_REFUSED; result = DNS_R_REFUSED;
goto failure; goto failure;
} }