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]
|
||||
|
||||
--- 9.6-ESV-R7 released ---
|
||||
|
||||
3318. [tuning] Reduce the amount of work performed while holding a
|
||||
|
||||
@@ -84,16 +84,19 @@ static const char *nsstats_desc[dns_nsstatscounter_max];
|
||||
static const char *resstats_desc[dns_resstatscounter_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 *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 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,6 +110,7 @@ static int nsstats_index[dns_nsstatscounter_max];
|
||||
static int resstats_index[dns_resstatscounter_max];
|
||||
static int zonestats_index[dns_zonestatscounter_max];
|
||||
static int sockstats_index[isc_sockstatscounter_max];
|
||||
static int dnssecstats_index[dns_dnssecstats_max];
|
||||
|
||||
static inline void
|
||||
set_desc(int counter, int maxcounter, const char *fdesc, const char **fdescs,
|
||||
@@ -408,6 +412,33 @@ init_desc(void) {
|
||||
"FDwatchRecvErr");
|
||||
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);
|
||||
@@ -417,6 +448,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);
|
||||
@@ -426,6 +459,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
|
||||
}
|
||||
|
||||
|
||||
@@ -44,3 +44,4 @@ rm -f signer/example.db
|
||||
rm -f ns2/algroll.db
|
||||
rm -f signer/example.db.after signer/example.db.before
|
||||
rm -f signer/example.db.changed
|
||||
rm -f ns3/lower.example.db ns3/upper.example.db ns3/upper.example.db.lower
|
||||
|
||||
@@ -119,3 +119,9 @@ ns.insecure.below-cname A 10.53.0.3
|
||||
|
||||
secure.below-cname NS ns.secure.below-cname
|
||||
ns.secure.below-cname 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
|
||||
|
||||
@@ -32,7 +32,7 @@ zonefile=example.db
|
||||
|
||||
for subdomain in secure bogus dynamic keyless nsec3 optout nsec3-unknown \
|
||||
optout-unknown multiple rsasha256 rsasha512 update-nsec3 \
|
||||
secure.below-cname expired
|
||||
secure.below-cname expired upper lower
|
||||
do
|
||||
cp ../ns3/keyset-$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
|
||||
@@ -188,4 +188,14 @@ zone "secure.below-cname.example" {
|
||||
file "secure.below-cname.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";
|
||||
|
||||
@@ -283,3 +283,31 @@ zonefile=secure.below-cname.example.db
|
||||
keyname=`$KEYGEN -r $RANDFILE -a RSASHA1 -b 1024 -n zone $zone`
|
||||
cat $infile $keyname.key >$zonefile
|
||||
$SIGNER -P -r $RANDFILE -o $zone $zonefile > /dev/null 2>&1
|
||||
|
||||
#
|
||||
# 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 -r $RANDFILE -a RSASHA1 -b 1024 $zone`
|
||||
zskname=`$KEYGEN -r $RANDFILE -a RSASHA1 -b 1024 -f KSK $zone`
|
||||
cat $infile $kskname.key $zskname.key > $zonefile
|
||||
$SIGNER -P -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 -r $RANDFILE -a RSASHA1 -b 1024 $zone`
|
||||
zskname=`$KEYGEN -r $RANDFILE -a RSASHA1 -b 1024 -f KSK $zone`
|
||||
cat $infile $kskname.key $zskname.key > $zonefile
|
||||
$SIGNER -P -r $RANDFILE -o $zone $zonefile > /dev/null 2>&1
|
||||
|
||||
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
|
||||
@@ -1129,5 +1129,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
|
||||
|
||||
100
lib/dns/dnssec.c
100
lib/dns/dnssec.c
@@ -35,16 +35,20 @@
|
||||
#include <dns/dnssec.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/keyvalues.h>
|
||||
#include <dns/log.h>
|
||||
#include <dns/message.h>
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdatalist.h>
|
||||
#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 { \
|
||||
@@ -74,6 +78,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.
|
||||
*/
|
||||
@@ -150,7 +160,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;
|
||||
@@ -162,11 +174,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));
|
||||
}
|
||||
|
||||
@@ -188,6 +205,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);
|
||||
@@ -215,8 +233,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);
|
||||
@@ -256,7 +280,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;
|
||||
|
||||
@@ -329,7 +353,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));
|
||||
@@ -360,6 +384,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);
|
||||
@@ -374,8 +399,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);
|
||||
@@ -383,10 +410,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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -397,16 +427,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;
|
||||
}
|
||||
|
||||
@@ -414,11 +450,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;
|
||||
@@ -426,7 +467,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;
|
||||
|
||||
@@ -505,21 +546,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/types.h>
|
||||
|
||||
@@ -31,6 +32,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
|
||||
|
||||
@@ -60,8 +63,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
|
||||
@@ -94,9 +97,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:
|
||||
|
||||
@@ -73,6 +73,7 @@ LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[];
|
||||
#define DNS_LOGMODULE_HINTS (&dns_modules[24])
|
||||
#define DNS_LOGMODULE_ACACHE (&dns_modules[25])
|
||||
#define DNS_LOGMODULE_DLZ (&dns_modules[26])
|
||||
#define DNS_LOGMODULE_DNSSEC (&dns_modules[27])
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
|
||||
@@ -64,6 +64,16 @@ enum {
|
||||
|
||||
dns_resstatscounter_max = 30,
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -79,6 +79,7 @@ LIBDNS_EXTERNAL_DATA isc_logmodule_t dns_modules[] = {
|
||||
{ "dns/hints", 0 },
|
||||
{ "dns/acache", 0 },
|
||||
{ "dns/dlz", 0 },
|
||||
{ "dns/dnssec", 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user