[v9_9] dnssec-signzone -Q

3686.	[func]		"dnssec-signzone -Q" drops signatures from keys
			that are still published but no longer active.
			[RT #34990]

(cherry picked from commit 0bbe3273a2)
This commit is contained in:
Evan Hunt 2013-12-11 13:24:13 -08:00
parent dda2ffdbcf
commit 2c73b0a857
7 changed files with 97 additions and 17 deletions

View file

@ -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]

View 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)) {
@ -2949,6 +2955,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");
@ -3049,11 +3058,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.
@ -3256,8 +3266,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':
@ -3343,8 +3357,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) {

View file

@ -490,10 +490,10 @@
</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
@ -501,9 +501,26 @@
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>
@ -766,7 +783,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>

View file

@ -1366,6 +1366,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
(

View 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;

View 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);
/*%<

View file

@ -214,6 +214,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