]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] dnssec-signzone -Q
authorEvan Hunt <each@isc.org>
Wed, 11 Dec 2013 21:14:46 +0000 (13:14 -0800)
committerEvan Hunt <each@isc.org>
Wed, 11 Dec 2013 21:25:21 +0000 (13:25 -0800)
3686. [func] "dnssec-signzone -Q" drops signatures from keys
that are still published but no longer active.
[RT #34990]

CHANGES
bin/dnssec/dnssec-signzone.c
bin/dnssec/dnssec-signzone.docbook
bin/tests/system/dnssec/tests.sh
lib/dns/dnssec.c
lib/dns/include/dns/dnssec.h
lib/dns/win32/libdns.def.in

diff --git a/CHANGES b/CHANGES
index 2a46d05fd5eecad3ffaae693c026bd1ebd37e75a..00fbee83899e86d000bde7a0d75bd4fb862f059c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+3686.  [func]          "dnssec-signzone -Q" drops signatures from keys
+                       that are still published but no longer active.
+                       [RT #34990]
+
 3685.  [bug]           "rndc refresh" didn't work correctly with slave
                        zones using inline-signing. [RT #35105]
 
index d0e5fb5499c7b4b80a38c1d37a98fe57d28558ec..3a10d63c3ee5c6c0ecde7e4074ff514cf93f9245 100644 (file)
@@ -175,7 +175,8 @@ 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 remove_orphansigs = ISC_FALSE;
+static isc_boolean_t remove_inactkeysigs = ISC_FALSE;
 static isc_boolean_t output_dnssec_only = ISC_FALSE;
 static isc_boolean_t output_stdout = ISC_FALSE;
 
@@ -554,9 +555,14 @@ 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);
+                       keep = (!expired && !remove_orphansigs);
                        vbprintf(2, "\trrsig by %s %s - dnskey not found\n",
                                 keep ? "retained" : "dropped", sigstr);
+               } else if (!dns_dnssec_keyactive(key->key, now) &&
+                          remove_inactkeysigs) {
+                       keep = ISC_FALSE;
+                       vbprintf(2, "\trrsig by %s dropped - key inactive\n",
+                                sigstr);
                } else if (issigningkey(key)) {
                        wassignedby[key->index] = ISC_TRUE;
 
@@ -571,7 +577,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
                                         "ttl change" : "failed to verify");
                                resign = ISC_TRUE;
                        }
-               } else if (!ispublishedkey(key) && remove_orphans) {
+               } else if (!ispublishedkey(key) && remove_orphansigs) {
                        vbprintf(2, "\trrsig by %s dropped - dnskey removed\n",
                                 sigstr);
                } else if (iszonekey(key)) {
@@ -2950,6 +2956,9 @@ usage(void) {
        fprintf(stderr, "use pseudorandom data (faster but less secure)\n");
        fprintf(stderr, "\t-P:\t");
        fprintf(stderr, "disable post-sign verification\n");
+       fprintf(stderr, "\t-Q:\t");
+       fprintf(stderr, "remove signatures from keys that are no "
+                               "longer active\n");
        fprintf(stderr, "\t-R:\t");
        fprintf(stderr, "remove signatures from keys that no longer exist\n");
        fprintf(stderr, "\t-T TTL:\tTTL for newly added DNSKEYs\n");
@@ -3050,11 +3059,12 @@ main(int argc, char *argv[]) {
        isc_boolean_t make_keyset = ISC_FALSE;
        isc_boolean_t set_salt = ISC_FALSE;
        isc_boolean_t set_optout = ISC_FALSE;
-       isc_boolean_t set_iter = ISC_FALSE;
+       isc_boolean_t set_iter = ISC_FALSE;
        isc_boolean_t nonsecify = ISC_FALSE;
 
+       /* Unused letters: Bb G J M q Yy (and F is reserved). */
 #define CMDLINE_FLAGS \
-       "3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:L:l:m:n:N:o:O:PpRr:s:ST:tuUv:X:xzZ:"
+       "3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:L:l:m:n:N:o:O:PpQRr:s:ST:tuUv:X:xzZ:"
 
        /*
         * Process memory debugging argument first.
@@ -3257,8 +3267,12 @@ main(int argc, char *argv[]) {
                        pseudorandom = ISC_TRUE;
                        break;
 
+               case 'Q':
+                       remove_inactkeysigs = ISC_TRUE;
+                       break;
+
                case 'R':
-                       remove_orphans = ISC_TRUE;
+                       remove_orphansigs = ISC_TRUE;
                        break;
 
                case 'r':
@@ -3344,8 +3358,7 @@ main(int argc, char *argv[]) {
        result = dst_lib_init2(mctx, ectx, engine, eflags);
        if (result != ISC_R_SUCCESS)
                fatal("could not initialize dst: %s",
-                     isc_result_totext(result));
-
+                     isc_result_totext(result)); 
        isc_stdtime_get(&now);
 
        if (startstr != NULL) {
index 02dd69bc7300713aaa4068e89f73fc2ba2bbe9fa..96500b7322764b9f72b386979867987c82e215db 100644 (file)
       </varlistentry>
 
       <varlistentry>
-        <term>-R</term>
+        <term>-Q</term>
         <listitem>
           <para>
-           Remove signatures from keys that no longer exist.
+           Remove signatures from keys that are no longer active.
           </para>
           <para>
             Normally, when a previously-signed zone is passed as input
             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.
+           copies of the old DNSKEY RRset.  The <option>-Q</option>
+            forces <command>dnssec-signzone</command> to remove
+            signatures from keys that are no longer active. This
+            enables ZSK rollover using the procedure described in
+            RFC 4641, section 4.2.1.1 ("Pre-Publish Key Rollover").
+          </para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>-R</term>
+        <listitem>
+          <para>
+           Remove signatures from keys that are no longer published.
+          </para>
+          <para>
+            This option is similar to <option>-Q</option>, except it
+            forces <command>dnssec-signzone</command> to signatures from
+            keys that are no longer published. This enables ZSK rollover
+            using the procedure described in RFC 4641, section 4.2.1.2
+            ("Double Signature Zone Signing Key Rollover").
           </para>
         </listitem>
       </varlistentry>
@@ -769,7 +786,7 @@ db.example.com.signed
         <refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citetitle>BIND 9 Administrator Reference Manual</citetitle>,
-      <citetitle>RFC 4033</citetitle>.
+      <citetitle>RFC 4033</citetitle>, <citetitle>RFC 4641</citetitle>.
     </para>
   </refsect1>
 
index d5376202531a8b2b38ae1f3d02a52c75311f6ac4..3d730e2e496fd0469037470fa3a18b76e5a66215 100644 (file)
@@ -1379,6 +1379,36 @@ 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 inactive keys ($n)"
+ret=0
+zone=example
+(
+cd signer
+cp -f example.db.in example.db
+$SIGNER -SD -o example example.db > /dev/null 2>&1
+echo '$INCLUDE "example.db.signed"' >> example.db
+# now retire key2 and resign the zone
+$SETTIME -I now $key2 > /dev/null 2>&1
+$SIGNER -SD -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 inactive keys ($n)"
+ret=0
+(
+cd signer
+$SIGNER -SDQ -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 retains unexpired signatures ($n)"
 ret=0
 (
index cf9740406a38166ead12cbb1a4d500dc83a2a9a2..2a4ab4f6cf933400028f94a3d2db3684ce14fb8d 100644 (file)
@@ -609,8 +609,8 @@ dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
        return (result);
 }
 
-static isc_boolean_t
-key_active(dst_key_t *key, isc_stdtime_t now) {
+isc_boolean_t
+dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now) {
        isc_result_t result;
        isc_stdtime_t publish, active, revoke, inactive, delete;
        isc_boolean_t pubset = ISC_FALSE, actset = ISC_FALSE;
@@ -764,7 +764,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)) {
+               if (!dns_dnssec_keyactive(keys[count], now)) {
                        dst_key_setinactive(pubkey, ISC_TRUE);
                        dst_key_free(&keys[count]);
                        keys[count] = pubkey;
index e443f91b635b8a78e35140b20bc06846d0dd1752..0625e89c1eb4d27f3e40659db7ac47a4efc0117d 100644 (file)
@@ -174,6 +174,7 @@ dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
                        dns_name_t *name, isc_mem_t *mctx,
                        unsigned int maxkeys, dst_key_t **keys,
                        unsigned int *nkeys);
+
 isc_result_t
 dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver,
                         dns_dbnode_t *node, dns_name_t *name,
@@ -186,6 +187,20 @@ dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver,
  */
 /*@}*/
 
+isc_boolean_t
+dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now);
+/*%<
+ *     
+ *     Returns ISC_TRUE if 'key' is active as of the time specified
+ *     in 'now' (i.e., if the activation date has passed, inactivation or
+ *     deletion date has not yet been reached, and the key is not revoked
+ *     -- or if it is a legacy key without metadata). Otherwise returns
+ *     ISC_FALSE.
+ *
+ *     Requires:
+ *\li          'key' is a valid key
+ */
+
 isc_result_t
 dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key);
 /*%<
index 585ed5abd86a2e3b5f2dbf3bb1dc3126e72a9ea8..026cd67f19651b621a37d8f472afaf5162139e0a 100644 (file)
@@ -225,6 +225,7 @@ dns_dns64_unlink
 dns_dnssec_findmatchingkeys
 dns_dnssec_findzonekeys
 dns_dnssec_findzonekeys2
+dns_dnssec_keyactive
 dns_dnssec_keyfromrdata
 dns_dnssec_keylistfromrdataset
 dns_dnssec_selfsigns