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:
parent
841b25fb62
commit
8171bf01ed
@ -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 &&
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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";
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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)); \
|
||||
} \
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)");
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user