2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-22 01:59:26 +00:00

Deprecate max-rsa-exponent-size, always use 4096 instead

The `max-rsa-exponent-size` could limit the exponents of the RSA
public keys during the DNSSEC verification.  Instead of providing
a cryptic (not cryptographic) knob, hardcode the max exponent to
be 4096 (the theoretical maximum for DNSSEC).
This commit is contained in:
Ondřej Surý 2025-04-28 17:22:18 +02:00
parent 841b25fb62
commit 8171bf01ed
No known key found for this signature in database
GPG Key ID: 2820F37E873DEA41
26 changed files with 46 additions and 119 deletions

View File

@ -648,7 +648,7 @@ matching_sigs(keyinfo_t *keytbl, dns_rdataset_t *rdataset,
}
result = dns_dnssec_verify(name, rdataset, ki->dst,
false, 0, mctx, &sigrdata,
false, mctx, &sigrdata,
NULL);
if (result != ISC_R_SUCCESS &&

View File

@ -303,7 +303,7 @@ signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
INCSTAT(nsigned);
if (tryverify) {
result = dns_dnssec_verify(name, rdataset, key, true, 0, mctx,
result = dns_dnssec_verify(name, rdataset, key, true, mctx,
&trdata, NULL);
if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) {
vbprintf(3, "\tsignature verified\n");
@ -460,7 +460,7 @@ static bool
setverifies(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
dns_rdata_t *rrsig) {
isc_result_t result;
result = dns_dnssec_verify(name, set, key, false, 0, mctx, rrsig, NULL);
result = dns_dnssec_verify(name, set, key, false, mctx, rrsig, NULL);
if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) {
INCSTAT(nverified);
return true;

View File

@ -3763,7 +3763,6 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
const char *cachename = NULL;
dns_order_t *order = NULL;
uint32_t udpsize;
uint32_t maxbits;
unsigned int resopts = 0;
dns_zone_t *zone = NULL;
uint32_t clients_per_query, max_clients_per_query;
@ -4603,21 +4602,6 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
}
view->nocookieudp = udpsize;
/*
* Set the maximum rsa exponent bits.
*/
obj = NULL;
result = named_config_get(maps, "max-rsa-exponent-size", &obj);
INSIST(result == ISC_R_SUCCESS);
maxbits = cfg_obj_asuint32(obj);
if (maxbits != 0 && maxbits < 35) {
maxbits = 35;
}
if (maxbits > 4096) {
maxbits = 4096;
}
view->maxbits = maxbits;
/*
* Set supported DNSSEC algorithms.
*/

View File

@ -28,6 +28,5 @@ $SIGNER -P -g -o $zone $zonefile >/dev/null
# Configure the resolving server with a static key.
keyfile_to_static_ds $keyname >trusted.conf
cp trusted.conf ../ns2/trusted.conf
cp trusted.conf ../ns3/trusted.conf
cd ../ns2 && $SHELL -e ./sign.sh

View File

@ -1,35 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* 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 https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
// NS3
options {
query-source address 10.53.0.3;
notify-source 10.53.0.3;
transfer-source 10.53.0.3;
port @PORT@;
pid-file "named.pid";
listen-on { 10.53.0.3; };
listen-on-v6 { none; };
recursion yes;
notify yes;
dnssec-validation yes;
max-rsa-exponent-size 35;
};
zone "." {
type hint;
file "../../_common/root.hint";
};
include "trusted.conf";

View File

@ -15,6 +15,5 @@
copy_setports ns1/named.conf.in ns1/named.conf
copy_setports ns2/named.conf.in ns2/named.conf
copy_setports ns3/named.conf.in ns3/named.conf
cd ns1 && $SHELL -e sign.sh

View File

@ -12,7 +12,6 @@
import os
import subprocess
import dns.message
import pytest
import isctest
@ -52,11 +51,3 @@ def test_rsa_big_exponent_keys_cant_load():
"dnssec-signzone: fatal: cannot load dnskey Kexample.+008+52810.key: out of range"
in file.read()
)
def test_rsa_big_exponent_keys_cant_validate():
msg = dns.message.make_query("a.example.", "A")
res2 = isctest.query.tcp(msg, "10.53.0.2")
isctest.check.noerror(res2)
res3 = isctest.query.tcp(msg, "10.53.0.3")
isctest.check.servfail(res3)

View File

@ -4496,12 +4496,11 @@ Tuning
This option is not to be confused with the :any:`notify-defer` option.
.. namedconf:statement:: max-rsa-exponent-size
:tags: dnssec, query
:tags: deprecated
:short: Sets the maximum RSA exponent size (in bits) when validating.
This sets the maximum RSA exponent size, in bits, that is accepted when
validating. Valid values are 35 to 4096 bits. The default, zero, is
also accepted and is equivalent to 4096.
The maximum RSA exponent size is now always 4096. This option is
deprecated, and will be rendered non-operational in a future release.
.. namedconf:statement:: prefetch
:tags: query

View File

@ -355,8 +355,8 @@ cleanup_databuf:
isc_result_t
dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
bool ignoretime, unsigned int maxbits, isc_mem_t *mctx,
dns_rdata_t *sigrdata, dns_name_t *wild) {
bool ignoretime, isc_mem_t *mctx, dns_rdata_t *sigrdata,
dns_name_t *wild) {
dns_rdata_rrsig_t sig;
dns_fixedname_t fnewname;
isc_region_t r;
@ -527,7 +527,7 @@ again:
r.base = sig.signature;
r.length = sig.siglen;
ret = dst_context_verify(ctx, maxbits, &r);
ret = dst_context_verify(ctx, &r);
if (ret == ISC_R_SUCCESS && downcase) {
char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(&sig.signer, namebuf, sizeof(namebuf));
@ -982,7 +982,7 @@ dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg,
sig_r.base = sig.signature;
sig_r.length = sig.siglen;
result = dst_context_verify(ctx, 0, &sig_r);
result = dst_context_verify(ctx, &sig_r);
if (result != ISC_R_SUCCESS) {
msg->sig0status = dns_tsigerror_badsig;
goto failure;
@ -1062,8 +1062,8 @@ dns_dnssec_signs(dns_rdata_t *rdata, const dns_name_t *name,
if (sig.algorithm == key.algorithm && sig.keyid == keytag) {
result = dns_dnssec_verify(name, rdataset, dstkey,
ignoretime, 0, mctx,
&sigrdata, NULL);
ignoretime, mctx, &sigrdata,
NULL);
if (result == ISC_R_SUCCESS) {
dst_key_free(&dstkey);
return true;

View File

@ -325,7 +325,7 @@ dst_context_sign(dst_context_t *dctx, isc_buffer_t *sig) {
}
isc_result_t
dst_context_verify(dst_context_t *dctx, int maxbits, isc_region_t *sig) {
dst_context_verify(dst_context_t *dctx, isc_region_t *sig) {
REQUIRE(VALID_CTX(dctx));
REQUIRE(sig != NULL);
@ -338,7 +338,7 @@ dst_context_verify(dst_context_t *dctx, int maxbits, isc_region_t *sig) {
return DST_R_NOTPUBLICKEY;
}
return dctx->key->func->verify(dctx, maxbits, sig);
return dctx->key->func->verify(dctx, sig);
}
isc_result_t

View File

@ -157,8 +157,7 @@ struct dst_func {
* Key operations
*/
isc_result_t (*sign)(dst_context_t *dctx, isc_buffer_t *sig);
isc_result_t (*verify)(dst_context_t *dctx, int maxbits,
const isc_region_t *sig);
isc_result_t (*verify)(dst_context_t *dctx, const isc_region_t *sig);
bool (*compare)(const dst_key_t *key1, const dst_key_t *key2);
isc_result_t (*generate)(dst_key_t *key, int parms,
void (*callback)(int));

View File

@ -186,8 +186,7 @@ gssapi_sign(dst_context_t *dctx, isc_buffer_t *sig) {
* Verify.
*/
static isc_result_t
gssapi_verify(dst_context_t *dctx, int maxbits ISC_ATTR_UNUSED,
const isc_region_t *sig) {
gssapi_verify(dst_context_t *dctx, const isc_region_t *sig) {
dst_gssapi_signverifyctx_t *ctx = dctx->ctxdata.gssctx;
isc_region_t message;
gss_buffer_desc gmessage, gsig;

View File

@ -69,7 +69,6 @@
return (hmac_sign(dctx, sig)); \
} \
static isc_result_t hmac##alg##_verify(dst_context_t *dctx, \
int maxbits ISC_ATTR_UNUSED, \
const isc_region_t *sig) { \
return (hmac_verify(dctx, sig)); \
} \

View File

@ -140,8 +140,8 @@ dns_dnssec_sign(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
isc_result_t
dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
bool ignoretime, unsigned int maxbits, isc_mem_t *mctx,
dns_rdata_t *sigrdata, dns_name_t *wild);
bool ignoretime, isc_mem_t *mctx, dns_rdata_t *sigrdata,
dns_name_t *wild);
/*%<
* Verifies the RRSIG record covering this rdataset signed by a specific
* key. This does not determine if the key's owner is authorized to sign

View File

@ -169,7 +169,6 @@ struct dns_view {
uint16_t nocookieudp;
uint16_t padding;
dns_acl_t *pad_acl;
unsigned int maxbits;
dns_dns64list_t dns64;
unsigned int dns64cnt;
bool usedns64;

View File

@ -284,13 +284,10 @@ dst_context_sign(dst_context_t *dctx, isc_buffer_t *sig);
*/
isc_result_t
dst_context_verify(dst_context_t *dctx, int maxbits, isc_region_t *sig);
dst_context_verify(dst_context_t *dctx, isc_region_t *sig);
/*%<
* Verifies the signature using the data and key stored in the context.
*
* 'maxbits' specifies the maximum number of bits permitted in the RSA
* exponent.
*
* Requires:
* \li "dctx" is a valid context.
* \li "sig" is a valid region.

View File

@ -838,8 +838,7 @@ err:
}
static isc_result_t
opensslecdsa_verify(dst_context_t *dctx, int maxbits ISC_ATTR_UNUSED,
const isc_region_t *sig) {
opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
isc_result_t ret;
dst_key_t *key = dctx->key;
int status;

View File

@ -211,8 +211,7 @@ err:
}
static isc_result_t
openssleddsa_verify(dst_context_t *dctx, int maxbits ISC_ATTR_UNUSED,
const isc_region_t *sig) {
openssleddsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
isc_result_t ret;
dst_key_t *key = dctx->key;
int status;

View File

@ -43,6 +43,8 @@
goto err; \
}
#define OPENSSLRSA_MAX_MODULUS_BITS 4096
typedef struct rsa_components {
bool bnfree;
const BIGNUM *e, *n, *d, *p, *q, *dmp1, *dmq1, *iqmp;
@ -289,12 +291,12 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
static bool
opensslrsa_check_exponent_bits(EVP_PKEY *pkey, int maxbits) {
/* Always use the new API first with OpenSSL 3.x. */
int bits = INT_MAX;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
BIGNUM *e = NULL;
if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &e) == 1) {
int bits = BN_num_bits(e);
bits = BN_num_bits(e);
BN_free(e);
return bits < maxbits;
}
#else
const RSA *rsa = EVP_PKEY_get0_RSA(pkey);
@ -302,15 +304,15 @@ opensslrsa_check_exponent_bits(EVP_PKEY *pkey, int maxbits) {
const BIGNUM *ce = NULL;
RSA_get0_key(rsa, NULL, &ce, NULL);
if (ce != NULL) {
return BN_num_bits(ce) < maxbits;
bits = BN_num_bits(ce);
}
}
#endif
return false;
return bits <= maxbits;
}
static isc_result_t
opensslrsa_verify(dst_context_t *dctx, int maxbits, const isc_region_t *sig) {
opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
dst_key_t *key = NULL;
int status = 0;
EVP_MD_CTX *evp_md_ctx = NULL;
@ -323,7 +325,8 @@ opensslrsa_verify(dst_context_t *dctx, int maxbits, const isc_region_t *sig) {
evp_md_ctx = dctx->ctxdata.evp_md_ctx;
pkey = key->keydata.pkeypair.pub;
if (maxbits != 0 && !opensslrsa_check_exponent_bits(pkey, maxbits)) {
if (!opensslrsa_check_exponent_bits(pkey, OPENSSLRSA_MAX_MODULUS_BITS))
{
return DST_R_VERIFYFAILURE;
}

View File

@ -1117,7 +1117,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
}
}
result = dst_context_verify(ctx, 0, &sig_r);
result = dst_context_verify(ctx, &sig_r);
if (result == DST_R_VERIFYFAILURE) {
result = DNS_R_TSIGVERIFYFAILURE;
tsig_log(msg->tsigkey, 2,
@ -1420,7 +1420,7 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
goto cleanup_context;
}
result = dst_context_verify(msg->tsigctx, 0, &sig_r);
result = dst_context_verify(msg->tsigctx, &sig_r);
if (result == DST_R_VERIFYFAILURE) {
tsig_log(msg->tsigkey, 2,
"signature failed to verify(2)");

View File

@ -1349,10 +1349,9 @@ selfsigned_dnskey(dns_validator_t *val) {
dst_key_free(&dstkey);
return ISC_R_QUOTA;
}
result = dns_dnssec_verify(
name, rdataset, dstkey, true,
val->view->maxbits, mctx, &sigrdata,
NULL);
result = dns_dnssec_verify(name, rdataset,
dstkey, true, mctx,
&sigrdata, NULL);
switch (result) {
case DNS_R_SIGFUTURE:
case DNS_R_SIGEXPIRED:
@ -1417,8 +1416,7 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata,
}
again:
result = dns_dnssec_verify(val->name, val->rdataset, key, ignore,
val->view->maxbits, val->view->mctx, rdata,
wild);
val->view->mctx, rdata, wild);
if ((result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE) &&
val->view->acceptexpired)
{

View File

@ -10334,9 +10334,9 @@ revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
if (dst_key_alg(dstkey) == sig.algorithm &&
dst_key_rid(dstkey) == sig.keyid)
{
result = dns_dnssec_verify(
keyname, &kfetch->dnskeyset, dstkey, false, 0,
mctx, &sigrr, dns_fixedname_name(&fixed));
result = dns_dnssec_verify(keyname, &kfetch->dnskeyset,
dstkey, false, mctx, &sigrr,
dns_fixedname_name(&fixed));
dnssec_log(kfetch->zone, ISC_LOG_DEBUG(3),
"Confirm revoked DNSKEY is self-signed: %s",
@ -10525,8 +10525,7 @@ keyfetch_done(void *arg) {
}
result = dns_dnssec_verify(keyname, dnskeys, dstkey,
false, 0, mctx, &sigrr,
NULL);
false, mctx, &sigrr, NULL);
dst_key_free(&dstkey);
dnssec_log(zone, ISC_LOG_DEBUG(3),

View File

@ -185,7 +185,7 @@ goodsig(const vctx_t *vctx, dns_rdata_t *sigrdata, const dns_name_t *name,
continue;
}
result = dns_dnssec_verify(name, rdataset, dstkeys[key], false,
0, vctx->mctx, sigrdata, NULL);
vctx->mctx, sigrdata, NULL);
if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) {
return true;
}

View File

@ -2447,8 +2447,7 @@ verify(dst_key_t *key, dns_name_t *name, dns_rdataset_t *rdataset,
again:
result = dns_dnssec_verify(name, rdataset, key, ignore,
client->view->maxbits, client->manager->mctx,
rdata, NULL);
client->manager->mctx, rdata, NULL);
if (result == DNS_R_SIGEXPIRED && client->view->acceptexpired) {
ignore = true;
goto again;

View File

@ -193,7 +193,7 @@ check_sig(const char *datapath, const char *sigpath, const char *keyname,
result = dst_context_adddata(ctx, &datareg);
assert_int_equal(result, ISC_R_SUCCESS);
result = dst_context_verify(ctx, 0, &sigreg);
result = dst_context_verify(ctx, &sigreg);
/*
* Compute the expected signature and emit it

View File

@ -155,7 +155,7 @@ ISC_RUN_TEST_IMPL(isc_rsa_verify) {
r.base = sigsha1;
r.length = 256;
ret = dst_context_verify(ctx, 0, &r);
ret = dst_context_verify(ctx, &r);
assert_int_equal(ret, ISC_R_SUCCESS);
dst_context_destroy(&ctx);
@ -176,7 +176,7 @@ ISC_RUN_TEST_IMPL(isc_rsa_verify) {
r.base = sigsha256;
r.length = 256;
ret = dst_context_verify(ctx, 0, &r);
ret = dst_context_verify(ctx, &r);
assert_int_equal(ret, ISC_R_SUCCESS);
dst_context_destroy(&ctx);
@ -196,7 +196,7 @@ ISC_RUN_TEST_IMPL(isc_rsa_verify) {
r.base = sigsha512;
r.length = 256;
ret = dst_context_verify(ctx, 0, &r);
ret = dst_context_verify(ctx, &r);
assert_int_equal(ret, ISC_R_SUCCESS);
dst_context_destroy(&ctx);