mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-22 18:19:42 +00:00
3387. [func] Support for a DS digest can be disabled at
runtime with disable-ds-digests. [RT #21581]
This commit is contained in:
parent
84c2220360
commit
058e44186b
3
CHANGES
3
CHANGES
@ -1,3 +1,6 @@
|
||||
3387. [func] Support for a DS digest can be disabled at
|
||||
runtime with disable-ds-digests. [RT #21581]
|
||||
|
||||
3386. [bug] Address locking violation when generating new NSEC /
|
||||
NSEC3 chains. [RT #31224]
|
||||
|
||||
|
@ -284,6 +284,7 @@ options {
|
||||
max-udp-size <replaceable>integer</replaceable>;
|
||||
root-delegation-only <optional> exclude { <replaceable>quoted_string</replaceable>; ... } </optional>;
|
||||
disable-algorithms <replaceable>string</replaceable> { <replaceable>string</replaceable>; ... };
|
||||
disable-ds-digests <replaceable>string</replaceable> { <replaceable>string</replaceable>; ... };
|
||||
dnssec-enable <replaceable>boolean</replaceable>;
|
||||
dnssec-validation <replaceable>boolean</replaceable>;
|
||||
dnssec-lookaside ( <replaceable>auto</replaceable> | <replaceable>no</replaceable> | <replaceable>domain</replaceable> trust-anchor <replaceable>domain</replaceable> );
|
||||
@ -472,6 +473,7 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
|
||||
max-udp-size <replaceable>integer</replaceable>;
|
||||
root-delegation-only <optional> exclude { <replaceable>quoted_string</replaceable>; ... } </optional>;
|
||||
disable-algorithms <replaceable>string</replaceable> { <replaceable>string</replaceable>; ... };
|
||||
disable-ds-digests <replaceable>string</replaceable> { <replaceable>string</replaceable>; ... };
|
||||
dnssec-enable <replaceable>boolean</replaceable>;
|
||||
dnssec-validation <replaceable>boolean</replaceable>;
|
||||
dnssec-lookaside ( <replaceable>auto</replaceable> | <replaceable>no</replaceable> | <replaceable>domain</replaceable> trust-anchor <replaceable>domain</replaceable> );
|
||||
|
@ -1216,6 +1216,48 @@ disable_algorithms(const cfg_obj_t *disabled, dns_resolver_t *resolver) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
disable_ds_digests(const cfg_obj_t *disabled, dns_resolver_t *resolver) {
|
||||
isc_result_t result;
|
||||
const cfg_obj_t *digests;
|
||||
const cfg_listelt_t *element;
|
||||
const char *str;
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *name;
|
||||
isc_buffer_t b;
|
||||
|
||||
dns_fixedname_init(&fixed);
|
||||
name = dns_fixedname_name(&fixed);
|
||||
str = cfg_obj_asstring(cfg_tuple_get(disabled, "name"));
|
||||
isc_buffer_init(&b, str, strlen(str));
|
||||
isc_buffer_add(&b, strlen(str));
|
||||
CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
|
||||
|
||||
digests = cfg_tuple_get(disabled, "digests");
|
||||
for (element = cfg_list_first(digests);
|
||||
element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
{
|
||||
isc_textregion_t r;
|
||||
dns_dsdigest_t digest;
|
||||
|
||||
DE_CONST(cfg_obj_asstring(cfg_listelt_value(element)), r.base);
|
||||
r.length = strlen(r.base);
|
||||
|
||||
/* disable_ds_digests handles numeric values. */
|
||||
result = dns_dsdigest_fromtext(&digest, &r);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(cfg_listelt_value(element),
|
||||
ns_g_lctx, ISC_LOG_ERROR,
|
||||
"invalid algorithm");
|
||||
CHECK(result);
|
||||
}
|
||||
CHECK(dns_resolver_disable_ds_digest(resolver, name, digest));
|
||||
}
|
||||
cleanup:
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
on_disable_list(const cfg_obj_t *disablelist, dns_name_t *zonename) {
|
||||
const cfg_listelt_t *element;
|
||||
@ -2275,6 +2317,20 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
|
||||
view->resolver));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set supported DS/DLV digest types.
|
||||
*/
|
||||
dns_resolver_reset_ds_digests(view->resolver);
|
||||
disabled = NULL;
|
||||
(void)ns_config_get(maps, "disable-ds-digests", &disabled);
|
||||
if (disabled != NULL) {
|
||||
for (element = cfg_list_first(disabled);
|
||||
element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
CHECK(disable_ds_digests(cfg_listelt_value(element),
|
||||
view->resolver));
|
||||
}
|
||||
|
||||
/*
|
||||
* A global or view "forwarders" option, if present,
|
||||
* creates an entry for "." in the forwarding table.
|
||||
|
@ -56,8 +56,8 @@ VERIFY=$TOP/bin/dnssec/dnssec-verify
|
||||
# v6synth
|
||||
SUBDIRS="acl allow_query addzone autosign builtin cacheclean checkconf
|
||||
@CHECKDS@ checknames checkzone database dlv dlvauto dlz dlzexternal
|
||||
dname dns64 dnssec ecdsa forward glue gost ixfr inline limits
|
||||
logfileconfig lwresd masterfile masterformat metadata notify
|
||||
dname dns64 dnssec dsdigest ecdsa forward glue gost ixfr inline
|
||||
limits logfileconfig lwresd masterfile masterformat metadata notify
|
||||
nsupdate pending pkcs11 redirect resolver rndc rpz rrsetorder
|
||||
rsabigexponent sortlist smartsign staticstub statistics stub
|
||||
tkey tsig tsiggss unknown upforwd verify views xfer xferquota
|
||||
|
@ -3595,6 +3595,7 @@ AC_CONFIG_FILES([
|
||||
bin/tests/system/dlz/prereq.sh
|
||||
bin/tests/system/dlzexternal/Makefile
|
||||
bin/tests/system/dlzexternal/ns1/named.conf
|
||||
bin/tests/system/dsdigest/prereq.sh
|
||||
bin/tests/system/ecdsa/prereq.sh
|
||||
bin/tests/system/filter-aaaa/Makefile
|
||||
bin/tests/system/gost/prereq.sh
|
||||
|
@ -5340,6 +5340,8 @@ badresp:1,adberr:0,findfail:0,valfail:0]
|
||||
<optional> querylog <replaceable>yes_or_no</replaceable> ; </optional>
|
||||
<optional> disable-algorithms <replaceable>domain</replaceable> { <replaceable>algorithm</replaceable>;
|
||||
<optional> <replaceable>algorithm</replaceable>; </optional> }; </optional>
|
||||
<optional> disable-ds-digests <replaceable>domain</replaceable> { <replaceable>digest_type</replaceable>;
|
||||
<optional> <replaceable>digest_type</replaceable>; </optional> }; </optional>
|
||||
<optional> acache-enable <replaceable>yes_or_no</replaceable> ; </optional>
|
||||
<optional> acache-cleaning-interval <replaceable>number</replaceable>; </optional>
|
||||
<optional> max-acache-size <replaceable>size_spec</replaceable> ; </optional>
|
||||
@ -5871,8 +5873,33 @@ options {
|
||||
specified name.
|
||||
Multiple <command>disable-algorithms</command>
|
||||
statements are allowed.
|
||||
Only the most specific will be applied.
|
||||
Only the best match <command>disable-algorithms</command>
|
||||
clause will be used to determine which algorithms are used.
|
||||
</para>
|
||||
<para>
|
||||
If all supported algorithms are disabled, the zones covered
|
||||
by the <command>disable-algorithms</command> will be treated
|
||||
as insecure.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>disable-ds-digests</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable the specified DS/DLV digest types at and below the
|
||||
specified name.
|
||||
Multiple <command>disable-ds-digests</command>
|
||||
statements are allowed.
|
||||
Only the best match <command>disable-ds-digests</command>
|
||||
clause will be used to determine which digest types are used.
|
||||
</para>
|
||||
<para>
|
||||
If all supported digest types are disabled, the zones covered
|
||||
by the <command>disable-ds-digests</command> will be treated
|
||||
as insecure.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -101,6 +101,7 @@ options {
|
||||
dialup <dialuptype>;
|
||||
directory <quoted_string>;
|
||||
disable-algorithms <string> { <string>; ... };
|
||||
disable-ds-digests <string> { <string>; ... };
|
||||
disable-empty-zone <string>;
|
||||
dns64 <netprefix> {
|
||||
break-dnssec <boolean>;
|
||||
|
@ -286,12 +286,61 @@ disabled_algorithms(const cfg_obj_t *disabled, isc_log_t *logctx) {
|
||||
r.length = strlen(r.base);
|
||||
|
||||
tresult = dns_secalg_fromtext(&alg, &r);
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(cfg_listelt_value(element), logctx,
|
||||
ISC_LOG_ERROR, "invalid algorithm '%s'",
|
||||
r.base);
|
||||
result = tresult;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
disabled_ds_digests(const cfg_obj_t *disabled, isc_log_t *logctx) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_result_t tresult;
|
||||
const cfg_listelt_t *element;
|
||||
const char *str;
|
||||
isc_buffer_t b;
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *name;
|
||||
const cfg_obj_t *obj;
|
||||
|
||||
dns_fixedname_init(&fixed);
|
||||
name = dns_fixedname_name(&fixed);
|
||||
obj = cfg_tuple_get(disabled, "name");
|
||||
str = cfg_obj_asstring(obj);
|
||||
isc_buffer_init(&b, str, strlen(str));
|
||||
isc_buffer_add(&b, strlen(str));
|
||||
tresult = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"bad domain name '%s'", str);
|
||||
result = tresult;
|
||||
}
|
||||
|
||||
obj = cfg_tuple_get(disabled, "digests");
|
||||
|
||||
for (element = cfg_list_first(obj);
|
||||
element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
{
|
||||
isc_textregion_t r;
|
||||
dns_dsdigest_t digest;
|
||||
isc_result_t tresult;
|
||||
|
||||
DE_CONST(cfg_obj_asstring(cfg_listelt_value(element)), r.base);
|
||||
r.length = strlen(r.base);
|
||||
|
||||
/* works with a numeric argument too */
|
||||
tresult = dns_dsdigest_fromtext(&digest, &r);
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(cfg_listelt_value(element), logctx,
|
||||
ISC_LOG_ERROR, "invalid digest type '%s'",
|
||||
r.base);
|
||||
result = tresult;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
@ -869,6 +918,23 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set supported DS/DLV digest types.
|
||||
*/
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(options, "disable-ds-digests", &obj);
|
||||
if (obj != NULL) {
|
||||
for (element = cfg_list_first(obj);
|
||||
element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
{
|
||||
obj = cfg_listelt_value(element);
|
||||
tresult = disabled_ds_digests(obj, logctx);
|
||||
if (tresult != ISC_R_SUCCESS)
|
||||
result = tresult;
|
||||
}
|
||||
}
|
||||
|
||||
dns_fixedname_init(&fixed);
|
||||
name = dns_fixedname_name(&fixed);
|
||||
|
||||
|
16
lib/dns/ds.c
16
lib/dns/ds.c
@ -67,7 +67,7 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
|
||||
REQUIRE(key != NULL);
|
||||
REQUIRE(key->type == dns_rdatatype_dnskey);
|
||||
|
||||
if (!dns_ds_digest_supported(digest_type))
|
||||
if (!dst_ds_digest_supported(digest_type))
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
|
||||
dns_fixedname_init(&fname);
|
||||
@ -167,17 +167,3 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
|
||||
return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds,
|
||||
&ds, &b));
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
dns_ds_digest_supported(unsigned int digest_type) {
|
||||
#ifdef HAVE_OPENSSL_GOST
|
||||
return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 ||
|
||||
digest_type == DNS_DSDIGEST_SHA256 ||
|
||||
digest_type == DNS_DSDIGEST_GOST ||
|
||||
digest_type == DNS_DSDIGEST_SHA384));
|
||||
#else
|
||||
return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 ||
|
||||
digest_type == DNS_DSDIGEST_SHA256 ||
|
||||
digest_type == DNS_DSDIGEST_SHA384));
|
||||
#endif
|
||||
}
|
||||
|
@ -277,6 +277,20 @@ dst_algorithm_supported(unsigned int alg) {
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
dst_ds_digest_supported(unsigned int digest_type) {
|
||||
#ifdef HAVE_OPENSSL_GOST
|
||||
return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 ||
|
||||
digest_type == DNS_DSDIGEST_SHA256 ||
|
||||
digest_type == DNS_DSDIGEST_GOST ||
|
||||
digest_type == DNS_DSDIGEST_SHA384));
|
||||
#else
|
||||
return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 ||
|
||||
digest_type == DNS_DSDIGEST_SHA256 ||
|
||||
digest_type == DNS_DSDIGEST_SHA384));
|
||||
#endif
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp) {
|
||||
dst_context_t *dctx;
|
||||
|
@ -58,12 +58,6 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
|
||||
* to 'buffer'.
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
dns_ds_digest_supported(unsigned int digest_type);
|
||||
/*%<
|
||||
* Is this digest algorithm supported by dns_ds_buildrdata()?
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_DS_H */
|
||||
|
@ -456,11 +456,17 @@ dns_resolver_reset_algorithms(dns_resolver_t *resolver);
|
||||
* Clear the disabled DNSSEC algorithms.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_resolver_reset_ds_digests(dns_resolver_t *resolver);
|
||||
/*%<
|
||||
* Clear the disabled DS/DLV digest types.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name,
|
||||
unsigned int alg);
|
||||
/*%<
|
||||
* Mark the give DNSSEC algorithm as disabled and below 'name'.
|
||||
* Mark the given DNSSEC algorithm as disabled and below 'name'.
|
||||
* Valid algorithms are less than 256.
|
||||
*
|
||||
* Returns:
|
||||
@ -469,20 +475,37 @@ dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name,
|
||||
*\li #ISC_R_NOMEMORY
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_resolver_disable_ds_digest(dns_resolver_t *resolver, dns_name_t *name,
|
||||
unsigned int digest_type);
|
||||
/*%<
|
||||
* Mark the given DS/DLV digest type as disabled and below 'name'.
|
||||
* Valid types are less than 256.
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li #ISC_R_RANGE
|
||||
*\li #ISC_R_NOMEMORY
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name,
|
||||
unsigned int alg);
|
||||
/*%<
|
||||
* Check if the given algorithm is supported by this resolver.
|
||||
* This checks if the algorithm has been disabled via
|
||||
* dns_resolver_disable_algorithm() then the underlying
|
||||
* crypto libraries if not specifically disabled.
|
||||
* This checks whether the algorithm has been disabled via
|
||||
* dns_resolver_disable_algorithm(), then checks the underlying
|
||||
* crypto libraries if it was not specifically disabled.
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
dns_resolver_digest_supported(dns_resolver_t *resolver, unsigned int digest_type);
|
||||
dns_resolver_ds_digest_supported(dns_resolver_t *resolver, dns_name_t *name,
|
||||
unsigned int digest_type);
|
||||
/*%<
|
||||
* Is this digest type supported.
|
||||
* Check if the given digest type is supported by this resolver.
|
||||
* This checks whether the digest type has been disabled via
|
||||
* dns_resolver_disable_ds_digest(), then checks the underlying
|
||||
* crypto libraries if it was not specifically disabled.
|
||||
*/
|
||||
|
||||
void
|
||||
|
@ -74,6 +74,7 @@ typedef struct dns_dns64 dns_dns64_t;
|
||||
typedef ISC_LIST(dns_dns64_t) dns_dns64list_t;
|
||||
typedef struct dns_dnsseckey dns_dnsseckey_t;
|
||||
typedef ISC_LIST(dns_dnsseckey_t) dns_dnsseckeylist_t;
|
||||
typedef isc_uint8_t dns_dsdigest_t;
|
||||
typedef struct dns_dumpctx dns_dumpctx_t;
|
||||
typedef struct dns_fetch dns_fetch_t;
|
||||
typedef struct dns_fixedname dns_fixedname_t;
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include <dns/types.h>
|
||||
#include <dns/name.h>
|
||||
#include <dns/secalg.h>
|
||||
#include <dns/ds.h>
|
||||
#include <dns/dsdigest.h>
|
||||
|
||||
#include <dst/gssapi.h>
|
||||
|
||||
@ -167,6 +169,16 @@ dst_algorithm_supported(unsigned int alg);
|
||||
* \li ISC_FALSE
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
dst_ds_digest_supported(unsigned int digest_type);
|
||||
/*%<
|
||||
* Checks that a given digest algorithm is supported by DST.
|
||||
*
|
||||
* Returns:
|
||||
* \li ISC_TRUE
|
||||
* \li ISC_FALSE
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp);
|
||||
/*%<
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/cert.h>
|
||||
#include <dns/ds.h>
|
||||
#include <dns/dsdigest.h>
|
||||
#include <dns/keyflags.h>
|
||||
#include <dns/keyvalues.h>
|
||||
#include <dns/rcode.h>
|
||||
@ -130,6 +132,15 @@
|
||||
{ 1, "SHA-1", 0 }, \
|
||||
{ 0, NULL, 0 }
|
||||
|
||||
/* RFC3658, RFC4509, RFC5933, RFC6605 */
|
||||
|
||||
#define DSDIGESTNAMES \
|
||||
{ DNS_DSDIGEST_SHA1, "SHA-1", 0 }, \
|
||||
{ DNS_DSDIGEST_SHA256, "SHA-256", 0 }, \
|
||||
{ DNS_DSDIGEST_GOST, "GOST", 0 }, \
|
||||
{ DNS_DSDIGEST_SHA384, "SHA-384", 0 }, \
|
||||
{ 0, NULL, 0}
|
||||
|
||||
struct tbl {
|
||||
unsigned int value;
|
||||
const char *name;
|
||||
@ -142,6 +153,7 @@ static struct tbl certs[] = { CERTNAMES };
|
||||
static struct tbl secalgs[] = { SECALGNAMES };
|
||||
static struct tbl secprotos[] = { SECPROTONAMES };
|
||||
static struct tbl hashalgs[] = { HASHALGNAMES };
|
||||
static struct tbl dsdigests[] = { DSDIGESTNAMES };
|
||||
|
||||
static struct keyflag {
|
||||
const char *name;
|
||||
@ -404,6 +416,34 @@ dns_keyflags_fromtext(dns_keyflags_t *flagsp, isc_textregion_t *source)
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_dsdigest_fromtext(dns_dsdigest_t *dsdigestp, isc_textregion_t *source) {
|
||||
unsigned int value;
|
||||
RETERR(dns_mnemonic_fromtext(&value, source, dsdigests, 0xff));
|
||||
*dsdigestp = value;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_dsdigest_totext(dns_dsdigest_t dsdigest, isc_buffer_t *target) {
|
||||
return (dns_mnemonic_totext(dsdigest, target, dsdigests));
|
||||
}
|
||||
|
||||
void
|
||||
dns_dsdigest_format(dns_dsdigest_t typ, char *cp, unsigned int size) {
|
||||
isc_buffer_t b;
|
||||
isc_region_t r;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(cp != NULL && size > 0);
|
||||
isc_buffer_init(&b, cp, size - 1);
|
||||
result = dns_dsdigest_totext(typ, &b);
|
||||
isc_buffer_usedregion(&b, &r);
|
||||
r.base[r.length] = 0;
|
||||
if (result != ISC_R_SUCCESS)
|
||||
r.base[0] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This uses lots of hard coded values, but how often do we actually
|
||||
* add classes?
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <dns/callbacks.h>
|
||||
#include <dns/cert.h>
|
||||
#include <dns/compress.h>
|
||||
#include <dns/dsdigest.h>
|
||||
#include <dns/enumtype.h>
|
||||
#include <dns/keyflags.h>
|
||||
#include <dns/keyvalues.h>
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/* draft-ietf-dnsext-delegation-signer-05.txt */
|
||||
/* RFC3658 */
|
||||
|
||||
#ifndef RDATA_GENERIC_DLV_32769_C
|
||||
#define RDATA_GENERIC_DLV_32769_C
|
||||
@ -28,7 +28,6 @@
|
||||
|
||||
#include <dns/ds.h>
|
||||
|
||||
|
||||
static inline isc_result_t
|
||||
fromtext_dlv(ARGS_FROMTEXT) {
|
||||
isc_token_t token;
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/* draft-ietf-dnsext-delegation-signer-05.txt */
|
||||
/* RFC3658 */
|
||||
|
||||
#ifndef RDATA_GENERIC_DS_43_C
|
||||
#define RDATA_GENERIC_DS_43_C
|
||||
@ -64,12 +64,10 @@ fromtext_ds(ARGS_FROMTEXT) {
|
||||
/*
|
||||
* Digest type.
|
||||
*/
|
||||
RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
|
||||
RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
|
||||
ISC_FALSE));
|
||||
if (token.value.as_ulong > 0xffU)
|
||||
RETTOK(ISC_R_RANGE);
|
||||
RETERR(uint8_tobuffer(token.value.as_ulong, target));
|
||||
c = (unsigned char) token.value.as_ulong;
|
||||
RETTOK(dns_dsdigest_fromtext(&c, &token.value.as_textregion));
|
||||
RETERR(mem_tobuffer(target, &c, 1));
|
||||
|
||||
/*
|
||||
* Digest.
|
||||
|
@ -404,6 +404,7 @@ struct dns_resolver {
|
||||
isc_rwlock_t alglock;
|
||||
#endif
|
||||
dns_rbt_t * algorithms;
|
||||
dns_rbt_t * digests;
|
||||
#if USE_MBSLOCK
|
||||
isc_rwlock_t mbslock;
|
||||
#endif
|
||||
@ -7352,6 +7353,7 @@ destroy(dns_resolver_t *res) {
|
||||
isc_mem_put(res->mctx, a, sizeof(*a));
|
||||
}
|
||||
dns_resolver_reset_algorithms(res);
|
||||
dns_resolver_reset_ds_digests(res);
|
||||
destroy_badcache(res);
|
||||
dns_resolver_resetmustbesecure(res);
|
||||
#if USE_ALGLOCK
|
||||
@ -7478,6 +7480,7 @@ dns_resolver_create(dns_view_t *view,
|
||||
ISC_LIST_INIT(res->alternates);
|
||||
res->udpsize = RECV_BUFFER_SIZE;
|
||||
res->algorithms = NULL;
|
||||
res->digests = NULL;
|
||||
res->badcache = NULL;
|
||||
res->badcount = 0;
|
||||
res->badhash = 0;
|
||||
@ -8667,11 +8670,118 @@ dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name,
|
||||
return (dst_algorithm_supported(alg));
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
dns_resolver_digest_supported(dns_resolver_t *resolver, unsigned int digest) {
|
||||
static void
|
||||
free_digest(void *node, void *arg) {
|
||||
unsigned char *digests = node;
|
||||
isc_mem_t *mctx = arg;
|
||||
|
||||
UNUSED(resolver);
|
||||
return (dns_ds_digest_supported(digest));
|
||||
isc_mem_put(mctx, digests, *digests);
|
||||
}
|
||||
|
||||
void
|
||||
dns_resolver_reset_ds_digests(dns_resolver_t *resolver) {
|
||||
|
||||
REQUIRE(VALID_RESOLVER(resolver));
|
||||
|
||||
#if USE_ALGLOCK
|
||||
RWLOCK(&resolver->alglock, isc_rwlocktype_write);
|
||||
#endif
|
||||
if (resolver->digests != NULL)
|
||||
dns_rbt_destroy(&resolver->digests);
|
||||
#if USE_ALGLOCK
|
||||
RWUNLOCK(&resolver->alglock, isc_rwlocktype_write);
|
||||
#endif
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_resolver_disable_ds_digest(dns_resolver_t *resolver, dns_name_t *name,
|
||||
unsigned int digest_type)
|
||||
{
|
||||
unsigned int len, mask;
|
||||
unsigned char *new;
|
||||
unsigned char *digests;
|
||||
isc_result_t result;
|
||||
dns_rbtnode_t *node = NULL;
|
||||
|
||||
REQUIRE(VALID_RESOLVER(resolver));
|
||||
if (digest_type > 255)
|
||||
return (ISC_R_RANGE);
|
||||
|
||||
#if USE_ALGLOCK
|
||||
RWLOCK(&resolver->alglock, isc_rwlocktype_write);
|
||||
#endif
|
||||
if (resolver->digests == NULL) {
|
||||
result = dns_rbt_create(resolver->mctx, free_digest,
|
||||
resolver->mctx, &resolver->digests);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
len = digest_type/8 + 2;
|
||||
mask = 1 << (digest_type%8);
|
||||
|
||||
result = dns_rbt_addnode(resolver->digests, name, &node);
|
||||
|
||||
if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) {
|
||||
digests = node->data;
|
||||
if (digests == NULL || len > *digests) {
|
||||
new = isc_mem_get(resolver->mctx, len);
|
||||
if (new == NULL) {
|
||||
result = ISC_R_NOMEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
memset(new, 0, len);
|
||||
if (digests != NULL)
|
||||
memcpy(new, digests, *digests);
|
||||
new[len-1] |= mask;
|
||||
*new = len;
|
||||
node->data = new;
|
||||
if (digests != NULL)
|
||||
isc_mem_put(resolver->mctx, digests,
|
||||
*digests);
|
||||
} else
|
||||
digests[len-1] |= mask;
|
||||
}
|
||||
result = ISC_R_SUCCESS;
|
||||
cleanup:
|
||||
#if USE_ALGLOCK
|
||||
RWUNLOCK(&resolver->alglock, isc_rwlocktype_write);
|
||||
#endif
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
dns_resolver_ds_digest_supported(dns_resolver_t *resolver, dns_name_t *name,
|
||||
unsigned int digest_type)
|
||||
{
|
||||
unsigned int len, mask;
|
||||
unsigned char *digests;
|
||||
void *data = NULL;
|
||||
isc_result_t result;
|
||||
isc_boolean_t found = ISC_FALSE;
|
||||
|
||||
REQUIRE(VALID_RESOLVER(resolver));
|
||||
|
||||
#if USE_ALGLOCK
|
||||
RWLOCK(&resolver->alglock, isc_rwlocktype_read);
|
||||
#endif
|
||||
if (resolver->digests == NULL)
|
||||
goto unlock;
|
||||
result = dns_rbt_findname(resolver->digests, name, 0, NULL, &data);
|
||||
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
|
||||
len = digest_type/8 + 2;
|
||||
mask = 1 << (digest_type%8);
|
||||
digests = data;
|
||||
if (len <= *digests && (digests[len-1] & mask) != 0)
|
||||
found = ISC_TRUE;
|
||||
}
|
||||
unlock:
|
||||
#if USE_ALGLOCK
|
||||
RWUNLOCK(&resolver->alglock, isc_rwlocktype_read);
|
||||
#endif
|
||||
if (found)
|
||||
return (ISC_FALSE);
|
||||
return (dst_ds_digest_supported(digest_type));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -255,17 +255,10 @@ dlv_algorithm_supported(dns_validator_t *val) {
|
||||
dlv.algorithm))
|
||||
continue;
|
||||
|
||||
#ifdef HAVE_OPENSSL_GOST
|
||||
if (dlv.digest_type != DNS_DSDIGEST_SHA256 &&
|
||||
dlv.digest_type != DNS_DSDIGEST_SHA1 &&
|
||||
dlv.digest_type != DNS_DSDIGEST_GOST)
|
||||
if (!dns_resolver_ds_digest_supported(val->view->resolver,
|
||||
val->event->name,
|
||||
dlv.digest_type))
|
||||
continue;
|
||||
#else
|
||||
if (dlv.digest_type != DNS_DSDIGEST_SHA256 &&
|
||||
dlv.digest_type != DNS_DSDIGEST_SHA1)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
@ -2275,11 +2268,12 @@ dlv_validatezonekey(dns_validator_t *val) {
|
||||
result = dns_rdata_tostruct(&dlvrdata, &dlv, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
if (!dns_resolver_digest_supported(val->view->resolver,
|
||||
dlv.digest_type))
|
||||
if (digest_types[dlv.digest_type] == 0)
|
||||
continue;
|
||||
|
||||
if (digest_types[dlv.digest_type] == 0)
|
||||
if (!dns_resolver_ds_digest_supported(val->view->resolver,
|
||||
val->event->name,
|
||||
dlv.digest_type))
|
||||
continue;
|
||||
|
||||
if (!dns_resolver_algorithm_supported(val->view->resolver,
|
||||
@ -2629,11 +2623,12 @@ validatezonekey(dns_validator_t *val) {
|
||||
result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
if (!dns_resolver_digest_supported(val->view->resolver,
|
||||
ds.digest_type))
|
||||
if (digest_types[ds.digest_type] == 0)
|
||||
continue;
|
||||
|
||||
if (digest_types[ds.digest_type] == 0)
|
||||
if (!dns_resolver_ds_digest_supported(val->view->resolver,
|
||||
val->event->name,
|
||||
ds.digest_type))
|
||||
continue;
|
||||
|
||||
if (!dns_resolver_algorithm_supported(val->view->resolver,
|
||||
@ -3299,8 +3294,8 @@ check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) {
|
||||
result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
if (dns_resolver_digest_supported(val->view->resolver,
|
||||
ds.digest_type) &&
|
||||
if (dns_resolver_ds_digest_supported(val->view->resolver,
|
||||
name, ds.digest_type) &&
|
||||
dns_resolver_algorithm_supported(val->view->resolver,
|
||||
name, ds.algorithm)) {
|
||||
dns_rdata_reset(&dsrdata);
|
||||
|
@ -231,7 +231,6 @@ dns_dnssec_verifymessage
|
||||
dns_dnsseckey_create
|
||||
dns_dnsseckey_destroy
|
||||
dns_ds_buildrdata
|
||||
dns_ds_digest_supported
|
||||
dns_dumpctx_detach
|
||||
dns_fwdtable_add
|
||||
dns_fwdtable_create
|
||||
@ -616,9 +615,11 @@ dns_resolver_createfetch2
|
||||
dns_resolver_destroyfetch
|
||||
dns_resolver_detach
|
||||
dns_resolver_disable_algorithm
|
||||
dns_resolver_disable_ds_digest
|
||||
dns_resolver_dispatchmgr
|
||||
dns_resolver_dispatchv4
|
||||
dns_resolver_dispatchv6
|
||||
dns_resolver_ds_digest_supported
|
||||
dns_resolver_flushbadcache
|
||||
dns_resolver_freeze
|
||||
dns_resolver_getbadcache
|
||||
@ -631,6 +632,7 @@ dns_resolver_nrunning
|
||||
dns_resolver_prime
|
||||
dns_resolver_printbadcache
|
||||
dns_resolver_reset_algorithms
|
||||
dns_resolver_reset_ds_digests
|
||||
dns_resolver_resetmustbesecure
|
||||
dns_resolver_setclientsperquery
|
||||
dns_resolver_setlamettl
|
||||
@ -980,6 +982,7 @@ dst_context_create
|
||||
dst_context_destroy
|
||||
dst_context_sign
|
||||
dst_context_verify
|
||||
dst_ds_digest_supported
|
||||
dst_gssapi_acceptctx
|
||||
dst_gssapi_acquirecred
|
||||
dst_gssapi_initctx
|
||||
|
@ -1007,6 +1007,21 @@ static cfg_type_t cfg_type_disablealgorithm = {
|
||||
&cfg_rep_tuple, disablealgorithm_fields
|
||||
};
|
||||
|
||||
static cfg_type_t cfg_type_dsdigestlist = {
|
||||
"dsdigestlist", cfg_parse_bracketed_list, cfg_print_bracketed_list,
|
||||
cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring };
|
||||
|
||||
static cfg_tuplefielddef_t disabledsdigest_fields[] = {
|
||||
{ "name", &cfg_type_astring, 0 },
|
||||
{ "digests", &cfg_type_dsdigestlist, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
static cfg_type_t cfg_type_disabledsdigest = {
|
||||
"disabledsdigest", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
|
||||
&cfg_rep_tuple, disabledsdigest_fields
|
||||
};
|
||||
|
||||
static cfg_tuplefielddef_t mustbesecure_fields[] = {
|
||||
{ "name", &cfg_type_astring, 0 },
|
||||
{ "value", &cfg_type_boolean, 0 },
|
||||
@ -1337,6 +1352,8 @@ view_clauses[] = {
|
||||
{ "deny-answer-aliases", &cfg_type_denyaliases, 0 },
|
||||
{ "disable-algorithms", &cfg_type_disablealgorithm,
|
||||
CFG_CLAUSEFLAG_MULTI },
|
||||
{ "disable-ds-digests", &cfg_type_disabledsdigest,
|
||||
CFG_CLAUSEFLAG_MULTI },
|
||||
{ "disable-empty-zone", &cfg_type_astring, CFG_CLAUSEFLAG_MULTI },
|
||||
{ "dns64", &cfg_type_dns64, CFG_CLAUSEFLAG_MULTI },
|
||||
{ "dns64-server", &cfg_type_astring, 0 },
|
||||
|
Loading…
x
Reference in New Issue
Block a user