]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3085. [func] New '-R' option in dnssec-signzone forces removal
authorEvan Hunt <each@isc.org>
Mon, 21 Mar 2011 07:26:47 +0000 (07:26 +0000)
committerEvan Hunt <each@isc.org>
Mon, 21 Mar 2011 07:26:47 +0000 (07:26 +0000)
of signatures which have not yet expired but
were generated by a key that no longer exists.
[RT #22471]

CHANGES
bin/dnssec/dnssec-signzone.c
bin/dnssec/dnssec-signzone.docbook
bin/tests/system/dnssec/tests.sh

diff --git a/CHANGES b/CHANGES
index 68da4cf442cb57760e1c1da0f15285fe080d8cb1..c847acedbf5926c852f92b968e226e19b295fc7f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+3085.  [func]          New '-R' option in dnssec-signzone forces removal
+                       of signatures which have not yet expired but
+                       were generated by a key that no longer exists.
+                       [RT #22471]
+
 3084.  [func]          A new command "rndc sync" dumps pending changes in
                        a dynamic zone to disk; "rndc sync -clean" also
                        removes the journal file after syncing.  Also,
index 717122653ab18bfec4179b66aa2c89addaa7e714..51b5a84af1d5975eb481efac035ccf4a5d9ed091 100644 (file)
@@ -29,7 +29,7 @@
  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dnssec-signzone.c,v 1.271 2011/03/11 12:37:01 marka Exp $ */
+/* $Id: dnssec-signzone.c,v 1.272 2011/03/21 07:26:47 each Exp $ */
 
 /*! \file */
 
@@ -172,6 +172,7 @@ static isc_boolean_t update_chain = ISC_FALSE;
 static isc_boolean_t set_keyttl = ISC_FALSE;
 static dns_ttl_t keyttl;
 static isc_boolean_t smartsign = ISC_FALSE;
+static isc_boolean_t remove_orphans = ISC_FALSE;
 static isc_boolean_t output_dnssec_only = ISC_FALSE;
 
 #define INCSTAT(counter)               \
@@ -316,6 +317,12 @@ issigningkey(dns_dnsseckey_t *key) {
        return (key->force_sign || key->hint_sign);
 }
 
+static inline isc_boolean_t
+ispublishedkey(dns_dnsseckey_t *key) {
+       return ((key->force_publish || key->hint_publish) &&
+               !key->hint_remove);
+}
+
 static inline isc_boolean_t
 iszonekey(dns_dnsseckey_t *key) {
        return (ISC_TF(dns_name_equal(dst_key_name(key->key), gorigin) &&
@@ -362,6 +369,8 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
        isc_result_t result;
        dst_key_t *pubkey = NULL, *privkey = NULL;
        dns_dnsseckey_t *key = NULL;
+       isc_stdtime_t delete;
+       isc_boolean_t delset;
 
        isc_rwlock_lock(&keylist_lock, isc_rwlocktype_read);
        key = keythatsigned_unlocked(rrsig);
@@ -401,7 +410,16 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
        } else {
                dns_dnsseckey_create(mctx, &pubkey, &key);
        }
-       key->force_publish = ISC_TRUE;
+
+       result = dst_key_gettime(key->key, DST_TIME_DELETE, &delete);
+       if (result == ISC_R_SUCCESS)
+               delset = ISC_TRUE;
+
+       if (delset && delete <= now)
+               key->force_publish = ISC_FALSE;
+       else
+               key->force_publish = ISC_TRUE;
+
        key->force_sign = ISC_FALSE;
        ISC_LIST_APPEND(keylist, key, link);
 
@@ -544,10 +562,9 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
                                 "private dnskey not found\n",
                                 sigstr);
                } else if (key == NULL || future) {
+                       keep = (!expired && !remove_orphans);
                        vbprintf(2, "\trrsig by %s %s - dnskey not found\n",
-                                expired ? "retained" : "dropped", sigstr);
-                       if (!expired)
-                               keep = ISC_TRUE;
+                                keep ? "retained" : "dropped", sigstr);
                } else if (issigningkey(key)) {
                        if (!expired && rrsig.originalttl == set->ttl &&
                            setverifies(name, set, key->key, &sigrdata)) {
@@ -563,6 +580,9 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
                                wassignedby[key->index] = ISC_TRUE;
                                resign = ISC_TRUE;
                        }
+               } else if (!ispublishedkey(key) && remove_orphans) {
+                       vbprintf(2, "\trrsig by %s dropped - dnskey removed\n",
+                                sigstr);
                } else if (iszonekey(key)) {
                        if (!expired && rrsig.originalttl == set->ttl &&
                            setverifies(name, set, key->key, &sigrdata)) {
@@ -639,7 +659,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
             key != NULL;
             key = ISC_LIST_NEXT(key, link))
        {
-               if (nowsignedby[key->index])
+               if (nowsignedby[key->index] && !ispublishedkey(key))
                        continue;
 
                if (!issigningkey(key))
@@ -3457,7 +3477,7 @@ main(int argc, char *argv[]) {
        isc_boolean_t set_iter = ISC_FALSE;
 
 #define CMDLINE_FLAGS \
-       "3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:l:m:n:N:o:O:pPr:s:ST:tuUv:X:xz"
+       "3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:l:m:n:N:o:O:PpRr:s:ST:tuUv:X:xz"
 
        /*
         * Process memory debugging argument first.
@@ -3647,6 +3667,10 @@ main(int argc, char *argv[]) {
                        pseudorandom = ISC_TRUE;
                        break;
 
+               case 'R':
+                       remove_orphans = ISC_TRUE;
+                       break;
+
                case 'r':
                        setup_entropy(mctx, isc_commandline_argument, &ectx);
                        break;
index dcf5c617fd530ed493fc0d132baeb67f29730db2..342c498651f96a83b0882bcd340ca58e92d3b2d3 100644 (file)
@@ -18,7 +18,7 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id: dnssec-signzone.docbook,v 1.48 2011/03/17 01:40:35 each Exp $ -->
+<!-- $Id: dnssec-signzone.docbook,v 1.49 2011/03/21 07:26:47 each Exp $ -->
 <refentry id="man.dnssec-signzone">
   <refentryinfo>
     <date>June 05, 2009</date>
@@ -76,8 +76,9 @@
       <arg><option>-N <replaceable class="parameter">soa-serial-format</replaceable></option></arg>
       <arg><option>-o <replaceable class="parameter">origin</replaceable></option></arg>
       <arg><option>-O <replaceable class="parameter">output-format</replaceable></option></arg>
-      <arg><option>-p</option></arg>
       <arg><option>-P</option></arg>
+      <arg><option>-p</option></arg>
+      <arg><option>-R</option></arg>
       <arg><option>-r <replaceable class="parameter">randomdev</replaceable></option></arg>
       <arg><option>-S</option></arg>
       <arg><option>-s <replaceable class="parameter">start-time</replaceable></option></arg>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term>-R</term>
+        <listitem>
+          <para>
+           Remove signatures from keys that no longer exist.
+          </para>
+          <para>
+            Normally, when a previously-signed zone is passed as input
+            to the signer, and a DNSKEY record has been removed and
+            replaced with a new one, signatures from the old key 
+            that are still within their validity period are retained.
+           This allows the zone to continue to validate with cached
+           copies of the old DNSKEY RRset.  The <option>-R</option> forces
+            <command>dnssec-signzone</command> to remove all orphaned
+            signatures.
+          </para>
+        </listitem>
+      </varlistentry>
       <varlistentry>
         <term>-r <replaceable class="parameter">randomdev</replaceable></term>
         <listitem>
index 5ef40d9e04d8ba8ab2c02205b5f73da666005008..0e2e520f709d0a343d8670df1959a9e836c671e9 100644 (file)
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: tests.sh,v 1.84 2011/03/21 03:30:48 marka Exp $
+# $Id: tests.sh,v 1.85 2011/03/21 07:26:47 each Exp $
 
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
 
+RANDFILE=random.data
+
 status=0
 n=1
 
@@ -930,12 +932,11 @@ status=`expr $status + $ret`
 
 echo "I:checking that we can sign a zone with out-of-zone records ($n)"
 ret=0
+zone=example
+key1=`$KEYGEN -K signer -q -r $RANDFILE -a NSEC3RSASHA1 -b 1024 -n zone $zone`
+key2=`$KEYGEN -K signer -q -r $RANDFILE -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone`
 (
 cd signer
-RANDFILE=../random.data
-zone=example
-key1=`$KEYGEN -q -r $RANDFILE -a NSEC3RSASHA1 -b 1024 -n zone $zone`
-key2=`$KEYGEN -q -r $RANDFILE -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone`
 cat example.db.in $key1.key $key2.key > example.db
 $SIGNER -o example -f example.db example.db > /dev/null 2>&1
 ) || ret=1
@@ -945,12 +946,11 @@ status=`expr $status + $ret`
 
 echo "I:checking that we can sign a zone (NSEC3) with out-of-zone records ($n)"
 ret=0
+zone=example
+key1=`$KEYGEN -K signer -q -r $RANDFILE -a NSEC3RSASHA1 -b 1024 -n zone $zone`
+key2=`$KEYGEN -K signer -q -r $RANDFILE -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone`
 (
 cd signer
-RANDFILE=../random.data
-zone=example
-key1=`$KEYGEN -q -r $RANDFILE -a NSEC3RSASHA1 -b 1024 -n zone $zone`
-key2=`$KEYGEN -q -r $RANDFILE -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone`
 cat example.db.in $key1.key $key2.key > example.db
 $SIGNER -3 - -H 10 -o example -f example.db example.db > /dev/null 2>&1
 awk '/^IQF9LQTLK/ {
@@ -969,12 +969,11 @@ status=`expr $status + $ret`
 
 echo "I:checking that dnsssec-signzone updates originalttl on ttl changes ($n)"
 ret=0
+zone=example
+key1=`$KEYGEN -K signer -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone $zone`
+key2=`$KEYGEN -K signer -q -r $RANDFILE -f KSK -a RSASHA1 -b 1024 -n zone $zone`
 (
 cd signer
-RANDFILE=../random.data
-zone=example
-key1=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone $zone`
-key2=`$KEYGEN -q -r $RANDFILE -f KSK -a RSASHA1 -b 1024 -n zone $zone`
 cat example.db.in $key1.key $key2.key > example.db
 $SIGNER -o example -f example.db.before example.db > /dev/null 2>&1
 sed 's/60.IN.SOA./50 IN SOA /' example.db.before > example.db.changed
@@ -985,6 +984,42 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+echo "I:checking dnssec-signzone keeps valid signatures from removed keys"
+ret=0
+zone=example
+key1=`$KEYGEN -K signer -q -r $RANDFILE -f KSK -a RSASHA1 -b 1024 -n zone $zone`
+key2=`$KEYGEN -K signer -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone $zone`
+keyid2=`echo $key2 | sed 's/^Kexample.+005+0*//'`
+key3=`$KEYGEN -K signer -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone $zone`
+keyid3=`echo $key3 | sed 's/^Kexample.+005+0*//'`
+(
+cd signer
+cat example.db.in $key1.key $key2.key > example.db
+$SIGNER -D -o example example.db > /dev/null 2>&1
+
+# now switch out key2 for key3 and resign the zone
+cat example.db.in $key1.key $key3.key > example.db
+echo '$INCLUDE "example.db.signed"' >> example.db
+$SIGNER -D -o example example.db > /dev/null 2>&1
+) || ret=1
+grep " $keyid2 " signer/example.db.signed > /dev/null 2>&1 || ret=1
+grep " $keyid3 " signer/example.db.signed > /dev/null 2>&1 || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking dnssec-signzone -R purges signatures from removed keys"
+ret=0
+(
+cd signer
+$SIGNER -RD -o example example.db > /dev/null 2>&1
+) || ret=1
+grep " $keyid2 " signer/example.db.signed > /dev/null 2>&1 && ret=1
+grep " $keyid3 " signer/example.db.signed > /dev/null 2>&1 || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:checking validated data are not cached longer than originalttl ($n)"
 ret=0
 $DIG $DIGOPTS +ttl +noauth a.ttlpatch.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1