]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2968. [security] Named could fail to prove a data set was insecure
authorMark Andrews <marka@isc.org>
Tue, 16 Nov 2010 01:48:32 +0000 (01:48 +0000)
committerMark Andrews <marka@isc.org>
Tue, 16 Nov 2010 01:48:32 +0000 (01:48 +0000)
                        before marking it as insecure.  One set of conditions
                        that can trigger this occurs naturally when rolling
                        DNSKEY algorithms.  [RT #22309]

CHANGES
bin/tests/system/dnssec/ns1/root.db.in
bin/tests/system/dnssec/ns1/sign.sh
bin/tests/system/dnssec/ns2/algroll.db.in [new file with mode: 0644]
bin/tests/system/dnssec/ns2/named.conf
bin/tests/system/dnssec/ns2/sign.sh
bin/tests/system/dnssec/tests.sh
lib/dns/validator.c

diff --git a/CHANGES b/CHANGES
index 7145af629520919efde369d63667fb76d67092f7..dbe2b3c4dc6d0dd5ee7f4979771cb6520f9ff8eb 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+2968.  [security]      Named could fail to prove a data set was insecure
+                       before marking it as insecure.  One set of conditions
+                       that can trigger this occurs naturally when rolling
+                       DNSKEY algorithms.  [RT #22309]
+
 2967.  [bug]           'host -D' now turns on debugging messages earlier.
                        [RT #22361]
 
index 24c5913d817580f42ca411083e679be59cd4b948..64e6c20a475220ab4f1551ba67948f95712fe333 100644 (file)
@@ -13,7 +13,7 @@
 ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 ; PERFORMANCE OF THIS SOFTWARE.
 
-; $Id: root.db.in,v 1.10 2007/06/19 23:47:02 tbox Exp $
+; $Id: root.db.in,v 1.10.626.1 2010/11/16 01:48:31 marka Exp $
 
 $TTL 300
 .                      IN SOA  gson.nominum.com. a.root.servers.nil. (
@@ -30,3 +30,5 @@ example.              NS      ns2.example.
 ns2.example.           A       10.53.0.2
 dlv.                   NS      ns2.dlv.
 ns2.dlv.               A       10.53.0.2
+algroll                        NS      ns2.algroll
+ns2.algroll.           A       10.53.0.2
index ba29471be474090e136a315d008e45ca4fe8fbfe..40995303ae594ddd2c64ea47211fdbc9a057658d 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: sign.sh,v 1.25.48.7 2010/01/15 23:47:33 tbox Exp $
+# $Id: sign.sh,v 1.25.48.7.4.1 2010/11/16 01:48:32 marka Exp $
 
 SYSTEMTESTTOP=../..
 . $SYSTEMTESTTOP/conf.sh
@@ -30,6 +30,7 @@ zonefile=root.db
 
 cp ../ns2/keyset-example. .
 cp ../ns2/keyset-dlv. .
+grep "8 [12]" ../ns2/dsset-algroll. > dsset-algroll.
 
 keyname=`$KEYGEN -r $RANDFILE -a RSAMD5 -b 768 -n zone $zone`
 
diff --git a/bin/tests/system/dnssec/ns2/algroll.db.in b/bin/tests/system/dnssec/ns2/algroll.db.in
new file mode 100644 (file)
index 0000000..d6d2745
--- /dev/null
@@ -0,0 +1,32 @@
+; Copyright (C) 2004, 2007-2010  Internet Systems Consortium, Inc. ("ISC")
+; Copyright (C) 2000-2002  Internet Software Consortium.
+;
+; 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: algroll.db.in,v 1.2.6.2 2010/11/16 01:48:32 marka Exp $
+
+$TTL 30        ; 5 minutes
+@                      IN SOA  mname1. . (
+                               2000042407 ; serial
+                               20         ; refresh (20 seconds)
+                               20         ; retry (20 seconds)
+                               1814400    ; expire (3 weeks)
+                               30       ; minimum (1 hour)
+                               )
+                       NS      ns2
+ns2                    A       10.53.0.2
+ns3                    A       10.53.0.3
+
+a                      A       10.0.0.1
+b                      A       10.0.0.2
+d                      A       10.0.0.4
index 7a0a153b5541b3f77c4cd05077f6e5da1b965df8..805de376503e3839c39b50667deef668cd034122 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: named.conf,v 1.30.336.3 2010/09/07 01:15:55 marka Exp $ */
+/* $Id: named.conf,v 1.30.336.4 2010/11/16 01:48:32 marka Exp $ */
 
 // NS2
 
@@ -90,4 +90,9 @@ zone "single-nsec3" {
        file "single-nsec3.db.signed";
 };
 
+zone "algroll" {
+       type master;
+       file "algroll.db.signed";
+};
+
 include "trusted.conf";
index 87b53c9482e5eadf0c2ea1bb3de43e6625cbcd7e..b3f0251a282030e0df16bbb23622326f14e71152 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: sign.sh,v 1.30.48.8.4.3 2010/09/07 02:06:00 marka Exp $
+# $Id: sign.sh,v 1.30.48.8.4.4 2010/11/16 01:48:32 marka Exp $
 
 SYSTEMTESTTOP=../..
 . $SYSTEMTESTTOP/conf.sh
@@ -142,3 +142,21 @@ keyname2=`$KEYGEN -r $RANDFILE -a RSASHA256 -b 1024 -n zone $zone`
 cat $infile $keyname1.key $keyname2.key >$zonefile
 
 $SIGNER -P -3 - -A -H 1 -g -r $RANDFILE -o $zone -k $keyname1 $zonefile $keyname2 > /dev/null
+
+#
+# algroll has just has the old DNSKEY records removed and is waiting
+# for them to be flushed from caches.  We still need to generate
+# RRSIGs for the old DNSKEY.
+#
+zone=algroll.
+infile=algroll.db.in
+zonefile=algroll.db
+
+keyold1=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -fk $zone`
+keyold2=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone $zone`
+keynew1=`$KEYGEN -q -r $RANDFILE -a RSASHA256 -b 1024 -n zone -fk $zone`
+keynew2=`$KEYGEN -q -r $RANDFILE -a RSASHA256 -b 1024 -n zone $zone`
+
+cat $infile $keynew1.key $keynew2.key >$zonefile
+
+$SIGNER -P -r $RANDFILE -o $zone -k $keyold1 -k $keynew1 $zonefile $keyold1 $keyold2 $keynew1 $keynew2 > /dev/null
index d04a58b84897ba8d6b1e58fcdc728e6c1b46264d..efdb547c0ddf2f41579e33e24be6fdefa1e2491c 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: tests.sh,v 1.53.48.4.4.4 2010/09/07 01:15:54 marka Exp $
+# $Id: tests.sh,v 1.53.48.4.4.5 2010/11/16 01:48:31 marka Exp $
 
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
@@ -939,6 +939,14 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+echo "I:checking that a zone finishing the transition from RSASHA1 to RSASHA256 validates secure ($n)"
+ret=0
+$DIG $DIGOPTS ns algroll. @10.53.0.4 > dig.out.ns4.test$n || ret=1
+grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
+grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 # Run a minimal update test if possible.  This is really just
 # a regression test for RT #2399; more tests should be added.
 
index 90c18bc95b3fa051669c56a8bfc483904b479d30..fc6f4544c3c8269f2cf75d0847dc569bc2277c55 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: validator.c,v 1.164.12.11.10.6 2010/09/03 02:55:18 marka Exp $ */
+/* $Id: validator.c,v 1.164.12.11.10.7 2010/11/16 01:48:32 marka Exp $ */
 
 #include <config.h>
 
@@ -393,6 +393,7 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
        isc_boolean_t want_destroy;
        isc_result_t result;
        isc_result_t eresult;
+       isc_result_t saved_result;
 
        UNUSED(task);
        INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
@@ -429,6 +430,17 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
                                val->keyset = &val->frdataset;
                }
                result = validate(val, ISC_TRUE);
+               if (result == DNS_R_NOVALIDSIG &&
+                   (val->attributes & VALATTR_TRIEDVERIFY) == 0)
+               {
+                       saved_result = result;
+                       validator_log(val, ISC_LOG_DEBUG(3),
+                                     "falling back to insecurity proof");
+                       val->attributes |= VALATTR_INSECURITY;
+                       result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
+                       if (result == DNS_R_NOTINSECURE)
+                               result = saved_result;
+               }
                if (result != DNS_R_WAIT)
                        validator_done(val, result);
        } else {
@@ -619,6 +631,7 @@ keyvalidated(isc_task_t *task, isc_event_t *event) {
        isc_boolean_t want_destroy;
        isc_result_t result;
        isc_result_t eresult;
+       isc_result_t saved_result;
 
        UNUSED(task);
        INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
@@ -645,6 +658,17 @@ keyvalidated(isc_task_t *task, isc_event_t *event) {
                if (val->frdataset.trust >= dns_trust_secure)
                        (void) get_dst_key(val, val->siginfo, &val->frdataset);
                result = validate(val, ISC_TRUE);
+               if (result == DNS_R_NOVALIDSIG &&
+                   (val->attributes & VALATTR_TRIEDVERIFY) == 0)
+               {
+                       saved_result = result;
+                       validator_log(val, ISC_LOG_DEBUG(3),
+                                     "falling back to insecurity proof");
+                       val->attributes |= VALATTR_INSECURITY;
+                       result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
+                       if (result == DNS_R_NOTINSECURE)
+                               result = saved_result;
+               }
                if (result != DNS_R_WAIT)
                        validator_done(val, result);
        } else {
@@ -1875,9 +1899,11 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
                 * was known and "sufficiently good".
                 */
                if (!dns_resolver_algorithm_supported(val->view->resolver,
-                                                     event->name,
-                                                     val->siginfo->algorithm))
+                                                   event->name,
+                                                   val->siginfo->algorithm)) {
+                       resume = ISC_FALSE;
                        continue;
+               }
 
                if (!resume) {
                        result = get_key(val, val->siginfo);
@@ -1888,16 +1914,12 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
                }
 
                /*
-                * The key is insecure, so mark the data as insecure also.
+                * There isn't a secure DNSKEY for this signature so move
+                * onto the next RRSIG.
                 */
                if (val->key == NULL) {
-                       if (val->mustbesecure) {
-                               validator_log(val, ISC_LOG_WARNING,
-                                             "must be secure failure");
-                               return (DNS_R_MUSTBESECURE);
-                       }
-                       markanswer(val, "validate");
-                       return (ISC_R_SUCCESS);
+                       resume = ISC_FALSE;
+                       continue;
                }
 
                do {
@@ -3703,6 +3725,20 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
                                 */
                                result = DNS_R_NOVALIDNSEC;
                                goto out;
+                       } else if (DNS_TRUST_PENDING(val->frdataset.trust) ||
+                                  DNS_TRUST_ANSWER(val->frdataset.trust)) {
+                               /*
+                                * If we have "trust == answer" then this namespace
+                                * has switched from insecure to should be secure.
+                                */
+                               result = create_validator(val, tname,
+                                                         dns_rdatatype_ds,
+                                                         &val->frdataset,
+                                                         NULL, dsvalidated,
+                                                         "proveunsecure");
+                               if (result != ISC_R_SUCCESS)
+                                       goto out;
+                               return (DNS_R_WAIT);
                        } else if (val->frdataset.trust < dns_trust_secure) {
                                /*
                                 * This shouldn't happen, since the negative