diff --git a/CHANGES b/CHANGES index ef65e72a7f..c009a27026 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,7 @@ -2000. [bug] memmove()/strtol() fix was incomplete. [#RT 15812] +2001. [func] Check the KSK flag when updating a secure dynamic zone. + New zone option "update-check-ksk yes;". [RT #15817] + +2000. [bug] memmove()/strtol() fix was incomplete. [RT #15812] 1999. [func] Implement "rrset-order fixed". [RT #13662] diff --git a/bin/named/config.c b/bin/named/config.c index cf9300b262..1e9b94ff0f 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: config.c,v 1.70 2006/03/03 00:43:34 marka Exp $ */ +/* $Id: config.c,v 1.71 2006/03/06 01:27:51 marka Exp $ */ /*! \file */ @@ -175,6 +175,7 @@ options {\n\ check-mx-cname warn;\n\ check-srv-cname warn;\n\ zero-no-soa-ttl yes;\n\ + update-check-ksk yes;\n\ };\n\ " diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook index 091a659887..3bc7561627 100644 --- a/bin/named/named.conf.docbook +++ b/bin/named/named.conf.docbook @@ -17,7 +17,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + Aug 13, 2004 @@ -280,6 +280,7 @@ options { allow-transfer { address_match_element; ... }; allow-update { address_match_element; ... }; allow-update-forwarding { address_match_element; ... }; + update-check-ksk boolean; notify notifytype; notify-source ( ipv4_address | * ) port ( integer | * ) ; @@ -426,6 +427,7 @@ view string optional_class allow-transfer { address_match_element; ... }; allow-update { address_match_element; ... }; allow-update-forwarding { address_match_element; ... }; + update-check-ksk boolean; notify notifytype; notify-source ( ipv4_address | * ) port ( integer | * ) ; @@ -511,6 +513,7 @@ zone string optional_class ( name | subdomain | wildcard | self ) string rrtypelist; ... }; + update-check-ksk boolean; notify notifytype; notify-source ( ipv4_address | * ) port ( integer | * ) ; diff --git a/bin/named/update.c b/bin/named/update.c index 8e083dd0d0..515d753fed 100644 --- a/bin/named/update.c +++ b/bin/named/update.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: update.c,v 1.128 2006/03/03 00:43:34 marka Exp $ */ +/* $Id: update.c,v 1.129 2006/03/06 01:27:51 marka Exp $ */ #include @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1604,6 +1605,44 @@ find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, return (result); } +static isc_boolean_t +ksk_sanity(dns_db_t *db, dns_dbversion_t *ver) { + isc_boolean_t ret = ISC_FALSE; + isc_boolean_t have_ksk = ISC_FALSE, have_nonksk = ISC_FALSE; + isc_result_t result; + dns_dbnode_t *node = NULL; + dns_rdataset_t rdataset; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_dnskey_t dnskey; + + dns_rdataset_init(&rdataset); + CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); + CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0, + &rdataset, NULL)); + CHECK(dns_rdataset_first(&rdataset)); + while (result == ISC_R_SUCCESS && (!have_ksk || !have_nonksk)) { + dns_rdataset_current(&rdataset, &rdata); + CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL)); + if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH)) + == DNS_KEYOWNER_ZONE) { + if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) + have_ksk = ISC_TRUE; + else + have_nonksk = ISC_TRUE; + } + dns_rdata_reset(&rdata); + result = dns_rdataset_next(&rdataset); + } + if (have_ksk && have_nonksk) + ret = ISC_TRUE; + failure: + if (dns_rdataset_isassociated(&rdataset)) + dns_rdataset_disassociate(&rdataset); + if (node != NULL) + dns_db_detachnode(db, &node); + return (ret); +} + /*% * Add RRSIG records for an RRset, recording the change in "diff". */ @@ -1611,7 +1650,7 @@ static isc_result_t add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception, - isc_stdtime_t expire) + isc_stdtime_t expire, isc_boolean_t check_ksk) { isc_result_t result; dns_dbnode_t *node = NULL; @@ -1632,6 +1671,11 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_db_detachnode(db, &node); for (i = 0; i < nkeys; i++) { + + if (check_ksk && type != dns_rdatatype_dnskey && + (dst_key_flags(keys[i]) & DNS_KEYFLAG_KSK) != 0) + continue; + /* Calculate the signature, creating a RRSIG RDATA. */ CHECK(dns_dnssec_sign(name, &rdataset, keys[i], &inception, &expire, @@ -1685,6 +1729,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t rdataset; dns_dbnode_t *node = NULL; + isc_boolean_t check_ksk; dns_diff_init(client->mctx, &diffnames); dns_diff_init(client->mctx, &affected); @@ -1705,6 +1750,17 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, inception = now - 3600; /* Allow for some clock skew. */ expire = now + sigvalidityinterval; + /* + * Do we look at the KSK flag on the DNSKEY to determining which + * keys sign which RRsets? First check the zone option then + * check the keys flags to make sure atleast one has a ksk set + * and one doesn't. + */ + check_ksk = ISC_TF((dns_zone_getoptions(zone) & + DNS_ZONEOPT_UPDATECHECKKSK) != 0); + if (check_ksk) + check_ksk = ksk_sanity(db, newver); + /* * Get the NSEC's TTL from the SOA MINIMUM field. */ @@ -1764,7 +1820,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, CHECK(add_sigs(db, newver, name, type, &sig_diff, zone_keys, nkeys, client->mctx, inception, - expire)); + expire, check_ksk)); } skip: /* Skip any other updates to the same RRset. */ @@ -1949,7 +2005,8 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, } else if (t->op == DNS_DIFFOP_ADD) { CHECK(add_sigs(db, newver, &t->name, dns_rdatatype_nsec, &sig_diff, zone_keys, nkeys, - client->mctx, inception, expire)); + client->mctx, inception, expire, + check_ksk)); } else { INSIST(0); } diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index ad1f6c1823..d7cb752f74 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zoneconf.c,v 1.131 2006/02/28 02:39:51 marka Exp $ */ +/* $Id: zoneconf.c,v 1.132 2006/03/06 01:27:52 marka Exp $ */ /*% */ @@ -720,6 +720,12 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, INSIST(0); dns_zone_setoption(zone, DNS_ZONEOPT_WARNSRVCNAME, warn); dns_zone_setoption(zone, DNS_ZONEOPT_IGNORESRVCNAME, ignore); + + obj = NULL; + result = ns_config_get(maps, "update-check-ksk", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setoption(zone, DNS_ZONEOPT_UPDATECHECKKSK, + cfg_obj_asboolean(obj)); } /* diff --git a/bin/tests/system/dnssec/ns3/sign.sh b/bin/tests/system/dnssec/ns3/sign.sh index e06cfa9658..68ea50997d 100644 --- a/bin/tests/system/dnssec/ns3/sign.sh +++ b/bin/tests/system/dnssec/ns3/sign.sh @@ -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.20 2006/01/04 00:37:24 marka Exp $ +# $Id: sign.sh,v 1.21 2006/03/06 01:27:52 marka Exp $ RANDFILE=../random.data @@ -43,9 +43,10 @@ zone=dynamic.example. infile=dynamic.example.db.in zonefile=dynamic.example.db -keyname=`$KEYGEN -r $RANDFILE -a RSAMD5 -b 768 -n zone $zone` +keyname1=`$KEYGEN -r $RANDFILE -a RSAMD5 -b 768 -n zone $zone` +keyname2=`$KEYGEN -r $RANDFILE -a RSAMD5 -b 1024 -n zone -f KSK $zone` -cat $infile $keyname.key >$zonefile +cat $infile $keyname1.key $keyname2.key >$zonefile $SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 8f44de9b72..14958e5e70 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -18,7 +18,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + BIND 9 Administrator Reference Manual @@ -4416,6 +4416,7 @@ category notify { null; }; allow-recursion { address_match_list }; allow-update { address_match_list }; allow-update-forwarding { address_match_list }; + update-check-ksk yes_or_no; allow-v6-synthesis { address_match_list }; blackhole { address_match_list }; avoid-v4-udp-ports { port_list }; @@ -5638,6 +5639,21 @@ options { + + + update-check-ksk + + + When regenerating the RRSIGs following a UPDATE + request to a secure zone, check the KSK flag on + the DNSKEY RR to determine if this key should be + used to generate the RRSIG. This flag is ignored + if there are not DNSKEY RRs both with and without + a KSK. Default yes. + + + + @@ -8004,6 +8020,7 @@ zone zone_name class allow-query { address_match_list }; allow-transfer { address_match_list }; allow-update-forwarding { address_match_list }; + update-check-ksk yes_or_no; also-notify { ip_addr port ip_port ; ip_addr port ip_port ; ... }; check-names (warn|fail|ignore) ; dialup dialup_option ; @@ -8489,6 +8506,16 @@ zone zone_name class + + update-check-ksk + + + See the description of + update-check-ksk in . + + + + database diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 1d5c6bf8d8..cef648a6eb 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: check.c,v 1.71 2006/03/03 00:43:35 marka Exp $ */ +/* $Id: check.c,v 1.72 2006/03/06 01:27:52 marka Exp $ */ /*! \file */ @@ -933,6 +933,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, { "check-mx-cname", MASTERZONE }, { "check-srv-cname", MASTERZONE }, { "masterfile-format", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE }, + { "update-check-ksk", MASTERZONE }, }; static optionstable dialups[] = { diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c index 958f9482d9..83a621831d 100644 --- a/lib/dns/dnssec.c +++ b/lib/dns/dnssec.c @@ -16,7 +16,7 @@ */ /* - * $Id: dnssec.c,v 1.85 2005/11/30 03:33:49 marka Exp $ + * $Id: dnssec.c,v 1.86 2006/03/06 01:27:52 marka Exp $ */ /*! \file */ @@ -520,10 +520,10 @@ dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_result_t dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver, - dns_dbnode_t *node, dns_name_t *name, - const char *directory, isc_mem_t *mctx, - unsigned int maxkeys, dst_key_t **keys, - unsigned int *nkeys) + dns_dbnode_t *node, dns_name_t *name, + const char *directory, isc_mem_t *mctx, + unsigned int maxkeys, dst_key_t **keys, + unsigned int *nkeys) { dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 7d8502e4e5..c2a1bf499a 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.h,v 1.143 2006/02/28 02:39:51 marka Exp $ */ +/* $Id: zone.h,v 1.144 2006/03/06 01:27:52 marka Exp $ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 @@ -65,6 +65,7 @@ typedef enum { #define DNS_ZONEOPT_IGNOREMXCNAME 0x00100000U /*%< ignore MX CNAME check */ #define DNS_ZONEOPT_WARNSRVCNAME 0x00200000U /*%< warn on SRV CNAME check */ #define DNS_ZONEOPT_IGNORESRVCNAME 0x00400000U /*%< ignore SRV CNAME check */ +#define DNS_ZONEOPT_UPDATECHECKKSK 0x00800000U /*%< check dnskey KSK flag */ #ifndef NOMINUM_PUBLIC /* diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index b4cd481cf2..84fb1e0b14 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namedconf.c,v 1.66 2006/02/28 02:39:52 marka Exp $ */ +/* $Id: namedconf.c,v 1.67 2006/03/06 01:27:52 marka Exp $ */ /*! \file */ @@ -844,6 +844,7 @@ zone_clauses[] = { { "check-srv-cname", &cfg_type_checkmode, 0 }, { "check-sibling", &cfg_type_boolean, 0 }, { "zero-no-soa-ttl", &cfg_type_boolean, 0 }, + { "update-check-ksk", &cfg_type_boolean, 0 }, { NULL, NULL, 0 } };