diff --git a/CHANGES b/CHANGES index 688b6a1afe..498c590ded 100644 --- a/CHANGES +++ b/CHANGES @@ -52,6 +52,9 @@ 5193. [bug] EID and NIMLOC failed to do multi-line output correctly. [GL #899] +5190. [bug] Ignore trust anchors using disabled algorithms. + [GL #806] + 5189. [cleanup] Remove revoked root DNSKEY from bind.keys. [GL #945] 5187. [test] Set time zone before running any tests in dnstap_test. diff --git a/bin/named/server.c b/bin/named/server.c index 5ec13dba0c..0181efacf3 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -165,23 +165,23 @@ * using it has a 'result' variable and a 'cleanup' label. */ #define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ + do { result = (op); \ + if (result != ISC_R_SUCCESS) goto cleanup; \ } while (0) #define TCHECK(op) \ - do { tresult = (op); \ - if (tresult != ISC_R_SUCCESS) { \ - isc_buffer_clear(*text); \ - goto cleanup; \ - } \ + do { tresult = (op); \ + if (tresult != ISC_R_SUCCESS) { \ + isc_buffer_clear(*text); \ + goto cleanup; \ + } \ } while (0) #define CHECKM(op, msg) \ do { result = (op); \ if (result != ISC_R_SUCCESS) { \ isc_log_write(named_g_lctx, \ - NAMED_LOGCATEGORY_GENERAL, \ + NAMED_LOGCATEGORY_GENERAL, \ NAMED_LOGMODULE_SERVER, \ ISC_LOG_ERROR, \ "%s: %s", msg, \ @@ -194,7 +194,7 @@ do { result = (op); \ if (result != ISC_R_SUCCESS) { \ isc_log_write(named_g_lctx, \ - NAMED_LOGCATEGORY_GENERAL, \ + NAMED_LOGCATEGORY_GENERAL, \ NAMED_LOGMODULE_SERVER, \ ISC_LOG_ERROR, \ "%s '%s': %s", msg, file, \ @@ -703,7 +703,8 @@ configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config, static isc_result_t dstkey_fromconfig(const cfg_obj_t *vconfig, const cfg_obj_t *key, - bool managed, dst_key_t **target, isc_mem_t *mctx) + bool managed, dst_key_t **target, const char **keynamestrp, + isc_mem_t *mctx) { dns_rdataclass_t viewclass; dns_rdata_dnskey_t keystruct; @@ -721,12 +722,14 @@ dstkey_fromconfig(const cfg_obj_t *vconfig, const cfg_obj_t *key, dst_key_t *dstkey = NULL; INSIST(target != NULL && *target == NULL); + INSIST(keynamestrp != NULL && *keynamestrp == NULL); flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags")); proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol")); alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm")); keyname = dns_fixedname_name(&fkeyname); keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name")); + *keynamestrp = keynamestr; if (managed) { const char *initmethod; @@ -760,6 +763,8 @@ dstkey_fromconfig(const cfg_obj_t *vconfig, const cfg_obj_t *key, if (flags > 0xffff) CHECKM(ISC_R_RANGE, "key flags"); + if (flags & DNS_KEYFLAG_REVOKE) + CHECKM(DST_R_BADKEYTYPE, "key flags revoke bit set"); if (proto > 0xff) CHECKM(ISC_R_RANGE, "key protocol"); if (alg > 0xff) @@ -799,26 +804,118 @@ dstkey_fromconfig(const cfg_obj_t *vconfig, const cfg_obj_t *key, return (ISC_R_SUCCESS); cleanup: - if (result == DST_R_NOCRYPTO) { + if (dstkey != NULL) { + dst_key_free(&dstkey); + } + + return (result); +} + +/*% + * Parse 'key' in the context of view configuration 'vconfig'. If successful, + * add the key to 'secroots' if both of the following conditions are true: + * + * - 'keyname_match' is NULL or it matches the owner name of 'key', + * - support for the algorithm used by 'key' is not disabled by 'resolver' + * for the owner name of 'key'. + * + * 'managed' is true for managed keys and false for trusted keys. 'mctx' is + * the memory context to use for allocating memory. + */ +static isc_result_t +process_key(const cfg_obj_t *key, const cfg_obj_t *vconfig, + dns_keytable_t *secroots, const dns_name_t *keyname_match, + dns_resolver_t *resolver, bool managed, isc_mem_t *mctx) +{ + const dns_name_t *keyname = NULL; + const char *keynamestr = NULL; + dst_key_t *dstkey = NULL; + unsigned int keyalg; + isc_result_t result; + + result = dstkey_fromconfig(vconfig, key, managed, &dstkey, &keynamestr, + mctx); + + switch (result) { + case ISC_R_SUCCESS: + /* + * Key was parsed correctly, its algorithm is supported by the + * crypto library, and it is not revoked. + */ + keyname = dst_key_name(dstkey); + keyalg = dst_key_alg(dstkey); + break; + case DST_R_UNSUPPORTEDALG: + case DST_R_BADKEYTYPE: + /* + * Key was parsed correctly, but it cannot be used; this is not + * a fatal error - log a warning about this key being ignored, + * but do not prevent any further ones from being processed. + */ + cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING, + "ignoring %s key for '%s': %s", + managed ? "managed" : "trusted", + keynamestr, isc_result_totext(result)); + return (ISC_R_SUCCESS); + case DST_R_NOCRYPTO: + /* + * Crypto support is not available. + */ cfg_obj_log(key, named_g_lctx, ISC_LOG_ERROR, "ignoring %s key for '%s': no crypto support", managed ? "managed" : "trusted", keynamestr); - } else if (result == DST_R_UNSUPPORTEDALG) { - cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING, - "skipping %s key for '%s': %s", - managed ? "managed" : "trusted", - keynamestr, isc_result_totext(result)); - } else { + return (result); + default: + /* + * Something unexpected happened; we have no choice but to + * indicate an error so that the configuration loading process + * is interrupted. + */ cfg_obj_log(key, named_g_lctx, ISC_LOG_ERROR, "configuring %s key for '%s': %s", managed ? "managed" : "trusted", keynamestr, isc_result_totext(result)); - result = ISC_R_FAILURE; + return (ISC_R_FAILURE); } - if (dstkey != NULL) + /* + * If the caller requested to only load keys for a specific name and + * the owner name of this key does not match the requested name, do not + * load it. + */ + if (keyname_match != NULL && !dns_name_equal(keyname_match, keyname)) { + goto done; + } + + /* + * Ensure that 'resolver' allows using the algorithm of this key for + * its owner name. If it does not, do not load the key and log a + * warning, but do not prevent further keys from being processed. + */ + if (!dns_resolver_algorithm_supported(resolver, keyname, keyalg)) { + cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING, + "ignoring %s key for '%s': algorithm is disabled", + managed ? "managed" : "trusted", keynamestr); + goto done; + } + + /* + * Add the key to 'secroots'. This key is taken from the + * configuration, so if it's a managed key then it's an initializing + * key; that's why 'managed' is duplicated below. + */ + result = dns_keytable_add(secroots, managed, managed, &dstkey); + + done: + /* + * Ensure 'dstkey' does not leak. Note that if dns_keytable_add() + * succeeds, ownership of the key structure is transferred to the key + * table, i.e. 'dstkey' is set to NULL. + */ + if (dstkey != NULL) { dst_key_free(&dstkey); + } return (result); } @@ -834,8 +931,7 @@ load_view_keys(const cfg_obj_t *keys, const cfg_obj_t *vconfig, const dns_name_t *keyname, isc_mem_t *mctx) { const cfg_listelt_t *elt, *elt2; - const cfg_obj_t *key, *keylist; - dst_key_t *dstkey = NULL; + const cfg_obj_t *keylist; isc_result_t result; dns_keytable_t *secroots = NULL; @@ -851,42 +947,13 @@ load_view_keys(const cfg_obj_t *keys, const cfg_obj_t *vconfig, elt2 != NULL; elt2 = cfg_list_next(elt2)) { - key = cfg_listelt_value(elt2); - result = dstkey_fromconfig(vconfig, key, managed, - &dstkey, mctx); - if (result == DST_R_UNSUPPORTEDALG) { - result = ISC_R_SUCCESS; - continue; - } - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - /* - * If keyname was specified, we only add that key. - */ - if (keyname != NULL && - !dns_name_equal(keyname, dst_key_name(dstkey))) - { - dst_key_free(&dstkey); - continue; - } - - /* - * This key is taken from the configuration, so - * if it's a managed key then it's an - * initializing key; that's why 'managed' - * is duplicated below. - */ - CHECK(dns_keytable_add(secroots, managed, - managed, &dstkey)); + CHECK(process_key(cfg_listelt_value(elt2), vconfig, + secroots, keyname, view->resolver, + managed, mctx)); } } cleanup: - if (dstkey != NULL) { - dst_key_free(&dstkey); - } if (secroots != NULL) { dns_keytable_detach(&secroots); } @@ -10599,7 +10666,7 @@ add_zone_tolist(dns_zone_t *zone, void *uap) { struct zonelistentry *zle; zle = isc_mem_get(dctx->mctx, sizeof *zle); - if (zle == NULL) + if (zle == NULL) return (ISC_R_NOMEMORY); zle->zone = NULL; dns_zone_attach(zone, &zle->zone); diff --git a/bin/tests/system/conf.sh.common b/bin/tests/system/conf.sh.common index 3304053b9b..2a8d658678 100644 --- a/bin/tests/system/conf.sh.common +++ b/bin/tests/system/conf.sh.common @@ -127,6 +127,29 @@ digcomp() { return $result } +# +# Useful variables in test scripts +# + +# Default algorithm for testing. +DEFAULT_ALGORITHM=ECDSAP256SHA256 +DEFAULT_ALGORITHM_NUMBER=13 +DEFAULT_BITS=256 + +# This is an alternative algorithm for test cases that require more than +# one algorithm (for example algorithm rollover). Must be different from +# DEFAULT_ALGORITHM. +ALTERNATIVE_ALGORITHM=RSASHA256 +ALTERNATIVE_ALGORITHM_NUMBER=8 +ALTERNATIVE_BITS=1280 + +# This is an algorithm that is used for tests against the +# "disable-algorithms" configuration option. Must be different from above +# algorithms. +DISABLED_ALGORITHM=ECDSAP384SHA384 +DISABLED_ALGORITHM_NUMBER=14 +DISABLED_BITS=384 + # # Useful functions in test scripts # @@ -281,6 +304,45 @@ get_named_xfer_stats() { echo "bytes=`grep "${PEER}" "${LOGFILE}" | sed -n "s/.*${ZONE}.* \([0-9][0-9]*\) bytes.*/\1/p" | tail -1`" } +# copy_setports - Copy Configuration File and Replace Ports +# +# Convenience function to copy a configuration file, replacing the tokens +# QUERYPORT, CONTROLPORT and EXTRAPORT[1-8] with the values of the equivalent +# environment variables. (These values are set by "run.sh", which calls the +# scripts invoking this function.) +# +# Usage: +# copy_setports infile outfile +# +copy_setports() { + # The indirect method of handling the substitution of the PORT variables + # (defining "atsign" then substituting for it in the "sed" statement) is + # required to prevent the "Configure" script (in the win32utils/ directory) + # from replacing the PORT substitution tokens when it processes + # this file and produces conf.sh. + atsign="@" + sed -e "s/${atsign}PORT${atsign}/${PORT}/g" \ + -e "s/${atsign}EXTRAPORT1${atsign}/${EXTRAPORT1}/g" \ + -e "s/${atsign}EXTRAPORT2${atsign}/${EXTRAPORT2}/g" \ + -e "s/${atsign}EXTRAPORT3${atsign}/${EXTRAPORT3}/g" \ + -e "s/${atsign}EXTRAPORT4${atsign}/${EXTRAPORT4}/g" \ + -e "s/${atsign}EXTRAPORT5${atsign}/${EXTRAPORT5}/g" \ + -e "s/${atsign}EXTRAPORT6${atsign}/${EXTRAPORT6}/g" \ + -e "s/${atsign}EXTRAPORT7${atsign}/${EXTRAPORT7}/g" \ + -e "s/${atsign}EXTRAPORT8${atsign}/${EXTRAPORT8}/g" \ + -e "s/${atsign}CONTROLPORT${atsign}/${CONTROLPORT}/g" \ + -e "s/${atsign}DEFAULT_ALGORITHM${atsign}/${DEFAULT_ALGORITHM}/g" \ + -e "s/${atsign}DEFAULT_ALGORITHM_NUMBER${atsign}/${DEFAULT_ALGORITHM_NUMBER}/g" \ + -e "s/${atsign}DEFAULT_BITS${atsign}/${DEFAULT_BITS}/g" \ + -e "s/${atsign}ALTERNATIVE_ALGORITHM${atsign}/${ALTERNATIVE_ALGORITHM}/g" \ + -e "s/${atsign}ALTERNATIVE_ALGORITHM_NUMBER${atsign}/${ALTERNATIVE_ALGORITHM_NUMBER}/g" \ + -e "s/${atsign}ALTERNATIVE_BITS${atsign}/${ALTERNATIVE_BITS}/g" \ + -e "s/${atsign}DISABLED_ALGORITHM${atsign}/${DISABLED_ALGORITHM}/g" \ + -e "s/${atsign}DISABLED_ALGORITHM_NUMBER${atsign}/${DISABLED_ALGORITHM_NUMBER}/g" \ + -e "s/${atsign}DISABLED_BITS${atsign}/${DISABLED_BITS}/g" \ + $1 > $2 +} + # # Export command paths # diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in index d9efc639d1..db050de257 100644 --- a/bin/tests/system/conf.sh.in +++ b/bin/tests/system/conf.sh.in @@ -17,16 +17,6 @@ # Find the top of the BIND9 tree. TOP=@abs_top_builddir@ -# Default algorithm for testing -DEFAULT_ALGORITHM=ECDSAP256SHA256 -DEFAULT_ALGORITHM_NUMBER=13 -DEFAULT_BITS=256 - -# must be different from DEFAULT_ALGORITHM -ALTERNATIVE_ALGORITHM=RSASHA256 -ALTERNATIVE_ALGORITHM_NUMBER=8 -ALTERNATIVE_BITS=1280 - ARPANAME=$TOP/bin/tools/arpaname CDS=$TOP/bin/dnssec/dnssec-cds CHECKCONF=$TOP/bin/check/named-checkconf @@ -146,36 +136,5 @@ HAVEJSONSTATS=@JSONSTATS@ ZLIB=@ZLIB@ NZD=@NZD_TOOLS@ -# copy_setports - Copy Configuration File and Replace Ports -# Unfortunately it has to be different on Windows. -# -# Convenience function to copy a configuration file, replacing the tokens -# QUERYPORT, CONTROLPORT and EXTRAPORT[1-8] with the values of the equivalent -# environment variables. (These values are set by "run.sh", which calls the -# scripts invoking this function.) -# -# Usage: -# copy_setports infile outfile - -copy_setports() { - sed -e "s/@PORT@/${PORT}/g" \ - -e "s/@EXTRAPORT1@/${EXTRAPORT1}/g" \ - -e "s/@EXTRAPORT2@/${EXTRAPORT2}/g" \ - -e "s/@EXTRAPORT3@/${EXTRAPORT3}/g" \ - -e "s/@EXTRAPORT4@/${EXTRAPORT4}/g" \ - -e "s/@EXTRAPORT5@/${EXTRAPORT5}/g" \ - -e "s/@EXTRAPORT6@/${EXTRAPORT6}/g" \ - -e "s/@EXTRAPORT7@/${EXTRAPORT7}/g" \ - -e "s/@EXTRAPORT8@/${EXTRAPORT8}/g" \ - -e "s/@CONTROLPORT@/${CONTROLPORT}/g" \ - -e "s/@DEFAULT_ALGORITHM@/${DEFAULT_ALGORITHM}/g" \ - -e "s/@DEFAULT_ALGORITHM_NUMBER@/${DEFAULT_ALGORITHM_NUMBER}/g" \ - -e "s/@DEFAULT_BITS@/${DEFAULT_BITS}/g" \ - -e "s/@ALTERNATIVE_ALGORITHM@/${ALTERNATIVE_ALGORITHM}/g" \ - -e "s/@ALTERNATIVE_ALGORITHM_NUMBER@/${ALTERNATIVE_ALGORITHM_NUMBER}/g" \ - -e "s/@ALTERNATIVE_BITS@/${ALTERNATIVE_BITS}/g" \ - $1 > $2 -} - # The rest is shared between Windows and Unices . $TOP/bin/tests/system/conf.sh.common diff --git a/bin/tests/system/conf.sh.win32 b/bin/tests/system/conf.sh.win32 index 2c45b2339d..71aef926d0 100644 --- a/bin/tests/system/conf.sh.win32 +++ b/bin/tests/system/conf.sh.win32 @@ -158,42 +158,5 @@ HAVEJSONSTATS=@JSONSTATS@ ZLIB=@ZLIB@ NZD=@NZD_TOOLS@ -# copy_setports - Copy Configuration File and Replace Ports -# Unfortunately it has to be different on Windows. -# -# Convenience function to copy a configuration file, replacing the tokens -# QUERYPORT, CONTROLPORT and EXTRAPORT[1-8] with the values of the equivalent -# environment variables. (These values are set by "run.sh", which calls the -# scripts invoking this function.) -# -# Usage: -# copy_setports infile outfile - -copy_setports() { - # The indirect method of handling the substitution of the PORT variables - # (defining "atsign" then substituting for it in the "sed" statement) is - # required because to prevent the "Configure" script (in the the - # bin9/win32utils directory) replacing the the PORT substitution - # tokens when it processes this file and produces conf.sh. - atsign="@" - sed -e "s/${atsign}PORT${atsign}/${PORT}/g" \ - -e "s/${atsign}EXTRAPORT1${atsign}/${EXTRAPORT1}/g" \ - -e "s/${atsign}EXTRAPORT2${atsign}/${EXTRAPORT2}/g" \ - -e "s/${atsign}EXTRAPORT3${atsign}/${EXTRAPORT3}/g" \ - -e "s/${atsign}EXTRAPORT4${atsign}/${EXTRAPORT4}/g" \ - -e "s/${atsign}EXTRAPORT5${atsign}/${EXTRAPORT5}/g" \ - -e "s/${atsign}EXTRAPORT6${atsign}/${EXTRAPORT6}/g" \ - -e "s/${atsign}EXTRAPORT7${atsign}/${EXTRAPORT7}/g" \ - -e "s/${atsign}EXTRAPORT8${atsign}/${EXTRAPORT8}/g" \ - -e "s/${atsign}CONTROLPORT${atsign}/${CONTROLPORT}/g" \ - -e "s/${atsign}DEFAULT_ALGORITHM${atsign}/${DEFAULT_ALGORITHM}/g" \ - -e "s/${atsign}DEFAULT_ALGORITHM_NUMBER${atsign}/${DEFAULT_ALGORITHM_NUMBER}/g" \ - -e "s/${atsign}DEFAULT_BITS${atsign}/${DEFAULT_BITS}/g" \ - -e "s/${atsign}ALTERNATIVE_ALGORITHM${atsign}/${ALTERNATIVE_ALGORITHM}/g" \ - -e "s/${atsign}ALTERNATIVE_ALGORITHM_NUMBER${atsign}/${ALTERNATIVE_ALGORITHM_NUMBER}/g" \ - -e "s/${atsign}ALTERNATIVE_BITS${atsign}/${ALTERNATIVE_BITS}/g" \ - $1 > $2 -} - # The rest is shared between Windows and Unices . $TOP/bin/tests/system/conf.sh.common diff --git a/bin/tests/system/dlv/clean.sh b/bin/tests/system/dlv/clean.sh index 7cc08433d9..9f3f1cb8c1 100644 --- a/bin/tests/system/dlv/clean.sh +++ b/bin/tests/system/dlv/clean.sh @@ -16,6 +16,7 @@ rm -f ns1/dsset-* rm -f ns1/*.signed rm -f ns1/signer.err rm -f ns1/root.db +rm -f ns1/trusted.conf rm -f ns2/K* rm -f ns2/dlvset-* rm -f ns2/dsset-* @@ -25,18 +26,19 @@ rm -f ns2/signer.err rm -f ns2/druz.db rm -f ns3/K* rm -f ns3/*.db -rm -f ns3/*.signed +rm -f ns3/*.signed ns3/*.signed.tmp rm -f ns3/dlvset-* rm -f ns3/dsset-* rm -f ns3/keyset-* -rm -f ns1/trusted.conf ns5/trusted.conf -rm -f ns3/trusted-dlv.conf ns5/trusted-dlv.conf +rm -f ns3/trusted*.conf rm -f ns3/signer.err +rm -f ns5/trusted*.conf rm -f ns6/K* rm -f ns6/*.db rm -f ns6/*.signed rm -f ns6/dsset-* rm -f ns6/signer.err +rm -f ns7/trusted*.conf ns8/trusted*.conf rm -f */named.memstats rm -f dig.out.ns*.test* rm -f ns*/named.lock diff --git a/bin/tests/system/dlv/ns1/root.db.in b/bin/tests/system/dlv/ns1/root.db.in index a4d4bd9269..f4faa25d3e 100644 --- a/bin/tests/system/dlv/ns1/root.db.in +++ b/bin/tests/system/dlv/ns1/root.db.in @@ -13,7 +13,14 @@ $TTL 120 @ NS ns.rootservers.utld ns A 10.53.0.1 ; +; A zone that is unsigned (utld=unsigned tld) that will include a second level +; zone that acts as a DLV. +; utld NS ns.utld ns.utld A 10.53.0.2 +; +; A zone that has a bad DNSKEY RRset but has good DLV records for its child +; zones. +; druz NS ns.druz ns.druz A 10.53.0.2 diff --git a/bin/tests/system/dlv/ns1/sign.sh b/bin/tests/system/dlv/ns1/sign.sh index d1bf35bb77..1c56240a44 100755 --- a/bin/tests/system/dlv/ns1/sign.sh +++ b/bin/tests/system/dlv/ns1/sign.sh @@ -34,3 +34,5 @@ echo_i "signed $zone" keyfile_to_trusted_keys $keyname2 > trusted.conf cp trusted.conf ../ns5 +cp trusted.conf ../ns7 +cp trusted.conf ../ns8 diff --git a/bin/tests/system/dlv/ns2/named.conf.in b/bin/tests/system/dlv/ns2/named.conf.in index b08bd13a03..d59ba719b1 100644 --- a/bin/tests/system/dlv/ns2/named.conf.in +++ b/bin/tests/system/dlv/ns2/named.conf.in @@ -22,6 +22,17 @@ options { dnssec-enable yes; }; +/* Root hints. */ zone "." { type hint; file "hints"; }; + +/* + * A zone that is unsigned (utld=unsigned tld) that will include a second level + * zone that acts as a DLV. + */ zone "utld" { type master; file "utld.db"; }; + +/* + * A zone that has a bad DNSKEY RRset but has good DLV records for its child + * zones. + */ zone "druz" { type master; file "druz.signed"; }; diff --git a/bin/tests/system/dlv/ns2/utld.db b/bin/tests/system/dlv/ns2/utld.db index 66f559d76f..4369968b0f 100644 --- a/bin/tests/system/dlv/ns2/utld.db +++ b/bin/tests/system/dlv/ns2/utld.db @@ -18,6 +18,12 @@ ns.rootservers A 10.53.0.1 dlv NS ns.dlv ns.dlv A 10.53.0.3 ; +disabled-algorithm-dlv NS ns.disabled-algorithm-dlv +ns.disabled-algorithm-dlv A 10.53.0.3 +; +unsupported-algorithm-dlv NS ns.unsupported-algorithm-dlv +ns.unsupported-algorithm-dlv A 10.53.0.3 +; child1 NS ns.child1 ns.child1 A 10.53.0.3 ; @@ -47,3 +53,9 @@ ns.child9 A 10.53.0.3 ; child10 NS ns.child10 ns.child10 A 10.53.0.3 +; +disabled-algorithm NS ns.disabled-algorithm +ns.disabled-algorithm A 10.53.0.3 +; +unsupported-algorithm NS ns.unsupported-algorithm +ns.unsupported-algorithm A 10.53.0.3 diff --git a/bin/tests/system/dlv/ns3/named.conf.in b/bin/tests/system/dlv/ns3/named.conf.in index 42d712b229..e55652295d 100644 --- a/bin/tests/system/dlv/ns3/named.conf.in +++ b/bin/tests/system/dlv/ns3/named.conf.in @@ -22,21 +22,121 @@ options { dnssec-enable yes; }; +/* Root hints. */ zone "." { type hint; file "hints"; }; -zone "dlv.utld" { type master; file "dlv.signed"; }; -zone "child1.utld" { type master; file "child1.signed"; }; // dlv -zone "child3.utld" { type master; file "child3.signed"; }; // dlv -zone "child4.utld" { type master; file "child4.signed"; }; // dlv -zone "child5.utld" { type master; file "child5.signed"; }; // dlv -zone "child7.utld" { type master; file "child7.signed"; }; // no dlv -zone "child8.utld" { type master; file "child8.signed"; }; // no dlv -zone "child9.utld" { type master; file "child9.signed"; }; // dlv -zone "child10.utld" { type master; file "child.db.in"; }; // dlv unsigned -zone "child1.druz" { type master; file "child1.druz.signed"; }; // dlv -zone "child3.druz" { type master; file "child3.druz.signed"; }; // dlv -zone "child4.druz" { type master; file "child4.druz.signed"; }; // dlv -zone "child5.druz" { type master; file "child5.druz.signed"; }; // dlv -zone "child7.druz" { type master; file "child7.druz.signed"; }; // no dlv -zone "child8.druz" { type master; file "child8.druz.signed"; }; // no dlv -zone "child9.druz" { type master; file "child9.druz.signed"; }; // dlv -zone "child10.druz" { type master; file "child.db.in"; }; // dlv unsigned + +/* DLV zone below unsigned TLD. */ +zone "dlv.utld" { type master; file "dlv.utld.signed"; }; + +/* DLV zone signed with a disabled algorithm below unsigned TLD. */ +zone "disabled-algorithm-dlv.utld." { + type master; + file "disabled-algorithm-dlv.utld.signed"; +}; + +/* DLV zone signed with an unsupported algorithm below unsigned TLD. */ +zone "unsupported-algorithm-dlv.utld." { + type master; + file "unsupported-algorithm-dlv.utld.signed"; +}; + +/* Signed zone below unsigned TLD with DLV entry. */ +zone "child1.utld" { type master; file "child1.signed"; }; + +/* + * Signed zone below unsigned TLD with DLV entry in DLV zone that is signed + * with a disabled algorithm. + */ +zone "child3.utld" { type master; file "child3.signed"; }; + +/* + * Signed zone below unsigned TLD with DLV entry. This one is slightly + * different because its children (the grandchildren) don't have a DS record in + * this zone. The grandchild zones are served by ns6. + * + */ +zone "child4.utld" { type master; file "child4.signed"; }; + +/* + * Signed zone below unsigned TLD with DLV entry in DLV zone that is signed + * with an unsupported algorithm. + */ +zone "child5.utld" { type master; file "child5.signed"; }; + +/* Signed zone below unsigned TLD without DLV entry. */ +zone "child7.utld" { type master; file "child7.signed"; }; + +/* + * Signed zone below unsigned TLD without DLV entry and no DS records for the + * grandchildren. + */ +zone "child8.utld" { type master; file "child8.signed"; }; + +/* Signed zone below unsigned TLD with DLV entry. */ +zone "child9.utld" { type master; file "child9.signed"; }; + +/* Unsigned zone below an unsigned TLD with DLV entry. */ +zone "child10.utld" { type master; file "child.db.in"; }; + +/* + * Zone signed with a disabled algorithm (an algorithm that is disabled in + * one of the test resolvers) with DLV entry. + */ +zone "disabled-algorithm.utld" { + type master; + file "disabled-algorithm.utld.signed"; +}; + +/* Zone signed with an unsupported algorithm with DLV entry. */ +zone "unsupported-algorithm.utld" { + type master; + file "unsupported-algorithm.utld.signed"; +}; + +/* + * Signed zone below signed TLD with good DLV entry but no chain of + * trust. + */ +zone "child1.druz" { type master; file "child1.druz.signed"; }; + +/* + * Signed zone below signed TLD with good DLV entry but no chain of + * trust. The DLV zone is signed with a disabled algorithm. + */ +zone "child3.druz" { type master; file "child3.druz.signed"; }; + +/* + * Signed zone below signed TLD with good DLV entry but no chain of + * trust. Also there are no DS records for the grandchildren. + */ +zone "child4.druz" { type master; file "child4.druz.signed"; }; + +/* + * Signed zone below signed TLD with good DLV entry but no chain of + * trust. The DLV zone is signed with an unsupported algorithm. + */ +zone "child5.druz" { type master; file "child5.druz.signed"; }; + +/* + * Signed zone below signed TLD without DLV entry, and no chain of + * trust. + */ +zone "child7.druz" { type master; file "child7.druz.signed"; }; + +/* + * Signed zone below signed TLD without DLV entry and no DS set. Also DS + * records for the grandchildren are not included in the zone. + */ +zone "child8.druz" { type master; file "child8.druz.signed"; }; + +/* + * Signed zone below signed TLD with good DLV entry but no DS set. Also DS + * records for the grandchildren are not included in the zone. + */ +zone "child9.druz" { type master; file "child9.druz.signed"; }; + +/* + * Unsigned zone below signed TLD with good DLV entry but no chain of + * trust. + */ +zone "child10.druz" { type master; file "child.db.in"; }; diff --git a/bin/tests/system/dlv/ns3/sign.sh b/bin/tests/system/dlv/ns3/sign.sh index fa51ae1daf..cc9979eba2 100755 --- a/bin/tests/system/dlv/ns3/sign.sh +++ b/bin/tests/system/dlv/ns3/sign.sh @@ -16,10 +16,19 @@ SYSTEMTESTTOP=../.. echo_i "dlv/ns3/sign.sh" -dlvzone=dlv.utld. +dlvzone="dlv.utld." dlvsets= dssets= +disableddlvzone="disabled-algorithm-dlv.utld." +disableddlvsets= +disableddssets= + +unsupporteddlvzone="unsupported-algorithm-dlv.utld." +unsupporteddlvsets= +unsupporteddssets= + +# Signed zone below unsigned TLD with DLV entry. zone=child1.utld. infile=child.db.in zonefile=child1.utld.db @@ -32,15 +41,17 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> dsfilename=../ns6/dsset-grand.`echo $zone |sed -e "s/\.$//g"`$TP cat $infile $keyname1.key $keyname2.key $dsfilename >$zonefile -$SIGNER -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" +# Signed zone below unsigned TLD with DLV entry in DLV zone that is signed +# with a disabled algorithm. zone=child3.utld. infile=child.db.in zonefile=child3.utld.db outfile=child3.signed -dlvsets="$dlvsets dlvset-`echo $zone |sed -e "s/.$//g"`$TP" +disableddlvsets="$disableddlvsets dlvset-`echo $zone |sed -e "s/.$//g"`$TP" keyname1=`$KEYGEN -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` @@ -48,10 +59,13 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> dsfilename=../ns6/dsset-grand.`echo $zone |sed -e "s/\.$//g"`$TP cat $infile $keyname1.key $keyname2.key $dsfilename >$zonefile -$SIGNER -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -l $disableddlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" +# Signed zone below unsigned TLD with DLV entry. This one is slightly +# different because its children (the grandchildren) don't have a DS record in +# this zone. The grandchild zones are served by ns6. zone=child4.utld. infile=child.db.in zonefile=child4.utld.db @@ -63,15 +77,17 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> cat $infile $keyname1.key $keyname2.key >$zonefile -$SIGNER -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" +# Signed zone below unsigned TLD with DLV entry in DLV zone that is signed +# with an unsupported algorithm. zone=child5.utld. infile=child.db.in zonefile=child5.utld.db outfile=child5.signed -dlvsets="$dlvsets dlvset-`echo $zone |sed -e "s/.$//g"`$TP" +unsupporteddlvsets="$unsupporteddlvsets dlvset-`echo $zone |sed -e "s/.$//g"`$TP" keyname1=`$KEYGEN -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` @@ -79,10 +95,10 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> dsfilename=../ns6/dsset-grand.`echo $zone |sed -e "s/\.$//g"`$TP cat $infile $keyname1.key $keyname2.key $dsfilename >$zonefile -$SIGNER -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -l $unsupporteddlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" - +# Signed zone below unsigned TLD without DLV entry. zone=child7.utld. infile=child.db.in zonefile=child7.utld.db @@ -94,10 +110,12 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> dsfilename=../ns6/dsset-grand.`echo $zone |sed -e "s/\.$//g"`$TP cat $infile $keyname1.key $keyname2.key $dsfilename >$zonefile -$SIGNER -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" +# Signed zone below unsigned TLD without DLV entry and no DS records for the +# grandchildren. zone=child8.utld. infile=child.db.in zonefile=child8.utld.db @@ -108,10 +126,10 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> cat $infile $keyname1.key $keyname2.key >$zonefile -$SIGNER -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" - +# Signed zone below unsigned TLD with DLV entry. zone=child9.utld. infile=child.db.in zonefile=child9.utld.db @@ -123,9 +141,11 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> cat $infile $keyname1.key $keyname2.key >$zonefile -$SIGNER -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" +# Unsigned zone below an unsigned TLD with DLV entry. We still need to sign +# the zone to generate the DLV set. zone=child10.utld. infile=child.db.in zonefile=child10.utld.db @@ -137,9 +157,50 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> cat $infile $keyname1.key $keyname2.key >$zonefile -$SIGNER -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" + +# Zone signed with a disabled algorithm (an algorithm that is disabled in +# one of the test resolvers) with DLV entry. +zone=disabled-algorithm.utld. +infile=child.db.in +zonefile=disabled-algorithm.utld.db +outfile=disabled-algorithm.utld.signed +dlvsets="$dlvsets dlvset-`echo $zone |sed -e "s/.$//g"`$TP" + +keyname1=`$KEYGEN -a $DISABLED_ALGORITHM -b $DISABLED_BITS -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -a $DISABLED_ALGORITHM -b $DISABLED_BITS -n zone $zone 2> /dev/null` + +cat $infile $keyname1.key $keyname2.key >$zonefile + +$SIGNER -O full -l $dlvzone -o $zone -f ${outfile} $zonefile > /dev/null 2> signer.err || cat signer.err +echo_i "signed $zone" + + +# Zone signed with an unsupported algorithm with DLV entry. +zone=unsupported-algorithm.utld. +infile=child.db.in +zonefile=unsupported-algorithm.utld.db +outfile=unsupported-algorithm.utld.signed +dlvsets="$dlvsets dlvset-`echo $zone |sed -e "s/.$//g"`$TP" + +keyname1=`$KEYGEN -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` +keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` + +cat $infile $keyname1.key $keyname2.key >$zonefile + +$SIGNER -O full -l $dlvzone -o $zone -f ${outfile}.tmp $zonefile > /dev/null 2> signer.err || cat signer.err +awk '$4 == "DNSKEY" { $7 = 255 } $4 == "RRSIG" { $6 = 255 } { print }' ${outfile}.tmp > $outfile + +cp ${keyname2}.key ${keyname2}.tmp +awk '$3 == "DNSKEY" { $6 = 255 } { print }' ${keyname2}.tmp > ${keyname2}.key +cp dlvset-${zone} dlvset-${zone}tmp +awk '$3 == "DLV" { $5 = 255 } { print }' dlvset-${zone}tmp > dlvset-${zone} + +echo_i "signed $zone" + +# Signed zone below signed TLD with DLV entry and DS set. zone=child1.druz. infile=child.db.in zonefile=child1.druz.db @@ -153,16 +214,18 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> dsfilename=../ns6/dsset-grand.`echo $zone |sed -e "s/\.$//g"`$TP cat $infile $keyname1.key $keyname2.key $dsfilename >$zonefile -$SIGNER -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" +# Signed zone below signed TLD with DLV entry and DS set. The DLV zone is +# signed with a disabled algorithm. zone=child3.druz. infile=child.db.in zonefile=child3.druz.db outfile=child3.druz.signed -dlvsets="$dlvsets dlvset-`echo $zone |sed -e "s/.$//g"`$TP" -dssets="$dssets dsset-`echo $zone |sed -e "s/.$//g"`$TP" +disableddlvsets="$disableddlvsets dlvset-`echo $zone |sed -e "s/.$//g"`$TP" +disableddssets="$disableddssets dsset-`echo $zone |sed -e "s/.$//g"`$TP" keyname1=`$KEYGEN -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` @@ -170,10 +233,12 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> dsfilename=../ns6/dsset-grand.`echo $zone |sed -e "s/\.$//g"`$TP cat $infile $keyname1.key $keyname2.key $dsfilename >$zonefile -$SIGNER -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -l $disableddlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" +# Signed zone below signed TLD with DLV entry and DS set, but missing +# DS records for the grandchildren. zone=child4.druz. infile=child.db.in zonefile=child4.druz.db @@ -186,16 +251,18 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> cat $infile $keyname1.key $keyname2.key >$zonefile -$SIGNER -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" +# Signed zone below signed TLD with DLV entry and DS set. The DLV zone is +# signed with an unsupported algorithm algorithm. zone=child5.druz. infile=child.db.in zonefile=child5.druz.db outfile=child5.druz.signed -dlvsets="$dlvsets dlvset-`echo $zone |sed -e "s/.$//g"`$TP" -dssets="$dssets dsset-`echo $zone |sed -e "s/.$//g"`$TP" +unsupporteddlvsets="$unsupporteddlvsets dlvset-`echo $zone |sed -e "s/.$//g"`$TP" +unsupporteddssets="$unsupportedssets dsset-`echo $zone |sed -e "s/.$//g"`$TP" keyname1=`$KEYGEN -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` @@ -203,10 +270,11 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> dsfilename=../ns6/dsset-grand.`echo $zone |sed -e "s/\.$//g"`$TP cat $infile $keyname1.key $keyname2.key $dsfilename >$zonefile -$SIGNER -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -l $unsupporteddlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" +# Signed zone below signed TLD without DLV entry, but with normal DS set. zone=child7.druz. infile=child.db.in zonefile=child7.druz.db @@ -219,10 +287,12 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> dsfilename=../ns6/dsset-grand.`echo $zone |sed -e "s/\.$//g"`$TP cat $infile $keyname1.key $keyname2.key $dsfilename >$zonefile -$SIGNER -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" +# Signed zone below signed TLD without DLV entry and no DS set. Also DS +# records for the grandchildren are not included in the zone. zone=child8.druz. infile=child.db.in zonefile=child8.druz.db @@ -233,10 +303,12 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> cat $infile $keyname1.key $keyname2.key >$zonefile -$SIGNER -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" +# Signed zone below signed TLD with DLV entry but no DS set. Also DS +# records for the grandchildren are not included in the zone. zone=child9.druz. infile=child.db.in zonefile=child9.druz.db @@ -248,9 +320,12 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> cat $infile $keyname1.key $keyname2.key >$zonefile -$SIGNER -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" + +# Unsigned zone below signed TLD with DLV entry and DS set. We still need to +# sign the zone to generate the DS sets. zone=child10.druz. infile=child.db.in zonefile=child10.druz.db @@ -263,24 +338,60 @@ keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> cat $infile $keyname1.key $keyname2.key >$zonefile -$SIGNER -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err +$SIGNER -O full -l $dlvzone -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err echo_i "signed $zone" - -zone=dlv.utld. -infile=dlv.db.in -zonefile=dlv.utld.db -outfile=dlv.signed - -keyname1=`$KEYGEN -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` - -cat $infile $dlvsets $keyname1.key $keyname2.key >$zonefile - -$SIGNER -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err -echo_i "signed $zone" - -keyfile_to_trusted_keys $keyname2 > trusted-dlv.conf -cp trusted-dlv.conf ../ns5 - cp $dssets ../ns2 +cp $disableddssets ../ns2 +cp $unsupporteddssets ../ns2 + +# DLV zones +infile=dlv.db.in +for zone in dlv.utld. disabled-algorithm-dlv.utld. unsupported-algorithm-dlv.utld. +do + zonefile="${zone}db" + outfile="${zone}signed" + + case $zone in + "dlv.utld.") + algorithm=$DEFAULT_ALGORITHM + bits=$DEFAULT_BITS + dlvfiles=$dlvsets + ;; + "disabled-algorithm-dlv.utld.") + algorithm=$DISABLED_ALGORITHM + bits=$DISABLED_BITS + dlvfiles=$disableddlvsets + ;; + "unsupported-algorithm-dlv.utld.") + algorithm=$DEFAULT_ALGORITHM + bits=$DEFAULT_BITS + dlvfiles=$unsupporteddlvsets + ;; + esac + + keyname1=`$KEYGEN -a $algorithm -b $bits -n zone $zone 2> /dev/null` + keyname2=`$KEYGEN -f KSK -a $algorithm -b $bits -n zone $zone 2> /dev/null` + + cat $infile $dlvfiles $keyname1.key $keyname2.key >$zonefile + + case $zone in + "dlv.utld.") + $SIGNER -O full -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err + keyfile_to_trusted_keys $keyname2 > ../ns5/trusted-dlv.conf + ;; + "disabled-algorithm-dlv.utld.") + $SIGNER -O full -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err + keyfile_to_trusted_keys $keyname2 > ../ns8/trusted-dlv-disabled.conf + ;; + "unsupported-algorithm-dlv.utld.") + cp ${keyname2}.key ${keyname2}.tmp + $SIGNER -O full -o $zone -f ${outfile}.tmp $zonefile > /dev/null 2> signer.err || cat signer.err + awk '$4 == "DNSKEY" { $7 = 255 } $4 == "RRSIG" { $6 = 255 } { print }' ${outfile}.tmp > $outfile + awk '$3 == "DNSKEY" { $6 = 255 } { print }' ${keyname2}.tmp > ${keyname2}.key + keyfile_to_trusted_keys $keyname2 > ../ns7/trusted-dlv-unsupported.conf + ;; + esac + + echo_i "signed $zone" +done diff --git a/bin/tests/system/dlv/ns5/named.conf.in b/bin/tests/system/dlv/ns5/named.conf.in index 11c6041fb9..2fbf620b5c 100644 --- a/bin/tests/system/dlv/ns5/named.conf.in +++ b/bin/tests/system/dlv/ns5/named.conf.in @@ -25,6 +25,7 @@ options { dnssec-enable yes; dnssec-validation yes; dnssec-lookaside "." trust-anchor "dlv.utld"; + disable-algorithms "utld." { @DISABLED_ALGORITHM@; }; }; zone "." { type hint; file "hints"; }; diff --git a/bin/tests/system/dlv/ns7/hints b/bin/tests/system/dlv/ns7/hints new file mode 100644 index 0000000000..cdf0f26f78 --- /dev/null +++ b/bin/tests/system/dlv/ns7/hints @@ -0,0 +1,12 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, You can obtain one at http://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +. 0 NS ns.rootservers.utld. +ns.rootservers.utld. 0 A 10.53.0.1 + diff --git a/bin/tests/system/dlv/ns7/named.conf.in b/bin/tests/system/dlv/ns7/named.conf.in new file mode 100644 index 0000000000..fd9c7c8aaa --- /dev/null +++ b/bin/tests/system/dlv/ns7/named.conf.in @@ -0,0 +1,31 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +include "trusted.conf"; +include "trusted-dlv-unsupported.conf"; + +options { + query-source address 10.53.0.7; + notify-source 10.53.0.7; + transfer-source 10.53.0.7; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.7; }; + listen-on-v6 { none; }; + recursion yes; + notify yes; + dnssec-enable yes; + dnssec-validation yes; + dnssec-lookaside "." trust-anchor "unsupported-algorithm-dlv.utld"; +}; + +zone "." { type hint; file "hints"; }; + diff --git a/bin/tests/system/dlv/ns8/hints b/bin/tests/system/dlv/ns8/hints new file mode 100644 index 0000000000..cdf0f26f78 --- /dev/null +++ b/bin/tests/system/dlv/ns8/hints @@ -0,0 +1,12 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, You can obtain one at http://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +. 0 NS ns.rootservers.utld. +ns.rootservers.utld. 0 A 10.53.0.1 + diff --git a/bin/tests/system/dlv/ns8/named.conf.in b/bin/tests/system/dlv/ns8/named.conf.in new file mode 100644 index 0000000000..6e58019fe1 --- /dev/null +++ b/bin/tests/system/dlv/ns8/named.conf.in @@ -0,0 +1,32 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +include "trusted.conf"; +include "trusted-dlv-disabled.conf"; + +options { + query-source address 10.53.0.8; + notify-source 10.53.0.8; + transfer-source 10.53.0.8; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.8; }; + listen-on-v6 { none; }; + recursion yes; + notify yes; + dnssec-enable yes; + dnssec-validation yes; + dnssec-lookaside "." trust-anchor "disabled-algorithm-dlv.utld"; + disable-algorithms "disabled-algorithm-dlv.utld." { @DISABLED_ALGORITHM@; }; +}; + +zone "." { type hint; file "hints"; }; + diff --git a/bin/tests/system/dlv/setup.sh b/bin/tests/system/dlv/setup.sh index e4737d47d5..e1bd565745 100644 --- a/bin/tests/system/dlv/setup.sh +++ b/bin/tests/system/dlv/setup.sh @@ -20,5 +20,7 @@ copy_setports ns3/named.conf.in ns3/named.conf copy_setports ns4/named.conf.in ns4/named.conf copy_setports ns5/named.conf.in ns5/named.conf copy_setports ns6/named.conf.in ns6/named.conf +copy_setports ns7/named.conf.in ns7/named.conf +copy_setports ns8/named.conf.in ns8/named.conf (cd ns1 && $SHELL -e sign.sh) diff --git a/bin/tests/system/dlv/tests.sh b/bin/tests/system/dlv/tests.sh index fdf31d954e..a3046303a7 100644 --- a/bin/tests/system/dlv/tests.sh +++ b/bin/tests/system/dlv/tests.sh @@ -19,37 +19,93 @@ rm -f dig.out.* DIGOPTS="+tcp +noadd +nosea +nostat +nocmd +dnssec -p ${PORT}" -echo_i "checking that DNSKEY reference by DLV validates as secure ($n)" +echo_i "checking that unsigned TLD zone DNSKEY referenced by DLV validates as secure ($n)" ret=0 $DIG $DIGOPTS child1.utld dnskey @10.53.0.5 > dig.out.ns5.test$n || ret=1 +grep "status: NOERROR" dig.out.ns5.test$n > /dev/null || ret=1 grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null || ret=1 n=`expr $n + 1` if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` -echo_i "checking that child DNSKEY reference by DLV validates as secure ($n)" +echo_i "checking that unsigned TLD child zone DNSKEY referenced by DLV validates as secure ($n)" ret=0 $DIG $DIGOPTS grand.child1.utld dnskey @10.53.0.5 > dig.out.ns5.test$n || ret=1 +grep "status: NOERROR" dig.out.ns5.test$n > /dev/null || ret=1 grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null || ret=1 n=`expr $n + 1` if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` -echo_i "checking that SOA reference by DLV in a DRUZ with DS validates as secure ($n)" +echo_i "checking that no chain of trust SOA referenced by DLV validates as secure ($n)" ret=0 $DIG $DIGOPTS child1.druz soa @10.53.0.5 > dig.out.ns5.test$n || ret=1 +grep "status: NOERROR" dig.out.ns5.test$n > /dev/null || ret=1 grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null || ret=1 n=`expr $n + 1` if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` -echo_i "checking that child SOA reference by DLV in a DRUZ with DS validates as secure ($n)" +echo_i "checking that no chain of trust child SOA referenced by DLV validates as secure ($n)" ret=0 $DIG $DIGOPTS grand.child1.druz soa @10.53.0.5 > dig.out.ns5.test$n || ret=1 +grep "status: NOERROR" dig.out.ns5.test$n > /dev/null || ret=1 grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null || ret=1 n=`expr $n + 1` if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` +# Test that a child zone that is signed with an unsupported algorithm, +# referenced by a good DLV zone, yields an insecure response. +echo_i "checking that unsupported algorithm TXT referenced by DLV validates as insecure ($n)" +ret=0 +$DIG $DIGOPTS foo.unsupported-algorithm.utld txt @10.53.0.3 > dig.out.ns3.test$n || ret=1 +$DIG $DIGOPTS foo.unsupported-algorithm.utld txt @10.53.0.5 > dig.out.ns5.test$n || ret=1 +grep "status: NOERROR" dig.out.ns5.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null && ret=1 +grep -q "foo\.unsupported-algorithm\.utld\..*TXT.*\"foo\"" dig.out.ns5.test$n || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +# Test that a child zone that is signed with a disabled algorithm, +# referenced by a good DLV zone, yields an insecure response. +echo_i "checking that disabled algorithm TXT referenced by DLV validates as insecure ($n)" +ret=0 +$DIG $DIGOPTS foo.disabled-algorithm.utld txt @10.53.0.3 > dig.out.ns3.test$n || ret=1 +$DIG $DIGOPTS foo.disabled-algorithm.utld txt @10.53.0.5 > dig.out.ns5.test$n || ret=1 +grep "status: NOERROR" dig.out.ns5.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null && ret=1 +grep -q "foo\.disabled-algorithm\.utld\..*TXT.*\"foo\"" dig.out.ns5.test$n || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +# Test that a child zone that is signed with a known algorithm, referenced by +# a DLV zone that is signed with a disabled algorithm, yields a bogus +# response. +echo_i "checking that good signed TXT referenced by disabled algorithm DLV validates as bogus ($n)" +ret=0 +$DIG $DIGOPTS foo.child3.utld txt @10.53.0.8 > dig.out.ns8.test$n || ret=1 +grep "status: SERVFAIL" dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 +grep -q "foo\.child3\.utld\..*TXT.*\"foo\"" dig.out.ns8.test$n && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +# Test that a child zone that is signed with a known algorithm, referenced by +# a DLV zone that is signed with an unsupported algorithm, yields a bogus +# response. +echo_i "checking that good signed TXT referenced by unsupported algorithm DLV validates as bogus ($n)" +ret=0 +$DIG $DIGOPTS foo.child5.utld txt @10.53.0.7 > dig.out.ns7.test$n || ret=1 +grep "status: SERVFAIL" dig.out.ns7.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns7.test$n > /dev/null && ret=1 +grep -q "foo\.child5\.utld\..*TXT.*\"foo\"" dig.out.ns7.test$n && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/bin/tests/system/dnssec/README b/bin/tests/system/dnssec/README index c45bd71f23..df83eb14e2 100644 --- a/bin/tests/system/dnssec/README +++ b/bin/tests/system/dnssec/README @@ -17,3 +17,6 @@ key for the root. It is used for testing failure cases. ns6 is a caching-only server configured to use DLV. ns7 is used for checking non-cacheable answers. + +ns8 is a caching-only server, configured with unsupported and disabled +algorithms. It is used for testing failure cases. diff --git a/bin/tests/system/dnssec/clean.sh b/bin/tests/system/dnssec/clean.sh index 9ca3f2c003..c49ee9a1ac 100644 --- a/bin/tests/system/dnssec/clean.sh +++ b/bin/tests/system/dnssec/clean.sh @@ -26,13 +26,14 @@ rm -f ./delve.out* rm -f ./dig.out.* rm -f ./dsfromkey.out.* rm -f ./keygen.err +rm -f ./dnssectools.out* rm -f ./named.secroots.test* rm -f ./nosign.before rm -f ./ns*/*.nta rm -f ./ns*/managed-keys.bind* ./ns*/*.mkeys* rm -f ./ns*/named.lock rm -f ./ns1/managed.key.id -rm -f ./ns1/root.db ./ns2/example.db ./ns3/secure.example.db +rm -f ./ns1/root.db ./ns2/example.db ./ns2/managed.db ./ns2/trusted.db rm -f ./ns2/algroll.db rm -f ./ns2/badparam.db ./ns2/badparam.db.bad rm -f ./ns2/cdnskey-kskonly.secure.db diff --git a/bin/tests/system/dnssec/ns1/root.db.in b/bin/tests/system/dnssec/ns1/root.db.in index 5ad5d9ef1d..7fdbab9c4e 100644 --- a/bin/tests/system/dnssec/ns1/root.db.in +++ b/bin/tests/system/dnssec/ns1/root.db.in @@ -8,12 +8,12 @@ ; information regarding copyright ownership. $TTL 300 -. IN SOA gson.nominum.com. a.root.servers.nil. ( - 2000042100 ; serial - 600 ; refresh - 600 ; retry - 1200 ; expire - 600 ; minimum +. IN SOA gson.nominum.com. a.root.servers.nil. ( + 2000042100 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum ) . NS a.root-servers.nil. a.root-servers.nil. A 10.53.0.1 @@ -22,8 +22,12 @@ example. NS ns2.example. ns2.example. A 10.53.0.2 dlv. NS ns2.dlv. ns2.dlv. A 10.53.0.2 -algroll NS ns2.algroll +algroll. NS ns2.algroll. ns2.algroll. A 10.53.0.2 +managed. NS ns2.managed. +ns2.managed. A 10.53.0.2 +trusted. NS ns2.trusted. +ns2.trusted. A 10.53.0.2 optout-tld NS ns6.optout-tld. ns6.optout-tld. A 10.53.0.6 in-addr.arpa. NS ns2.example. diff --git a/bin/tests/system/dnssec/ns1/sign.sh b/bin/tests/system/dnssec/ns1/sign.sh index 313b03c1de..4df96bf1e0 100644 --- a/bin/tests/system/dnssec/ns1/sign.sh +++ b/bin/tests/system/dnssec/ns1/sign.sh @@ -22,6 +22,8 @@ zonefile=root.db (cd ../ns6 && $SHELL sign.sh ) (cd ../ns7 && $SHELL sign.sh ) +echo_i "ns1/sign.sh" + cp "../ns2/dsset-example$TP" . cp "../ns2/dsset-dlv$TP" . cp "../ns2/dsset-in-addr.arpa$TP" . diff --git a/bin/tests/system/dnssec/ns2/key.db.in b/bin/tests/system/dnssec/ns2/key.db.in new file mode 100644 index 0000000000..4a91fff2a3 --- /dev/null +++ b/bin/tests/system/dnssec/ns2/key.db.in @@ -0,0 +1,43 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, You can obtain one at http://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$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 ns2 +ns2 A 10.53.0.2 + +a A 10.0.0.1 +b A 10.0.0.2 +d A 10.0.0.4 + +; A secure subdomain +secure NS ns3.secure +ns3.secure A 10.53.0.3 + +; A subdomain that is signed with an unsupported algorithm +unsupported NS ns3.unsupported +ns3.unsupported A 10.53.0.3 + +; A secure subdomain with a disabled algorithm +disabled NS ns3.disabled +ns3.disabled A 10.53.0.3 + +; A secure subdomain with a disabled algorithm, but not in bailiwick +enabled NS ns3.enabled +ns3.enabled A 10.53.0.3 + +; A secure subdomain with a revoked trust anchor +revoked NS ns3.revoked +ns3.revoked A 10.53.0.3 diff --git a/bin/tests/system/dnssec/ns2/named.conf.in b/bin/tests/system/dnssec/ns2/named.conf.in index f6ac4bfc34..15d2b0a8b7 100644 --- a/bin/tests/system/dnssec/ns2/named.conf.in +++ b/bin/tests/system/dnssec/ns2/named.conf.in @@ -46,6 +46,16 @@ zone "dlv" { file "dlv.db.signed"; }; +zone "trusted" { + type master; + file "trusted.db.signed"; +}; + +zone "managed" { + type master; + file "managed.db.signed"; +}; + zone "example" { type master; file "example.db.signed"; diff --git a/bin/tests/system/dnssec/ns2/sign.sh b/bin/tests/system/dnssec/ns2/sign.sh index 65ff46b536..eb2721598f 100644 --- a/bin/tests/system/dnssec/ns2/sign.sh +++ b/bin/tests/system/dnssec/ns2/sign.sh @@ -14,24 +14,59 @@ set -e +# Sign child zones (served by ns3). +( cd ../ns3 && $SHELL sign.sh ) + +echo_i "ns2/sign.sh" + +# Get the DS records for the "trusted." and "managed." zones. +for subdomain in secure unsupported disabled enabled +do + cp "../ns3/dsset-$subdomain.managed$TP" . + cp "../ns3/dsset-$subdomain.trusted$TP" . +done + +# Sign the "trusted." and "managed." zones. +zone=managed. +infile=key.db.in +zonefile=managed.db + +keyname1=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone -f KSK "$zone") +keyname2=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone "$zone") + +cat "$infile" "$keyname1.key" "$keyname2.key" > "$zonefile" + +"$SIGNER" -P -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 + +zone=trusted. +infile=key.db.in +zonefile=trusted.db + +keyname1=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone -f KSK "$zone") +keyname2=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone "$zone") + +cat "$infile" "$keyname1.key" "$keyname2.key" > "$zonefile" + +"$SIGNER" -P -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 + +# The "example." zone. zone=example. infile=example.db.in zonefile=example.db -# Have the child generate a zone key and pass it to us. - -( cd ../ns3 && $SHELL sign.sh ) - +# Get the DS records for the "example." zone. for subdomain in secure badds bogus dynamic keyless nsec3 optout \ nsec3-unknown optout-unknown multiple rsasha256 rsasha512 \ kskonly update-nsec3 auto-nsec auto-nsec3 secure.below-cname \ ttlpatch split-dnssec split-smart expired expiring upper lower \ - dnskey-unknown dnskey-nsec3-unknown managed-future revkey \ + dnskey-unknown dnskey-unsupported dnskey-unsupported-2 \ + dnskey-nsec3-unknown managed-future revkey \ dname-at-apex-nsec3 occluded do cp "../ns3/dsset-$subdomain.example$TP" . done +# Sign the "example." zone. keyname1=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone -f KSK "$zone") keyname2=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone "$zone") diff --git a/bin/tests/system/dnssec/ns3/key.db.in b/bin/tests/system/dnssec/ns3/key.db.in new file mode 100644 index 0000000000..3847e2ea10 --- /dev/null +++ b/bin/tests/system/dnssec/ns3/key.db.in @@ -0,0 +1,24 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, You can obtain one at http://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$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 ns3 +ns3 A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff --git a/bin/tests/system/dnssec/ns3/named.conf.in b/bin/tests/system/dnssec/ns3/named.conf.in index fc43832b4e..aa9783a5ae 100644 --- a/bin/tests/system/dnssec/ns3/named.conf.in +++ b/bin/tests/system/dnssec/ns3/named.conf.in @@ -314,6 +314,56 @@ zone "occluded.example" { file "occluded.example.db.signed"; }; +zone "secure.managed" { + type master; + file "secure.managed.db.signed"; +}; + +zone "disabled.managed" { + type master; + file "disabled.managed.db.signed"; +}; + +zone "enabled.managed" { + type master; + file "enabled.managed.db.signed"; +}; + +zone "unsupported.managed" { + type master; + file "unsupported.managed.db.signed"; +}; + +zone "revoked.managed" { + type master; + file "revoked.managed.db.signed"; +}; + +zone "secure.trusted" { + type master; + file "secure.trusted.db.signed"; +}; + +zone "disabled.trusted" { + type master; + file "disabled.trusted.db.signed"; +}; + +zone "enabled.trusted" { + type master; + file "enabled.trusted.db.signed"; +}; + +zone "unsupported.trusted" { + type master; + file "unsupported.trusted.db.signed"; +}; + +zone "revoked.trusted" { + type master; + file "revoked.trusted.db.signed"; +}; + include "siginterval.conf"; include "trusted.conf"; diff --git a/bin/tests/system/dnssec/ns3/sign.sh b/bin/tests/system/dnssec/ns3/sign.sh index 055cd9444d..a9a063e0ef 100644 --- a/bin/tests/system/dnssec/ns3/sign.sh +++ b/bin/tests/system/dnssec/ns3/sign.sh @@ -14,6 +14,68 @@ set -e +echo_i "ns3/sign.sh" + +infile=key.db.in +for tld in managed trusted +do + # A secure zone to test. + zone=secure.${tld} + zonefile=${zone}.db + + keyname1=$("$KEYGEN" -f KSK -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") + cat "$infile" "$keyname1.key" > "$zonefile" + "$SIGNER" -z -P -3 - -o "$zone" -O full -f ${zonefile}.signed "$zonefile" > /dev/null 2>&1 + + # Zone to test trust anchor that matches disabled algorithm. + zone=disabled.${tld} + zonefile=${zone}.db + + keyname2=$("$KEYGEN" -f KSK -q -a "$DISABLED_ALGORITHM" -b "$DISABLED_BITS" -n zone "$zone") + cat "$infile" "$keyname2.key" > "$zonefile" + "$SIGNER" -z -P -3 - -o "$zone" -O full -f ${zonefile}.signed "$zonefile" > /dev/null 2>&1 + + # Zone to test trust anchor that has disabled algorithm for other domain. + zone=enabled.${tld} + zonefile=${zone}.db + + keyname3=$("$KEYGEN" -f KSK -q -a "$DISABLED_ALGORITHM" -b "$DISABLED_BITS" -n zone "$zone") + cat "$infile" "$keyname3.key" > "$zonefile" + "$SIGNER" -z -P -3 - -o "$zone" -O full -f ${zonefile}.signed "$zonefile" > /dev/null 2>&1 + + # Zone to test trust anchor with unsupported algorithm. + zone=unsupported.${tld} + zonefile=${zone}.db + + keyname4=$("$KEYGEN" -f KSK -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") + cat "$infile" "$keyname4.key" > "$zonefile" + "$SIGNER" -z -P -3 - -o "$zone" -O full -f ${zonefile}.tmp "$zonefile" > /dev/null 2>&1 + awk '$4 == "DNSKEY" { $7 = 255 } $4 == "RRSIG" { $6 = 255 } { print }' ${zonefile}.tmp > ${zonefile}.signed + + # Make trusted-keys and managed keys conf sections for ns8. + mv ${keyname4}.key ${keyname4}.tmp + awk '$1 == "unsupported.'"${tld}"'." { $6 = 255 } { print }' ${keyname4}.tmp > ${keyname4}.key + + # Zone to test trust anchor that is revoked. + zone=revoked.${tld} + zonefile=${zone}.db + + keyname5=$("$KEYGEN" -f KSK -f REVOKE -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") + cat "$infile" "$keyname5.key" > "$zonefile" + "$SIGNER" -z -P -3 - -o "$zone" -O full -f ${zonefile}.signed "$zonefile" > /dev/null 2>&1 + + case $tld in + "managed") + keyfile_to_managed_keys $keyname1 $keyname2 $keyname3 $keyname4 $keyname5 > ../ns8/managed.conf + ;; + "trusted") + keyfile_to_trusted_keys $keyname1 $keyname2 $keyname3 $keyname4 $keyname5 > ../ns8/trusted.conf + ;; + esac +done + +echo_i "ns3/sign.sh: example zones" + zone=secure.example. infile=secure.example.db.in zonefile=secure.example.db @@ -209,7 +271,7 @@ cat "$infile" "$keyname.key" > "$zonefile" "$SIGNER" -P -3 - -o "$zone" -O full -f ${zonefile}.tmp "$zonefile" > /dev/null 2>&1 -awk '$4 == "DNSKEY" { $7 = 100; print } $4 == "RRSIG" { $6 = 100; print } { print }' ${zonefile}.tmp > ${zonefile}.signed +awk '$4 == "DNSKEY" { $7 = 100 } $4 == "RRSIG" { $6 = 100 } { print }' ${zonefile}.tmp > ${zonefile}.signed DSFILE="dsset-$(echo ${zone} |sed -e "s/\\.$//g")$TP" $DSFROMKEY -A -f ${zonefile}.signed "$zone" > "$DSFILE" @@ -228,7 +290,7 @@ cat "$infile" "$keyname.key" > "$zonefile" "$SIGNER" -P -3 - -o "$zone" -O full -f ${zonefile}.tmp "$zonefile" > /dev/null 2>&1 -awk '$4 == "DNSKEY" { $7 = 255; print } $4 == "RRSIG" { $6 = 255; print } { print }' ${zonefile}.tmp > ${zonefile}.signed +awk '$4 == "DNSKEY" { $7 = 255 } $4 == "RRSIG" { $6 = 255 } { print }' ${zonefile}.tmp > ${zonefile}.signed DSFILE="dsset-$(echo ${zone} |sed -e "s/\\.$//g")$TP" $DSFROMKEY -A -f ${zonefile}.signed "$zone" > "$DSFILE" @@ -246,7 +308,6 @@ zsk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") cat "$infile" "$ksk.key" "$zsk.key" unsupported-algorithm.key > "$zonefile" -# "$SIGNER" -P -3 - -o "$zone" -f ${zonefile}.signed "$zonefile" > /dev/null 2>&1 "$SIGNER" -P -3 - -o "$zone" -f ${zonefile}.signed "$zonefile" > /dev/null 2>&1 # diff --git a/bin/tests/system/dnssec/ns5/sign.sh b/bin/tests/system/dnssec/ns5/sign.sh index 9f9c39fb73..83f08769c0 100644 --- a/bin/tests/system/dnssec/ns5/sign.sh +++ b/bin/tests/system/dnssec/ns5/sign.sh @@ -14,6 +14,8 @@ set -e +echo_i "ns5/sign.sh" + zone=. infile=../ns1/root.db.in zonefile=root.db.signed diff --git a/bin/tests/system/dnssec/ns6/sign.sh b/bin/tests/system/dnssec/ns6/sign.sh index 54a21548bc..80d8881c15 100644 --- a/bin/tests/system/dnssec/ns6/sign.sh +++ b/bin/tests/system/dnssec/ns6/sign.sh @@ -14,6 +14,8 @@ set -e +echo_i "ns6/sign.sh" + zone=optout-tld infile=optout-tld.db.in zonefile=optout-tld.db diff --git a/bin/tests/system/dnssec/ns7/sign.sh b/bin/tests/system/dnssec/ns7/sign.sh index a5d8dc0bd2..625300339c 100644 --- a/bin/tests/system/dnssec/ns7/sign.sh +++ b/bin/tests/system/dnssec/ns7/sign.sh @@ -14,6 +14,8 @@ set -e +echo_i "ns7/sign.sh" + zone=split-rrsig infile=split-rrsig.db.in zonefile=split-rrsig.db diff --git a/bin/tests/system/dnssec/ns8/named.conf.in b/bin/tests/system/dnssec/ns8/named.conf.in new file mode 100644 index 0000000000..de95e26301 --- /dev/null +++ b/bin/tests/system/dnssec/ns8/named.conf.in @@ -0,0 +1,46 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +// NS8 + +options { + query-source address 10.53.0.8; + notify-source 10.53.0.8; + transfer-source 10.53.0.8; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.8; }; + listen-on-v6 { none; }; + recursion yes; + dnssec-enable yes; + dnssec-validation yes; + minimal-responses no; + disable-algorithms "disabled.managed." { @DISABLED_ALGORITHM@; }; + disable-algorithms "disabled.trusted." { @DISABLED_ALGORITHM@; }; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.8 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../common/root.hint"; +}; + +include "managed.conf"; +include "trusted.conf"; + diff --git a/bin/tests/system/dnssec/setup.sh b/bin/tests/system/dnssec/setup.sh index 62cf46cff0..2238153204 100644 --- a/bin/tests/system/dnssec/setup.sh +++ b/bin/tests/system/dnssec/setup.sh @@ -25,6 +25,7 @@ copy_setports ns5/named1.conf.in ns5/named.conf copy_setports ns6/named.conf.in ns6/named.conf copy_setports ns7/named.conf.in ns7/named.conf +copy_setports ns8/named.conf.in ns8/named.conf ( cd ns1 diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index 4f49d79602..0e4128de12 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -1432,6 +1432,47 @@ get_rsasha1_key_ids_from_sigs() { ' signer/example.db.signed | sort -u } +echo_i "checking that a key using an unsupported algorithm cannot be generated ($n)" +ret=0 +zone=example +# If dnssec-keygen fails, the test script will exit immediately. Prevent that +# from happening, and also trigger a test failure if dnssec-keygen unexpectedly +# succeeds, by using "&& ret=1". +$KEYGEN -a 255 $zone > dnssectools.out.test$n 2>&1 && ret=1 +grep -q "unsupported algorithm: 255" dnssectools.out.test$n || ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +echo_i "checking that a DS record cannot be generated for a key using an unsupported algorithm ($n)" +ret=0 +zone=example +# Fake an unsupported algorithm key +unsupportedkey=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") +awk '$3 == "DNSKEY" { $6 = 255 } { print }' ${unsupportedkey}.key > ${unsupportedkey}.tmp +mv ${unsupportedkey}.tmp ${unsupportedkey}.key +# If dnssec-dsfromkey fails, the test script will exit immediately. Prevent +# that from happening, and also trigger a test failure if dnssec-dsfromkey +# unexpectedly succeeds, by using "&& ret=1". +$DSFROMKEY ${unsupportedkey} > dnssectools.out.test$n 2>&1 && ret=1 +grep -q "algorithm is unsupported" dnssectools.out.test$n || ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +echo_i "checking that a zone cannot be signed with a key using an unsupported algorithm ($n)" +ret=0 +ret=0 +cat signer/example.db.in "${unsupportedkey}.key" > signer/example.db +# If dnssec-signzone fails, the test script will exit immediately. Prevent that +# from happening, and also trigger a test failure if dnssec-signzone +# unexpectedly succeeds, by using "&& ret=1". +$SIGNER -o example signer/example.db ${unsupportedkey} > dnssectools.out.test$n 2>&1 && ret=1 +grep -q "algorithm is unsupported" dnssectools.out.test$n || ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + echo_i "checking that we can sign a zone with out-of-zone records ($n)" ret=0 zone=example @@ -3681,17 +3722,156 @@ n=$((n+1)) test "$ret" -eq 0 || echo_i "failed" status=$((status+ret)) -# Note: after this check, ns4 will not be validating any more; do not add any -# further validation tests employing ns4 below this check. -echo_i "check that validation defaults to off when dnssec-enable is off ($n)" +# +# DNSSEC tests related to unsupported, disabled and revoked trust anchors. +# + +# This nameserver (ns8) is loaded with a bunch of trust anchors. Some of them +# are good (enabled.managed, enabled.trusted, secure.managed, secure.trusted), +# and some of them are bad (disabled.managed, revoked.managed, unsupported.managed, +# disabled.trusted, revoked.trusted, unsupported.trusted). Make sure that the bad +# trust anchors are ignored. This is tested by looking for the corresponding +# lines in the logfile. +echo_i "checking that keys with unsupported algorithms and disabled algorithms are ignored ($n)" ret=0 -# Sanity check - validation should be enabled. -rndccmd 10.53.0.4 validation status | grep "enabled" > /dev/null || ret=1 -# Set "dnssec-enable" to "no" and reconfigure. -copy_setports ns4/named5.conf.in ns4/named.conf -rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i -# Check validation status again. -rndccmd 10.53.0.4 validation status | grep "disabled" > /dev/null || ret=1 +grep -q "ignoring trusted key for 'disabled\.trusted\.': algorithm is disabled" ns8/named.run || ret=1 +grep -q "ignoring trusted key for 'unsupported\.trusted\.': algorithm is unsupported" ns8/named.run || ret=1 +grep -q "ignoring trusted key for 'revoked\.trusted\.': bad key type" ns8/named.run || ret=1 +grep -q "ignoring managed key for 'disabled\.managed\.': algorithm is disabled" ns8/named.run || ret=1 +grep -q "ignoring managed key for 'unsupported\.managed\.': algorithm is unsupported" ns8/named.run || ret=1 +grep -q "ignoring trusted key for 'revoked\.trusted\.': bad key type" ns8/named.run || ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +# The next two tests are fairly normal DNSSEC queries to signed zones with a +# default algorithm. First, a query is made against the server that is +# authoritative for the given zone (ns3). Second, a query is made against a +# resolver with trust anchors for the given zone (ns8). Both are expected to +# return an authentic data positive response. +echo_i "checking that a trusted key using a supported algorithm validates as secure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.secure.trusted A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.secure.trusted A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +echo_i "checking that a managed key using a supported algorithm validates as secure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.secure.managed A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.secure.managed A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +# The next two queries ensure that a zone signed with a DNSKEY with an unsupported +# algorithm will yield insecure positive responses. These trust anchors in ns8 are +# ignored and so this domain is treated as insecure. The AD bit should not be set +# in the response. +echo_i "checking that a trusted key using an unsupported algorithm validates as insecure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.unsupported.trusted A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.unsupported.trusted A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +echo_i "checking that a managed key using an unsupported algorithm validates as insecure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.unsupported.managed A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.unsupported.managed A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +# The next two queries ensure that a zone signed with a DNSKEY that the nameserver +# has a disabled algorithm match for will yield insecure positive responses. +# These trust anchors in ns8 are ignored and so this domain is treated as insecure. +# The AD bit should not be set in the response. +echo_i "checking that a trusted key using a disabled algorithm validates as insecure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.disabled.trusted A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.disabled.trusted A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +echo_i "checking that a managed key using a disabled algorithm validates as insecure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.disabled.managed A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.disabled.managed A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +# The next two queries ensure that a zone signed with a DNSKEY that the +# nameserver has a disabled algorithm for, but for a different domain, will +# yield secure positive responses. Since "enabled.trusted." and +# "enabled.managed." do not match the "disable-algorithms" option, no +# special rules apply and these zones should validate as secure, with the AD +# bit set. +echo_i "checking that a trusted key using an algorithm disabled for another domain validates as secure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.enabled.trusted A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.enabled.trusted A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +echo_i "checking that a managed key using an algorithm disabled for another domain validates as secure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.enabled.managed A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.enabled.managed A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +# A configured revoked trust anchor is ignored and thus the two queries below +# should result in insecure responses, since no trust points for the +# "revoked.trusted." and "revoked.managed." zones are created. +echo_i "checking that a trusted key that is revoked validates as insecure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.revoked.trusted A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.revoked.trusted A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +echo_i "checking that a managed key that is revoked validates as insecure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.revoked.managed A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.revoked.managed A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 n=$((n+1)) test "$ret" -eq 0 || echo_i "failed" status=$((status+ret)) diff --git a/bin/tests/system/inline/ns3/named.conf.in b/bin/tests/system/inline/ns3/named.conf.in index 1dff0b5679..a8c434dc02 100644 --- a/bin/tests/system/inline/ns3/named.conf.in +++ b/bin/tests/system/inline/ns3/named.conf.in @@ -168,3 +168,10 @@ zone "removedkeys-secondary" { auto-dnssec maintain; file "removedkeys-secondary.bk"; }; + +zone "unsupported" { + type master; + file "unsupported.db"; + inline-signing yes; + auto-dnssec maintain; +}; diff --git a/bin/tests/system/inline/ns3/sign.sh b/bin/tests/system/inline/ns3/sign.sh index 15b5424215..621f077683 100755 --- a/bin/tests/system/inline/ns3/sign.sh +++ b/bin/tests/system/inline/ns3/sign.sh @@ -12,6 +12,11 @@ SYSTEMTESTTOP=../.. . $SYSTEMTESTTOP/conf.sh +# Fake an unsupported key +unsupportedkey=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone unsupported) +awk '$3 == "DNSKEY" { $6 = 255 } { print }' ${unsupportedkey}.key > ${unsupportedkey}.tmp +mv ${unsupportedkey}.tmp ${unsupportedkey}.key + zone=bits rm -f K${zone}.+*+*.key rm -f K${zone}.+*+*.private diff --git a/bin/tests/system/inline/setup.sh b/bin/tests/system/inline/setup.sh index 23a9c18dc8..4c207ee22c 100644 --- a/bin/tests/system/inline/setup.sh +++ b/bin/tests/system/inline/setup.sh @@ -27,6 +27,7 @@ cp ns2/bits.db.in ns2/retransfer3.db cp ns3/master.db.in ns3/master.db cp ns3/master.db.in ns3/dynamic.db cp ns3/master.db.in ns3/updated.db +cp ns3/master.db.in ns3/unsupported.db cp ns3/master.db.in ns3/expired.db cp ns3/master.db.in ns3/nsec3.db cp ns3/master.db.in ns3/externalkey.db diff --git a/bin/tests/system/inline/tests.sh b/bin/tests/system/inline/tests.sh index 12c0926b24..60e578371e 100755 --- a/bin/tests/system/inline/tests.sh +++ b/bin/tests/system/inline/tests.sh @@ -27,6 +27,13 @@ do sleep 1 done +n=`expr $n + 1` +echo_i "checking that an unsupported algorithm is not used for signing ($n)" +ret=0 +grep -q "algorithm is unsupported" ns3/named.run || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + n=`expr $n + 1` echo_i "checking that rrsigs are replaced with ksk only ($n)" ret=0 diff --git a/bin/tests/system/mkeys/tests.sh b/bin/tests/system/mkeys/tests.sh index da6d2643eb..cfee9c89ff 100644 --- a/bin/tests/system/mkeys/tests.sh +++ b/bin/tests/system/mkeys/tests.sh @@ -763,12 +763,12 @@ rm -f ns6/managed-keys.bind* nextpart ns6/named.run > /dev/null $PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} mkeys ns6 # log when an unsupported algorithm is encountered during startup -wait_for_log "skipping managed key for 'unsupported\.': algorithm is unsupported" ns6/named.run +wait_for_log "ignoring managed key for 'unsupported\.': algorithm is unsupported" ns6/named.run if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo_i "skipping unsupported algorithm in managed-keys ($n)" +echo_i "ignoring unsupported algorithm in managed-keys ($n)" ret=0 mkeys_status_on 6 > rndc.out.$n 2>&1 # there should still be only two keys listed (for . and rsasha256.) @@ -793,7 +793,7 @@ if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo_i "skipping unsupported algorithm in rollover ($n)" +echo_i "ignoring unsupported algorithm in rollover ($n)" ret=0 mkeys_reload_on 1 mkeys_refresh_on 6 diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 42fe63e1d6..dc9a477c09 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -5051,6 +5051,12 @@ options { by the disable-algorithms will be treated as insecure. + + Configured trust anchors in trusted-keys + or managed-keys that match a disabled + algorithm will be ignored and treated as if they were not + configured at all. + diff --git a/doc/design/unsupported-algorithms-in-bind9 b/doc/design/unsupported-algorithms-in-bind9 new file mode 100644 index 0000000000..25fef1a49a --- /dev/null +++ b/doc/design/unsupported-algorithms-in-bind9 @@ -0,0 +1,139 @@ +Copyright (C) Internet Systems Consortium, Inc. ("ISC") + +See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. + +# Unsupported algorithms in BIND 9 + +Following RFC 6944 and jumping ahead to draft-ietf-dnsop-algorithm-update-04, +BIND 9 takes preparations to remove support for deprecated DNSSEC algorithms. +These include RSAMD5, DSA, and ECC-GOST. + +How does this impact BIND 9 behavior? In order to determine this, we first +need to establish in what contexts can DNSSEC algorithms be used. Two logical +categories of such contexts can be identified: signing and validation. + +## DNSSEC signing + +### DNSSEC tools + +BIND 9 DNSSEC tools do not allow generating new keys using unsupported +algorithms: + + $ dnssec-keygen -a RSAMD5 example. + dnssec-keygen: fatal: unsupported algorithm: 1 + +The tools also refuse to work with previously generated keys using unsupported +algorithms: + + $ dnssec-dsfromkey Kexample.+001+53634 + dnssec-dsfromkey: fatal: can't load Kexample.+001+53634.key: algorithm is unsupported + + $ dnssec-signzone example.db Kexample.+001+53634 + dnssec-signzone: fatal: cannot load dnskey Kexample.+001+53634: algorithm is unsupported + +A DNSKEY RR with an unsupported algorithm may be *included* in a zone, as long +as it is not used for *signing* that zone. + +BIND 9 also does not allow unsupported algorithms to be used with `auto-dnssec`: + + zone "example" IN { + type master; + file "db/example.db"; + key-directory "keys/example"; + inline-signing yes; + auto-dnssec maintain; + } + ... + dns_dnssec_findmatchingkeys: error reading key file Kexample.+001+53634.private: algorithm is unsupported + +(DISCUSS: We might want to fail hard for such configurations.) + +## DNSSEC validation + +A validator has more possible interactions with unsupported algorithms: + + * a key using one of these algorithms may be configured as a trust anchor, + * a DLV record for such a key may be placed in a DLV zone. + * upstream answers may contain signatures using such algorithms, + +### Disabled algorithms + +The `disable-algorithms` clause in `named.conf` can be used to prevent the +specified algorithms from being used when validating responses at and below a +certain name. For example, the following configuration: + + disable-algorithms "example." { RSASHA512; }; + +will mark RSASHA512 as disabled at and below `example.`. This effectively +means that for this domain and all domains below it, the RSASHA512 algorithm is +treated as unsupported. + +### Trust anchors + +In BIND 9, trust anchors can be configured using two clauses: + + * `trusted-keys`, which contains hardcoded (static) trust anchors, + * `managed-keys`, which will be kept up to date automatically, following the + zone's key rollovers (according to the algorithm specified in RFC 5011). + +When put into the above clauses, keys using unsupported algorithms will be +ignored: + + trusted.conf:3: skipping trusted key for 't.example.': algorithm is unsupported + managed.conf:3: skipping managed key for 'm.example.': algorithm is unsupported + +BIND 9 also ignores any configured trust anchor whose owner name and algorithm +match any `disable-algorithms` clause present in `named.conf`. + +If a given trust point is left with no trust anchors using supported +algorithms, BIND 9 will act as if the trust point was not configured at all and +if there are no trust points configured higher up the tree, names at the trust +point and below it will be treated as insecure. + +Note that prior to BIND 9.13.6, configured trust anchors that matched disabled +algorithms were not ignored and that lead to SERVFAILs for associated domains. +This behavior has changed to be more consistent with unsupported algorithms: +BIND 9 will ignore such trust anchors, and responses for those domains will +now be treated as insecure. + +### DLV + +If a DLV record in a DLV zone points to a DNSKEY using an unsupported algorithm +or an algorithm which has been disabled for the relevant part of the tree using +a `disable-algorithms` clause in `named.conf`, the corresponding zone will be +treated as insecure. + +However, if the trust anchor specified for the DLV zone itself uses an +unsupported or disabled algorithm, no DLV record in that DLV zone can be +treated as secure and thus attempts to resolve names in the domains pointed to +by the records in that DLV zone will yield SERVFAIL responses. Consider the +following example: + + trusted-keys { + "dlv.example." 257 3 1 ...; + }; + + options { + ... + dnssec-lookaside "foo." trust-anchor "dlv.example"; + }; + +The example above specifies a DLV trust anchor using the RSAMD5 algorithm +(algorithm number 1), which effectively prevents resolution of data in any zone +at and below `foo.` that is listed in `dlv.example` (and does not have a valid, +non-DLV chain of trust established otherwise). This outcome is different than +for a trust anchor which uses an unsupported or disabled algorithm and is not +associated with a `dnssec-lookaside` clause; the reason for this is that in the +case of a DLV-referenced, unusable key, the trust point is still defined, but +has no keys associated with it, whereas non-DLV-referenced, unusable keys are +ignored altogether and do not cause an associated trust point to be defined. + +### Algorithm rollover + +A zone for which BIND 9 has a trust anchor configured may decide to do an +algorithm rollover to an unsupported algorithm. If configured with +`managed-keys`, BIND 9 will ignore the newly introduced DNSKEY if it does +not support the algorithm. That means that the moment the predecessor DNSKEY +gets revoked, BIND 9 will no longer have any trust anchors for the given zone +and it will treat the trust point as if it does not exist, meaning that +the corresponding zone will now validate as insecure. diff --git a/util/copyrights b/util/copyrights index 65174fb236..1c32e0d0eb 100644 --- a/util/copyrights +++ b/util/copyrights @@ -1531,6 +1531,7 @@ ./doc/design/resolver TXT.BRIEF 1999,2000,2001,2004,2016,2018,2019 ./doc/design/search TXT.BRIEF 1999,2000,2001,2004,2016,2018,2019 ./doc/design/tasks TXT.BRIEF 1999,2000,2001,2004,2016,2018,2019 +./doc/design/unsupported-algorithms-in-bind9 TXT.BRIEF 2019 ./doc/design/verify TXT.BRIEF 2012,2016,2018,2019 ./doc/design/windows-nt TXT.BRIEF 1999,2000,2001,2004,2016,2018,2019 ./doc/design/zone TXT.BRIEF 1999,2000,2001,2004,2016,2018,2019