mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
Handle RRSIG signer case consistently
3329. [bug] Handle RRSIG signer-name case consistently: We generate RRSIG records with the signer-name in lower case. We accept them with any case, but if they fail to validate, we try again in lower case. [RT #27451]
This commit is contained in:
6
CHANGES
6
CHANGES
@@ -1,3 +1,9 @@
|
||||
3329. [bug] Handle RRSIG signer-name case consistently: We
|
||||
generate RRSIG records with the signer-name in
|
||||
lower case. We accept them with any case, but if
|
||||
they fail to validate, we try again in lower case.
|
||||
[RT #27451]
|
||||
|
||||
3328. [bug] Fixed inconsistent data checking in dst_parse.c.
|
||||
[RT #29401]
|
||||
|
||||
|
@@ -84,18 +84,21 @@ static const char *resstats_desc[dns_resstatscounter_max];
|
||||
static const char *adbstats_desc[dns_adbstats_max];
|
||||
static const char *zonestats_desc[dns_zonestatscounter_max];
|
||||
static const char *sockstats_desc[isc_sockstatscounter_max];
|
||||
static const char *dnssecstats_desc[dns_dnssecstats_max];
|
||||
#ifdef HAVE_LIBXML2
|
||||
static const char *nsstats_xmldesc[dns_nsstatscounter_max];
|
||||
static const char *resstats_xmldesc[dns_resstatscounter_max];
|
||||
static const char *adbstats_xmldesc[dns_adbstats_max];
|
||||
static const char *zonestats_xmldesc[dns_zonestatscounter_max];
|
||||
static const char *sockstats_xmldesc[isc_sockstatscounter_max];
|
||||
static const char *dnssecstats_xmldesc[dns_dnssecstats_max];
|
||||
#else
|
||||
#define nsstats_xmldesc NULL
|
||||
#define resstats_xmldesc NULL
|
||||
#define adbstats_xmldesc NULL
|
||||
#define zonestats_xmldesc NULL
|
||||
#define sockstats_xmldesc NULL
|
||||
#define dnssecstats_xmldesc NULL
|
||||
#endif /* HAVE_LIBXML2 */
|
||||
|
||||
#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0)
|
||||
@@ -107,9 +110,10 @@ static const char *sockstats_xmldesc[isc_sockstatscounter_max];
|
||||
*/
|
||||
static int nsstats_index[dns_nsstatscounter_max];
|
||||
static int resstats_index[dns_resstatscounter_max];
|
||||
static int adbstats_index[dns_adbstats_max];
|
||||
static int zonestats_index[dns_zonestatscounter_max];
|
||||
static int sockstats_index[isc_sockstatscounter_max];
|
||||
static int adbstats_index[dns_adbstats_max];
|
||||
static int dnssecstats_index[dns_dnssecstats_max];
|
||||
|
||||
static inline void
|
||||
set_desc(int counter, int maxcounter, const char *fdesc, const char **fdescs,
|
||||
@@ -445,6 +449,33 @@ init_desc(void) {
|
||||
"UnixActive");
|
||||
INSIST(i == isc_sockstatscounter_max);
|
||||
|
||||
/* Initialize DNSSEC statistics */
|
||||
for (i = 0; i < dns_dnssecstats_max; i++)
|
||||
dnssecstats_desc[i] = NULL;
|
||||
#ifdef HAVE_LIBXML2
|
||||
for (i = 0; i < dns_dnssecstats_max; i++)
|
||||
dnssecstats_xmldesc[i] = NULL;
|
||||
#endif
|
||||
|
||||
#define SET_DNSSECSTATDESC(counterid, desc, xmldesc) \
|
||||
do { \
|
||||
set_desc(dns_dnssecstats_ ## counterid, \
|
||||
dns_dnssecstats_max, \
|
||||
desc, dnssecstats_desc,\
|
||||
xmldesc, dnssecstats_xmldesc); \
|
||||
dnssecstats_index[i++] = dns_dnssecstats_ ## counterid; \
|
||||
} while (0)
|
||||
|
||||
i = 0;
|
||||
SET_DNSSECSTATDESC(asis, "dnssec validation success with signer "
|
||||
"\"as is\"", "DNSSECasis");
|
||||
SET_DNSSECSTATDESC(downcase, "dnssec validation success with signer "
|
||||
"lower cased", "DNSSECdowncase");
|
||||
SET_DNSSECSTATDESC(wildcard, "dnssec validation of wildcard signature",
|
||||
"DNSSECwild");
|
||||
SET_DNSSECSTATDESC(fail, "dnssec validation failures", "DNSSECfail");
|
||||
INSIST(i == dns_dnssecstats_max);
|
||||
|
||||
/* Sanity check */
|
||||
for (i = 0; i < dns_nsstatscounter_max; i++)
|
||||
INSIST(nsstats_desc[i] != NULL);
|
||||
@@ -456,6 +487,8 @@ init_desc(void) {
|
||||
INSIST(zonestats_desc[i] != NULL);
|
||||
for (i = 0; i < isc_sockstatscounter_max; i++)
|
||||
INSIST(sockstats_desc[i] != NULL);
|
||||
for (i = 0; i < dns_dnssecstats_max; i++)
|
||||
INSIST(dnssecstats_desc[i] != NULL);
|
||||
#ifdef HAVE_LIBXML2
|
||||
for (i = 0; i < dns_nsstatscounter_max; i++)
|
||||
INSIST(nsstats_xmldesc[i] != NULL);
|
||||
@@ -467,6 +500,8 @@ init_desc(void) {
|
||||
INSIST(zonestats_xmldesc[i] != NULL);
|
||||
for (i = 0; i < isc_sockstatscounter_max; i++)
|
||||
INSIST(sockstats_xmldesc[i] != NULL);
|
||||
for (i = 0; i < dns_dnssecstats_max; i++)
|
||||
INSIST(dnssecstats_xmldesc[i] != NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -60,5 +60,7 @@ rm -f signer/nsec3param.out
|
||||
rm -f ns3/ttlpatch.example.db ns3/ttlpatch.example.db.signed
|
||||
rm -f ns3/ttlpatch.example.db.patched
|
||||
rm -f ns3/split-smart.example.db
|
||||
rm -f ns3/lower.example.db ns3/upper.example.db ns3/upper.example.db.lower
|
||||
rm -f nosign.before
|
||||
rm -f signing.out*
|
||||
|
||||
|
@@ -138,3 +138,9 @@ ns.split-dnssec A 10.53.0.3
|
||||
|
||||
split-smart NS ns.split-smart
|
||||
ns.split-smart A 10.53.0.3
|
||||
|
||||
upper NS ns.upper
|
||||
ns.upper A 10.53.0.3
|
||||
|
||||
LOWER NS NS.LOWER
|
||||
NS.LOWER A 10.53.0.3
|
||||
|
@@ -33,7 +33,7 @@ zonefile=example.db
|
||||
for subdomain in secure bogus dynamic keyless nsec3 optout nsec3-unknown \
|
||||
optout-unknown multiple rsasha256 rsasha512 kskonly update-nsec3 \
|
||||
auto-nsec auto-nsec3 secure.below-cname ttlpatch split-dnssec \
|
||||
split-smart expired
|
||||
split-smart expired upper lower
|
||||
do
|
||||
cp ../ns3/dsset-$subdomain.example. .
|
||||
done
|
||||
|
26
bin/tests/system/dnssec/ns3/lower.example.db.in
Normal file
26
bin/tests/system/dnssec/ns3/lower.example.db.in
Normal file
@@ -0,0 +1,26 @@
|
||||
; Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; Permission to use, copy, modify, and/or distribute this software for any
|
||||
; purpose with or without fee is hereby granted, provided that the above
|
||||
; copyright notice and this permission notice appear in all copies.
|
||||
;
|
||||
; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
; PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
; $Id: lower.example.db.in,v 1.1.2.1 2012/01/17 08:31:00 marka Exp $
|
||||
|
||||
$TTL 300 ; 5 minutes
|
||||
@ IN SOA MNAME1. . (
|
||||
2012042407 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
@ NS NS
|
||||
NS A 10.53.0.3
|
@@ -245,4 +245,14 @@ zone "nosign.example" {
|
||||
file "nosign.example.db.signed";
|
||||
};
|
||||
|
||||
zone "upper.example" {
|
||||
type master;
|
||||
file "upper.example.db.signed";
|
||||
};
|
||||
|
||||
zone "LOWER.EXAMPLE" {
|
||||
type master;
|
||||
file "lower.example.db.signed";
|
||||
};
|
||||
|
||||
include "trusted.conf";
|
||||
|
@@ -383,6 +383,34 @@ cp $infile $zonefile
|
||||
$SIGNER -S -r $RANDFILE -e now+1mi -o $zone $zonefile > /dev/null 2>&1
|
||||
rm -f ${zskname}.private ${kskname}.private
|
||||
|
||||
#
|
||||
# A zone where the signer's name has been forced to uppercase.
|
||||
#
|
||||
zone="upper.example."
|
||||
infile="upper.example.db.in"
|
||||
zonefile="upper.example.db"
|
||||
lower="upper.example.db.lower"
|
||||
signedfile="upper.example.db.signed"
|
||||
kskname=`$KEYGEN -q -r $RANDFILE $zone`
|
||||
zskname=`$KEYGEN -q -r $RANDFILE -f KSK $zone`
|
||||
cp $infile $zonefile
|
||||
$SIGNER -P -S -r $RANDFILE -o $zone -f $lower $zonefile > /dev/null 2>&1
|
||||
$CHECKZONE -D upper.example $lower 2>&- | \
|
||||
awk '$4 == "RRSIG" {$12 = toupper($12); print; next} { print }' > $signedfile
|
||||
|
||||
#
|
||||
# Check that the signer's name is in lower case when zone name is in
|
||||
# upper case.
|
||||
#
|
||||
zone="LOWER.EXAMPLE."
|
||||
infile="lower.example.db.in"
|
||||
zonefile="lower.example.db"
|
||||
signedfile="lower.example.db.signed"
|
||||
kskname=`$KEYGEN -q -r $RANDFILE $zone`
|
||||
zskname=`$KEYGEN -q -r $RANDFILE -f KSK $zone`
|
||||
cp $infile $zonefile
|
||||
$SIGNER -P -S -r $RANDFILE -o $zone $zonefile > /dev/null 2>&1
|
||||
|
||||
#
|
||||
# Zone with signatures about to expire, and dynamic, but configured
|
||||
# not to resign with 'auto-resign no;'
|
||||
|
26
bin/tests/system/dnssec/ns3/upper.example.db.in
Normal file
26
bin/tests/system/dnssec/ns3/upper.example.db.in
Normal file
@@ -0,0 +1,26 @@
|
||||
; Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; Permission to use, copy, modify, and/or distribute this software for any
|
||||
; purpose with or without fee is hereby granted, provided that the above
|
||||
; copyright notice and this permission notice appear in all copies.
|
||||
;
|
||||
; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
; PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
; $Id: upper.example.db.in,v 1.1.2.1 2012/01/17 08:31:00 marka Exp $
|
||||
|
||||
$TTL 300 ; 5 minutes
|
||||
@ IN SOA mname1. . (
|
||||
2012042407 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
@ NS ns
|
||||
ns A 10.53.0.3
|
@@ -1655,5 +1655,25 @@ n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:testing legacy upper case signer name validation ($n)"
|
||||
ret=0
|
||||
$DIG +tcp +dnssec -p 5300 +noadd +noauth soa upper.example @10.53.0.4 \
|
||||
> dig.out.ns4.test$n 2>&1
|
||||
grep 'flags:.* ad;' dig.out.ns4.test$n >/dev/null || ret=1
|
||||
grep 'RRSIG.*SOA.* UPPER\.EXAMPLE\. ' dig.out.ns4.test$n > /dev/null || ret=1
|
||||
n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:testing that we lower case signer name ($n)"
|
||||
ret=0
|
||||
$DIG +tcp +dnssec -p 5300 +noadd +noauth soa LOWER.EXAMPLE @10.53.0.4 \
|
||||
> dig.out.ns4.test$n 2>&1
|
||||
grep 'flags:.* ad;' dig.out.ns4.test$n >/dev/null || ret=1
|
||||
grep 'RRSIG.*SOA.* lower\.example\. ' dig.out.ns4.test$n > /dev/null || ret=1
|
||||
n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:exit status: $status"
|
||||
exit $status
|
||||
|
@@ -44,10 +44,13 @@
|
||||
#include <dns/rdataset.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/result.h>
|
||||
#include <dns/stats.h>
|
||||
#include <dns/tsig.h> /* for DNS_TSIG_FUDGE */
|
||||
|
||||
#include <dst/result.h>
|
||||
|
||||
LIBDNS_EXTERNAL_DATA isc_stats_t *dns_dnssec_stats;
|
||||
|
||||
#define is_response(msg) (msg->flags & DNS_MESSAGEFLAG_QR)
|
||||
|
||||
#define RETERR(x) do { \
|
||||
@@ -77,6 +80,12 @@ digest_callback(void *arg, isc_region_t *data) {
|
||||
return (dst_context_adddata(ctx, data));
|
||||
}
|
||||
|
||||
static inline void
|
||||
inc_stat(isc_statscounter_t counter) {
|
||||
if (dns_dnssec_stats != NULL)
|
||||
isc_stats_increment(dns_dnssec_stats, counter);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make qsort happy.
|
||||
*/
|
||||
@@ -153,7 +162,9 @@ dns_dnssec_keyfromrdata(dns_name_t *name, dns_rdata_t *rdata, isc_mem_t *mctx,
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
digest_sig(dst_context_t *ctx, dns_rdata_t *sigrdata, dns_rdata_rrsig_t *sig) {
|
||||
digest_sig(dst_context_t *ctx, isc_boolean_t downcase, dns_rdata_t *sigrdata,
|
||||
dns_rdata_rrsig_t *rrsig)
|
||||
{
|
||||
isc_region_t r;
|
||||
isc_result_t ret;
|
||||
dns_fixedname_t fname;
|
||||
@@ -165,11 +176,16 @@ digest_sig(dst_context_t *ctx, dns_rdata_t *sigrdata, dns_rdata_rrsig_t *sig) {
|
||||
ret = dst_context_adddata(ctx, &r);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
return (ret);
|
||||
dns_fixedname_init(&fname);
|
||||
RUNTIME_CHECK(dns_name_downcase(&sig->signer,
|
||||
dns_fixedname_name(&fname), NULL)
|
||||
== ISC_R_SUCCESS);
|
||||
dns_name_toregion(dns_fixedname_name(&fname), &r);
|
||||
if (downcase) {
|
||||
dns_fixedname_init(&fname);
|
||||
|
||||
RUNTIME_CHECK(dns_name_downcase(&rrsig->signer,
|
||||
dns_fixedname_name(&fname),
|
||||
NULL) == ISC_R_SUCCESS);
|
||||
dns_name_toregion(dns_fixedname_name(&fname), &r);
|
||||
} else
|
||||
dns_name_toregion(&rrsig->signer, &r);
|
||||
|
||||
return (dst_context_adddata(ctx, &r));
|
||||
}
|
||||
|
||||
@@ -191,6 +207,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
isc_uint32_t flags;
|
||||
unsigned int sigsize;
|
||||
dns_fixedname_t fnewname;
|
||||
dns_fixedname_t fsigner;
|
||||
|
||||
REQUIRE(name != NULL);
|
||||
REQUIRE(dns_name_countlabels(name) <= 255);
|
||||
@@ -218,8 +235,14 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
sig.common.rdtype = dns_rdatatype_rrsig;
|
||||
ISC_LINK_INIT(&sig.common, link);
|
||||
|
||||
/*
|
||||
* Downcase signer.
|
||||
*/
|
||||
dns_name_init(&sig.signer, NULL);
|
||||
dns_name_clone(dst_key_name(key), &sig.signer);
|
||||
dns_fixedname_init(&fsigner);
|
||||
RUNTIME_CHECK(dns_name_downcase(dst_key_name(key),
|
||||
dns_fixedname_name(&fsigner), NULL) == ISC_R_SUCCESS);
|
||||
dns_name_clone(dns_fixedname_name(&fsigner), &sig.signer);
|
||||
|
||||
sig.covered = set->type;
|
||||
sig.algorithm = dst_key_alg(key);
|
||||
@@ -259,7 +282,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
/*
|
||||
* Digest the SIG rdata.
|
||||
*/
|
||||
ret = digest_sig(ctx, &tmpsigrdata, &sig);
|
||||
ret = digest_sig(ctx, ISC_FALSE, &tmpsigrdata, &sig);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_context;
|
||||
|
||||
@@ -332,7 +355,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
memcpy(sig.signature, r.base, sig.siglen);
|
||||
|
||||
ret = dns_rdata_fromstruct(sigrdata, sig.common.rdclass,
|
||||
sig.common.rdtype, &sig, buffer);
|
||||
sig.common.rdtype, &sig, buffer);
|
||||
|
||||
cleanup_array:
|
||||
isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t));
|
||||
@@ -363,6 +386,7 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
dst_context_t *ctx = NULL;
|
||||
int labels = 0;
|
||||
isc_uint32_t flags;
|
||||
isc_boolean_t downcase = ISC_FALSE;
|
||||
|
||||
REQUIRE(name != NULL);
|
||||
REQUIRE(set != NULL);
|
||||
@@ -377,8 +401,10 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
if (set->type != sig.covered)
|
||||
return (DNS_R_SIGINVALID);
|
||||
|
||||
if (isc_serial_lt(sig.timeexpire, sig.timesigned))
|
||||
if (isc_serial_lt(sig.timeexpire, sig.timesigned)) {
|
||||
inc_stat(dns_dnssecstats_fail);
|
||||
return (DNS_R_SIGINVALID);
|
||||
}
|
||||
|
||||
if (!ignoretime) {
|
||||
isc_stdtime_get(&now);
|
||||
@@ -386,10 +412,13 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
/*
|
||||
* Is SIG temporally valid?
|
||||
*/
|
||||
if (isc_serial_lt((isc_uint32_t)now, sig.timesigned))
|
||||
if (isc_serial_lt((isc_uint32_t)now, sig.timesigned)) {
|
||||
inc_stat(dns_dnssecstats_fail);
|
||||
return (DNS_R_SIGFUTURE);
|
||||
else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now))
|
||||
} else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now)) {
|
||||
inc_stat(dns_dnssecstats_fail);
|
||||
return (DNS_R_SIGEXPIRED);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -400,16 +429,22 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
case dns_rdatatype_ns:
|
||||
case dns_rdatatype_soa:
|
||||
case dns_rdatatype_dnskey:
|
||||
if (!dns_name_equal(name, &sig.signer))
|
||||
if (!dns_name_equal(name, &sig.signer)) {
|
||||
inc_stat(dns_dnssecstats_fail);
|
||||
return (DNS_R_SIGINVALID);
|
||||
}
|
||||
break;
|
||||
case dns_rdatatype_ds:
|
||||
if (dns_name_equal(name, &sig.signer))
|
||||
if (dns_name_equal(name, &sig.signer)) {
|
||||
inc_stat(dns_dnssecstats_fail);
|
||||
return (DNS_R_SIGINVALID);
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
if (!dns_name_issubdomain(name, &sig.signer))
|
||||
if (!dns_name_issubdomain(name, &sig.signer)) {
|
||||
inc_stat(dns_dnssecstats_fail);
|
||||
return (DNS_R_SIGINVALID);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -417,11 +452,16 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
* Is the key allowed to sign data?
|
||||
*/
|
||||
flags = dst_key_flags(key);
|
||||
if (flags & DNS_KEYTYPE_NOAUTH)
|
||||
if (flags & DNS_KEYTYPE_NOAUTH) {
|
||||
inc_stat(dns_dnssecstats_fail);
|
||||
return (DNS_R_KEYUNAUTHORIZED);
|
||||
if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE)
|
||||
}
|
||||
if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) {
|
||||
inc_stat(dns_dnssecstats_fail);
|
||||
return (DNS_R_KEYUNAUTHORIZED);
|
||||
}
|
||||
|
||||
again:
|
||||
ret = dst_context_create(key, mctx, &ctx);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_struct;
|
||||
@@ -429,7 +469,7 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
/*
|
||||
* Digest the SIG rdata (not including the signature).
|
||||
*/
|
||||
ret = digest_sig(ctx, sigrdata, &sig);
|
||||
ret = digest_sig(ctx, downcase, sigrdata, &sig);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_context;
|
||||
|
||||
@@ -508,21 +548,40 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
r.base = sig.signature;
|
||||
r.length = sig.siglen;
|
||||
ret = dst_context_verify(ctx, &r);
|
||||
if (ret == DST_R_VERIFYFAILURE)
|
||||
ret = DNS_R_SIGINVALID;
|
||||
if (ret == ISC_R_SUCCESS && downcase) {
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
dns_name_format(&sig.signer, namebuf, sizeof(namebuf));
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO,
|
||||
"sucessfully validated after lower casing "
|
||||
"signer '%s'", namebuf);
|
||||
inc_stat(dns_dnssecstats_downcase);
|
||||
} else if (ret == ISC_R_SUCCESS)
|
||||
inc_stat(dns_dnssecstats_asis);
|
||||
|
||||
cleanup_array:
|
||||
isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t));
|
||||
cleanup_context:
|
||||
dst_context_destroy(&ctx);
|
||||
if (ret == DST_R_VERIFYFAILURE && !downcase) {
|
||||
downcase = ISC_TRUE;
|
||||
goto again;
|
||||
}
|
||||
cleanup_struct:
|
||||
dns_rdata_freestruct(&sig);
|
||||
|
||||
if (ret == DST_R_VERIFYFAILURE)
|
||||
ret = DNS_R_SIGINVALID;
|
||||
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
inc_stat(dns_dnssecstats_fail);
|
||||
|
||||
if (ret == ISC_R_SUCCESS && labels - sig.labels > 0) {
|
||||
if (wild != NULL)
|
||||
RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname,
|
||||
dns_fixedname_name(&fnewname),
|
||||
wild, NULL) == ISC_R_SUCCESS);
|
||||
inc_stat(dns_dnssecstats_wildcard);
|
||||
ret = DNS_R_FROMWILDCARD;
|
||||
}
|
||||
return (ret);
|
||||
|
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <isc/lang.h>
|
||||
#include <isc/stdtime.h>
|
||||
#include <isc/stats.h>
|
||||
|
||||
#include <dns/diff.h>
|
||||
#include <dns/types.h>
|
||||
@@ -32,6 +33,8 @@
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
LIBDNS_EXTERNAL_DATA extern isc_stats_t *dns_dnssec_stats;
|
||||
|
||||
/*%< Maximum number of keys supported in a zone. */
|
||||
#define DNS_MAXZONEKEYS 32
|
||||
|
||||
@@ -96,8 +99,8 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
isc_stdtime_t *inception, isc_stdtime_t *expire,
|
||||
isc_mem_t *mctx, isc_buffer_t *buffer, dns_rdata_t *sigrdata);
|
||||
/*%<
|
||||
* Generates a SIG record covering this rdataset. This has no effect
|
||||
* on existing SIG records.
|
||||
* Generates a RRSIG record covering this rdataset. This has no effect
|
||||
* on existing RRSIG records.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'name' (the owner name of the record) is a valid name
|
||||
@@ -130,9 +133,9 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
isc_boolean_t ignoretime, isc_mem_t *mctx,
|
||||
dns_rdata_t *sigrdata, dns_name_t *wild);
|
||||
/*%<
|
||||
* Verifies the SIG record covering this rdataset signed by a specific
|
||||
* key. This does not determine if the key's owner is authorized to
|
||||
* sign this record, as this requires a resolver or database.
|
||||
* 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
|
||||
* this record, as this requires a resolver or database.
|
||||
* If 'ignoretime' is ISC_TRUE, temporal validity will not be checked.
|
||||
*
|
||||
* Requires:
|
||||
|
@@ -68,6 +68,16 @@ enum {
|
||||
|
||||
dns_resstatscounter_max = 34,
|
||||
|
||||
/*
|
||||
* DNSSEC stats.
|
||||
*/
|
||||
dns_dnssecstats_asis = 0,
|
||||
dns_dnssecstats_downcase = 1,
|
||||
dns_dnssecstats_wildcard = 2,
|
||||
dns_dnssecstats_fail = 3,
|
||||
|
||||
dns_dnssecstats_max = 4,
|
||||
|
||||
/*%
|
||||
* Zone statistics counters.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user