]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3632. [bug] Signature from newly inactive keys were not being
authorMark Andrews <marka@isc.org>
Thu, 15 Aug 2013 00:48:05 +0000 (10:48 +1000)
committerMark Andrews <marka@isc.org>
Thu, 15 Aug 2013 01:45:42 +0000 (11:45 +1000)
                        removed.  [RT #32178]

(cherry picked from commit 7ace3277956c49f7554b7130ef761bde3b35db30)

14 files changed:
CHANGES
bin/dnssec/dnssectool.c
bin/named/update.c
bin/tests/system/dnssec/clean.sh
bin/tests/system/dnssec/ns3/named.conf
bin/tests/system/dnssec/ns3/publish-inactive.example.db.in [new file with mode: 0644]
bin/tests/system/dnssec/ns3/sign.sh
bin/tests/system/dnssec/tests.sh
lib/dns/dnssec.c
lib/dns/dst_api.c
lib/dns/dst_internal.h
lib/dns/include/dst/dst.h
lib/dns/win32/libdns.def
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index 2705bf661017c528e1279b94cef49e17344cb802..00bfc9f35f04c7c90c704130c4d77d0c6385d640 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+3632.  [bug]           Signature from newly inactive keys were not being
+                       removed. [RT #32178]
+
 3631.  [bug]           Remove spurious warning about missing signatures when
                        qtype is SIG. [RT #34600]
 
index 882b042f1b8ee101083b9048e01a705fa2da43f4..8977d2a3e915b773cf679dbb28fd4f1c156d156d 100644 (file)
@@ -298,11 +298,35 @@ strtotime(const char *str, isc_int64_t now, isc_int64_t base) {
        isc_result_t result;
        const char *orig = str;
        char *endp;
+       int n;
 
        if ((str[0] == '0' || str[0] == '-') && str[1] == '\0')
                return ((isc_stdtime_t) 0);
 
-       if (strncmp(str, "now", 3) == 0) {
+       /*
+        * We accept times in the following formats:
+        *   now([+-]offset)
+        *   YYYYMMDD([+-]offset)
+        *   YYYYMMDDhhmmss([+-]offset)
+        *   [+-]offset
+        */
+       n = strspn(str, "0123456789");
+       if ((n == 8 || n == 14) &&
+           (str[n] == '\0' || str[n] == '-' || str[n] == '+'))
+       {
+               char timestr[15];
+
+               strlcpy(timestr, str, sizeof(timestr));
+               timestr[n] = 0;
+               if (n == 8)
+                       strlcat(timestr, "000000", sizeof(timestr));
+               result = dns_time64_fromtext(timestr, &val);
+               if (result != ISC_R_SUCCESS)
+                       fatal("time value %s is invalid: %s", orig,
+                             isc_result_totext(result));
+               base = val;
+               str += n;
+       } else if (strncmp(str, "now", 3) == 0) {
                base = now;
                str += 3;
        }
@@ -317,18 +341,7 @@ strtotime(const char *str, isc_int64_t now, isc_int64_t base) {
                offset = strtol(str + 1, &endp, 0);
                offset = time_units((isc_stdtime_t) offset, endp, orig);
                val = base - offset;
-       } else if (strlen(str) == 8U) {
-               char timestr[15];
-               sprintf(timestr, "%s000000", str);
-               result = dns_time64_fromtext(timestr, &val);
-               if (result != ISC_R_SUCCESS)
-                       fatal("time value %s is invalid: %s", orig,
-                             isc_result_totext(result));
-       } else if (strlen(str) > 14U) {
-               fatal("time value %s is invalid", orig);
        } else {
-               result = dns_time64_fromtext(str, &val);
-               if (result != ISC_R_SUCCESS)
                        fatal("time value %s is invalid: %s", orig,
                              isc_result_totext(result));
        }
index afbf447ff56d115037858fa0e7d1ec7e52310401..f07bcc7e45eb9d0d8c2ebc16084eaacd3600484d 100644 (file)
@@ -2004,7 +2004,8 @@ del_keysigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
                for (i = 0; i < nkeys; i++) {
                        if (rrsig.keyid == dst_key_id(keys[i])) {
                                found = ISC_TRUE;
-                               if (!dst_key_isprivate(keys[i])) {
+                               if (!dst_key_inactive(keys[i]) &&
+                                   !dst_key_isprivate(keys[i])) {
                                        /*
                                         * The re-signing code in zone.c
                                         * will mark this as offline.
index 1ad2fb2ecf4bdd515bb9f60f0b725340de7b2d7b..d1903ba287946f9990c414bedd7b4994a4b62304 100644 (file)
@@ -53,6 +53,7 @@ rm -f ns4/named.conf
 rm -f ns4/managed-keys.bind*
 rm -f ns3/auto-nsec.example.db ns3/auto-nsec3.example.db
 rm -f ns3/secure.below-cname.example.db
+rm -f ns3/publish-inactive.example.db
 rm -f signer/example.db.after signer/example.db.before
 rm -f signer/example.db.changed
 rm -f ns3/ttlpatch.example.db ns3/ttlpatch.example.db.signed
index 5a2933968d3bae409965d4560904e91dd10bce33..6d936897e353db8cc6f83309d4376163b4631ed9 100644 (file)
@@ -33,6 +33,7 @@ options {
        notify yes;
        dnssec-enable yes;
        dnssec-validation yes;
+       session-keyfile "session.key";
 };
 
 key rndc_key {
@@ -238,4 +239,11 @@ zone "LOWER.EXAMPLE" {
        file "lower.example.db.signed";
 };
 
+zone "publish-inactive.example" {
+       type master;
+       file "publish-inactive.example.db";
+       auto-dnssec maintain;
+       update-policy local;
+};
+
 include "trusted.conf";
diff --git a/bin/tests/system/dnssec/ns3/publish-inactive.example.db.in b/bin/tests/system/dnssec/ns3/publish-inactive.example.db.in
new file mode 100644 (file)
index 0000000..16c278b
--- /dev/null
@@ -0,0 +1,31 @@
+; 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: insecure.example.db,v 1.9 2007/06/19 23:47:02 tbox Exp $
+
+$TTL 300       ; 5 minutes
+@                      IN SOA  mname1. . (
+                               2000042407 ; 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
+
+a                      A       10.0.0.1
+b                      A       10.0.0.2
+d                      A       10.0.0.4
+z                      A       10.0.0.26
index 7ed6291b212f330bece292ddd520b826242f6e3a..9b9e509db1121db8ac7a841186f44f9c29e5295d 100644 (file)
@@ -382,3 +382,17 @@ 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
+
+#
+# publish a new key while deactivating another key at the same time.
+#
+zone=publish-inactive.example
+infile=publish-inactive.example.db.in
+zonefile=publish-inactive.example.db
+now=`date -u +%Y%m%d%H%M%S`
+kskname=`$KEYGEN -q -r $RANDFILE -f KSK $zone`
+kskname=`$KEYGEN -P $now+90s -A $now+3600s -q -r $RANDFILE -f KSK $zone`
+kskname=`$KEYGEN -I $now+90s -q -r $RANDFILE -f KSK $zone`
+zskname=`$KEYGEN -q -r $RANDFILE $zone`
+cp $infile $zonefile
+$SIGNER -S -r $RANDFILE -o $zone $zonefile > /dev/null 2>&1
index fadfdf6299f0fb7ee7ecc06f9bc70b9abb15dfaf..2df9bf30fcc93defc5b6911d87c47fa5ba24e2f3 100644 (file)
@@ -1880,5 +1880,25 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+echo "I:check simultaneous inactivation and publishing of dnskeys removes inactive signature ($n)"
+ret=0
+cnt=0
+while :
+do
+$DIG $DIGOPTS publish-inactive.example @10.53.0.3 dnskey > dig.out.ns3.test$n
+keys=`awk '$5 == 257 { print; }' dig.out.ns3.test$n | wc -l`
+test $keys -gt 2 && break
+cnt=`expr $cnt + 1`
+test $cnt -gt 120 && break
+sleep 1
+done
+test $keys -gt 2 || ret=1
+sigs=`grep RRSIG dig.out.ns3.test$n | wc -l`
+sigs=`expr $sigs + 0`
+n=`expr $n + 1`
+test $sigs -eq 2 || ret=1
+if test $ret != 0 ; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:exit status: $status"
 exit $status
index 587bd1c3c23342977eb25c0d4745bce436951abe..9eea11278becff68cfecc98ecb32be82c52c6c1a 100644 (file)
@@ -753,6 +753,7 @@ dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver,
                 * If a key is marked inactive, skip it
                 */
                if (!key_active(keys[count], now)) {
+                       dst_key_setinactive(pubkey, ISC_TRUE);
                        dst_key_free(&keys[count]);
                        keys[count] = pubkey;
                        pubkey = NULL;
index 53978bce070182f1300af38335519b64a13a8468..905d849576edcd4b64358149e46ef95dd8d6590a 100644 (file)
@@ -1291,10 +1291,27 @@ get_key_struct(dns_name_t *name, unsigned int alg,
                key->times[i] = 0;
                key->timeset[i] = ISC_FALSE;
        }
+       key->inactive = ISC_FALSE;
        key->magic = KEY_MAGIC;
        return (key);
 }
 
+isc_boolean_t
+dst_key_inactive(const dst_key_t *key) {
+
+       REQUIRE(VALID_KEY(key));
+
+       return (key->inactive);
+}
+
+void
+dst_key_setinactive(dst_key_t *key, isc_boolean_t inactive) {
+
+       REQUIRE(VALID_KEY(key));
+
+       key->inactive = inactive;
+}
+
 /*%
  * Reads a public key from disk
  */
index ee824f40e88a9bd71aeaa74187655b98426756d7..1dd528f3471aefc9ab4fcd8e0e2e005e5d94c0e5 100644 (file)
@@ -125,6 +125,8 @@ struct dst_key {
        isc_boolean_t   timeset[DST_MAX_TIMES + 1];  /*%< data set? */
        isc_stdtime_t   nums[DST_MAX_NUMERIC + 1];   /*%< numeric metadata */
        isc_boolean_t   numset[DST_MAX_NUMERIC + 1]; /*%< data set? */
+       isc_boolean_t   inactive;      /*%< private key not present as it is
+                                           inactive */
 
        int             fmt_major;     /*%< private key format, major version */
        int             fmt_minor;     /*%< private key format, minor version */
index 87d844bf2270c69c7a3442f03f74810cc824d84f..e6ea09e6e2178c1effee76cc7eba438ce89cb5d8 100644 (file)
@@ -887,6 +887,23 @@ dst_key_restore(dns_name_t *name, unsigned int alg, unsigned int flags,
                unsigned int protocol, dns_rdataclass_t rdclass,
                isc_mem_t *mctx, const char *keystr, dst_key_t **keyp);
 
+isc_boolean_t
+dst_key_inactive(const dst_key_t *key);
+/*%<
+ * Determines if the private key is missing due the key being deemed inactive.
+ *
+ * Requires:
+ *     'key' to be valid.
+ */
+
+void
+dst_key_setinactive(dst_key_t *key, isc_boolean_t inactive);
+/*%<
+ * Set key inactive state.
+ *
+ * Requires:
+ *     'key' to be valid.
+ */
 
 ISC_LANG_ENDDECLS
 
index 261da77727996c3f49199edca57c0e47b19b6b3a..21f5d2c238293f1785ea89d21d4773a9988f25c0 100644 (file)
@@ -957,6 +957,7 @@ dst_key_generate2
 dst_key_getprivateformat
 dst_key_gettime
 dst_key_id
+dst_key_inactive
 dst_key_isnullkey
 dst_key_isprivate
 dst_key_iszonekey
@@ -969,6 +970,7 @@ dst_key_rid
 dst_key_secretsize
 dst_key_setbits
 dst_key_setflags
+dst_key_setinactive
 dst_key_setprivateformat
 dst_key_settime
 dst_key_sigsize
index cdcc9ea787d591e389b3e0287341debbf4d9518f..a654167e989902459ad48e9ad783f9cf895f3a5a 100644 (file)
@@ -4889,7 +4889,9 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
                                 * We want the earliest offline expire time
                                 * iff there is a new offline signature.
                                 */
-                               if (!dst_key_isprivate(keys[i])) {
+                               if (!dst_key_inactive(keys[i]) &&
+                                   !dst_key_isprivate(keys[i]))
+                               {
                                        isc_int64_t timeexpire =
                                           dns_time64_from32(rrsig.timeexpire);
                                        if (warn != 0 && warn > timeexpire)