]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
sync with trunk
authorYuri Schaeffer <yuri@nlnetlabs.nl>
Fri, 18 Jan 2013 11:39:03 +0000 (11:39 +0000)
committerYuri Schaeffer <yuri@nlnetlabs.nl>
Fri, 18 Jan 2013 11:39:03 +0000 (11:39 +0000)
git-svn-id: file:///svn/unbound/branches/edns-subnet@2812 be551aaa-1e26-0410-a405-d3ace91eadb9

27 files changed:
Makefile.in
configure
configure.ac
doc/Changelog
doc/FEATURES
doc/unbound-anchor.8.in
iterator/iter_fwd.c
iterator/iter_hints.c
pythonmod/doc/examples/example0-1.py
services/outside_network.c
smallapp/unbound-anchor.c
testcode/ldns-testpkts.c
testcode/ldns-testpkts.h
testcode/replay.c
testcode/unitverify.c
testdata/09-unbound-control.tpkg
testdata/10-unbound-anchor.tpkg
testdata/val_cnametocnamewctoposwc.rpl [new file with mode: 0644]
testdata/val_ds_cnamesub.rpl [new file with mode: 0644]
testdata/val_nsec3_cnametocnamewctoposwc.rpl [new file with mode: 0644]
testdata/val_nsec3_entnodata_optout.rpl [new file with mode: 0644]
testdata/val_nsec3_entnodata_optout_badopt.rpl [new file with mode: 0644]
testdata/val_nsec3_entnodata_optout_match.rpl [new file with mode: 0644]
util/config_file.c
util/iana_ports.inc
util/net_help.c
validator/validator.c

index acb0eaffce927827d250bc007a62b5899300a9b5..a9f8384d5a835068107fa4635bb151225fd2bd3f 100644 (file)
@@ -363,7 +363,7 @@ pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
        $(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h \
        $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
 
-pythonmod/interface.h: $(srcdir)/pythonmod/interface.i $(srcdir)/config.h
+pythonmod/interface.h: $(srcdir)/pythonmod/interface.i config.h
        @-if test ! -d pythonmod; then $(INSTALL) -d pythonmod; fi
        $(SWIG) $(CPPFLAGS) -o $@ -python $(srcdir)/pythonmod/interface.i
 
@@ -394,12 +394,14 @@ clean:
        rm -f *.o *.d *.lo *~ tags
        rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la
        rm -f $(ALL_SRC:.c=.lint)
+       rm -f _unbound.la libunbound/python/libunbound_wrap.c libunbound/python/unbound.py pythonmod/interface.h pythonmod/unboundmodule.py
        rm -rf autom4te.cache .libs build doc/html doc/xml
 
 realclean: clean
        rm -f config.status config.log config.h.in config.h
        rm -f configure config.sub config.guess ltmain.sh aclocal.m4 libtool
        rm -f util/configlexer.c util/configparser.c util/configparser.h
+       rm -f doc/example.conf doc/libunbound.3 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound-control.8 doc/unbound.8 doc/unbound.conf.5
        rm -f $(TEST_BIN)
        rm -f Makefile 
 
@@ -444,7 +446,7 @@ pythonmod-install:
 
 pyunbound-install:
        $(INSTALL) -m 755 -d $(DESTDIR)$(PYTHON_SITE_PKG)
-       $(INSTALL) -c -m 644 libunbound/python/unbound.py $(DESTDIR)$(PYTHON_SITE_PKG)/unbound.py
+       $(INSTALL) -c -m 644 $(srcdir)/libunbound/python/unbound.py $(DESTDIR)$(PYTHON_SITE_PKG)/unbound.py
        $(LIBTOOL) --mode=install cp _unbound.la $(DESTDIR)$(PYTHON_SITE_PKG)
        $(LIBTOOL) --mode=finish $(DESTDIR)$(PYTHON_SITE_PKG)
 
index 29a05111a562cdd04e72e3c24320aff3a3a3d65a..4bddb6831bc065d7670290263e9bc37603d659ee 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for unbound 1.4.19.
+# Generated by GNU Autoconf 2.68 for unbound 1.4.20.
 #
 # Report bugs to <unbound-bugs@nlnetlabs.nl>.
 #
@@ -570,8 +570,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='unbound'
 PACKAGE_TARNAME='unbound'
-PACKAGE_VERSION='1.4.19'
-PACKAGE_STRING='unbound 1.4.19'
+PACKAGE_VERSION='1.4.20'
+PACKAGE_STRING='unbound 1.4.20'
 PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
 PACKAGE_URL=''
 
@@ -1357,7 +1357,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures unbound 1.4.19 to adapt to many kinds of systems.
+\`configure' configures unbound 1.4.20 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1423,7 +1423,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of unbound 1.4.19:";;
+     short | recursive ) echo "Configuration of unbound 1.4.20:";;
    esac
   cat <<\_ACEOF
 
@@ -1591,7 +1591,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-unbound configure 1.4.19
+unbound configure 1.4.20
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2117,7 +2117,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by unbound $as_me 1.4.19, which was
+It was created by unbound $as_me 1.4.20, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -2467,7 +2467,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 LIBUNBOUND_CURRENT=3
-LIBUNBOUND_REVISION=4
+LIBUNBOUND_REVISION=5
 LIBUNBOUND_AGE=1
 # 1.0.0 had 0:12:0
 # 1.0.1 had 0:13:0
@@ -2503,6 +2503,7 @@ LIBUNBOUND_AGE=1
 # 1.4.17 had 3:2:1
 # 1.4.18 had 3:3:1
 # 1.4.19 had 3:4:1
+# 1.4.20 had 3:5:1
 
 #   Current  -- the number of the binary API that we're implementing
 #   Revision -- which iteration of the implementation of the binary
@@ -18626,7 +18627,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by unbound $as_me 1.4.19, which was
+This file was extended by unbound $as_me 1.4.20, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -18692,7 +18693,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-unbound config.status 1.4.19
+unbound config.status 1.4.20
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
index 1acb7bfd7f66a7251db93cf70bf4f4881e0b24a6..feef9e426648afb7617ef262fec7c186549b1838 100644 (file)
@@ -6,10 +6,10 @@ sinclude(acx_pthread.m4)
 sinclude(acx_python.m4)
 sinclude(ac_pkg_swig.m4)
 
-AC_INIT(unbound, 1.4.19, unbound-bugs@nlnetlabs.nl, unbound)
+AC_INIT(unbound, 1.4.20, unbound-bugs@nlnetlabs.nl, unbound)
 
 LIBUNBOUND_CURRENT=3
-LIBUNBOUND_REVISION=4
+LIBUNBOUND_REVISION=5
 LIBUNBOUND_AGE=1
 # 1.0.0 had 0:12:0
 # 1.0.1 had 0:13:0
@@ -45,6 +45,7 @@ LIBUNBOUND_AGE=1
 # 1.4.17 had 3:2:1
 # 1.4.18 had 3:3:1
 # 1.4.19 had 3:4:1
+# 1.4.20 had 3:5:1
 
 #   Current  -- the number of the binary API that we're implementing
 #   Revision -- which iteration of the implementation of the binary
index ac60fc4561cd3b5b54fd9484f644ca1a037dc47a..46a97ae96d872e261a1a3019c16a4e151a88ce66 100644 (file)
@@ -1,3 +1,77 @@
+17 January 2013: Wouter
+       - unbound-anchors checks the emailAddress of the signer of the
+         root.xml file, default is dnssec@iana.org.  It also checks that
+         the signer has the correct key usage for a digital signature.
+       - update iana port list.
+
+3 January 2013: Wouter
+       - Test that unbound-control checks client credentials.
+       - Test that unbound can handle a CNAME at an intermediate node in
+         the chain of trust (where it seeks a DS record).
+       - Check the commonName of the signer of the root.xml file in
+         unbound-anchor, default is dnssec@iana.org.
+
+2 January 2013: Wouter
+       - Fix openssl lock free on exit (reported by Robert Fleischman).
+       - iana portlist updated.
+       - Tested that unbound implements the RFC5155 Technical Errata id 3441.
+         Unbound already implements insecure classification of an empty
+         nonterminal in NSEC3 optout zone.
+
+20 December 2012: Wouter
+       - Fix unbound-anchor xml parse of entity declarations for safety.
+
+19 December 2012: Wouter
+       - iana portlist updated.
+
+18 December 2012: Wouter
+       - iana portlist updated.
+
+14 December 2012: Wouter
+       - Change of D.ROOT-SERVERS.NET A address in default root hints.
+
+12 December 2012: Wouter
+       - 1.4.19 release.
+       - trunk has 1.4.20 under development.
+
+5 December 2012: Wouter
+       - note support for AAAA RR type RFC.
+
+4 December 2012: Wouter
+       - 1.4.19rc1 tag.
+
+30 November 2012: Wouter
+       - bug 481: fix python example0.
+       - iana portlist updated.
+
+27 November 2012: Wouter
+       - iana portlist updated.
+
+9 November 2012: Wouter
+       - Fix unbound-control forward disables configured stubs below it.
+
+7 November 2012: Wouter
+       - Fixup ldns-testpkts, identical to ldns/examples.
+       - iana portlist updated.
+
+30 October 2012: Wouter
+       - Fix bug #477: unbound-anchor segfaults if EDNS is blocked.
+
+29 October 2012: Matthijs
+       - Fix validation for responses with both CNAME and wildcard
+         expanded CNAME records in answer section.
+
+8 October 2012: Wouter
+       - update ldns-testpkts.c to ldns 1.6.14 version.
+       - fix build of pythonmod in objdir, for unbound.py.
+       - make clean and makerealclean remove generated python and docs.
+
+5 October 2012: Wouter
+       - fix build of pythonmod in objdir (thanks Jakob Schlyter).
+
+3 October 2012: Wouter
+       - fix text in unbound-anchor man page.
+
 1 October 2012: Wouter
        - ignore trusted-keys globs that have no files (from Paul Wouters).
 
index b695eeb9d483909ea6f0dfcbac30bb646c5361c8..93ed2925718cbc6479a39459912d37e3e5064aa0 100644 (file)
@@ -24,6 +24,7 @@ RFC 1034-1035: as a recursive, caching server. Not authoritative.
   including CNAMEs, referrals, wildcards, classes, ...
   AAAA type, and IP6 dual stack support.
   type ANY queries are supported, class ANY queries are supported.
+RFC 1123, 6.1 Requirements for DNS of internet hosts.
 RFC 4033-4035: as a validating caching server (unbound daemon). 
   as a validating stub (libunbound).
 RFC 1918.
@@ -91,6 +92,7 @@ AAAA type
 2672: DNAME type.
 OPT type
 3123: APL
+3596: AAAA
 SSHFP type
 4025: IPSECKEY
 4033-4035: DS, RRSIG, NSEC, DNSKEY
index 8713658f19ab1cb34a91caa8e710bb6e359244c4..64a4ef3ba154b20ddfeeb753fdc2a602914e402c 100644 (file)
@@ -45,7 +45,7 @@ all checks are successful, it updates the root anchor file.  Otherwise
 the root anchor file is unchanged.  It performs RFC5011 tracking if the
 DNSSEC information available via the DNS makes that possible.
 .P
-If does not perform an update if the certificate is expired, if the network
+It does not perform an update if the certificate is expired, if the network
 is down or other errors occur.
 .P
 The available options are:
@@ -77,6 +77,11 @@ The pathname to the root\-anchors.p7s file on the server. (forms URL with \-u).
 The default is /root\-anchors/root\-anchors.p7s.  This file has to be a PKCS7
 signature over the xml file, using the pem file (\-c) as trust anchor.
 .TP
+.B \-n \fIname
+The emailAddress for the Subject of the signer's certificate from the p7s
+signature file.  Only signatures from this name are allowed.  default is
+dnssec@iana.org.  If you pass "" then the emailAddress is not checked.
+.TP
 .B \-4
 Use IPv4 for domain resolution and contacting the server on https.  Default is
 to use IPv4 and IPv6 where appropriate.
@@ -126,9 +131,6 @@ but then ignores the result and goes on to use the xml fallback method.
 .TP
 .B \-h
 Show the version and commandline option help.
-.TP
-.B \-v
-More verbose.  Prints output detailing what happens.
 .SH "EXIT CODE"
 This tool exits with value 1 if the root anchor was updated using the
 certificate or if the builtin root-anchor was used.  It exits with code
index 17ca566746de2afa7f3804cb2593a3f69c601f18..3f91b527f5240cef12eac3a11a4cab00f343f8ad 100644 (file)
@@ -270,25 +270,6 @@ read_forwards(struct iter_forwards* fwd, struct config_file* cfg)
        return 1;
 }
 
-/** see if zone needs to have a hole inserted */
-static int
-need_hole_insert(rbtree_t* tree, struct iter_forward_zone* zone)
-{
-       struct iter_forward_zone k;
-       if(rbtree_search(tree, zone))
-               return 0; /* exact match exists */
-       k = *zone;
-       k.node.key = &k;
-       /* search up the tree */
-       do {
-               dname_remove_label(&k.name, &k.namelen);
-               k.namelabs --;
-               if(rbtree_search(tree, &k))
-                       return 1; /* found an upper forward zone, need hole */
-       } while(k.namelabs > 1);
-       return 0; /* no forwards above, no holes needed */
-}
-
 /** insert a stub hole (if necessary) for stub name */
 static int
 fwd_add_stub_hole(struct iter_forwards* fwd, uint16_t c, uint8_t* nm)
@@ -298,11 +279,8 @@ fwd_add_stub_hole(struct iter_forwards* fwd, uint16_t c, uint8_t* nm)
        key.dclass = c;
        key.name = nm;
        key.namelabs = dname_count_size_labels(key.name, &key.namelen);
-       if(need_hole_insert(fwd->tree, &key)) {
-               return forwards_insert_data(fwd, key.dclass, key.name,
-                       key.namelen, key.namelabs, NULL);
-       }
-       return 1;
+       return forwards_insert_data(fwd, key.dclass, key.name,
+               key.namelen, key.namelabs, NULL);
 }
 
 /** make NULL entries for stubs */
index 09e4731135dd4b80bdb9f5ec974f8b3c671f2a99..53ac8ff0f0c5c7a1f735ccda62a0782536ac2401 100644 (file)
@@ -119,7 +119,7 @@ compile_time_root_prime(int do_ip4, int do_ip6)
         ;           on server           FTP.INTERNIC.NET
         ;       -OR-                    RS.INTERNIC.NET
         ;
-        ;       related version of root zone:   2010061700
+        ;       related version of root zone:   changes-on-20120103
         */
        struct delegpt* dp = delegpt_create_mlc((uint8_t*)"\000");
        if(!dp)
@@ -129,7 +129,7 @@ compile_time_root_prime(int do_ip4, int do_ip6)
        if(!ah(dp, "A.ROOT-SERVERS.NET.", "198.41.0.4"))        goto failed;
        if(!ah(dp, "B.ROOT-SERVERS.NET.", "192.228.79.201")) goto failed;
        if(!ah(dp, "C.ROOT-SERVERS.NET.", "192.33.4.12"))       goto failed;
-       if(!ah(dp, "D.ROOT-SERVERS.NET.", "128.8.10.90"))       goto failed;
+       if(!ah(dp, "D.ROOT-SERVERS.NET.", "199.7.91.13"))       goto failed;
        if(!ah(dp, "E.ROOT-SERVERS.NET.", "192.203.230.10")) goto failed;
        if(!ah(dp, "F.ROOT-SERVERS.NET.", "192.5.5.241"))       goto failed;
        if(!ah(dp, "G.ROOT-SERVERS.NET.", "192.112.36.4"))      goto failed;
index 98a9acccdeafd63d2491036c72aec88919ff09a3..3b234f1e099c513c5e83fb496627157dfa10ddbc 100644 (file)
@@ -1,7 +1,4 @@
 
-print mod_env.fname   # Print module script name
-mod_env.data = "test" # Store global module data
-
 def init(id, cfg):
    log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
    return True
index a8c11a19fe4142e7dd6e066f02ecf51ddce41f78..e8ad53f925d510856cd835d9ac601474801698bf 100644 (file)
@@ -1835,7 +1835,7 @@ outnet_serviced_query(struct outside_network* outnet,
        struct service_callback* cb;
        serviced_gen_query(buff, qname, qnamelen, qtype, qclass, flags);
        sq = lookup_serviced(outnet, buff, dnssec, addr, addrlen);
-       /* duplicate entries are inclded in the callback list, because
+       /* duplicate entries are included in the callback list, because
         * there is a counterpart registration by our caller that needs to
         * be doubly-removed (with callbacks perhaps). */
        if(!(cb = (struct service_callback*)malloc(sizeof(*cb))))
index e14ca733fd7c7cf0fb919277158368952f26330b..37521729baceaf713628ee8d68b2337abdfbfbef 100644 (file)
 #include <openssl/rand.h>
 #endif
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
 #include <openssl/pem.h>
 
 /** name of server in URL to fetch HTTPS from */
 #define XMLNAME "root-anchors/root-anchors.xml"
 /** path on HTTPS server to p7s file */
 #define P7SNAME "root-anchors/root-anchors.p7s"
+/** name of the signer of the certificate */
+#define P7SIGNER "dnssec@iana.org"
 /** port number for https access */
 #define HTTPS_PORT 443
 
@@ -184,6 +187,7 @@ usage()
        printf("-u name         server in https url, default %s\n", URLNAME);
        printf("-x path         pathname to xml in url, default %s\n", XMLNAME);
        printf("-s path         pathname to p7s in url, default %s\n", P7SNAME);
+       printf("-n name         signer's subject emailAddress, default %s\n", P7SIGNER);
        printf("-4              work using IPv4 only\n");
        printf("-6              work using IPv6 only\n");
        printf("-f resolv.conf  use given resolv.conf to resolve -u name\n");
@@ -540,6 +544,11 @@ resolve_host_ip(struct ub_ctx* ctx, char* host, int port, int tp, int cl,
                ub_ctx_delete(ctx);
                exit(0);
        }
+       if(!res->havedata || res->rcode || !res->data) {
+               if(verb) printf("resolve %s %s: no result\n", host,
+                       (tp==LDNS_RR_TYPE_A)?"A":"AAAA");
+               return;
+       }
        for(i = 0; res->data[i]; i++) {
                struct ip_list* ip = RR_to_ip(tp, res->data[i], res->len[i],
                        port);
@@ -1498,6 +1507,20 @@ xml_endelem(void *userData, const XML_Char *name)
        }
 }
 
+/* Stop the parser when an entity declaration is encountered. For safety. */
+static void
+xml_entitydeclhandler(void *userData,
+       const XML_Char *ATTR_UNUSED(entityName),
+       int ATTR_UNUSED(is_parameter_entity),
+       const XML_Char *ATTR_UNUSED(value), int ATTR_UNUSED(value_length),
+       const XML_Char *ATTR_UNUSED(base),
+       const XML_Char *ATTR_UNUSED(systemId),
+       const XML_Char *ATTR_UNUSED(publicId),
+       const XML_Char *ATTR_UNUSED(notationName))
+{
+       XML_StopParser((XML_Parser)userData, XML_FALSE);
+}
+
 /**
  * XML parser setup of the callbacks for the tags
  */
@@ -1526,6 +1549,7 @@ xml_parse_setup(XML_Parser parser, struct xml_data* data, time_t now)
                if(verb) printf("out of memory\n");
                exit(0);
        }
+       XML_SetEntityDeclHandler(parser, xml_entitydeclhandler);
        XML_SetElementHandler(parser, xml_startelem, xml_endelem);
        XML_SetCharacterDataHandler(parser, xml_charhandle);
 }
@@ -1603,12 +1627,113 @@ xml_parse(BIO* xml, time_t now)
        }
 }
 
+/* get key usage out of its extension, returns 0 if no key_usage extension */
+static unsigned long
+get_usage_of_ex(X509* cert)
+{
+       unsigned long val = 0;
+       ASN1_BIT_STRING* s;
+       if((s=X509_get_ext_d2i(cert, NID_key_usage, NULL, NULL))) {
+               if(s->length > 0) {
+                       val = s->data[0];
+                       if(s->length > 1)
+                               val |= s->data[1] << 8;
+               }
+               ASN1_BIT_STRING_free(s);
+       }
+       return val;
+}
+
+/** get valid signers from the list of signers in the signature */
+static STACK_OF(X509)*
+get_valid_signers(PKCS7* p7, char* p7signer)
+{
+       int i;
+       STACK_OF(X509)* validsigners = sk_X509_new_null();
+       STACK_OF(X509)* signers = PKCS7_get0_signers(p7, NULL, 0);
+       unsigned long usage = 0;
+       if(!validsigners) {
+               if(verb) printf("out of memory\n");
+               sk_X509_free(signers);
+               return NULL;
+       }
+       if(!signers) {
+               if(verb) printf("no signers in pkcs7 signature\n");
+               sk_X509_free(validsigners);
+               return NULL;
+       }
+       for(i=0; i<sk_X509_num(signers); i++) {
+               X509_NAME* nm = X509_get_subject_name(
+                       sk_X509_value(signers, i));
+               char buf[1024];
+               if(!nm) {
+                       if(verb) printf("signer %d: cert has no subject name\n", i);
+                       continue;
+               }
+               if(verb && nm) {
+                       char* nmline = X509_NAME_oneline(nm, buf,
+                               (int)sizeof(buf));
+                       printf("signer %d: Subject: %s\n", i,
+                               nmline?nmline:"no subject");
+                       if(verb >= 3 && X509_NAME_get_text_by_NID(nm,
+                               NID_commonName, buf, (int)sizeof(buf)))
+                               printf("commonName: %s\n", buf);
+                       if(verb >= 3 && X509_NAME_get_text_by_NID(nm,
+                               NID_pkcs9_emailAddress, buf, (int)sizeof(buf)))
+                               printf("emailAddress: %s\n", buf);
+               }
+               if(verb) {
+                       int ku_loc = X509_get_ext_by_NID(
+                               sk_X509_value(signers, i), NID_key_usage, -1);
+                       if(verb >= 3 && ku_loc >= 0) {
+                               X509_EXTENSION *ex = X509_get_ext(
+                                       sk_X509_value(signers, i), ku_loc);
+                               if(ex) {
+                                       printf("keyUsage: ");
+                                       X509V3_EXT_print_fp(stdout, ex, 0, 0);
+                                       printf("\n");
+                               }
+                       }
+               }
+               if(!p7signer || strcmp(p7signer, "")==0) {
+                       /* there is no name to check, return all records */
+                       if(verb) printf("did not check commonName of signer\n");
+               } else {
+                       if(!X509_NAME_get_text_by_NID(nm,
+                               NID_pkcs9_emailAddress,
+                               buf, (int)sizeof(buf))) {
+                               if(verb) printf("removed cert with no name\n");
+                               continue; /* no name, no use */
+                       }
+                       if(strcmp(buf, p7signer) != 0) {
+                               if(verb) printf("removed cert with wrong name\n");
+                               continue; /* wrong name, skip it */
+                       }
+               }
+
+               /* check that the key usage allows digital signatures
+                * (the p7s) */
+               usage = get_usage_of_ex(sk_X509_value(signers, i));
+               if(!(usage & KU_DIGITAL_SIGNATURE)) {
+                       if(verb) printf("removed cert with no key usage Digital Signature allowed\n");
+                       continue;
+               }
+
+               /* we like this cert, add it to our list of valid
+                * signers certificates */
+               sk_X509_push(validsigners, sk_X509_value(signers, i));
+       }
+       sk_X509_free(signers);
+       return validsigners;
+}
+
 /** verify a PKCS7 signature, false on failure */
 static int
-verify_p7sig(BIO* data, BIO* p7s, STACK_OF(X509)* trust)
+verify_p7sig(BIO* data, BIO* p7s, STACK_OF(X509)* trust, char* p7signer)
 {
        PKCS7* p7;
        X509_STORE *store = X509_STORE_new();
+       STACK_OF(X509)* validsigners;
        int secure = 0;
        int i;
 #ifdef X509_V_FLAG_CHECK_SS_SIGNATURE
@@ -1630,6 +1755,9 @@ verify_p7sig(BIO* data, BIO* p7s, STACK_OF(X509)* trust)
 #endif
                return 0;
        }
+#ifdef X509_V_FLAG_CHECK_SS_SIGNATURE
+       X509_VERIFY_PARAM_free(param);
+#endif
 
        (void)BIO_reset(p7s);
        (void)BIO_reset(data);
@@ -1654,7 +1782,15 @@ verify_p7sig(BIO* data, BIO* p7s, STACK_OF(X509)* trust)
        }
        if(verb >= 2) printf("setup the X509_STORE\n");
 
-       if(PKCS7_verify(p7, NULL, store, data, NULL, 0) == 1) {
+       /* check what is in the Subject name of the certificates,
+        * and build a stack that contains only the right certificates */
+       validsigners = get_valid_signers(p7, p7signer);
+       if(!validsigners) {
+                       X509_STORE_free(store);
+                       PKCS7_free(p7);
+                       return 0;
+       }
+       if(PKCS7_verify(p7, validsigners, store, data, NULL, PKCS7_NOINTERN) == 1) {
                secure = 1;
                if(verb) printf("the PKCS7 signature verified\n");
        } else {
@@ -1663,6 +1799,7 @@ verify_p7sig(BIO* data, BIO* p7s, STACK_OF(X509)* trust)
                }
        }
 
+       sk_X509_free(validsigners);
        X509_STORE_free(store);
        PKCS7_free(p7);
        return secure;
@@ -1723,12 +1860,12 @@ write_root_anchor(char* root_anchor_file, BIO* ds)
 /** Perform the verification and update of the trustanchor file */
 static void
 verify_and_update_anchor(char* root_anchor_file, BIO* xml, BIO* p7s,
-       STACK_OF(X509)* cert)
+       STACK_OF(X509)* cert, char* p7signer)
 {
        BIO* ds;
 
        /* verify xml file */
-       if(!verify_p7sig(xml, p7s, cert)) {
+       if(!verify_p7sig(xml, p7s, cert, p7signer)) {
                printf("the PKCS7 signature failed\n");
                exit(0);
        }
@@ -1752,7 +1889,7 @@ static void do_wsa_cleanup(void) { WSACleanup(); }
 /** perform actual certupdate work */
 static int
 do_certupdate(char* root_anchor_file, char* root_cert_file,
-       char* urlname, char* xmlname, char* p7sname,
+       char* urlname, char* xmlname, char* p7sname, char* p7signer,
        char* res_conf, char* root_hints, char* debugconf,
        int ip4only, int ip6only, int port, struct ub_result* dnskey)
 {
@@ -1785,7 +1922,7 @@ do_certupdate(char* root_anchor_file, char* root_cert_file,
        p7s = https(ip_list, p7sname, urlname);
 
        /* verify and update the root anchor */
-       verify_and_update_anchor(root_anchor_file, xml, p7s, cert);
+       verify_and_update_anchor(root_anchor_file, xml, p7s, cert, p7signer);
        if(verb) printf("success: the anchor has been updated "
                        "using the cert\n");
 
@@ -2035,7 +2172,7 @@ probe_date_allows_certupdate(char* root_anchor_file)
 /** perform the unbound-anchor work */
 static int
 do_root_update_work(char* root_anchor_file, char* root_cert_file,
-       char* urlname, char* xmlname, char* p7sname,
+       char* urlname, char* xmlname, char* p7sname, char* p7signer,
        char* res_conf, char* root_hints, char* debugconf,
        int ip4only, int ip6only, int force, int port)
 {
@@ -2068,8 +2205,8 @@ do_root_update_work(char* root_anchor_file, char* root_cert_file,
        if((dnskey->rcode == 0 &&
                probe_date_allows_certupdate(root_anchor_file)) || force) {
                if(do_certupdate(root_anchor_file, root_cert_file, urlname,
-                       xmlname, p7sname, res_conf, root_hints, debugconf,
-                       ip4only, ip6only, port, dnskey))
+                       xmlname, p7sname, p7signer, res_conf, root_hints,
+                       debugconf, ip4only, ip6only, port, dnskey))
                        return 1;
                return used_builtin;
        }
@@ -2092,12 +2229,13 @@ int main(int argc, char* argv[])
        char* urlname = URLNAME;
        char* xmlname = XMLNAME;
        char* p7sname = P7SNAME;
+       char* p7signer = P7SIGNER;
        char* res_conf = NULL;
        char* root_hints = NULL;
        char* debugconf = NULL;
        int dolist=0, ip4only=0, ip6only=0, force=0, port = HTTPS_PORT;
        /* parse the options */
-       while( (c=getopt(argc, argv, "46C:FP:a:c:f:hlr:s:u:vx:")) != -1) {
+       while( (c=getopt(argc, argv, "46C:FP:a:c:f:hln:r:s:u:vx:")) != -1) {
                switch(c) {
                case 'l':
                        dolist = 1;
@@ -2123,6 +2261,9 @@ int main(int argc, char* argv[])
                case 's':
                        p7sname = optarg;
                        break;
+               case 'n':
+                       p7signer = optarg;
+                       break;
                case 'f':
                        res_conf = optarg;
                        break;
@@ -2160,6 +2301,6 @@ int main(int argc, char* argv[])
        if(dolist) do_list_builtin();
 
        return do_root_update_work(root_anchor_file, root_cert_file, urlname,
-               xmlname, p7sname, res_conf, root_hints, debugconf, ip4only,
-               ip6only, force, port);
+               xmlname, p7sname, p7signer, res_conf, root_hints, debugconf,
+               ip4only, ip6only, force, port);
 }
index 632b289e59f53f2f4d3287a14d259b08c32131a3..81fb1b36f6f56aee92e63a836bf8b08b2d73806f 100644 (file)
@@ -325,7 +325,7 @@ data_buffer2wire(ldns_buffer *data_buffer)
        uint8_t *hexbuf;
        int hexbufpos = 0;
        size_t wirelen;
-       uint8_t *data_wire = (uint8_t *) ldns_buffer_export(data_buffer);
+       uint8_t *data_wire = (uint8_t *) ldns_buffer_begin(data_buffer);
        uint8_t *wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
        
        hexbuf = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
@@ -342,6 +342,12 @@ data_buffer2wire(ldns_buffer *data_buffer)
                                        (c >= 'a' && c <= 'f') ||
                                        (c >= 'A' && c <= 'F') )
                                {
+                                       if (hexbufpos >= LDNS_MAX_PACKETLEN) {
+                                               error("buffer overflow");
+                                               LDNS_FREE(hexbuf);
+                                               return 0;
+
+                                       }
                                        hexbuf[hexbufpos] = (uint8_t) c;
                                        hexbufpos++;
                                } else if (c == ';') {
@@ -356,14 +362,14 @@ data_buffer2wire(ldns_buffer *data_buffer)
                                }
                                break;
                        case 2:
+                               if (hexbufpos >= LDNS_MAX_PACKETLEN) {
+                                       error("buffer overflow");
+                                       LDNS_FREE(hexbuf);
+                                       return 0;
+                               }
                                hexbuf[hexbufpos] = (uint8_t) c;
                                hexbufpos++;
                                break;
-                       default:
-                               error("unknown state while reading");
-                               LDNS_FREE(hexbuf);
-                               return 0;
-                               break;
                }
        }
 
@@ -373,6 +379,11 @@ data_buffer2wire(ldns_buffer *data_buffer)
        
        /* lenient mode: length must be multiple of 2 */
        if (hexbufpos % 2 != 0) {
+               if (hexbufpos >= LDNS_MAX_PACKETLEN) {
+                       error("buffer overflow");
+                       LDNS_FREE(hexbuf);
+                       return 0;
+               }
                hexbuf[hexbufpos] = (uint8_t) '0';
                hexbufpos++;
        }
@@ -417,7 +428,7 @@ get_origin(const char* name, int lineno, ldns_rdf** origin, char* parse)
 /* Reads one entry from file. Returns entry or NULL on error. */
 struct entry*
 read_entry(FILE* in, const char* name, int *lineno, uint32_t* default_ttl, 
-       ldns_rdf** origin, ldns_rdf** prev_rr)
+       ldns_rdf** origin, ldns_rdf** prev_rr, int skip_whitespace)
 {
        struct entry* current = NULL;
        char line[MAX_LINE];
@@ -489,6 +500,7 @@ read_entry(FILE* in, const char* name, int *lineno, uint32_t* default_ttl,
                        reading_hex = false;
                        cur_reply->reply_from_hex = data_buffer2wire(hex_data_buffer);
                        ldns_buffer_free(hex_data_buffer);
+                       hex_data_buffer = NULL;
                } else if(reading_hex) {
                        ldns_buffer_printf(hex_data_buffer, line);
                } else if(str_keyword(&parse, "HEX_EDNSDATA_BEGIN")) {
@@ -502,22 +514,28 @@ read_entry(FILE* in, const char* name, int *lineno, uint32_t* default_ttl,
                        reading_hex_ednsdata = false;
                        cur_reply->raw_ednsdata = data_buffer2wire(hex_ednsdata_buffer);
                        ldns_buffer_free(hex_ednsdata_buffer);
+                       hex_ednsdata_buffer = NULL;
                } else if(reading_hex_ednsdata) {
                        ldns_buffer_printf(hex_ednsdata_buffer, line);
                } else if(str_keyword(&parse, "ENTRY_END")) {
+                       if (hex_data_buffer)
+                               ldns_buffer_free(hex_data_buffer);
                        return current;
                } else {
                        /* it must be a RR, parse and add to packet. */
                        ldns_rr* n = NULL;
                        ldns_status status;
+                       char* rrstr = line;
+                       if (skip_whitespace)
+                               rrstr = parse;
                        if(add_section == LDNS_SECTION_QUESTION)
                                status = ldns_rr_new_question_frm_str(
-                                       &n, parse, *origin, prev_rr);
-                       else status = ldns_rr_new_frm_str(&n, parse, 
+                                       &n, rrstr, *origin, prev_rr);
+                       else status = ldns_rr_new_frm_str(&n, rrstr,
                                *default_ttl, *origin, prev_rr);
                        if(status != LDNS_STATUS_OK)
                                error("%s line %d:\n\t%s: %s", name, *lineno,
-                                       ldns_get_errorstr_by_id(status), parse);
+                                       ldns_get_errorstr_by_id(status), rrstr);
                        ldns_pkt_push_rr(cur_reply->reply, add_section, n);
                }
 
@@ -535,7 +553,7 @@ read_entry(FILE* in, const char* name, int *lineno, uint32_t* default_ttl,
 
 /* reads the canned reply file and returns a list of structs */
 struct entry* 
-read_datafile(const char* name)
+read_datafile(const char* name, int skip_whitespace)
 {
        struct entry* list = NULL;
        struct entry* last = NULL;
@@ -552,7 +570,7 @@ read_datafile(const char* name)
        }
 
        while((current = read_entry(in, name, &lineno, &default_ttl, 
-               &origin, &prev_rr)))
+               &origin, &prev_rr, skip_whitespace)))
        {
                if(last)
                        last->next = current;
@@ -871,7 +889,7 @@ handle_query(uint8_t* inbuf, ssize_t inlen, struct entry* entries, int* count,
                                /* still try to adjust ID */
                                answer_size = ldns_buffer_capacity(p->reply_from_hex);
                                outbuf = LDNS_XMALLOC(uint8_t, answer_size);
-                               memcpy(outbuf, ldns_buffer_export(p->reply_from_hex), answer_size);
+                               memcpy(outbuf, ldns_buffer_begin(p->reply_from_hex), answer_size);
                                if(entry->copy_id) {
                                        ldns_write_uint16(outbuf, 
                                                ldns_pkt_id(query_pkt));
index b4d1c4b8e6156d542c434648d063160a4e6b0f4f..88dd422f322f4c923f6b6b7b521e71bad431c874 100644 (file)
@@ -207,8 +207,9 @@ struct entry {
 /**
  * reads the canned reply file and returns a list of structs 
  * does an exit on error.
+ * @param skip_whitespace: skip leftside whitespace.
  */
-struct entry* read_datafile(const char* name);
+struct entry* read_datafile(const char* name, int skip_whitespace);
 
 /**
  * Delete linked list of entries.
@@ -227,10 +228,12 @@ void delete_entry(struct entry* list);
  *     later it stores the $ORIGIN value last seen. Often &NULL or the zone
  *     name on first call.
  * @param prev_rr: previous rr name for correcter parsing. &NULL on first call.
+ * @param skip_whitespace: skip leftside whitespace.
  * @return: The entry read (malloced) or NULL if no entry could be read.
  */
 struct entry* read_entry(FILE* in, const char* name, int *lineno, 
-       uint32_t* default_ttl, ldns_rdf** origin, ldns_rdf** prev_rr);
+       uint32_t* default_ttl, ldns_rdf** origin, ldns_rdf** prev_rr,
+       int skip_whitespace);
 
 /**
  * finds entry in list, or returns NULL.
index 3d3aa01a08d1014d97cf1cbf3b0b24c8703abc54..2ce647da11974f607d63cf3d1e5325a12a1786d3 100644 (file)
@@ -193,7 +193,7 @@ replay_range_read(char* remain, FILE* in, const char* name, int* lineno,
                /* set position before line; read entry */
                (*lineno)--;
                fseeko(in, pos, SEEK_SET);
-               entry = read_entry(in, name, lineno, ttl, or, prev);
+               entry = read_entry(in, name, lineno, ttl, or, prev, 1);
                if(!entry)
                        fatal_exit("%d: bad entry", *lineno);
                entry->next = NULL;
@@ -393,7 +393,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
        } 
 
        if(readentry) {
-               mom->match = read_entry(in, name, lineno, ttl, or, prev);
+               mom->match = read_entry(in, name, lineno, ttl, or, prev, 1);
                if(!mom->match) {
                        free(mom);
                        return NULL;
index 5da66496820666c991f035e3eec5fe061a869917..d3fbf25f5312d2e1c8ae72c01398c2a6cd10b126 100644 (file)
@@ -298,7 +298,7 @@ verifytest_file(const char* fname, const char* at_date)
        struct alloc_cache alloc;
        ldns_buffer* buf = ldns_buffer_new(65535);
        struct entry* e;
-       struct entry* list = read_datafile(fname);
+       struct entry* list = read_datafile(fname, 1);
        struct module_env env;
        struct val_env ve;
        uint32_t now = time(NULL);
@@ -342,7 +342,7 @@ dstest_file(const char* fname)
        struct alloc_cache alloc;
        ldns_buffer* buf = ldns_buffer_new(65535);
        struct entry* e;
-       struct entry* list = read_datafile(fname);
+       struct entry* list = read_datafile(fname, 1);
        struct module_env env;
 
        if(!list)
@@ -475,7 +475,7 @@ nsec3_hash_test(const char* fname)
        struct alloc_cache alloc;
        ldns_buffer* buf = ldns_buffer_new(65535);
        struct entry* e;
-       struct entry* list = read_datafile(fname);
+       struct entry* list = read_datafile(fname, 1);
 
        if(!list)
                fatal_exit("could not read %s: %s", fname, strerror(errno));
index e45a0525c5aa2cfc6cfd3d823ad03459c16d2a57..d7a9ceb269321ca664a02f5fa1d82389af69fbdc 100644 (file)
Binary files a/testdata/09-unbound-control.tpkg and b/testdata/09-unbound-control.tpkg differ
index 85f63e842b1ce6ee87549c9a9843827afc23dcf1..de8fb4df78715d4ec239dd07bfe53a52d0a5dbc6 100644 (file)
Binary files a/testdata/10-unbound-anchor.tpkg and b/testdata/10-unbound-anchor.tpkg differ
diff --git a/testdata/val_cnametocnamewctoposwc.rpl b/testdata/val_cnametocnamewctoposwc.rpl
new file mode 100644 (file)
index 0000000..12f83e8
--- /dev/null
@@ -0,0 +1,208 @@
+; config options
+; The island of trust is at example.com
+server:
+       trust-anchor: "example.com.    IN      DNSKEY  257 3 8 AwEAAdL6YJdvoKQJEt/SgB6MrbQ2RDwnrcQQb6bDE8FpGgLen6hvF31ntVsZ3RZzhCmwL6lvumOLFIRKaP9ZBEVutT9iMoF2dNRbT0TCUrv6uQNHcuCZ0BJhuDNBU42f3yOnfFv7PKxd0NP+yFHJkvDQAVLMB5GeUQuYnvgQGeZsf/3b"
+       val-override-date: "-1"
+       target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with a regular cname to wildcard cname to wildcard response
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+       ADDRESS 193.0.14.129 
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS        K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET.    IN      A       193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+start.example.com. IN A
+SECTION AUTHORITY
+com.   IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.    IN      A       192.5.6.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+       ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com.    IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.     IN      A       192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+start.example.com. IN A
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.        120     IN      A       1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com.   3600    IN      NS      ns.example.com.
+example.com.   3600    IN      RRSIG   NS 8 2 3600 20121126123249 20121029123249 64050 example.com. cpLjgKPacNxVIGo59tYMZ98GVYpH28WHRWj3AeIHK0StYFcAlflGLdkae1LEgMwfUmzrayrA5GMe3AH8LyuTgA2Dn1oNFxGfuShQvK2MFQ+LxvQfiuoqlAlL5Aa94IWcSoU/wLrr66I1K8oSB2yK1Tyyv73c2N40D1mBbzIE70U=
+SECTION ADDITIONAL
+ns.example.com.        3600    IN      A       1.2.3.4
+ns.example.com.        3600    IN      RRSIG   A 8 2 3600 20121126123249 20121029123249 64050 example.com. zxGyimwFsd39j8T7jJ+tSAQPwZ7tjk6HHmzosTMCRePM4k4newbLb5HbrpucSiW/plaEZvjRTDTJ6bPkw0msPXjPCI/22Zh236XO5vhGtMOlxDgAEazuhifVF6UsM7GZwONPBCvw705HgWQyCR1YlTK2w9ffH3GopU9f4oP7Pmk=
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com.   3600    IN      DNSKEY  256 3 8 AwEAAdWzfjQD2bfQuoQGNYuS0ByosBxiTkoKcy9kMoWOQ/jx9rvTRhHImWxTxFtIyZOoRgn6E6mE71e5Y1q1nuyH544Em+4rNRMMW4bzecQmMmPk+B97MqW9aW6e4BwiCTt52IGfL++5GORYcaITw9UOlQLYH1oHHUNUC6ebHENofLTj ;{id = 64050 (zsk), size = 1024b}
+example.com.   3600    IN      DNSKEY  257 3 8 AwEAAdL6YJdvoKQJEt/SgB6MrbQ2RDwnrcQQb6bDE8FpGgLen6hvF31ntVsZ3RZzhCmwL6lvumOLFIRKaP9ZBEVutT9iMoF2dNRbT0TCUrv6uQNHcuCZ0BJhuDNBU42f3yOnfFv7PKxd0NP+yFHJkvDQAVLMB5GeUQuYnvgQGeZsf/3b ;{id = 46426 (ksk), size = 1024b}
+example.com.   3600    IN      RRSIG   DNSKEY 8 2 3600 20121126123249 20121029123249 46426 example.com. pisNb/A40XDEiMpcYtxc+yO6osISyfpqz+0UZ61pd70+TLXMF197zr9SqOVJHyRI6G2lSnFggxYrZDpxLbxOW0RY/KfjD3xlI14M/2DieJ1NdlQuYFGgTwxcoINUJ/wRd4YUxkF4JS0D4NBdQ0yQYR0KqDr84oyhnULEHX6WB7s=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+start.example.com. IN A
+SECTION ANSWER
+start.example.com.     3600    IN      CNAME   x.y.z.wc.example.com.
+start.example.com.     3600    IN      RRSIG   CNAME 8 3 3600 20121126131853 20121029131853 64050 example.com. uN8+hg2b9kqpso4zTtpb8CdkGkgOdlbayH1Ui7NVSi1Y8un8FDG4NHy2gpCi0zIMpeAOa5bENe3cdTEwYZKHQdvnGjaI/zFWpFAzXsEFg0VlLxDQXSzRB6GtoFoUEYiZBHsmLIy3zWjuihlWK9fRzyPyVtBDDmqU8KK7+H3BYp0=
+x.y.z.wc.example.com.  3600    IN      CNAME   x.y.z.end.example.com.
+x.y.z.wc.example.com.  3600    IN      RRSIG   CNAME 8 3 3600 20121126131853 20121029131853 64050 example.com. NQTIY1uMK1jxVMHOaMB4shedyhdAERZuPiZXytfqSH36hDVMf1C8tSxdbCjJ90lOLEWNtMmT09l5kh14gp1XIaBHzLuDsYmZJVeudBGCaQRkbM5focd2VMd8V4hHQk4odwsRrSY6IETftHeqeFiRifru/rI3x5Dlv8awI6V5TZI=
+x.y.z.end.example.com. 3600    IN      A       1.2.3.5
+x.y.z.end.example.com. 3600    IN      RRSIG   A 8 3 3600 20121126131826 20121029131826 64050 example.com. iS1Pe45xt8SLGlmfmrSPTrnIAlwpIX8leTrsoLgpQJc98aA0XJmO/D32CbMTRZzAM1oBVggm80ht2RIQkX3W1NvN/prcu+Gp0Zrm0rtW+7Q7VwcSbo7jyHh5K8Mppp2OsCleexco5NVAKpDMvD0nyG+CsKtNMQpKK2DlumQsraE=
+SECTION AUTHORITY
+*.wc.example.com.      86400   IN      NSEC    www.example.com. CNAME RRSIG NSEC 
+*.wc.example.com.      86400   IN      RRSIG   NSEC 8 3 86400 20121126131853 20121029131853 64050 example.com. YrmCLu0uGgD2gcU4p12BGnUGYcrKmfg82MJHSF5OnVmmJxXiSbSBnZPahbJNGA/kPLt+SlDyBTcssZKXWxM6bW7WF57OwffOj7rMyr5vhx7J6OsuWKotPVqnUFDx9j/rOum24yCKqoBWvpW/RYUHLuX1Wm05WMCgNWhuN4wqwiU=
+*.end.example.com.     86400   IN      NSEC    escapedtext.example.com. A RRSIG NSEC 
+*.end.example.com.     86400   IN      RRSIG   NSEC 8 3 86400 20121126131826 20121029131826 64050 example.com. P6uJSImaee+5NHlTP06pMxgO69qxjJc0Uo1+htjVyE8f15MhG8A7NttvzggbtyzmfLMPr7TilM+Mm7hC3pIk/TeBEdH8p+8qypnY0NzPntz5z1+6C6ZTjDXp6NxDwMz7th31r3B3u4xo/K4qMnXmrAFOIE5Lopk0uDGXfjKPCKE=
+example.com.   3600    IN      NS      ns.example.com.
+example.com.   3600    IN      RRSIG   NS 8 2 3600 20121126131826 20121029131826 64050 example.com. NgY7UAdkXprnCi/O6c5XoB82tqLBd1bY9LmDG9wwN0zEUR5aHQcOmX9waHyqXQI86SOFQbGCvO2wDLqdqWniw1IYf4S66Vf9KrpaH2gVbvHKiEpGJPeDYQcD5xkv50Lsp4ktcLyuO/dk8ORCP7E2yC5IQVNeFgUfaqttZcJoxuQ=
+SECTION ADDITIONAL
+ns.example.com.        3600    IN      A       1.2.3.4
+ns.example.com.        3600    IN      RRSIG   A 8 2 3600 20121126131826 20121029131826 64050 example.com. L/EsWsRNhM0Lt8877XYfm0FkVc+utuRPYlW/yxEi/Nzs/mTb9BMrOygsW0qfpYakYgfFvinR7S7ce9/naWidzGkWKYR85g2WFms3/TgchpmfjZHEsNyuT8zsiGrj3bQ3RxpT5cmt/IS2QlOak/RhdtawKfd9aqkMTVpP2idEQwY=
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.y.z.wc.example.com. IN A
+SECTION ANSWER
+x.y.z.wc.example.com.  3600    IN      CNAME   x.y.z.end.example.com.
+x.y.z.wc.example.com.  3600    IN      RRSIG   CNAME 8 3 3600 20121126131853 20121029131853 64050 example.com. NQTIY1uMK1jxVMHOaMB4shedyhdAERZuPiZXytfqSH36hDVMf1C8tSxdbCjJ90lOLEWNtMmT09l5kh14gp1XIaBHzLuDsYmZJVeudBGCaQRkbM5focd2VMd8V4hHQk4odwsRrSY6IETftHeqeFiRifru/rI3x5Dlv8awI6V5TZI=
+x.y.z.end.example.com. 3600    IN      A       1.2.3.5
+x.y.z.end.example.com. 3600    IN      RRSIG   A 8 3 3600 20121126131826 20121029131826 64050 example.com. iS1Pe45xt8SLGlmfmrSPTrnIAlwpIX8leTrsoLgpQJc98aA0XJmO/D32CbMTRZzAM1oBVggm80ht2RIQkX3W1NvN/prcu+Gp0Zrm0rtW+7Q7VwcSbo7jyHh5K8Mppp2OsCleexco5NVAKpDMvD0nyG+CsKtNMQpKK2DlumQsraE=
+SECTION AUTHORITY
+*.wc.example.com.      86400   IN      NSEC    www.example.com. CNAME RRSIG NSEC 
+*.wc.example.com.      86400   IN      RRSIG   NSEC 8 3 86400 20121126131853 20121029131853 64050 example.com. YrmCLu0uGgD2gcU4p12BGnUGYcrKmfg82MJHSF5OnVmmJxXiSbSBnZPahbJNGA/kPLt+SlDyBTcssZKXWxM6bW7WF57OwffOj7rMyr5vhx7J6OsuWKotPVqnUFDx9j/rOum24yCKqoBWvpW/RYUHLuX1Wm05WMCgNWhuN4wqwiU=
+*.end.example.com.     86400   IN      NSEC    escapedtext.example.com. A RRSIG NSEC 
+*.end.example.com.     86400   IN      RRSIG   NSEC 8 3 86400 20121126131826 20121029131826 64050 example.com. P6uJSImaee+5NHlTP06pMxgO69qxjJc0Uo1+htjVyE8f15MhG8A7NttvzggbtyzmfLMPr7TilM+Mm7hC3pIk/TeBEdH8p+8qypnY0NzPntz5z1+6C6ZTjDXp6NxDwMz7th31r3B3u4xo/K4qMnXmrAFOIE5Lopk0uDGXfjKPCKE=
+example.com.   3600    IN      NS      ns.example.com.
+example.com.   3600    IN      RRSIG   NS 8 2 3600 20121126131826 20121029131826 64050 example.com. NgY7UAdkXprnCi/O6c5XoB82tqLBd1bY9LmDG9wwN0zEUR5aHQcOmX9waHyqXQI86SOFQbGCvO2wDLqdqWniw1IYf4S66Vf9KrpaH2gVbvHKiEpGJPeDYQcD5xkv50Lsp4ktcLyuO/dk8ORCP7E2yC5IQVNeFgUfaqttZcJoxuQ=
+SECTION ADDITIONAL
+ns.example.com.        3600    IN      A       1.2.3.4
+ns.example.com.        3600    IN      RRSIG   A 8 2 3600 20121126131826 20121029131826 64050 example.com. L/EsWsRNhM0Lt8877XYfm0FkVc+utuRPYlW/yxEi/Nzs/mTb9BMrOygsW0qfpYakYgfFvinR7S7ce9/naWidzGkWKYR85g2WFms3/TgchpmfjZHEsNyuT8zsiGrj3bQ3RxpT5cmt/IS2QlOak/RhdtawKfd9aqkMTVpP2idEQwY=
+ENTRY_END
+
+ENTRY_BEGING
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.y.z.end.example.com. IN A
+SECTION ANSWER
+x.y.z.end.example.com. 3600    IN      A       1.2.3.5
+x.y.z.end.example.com. 3600    IN      RRSIG   A 8 3 3600 20121126131826 20121029131826 64050 example.com. iS1Pe45xt8SLGlmfmrSPTrnIAlwpIX8leTrsoLgpQJc98aA0XJmO/D32CbMTRZzAM1oBVggm80ht2RIQkX3W1NvN/prcu+Gp0Zrm0rtW+7Q7VwcSbo7jyHh5K8Mppp2OsCleexco5NVAKpDMvD0nyG+CsKtNMQpKK2DlumQsraE=
+SECTION AUTHORITY
+*.end.example.com.     86400   IN      NSEC    escapedtext.example.com. A RRSIG NSEC 
+*.end.example.com.     86400   IN      RRSIG   NSEC 8 3 86400 20121126131826 20121029131826 64050 example.com. P6uJSImaee+5NHlTP06pMxgO69qxjJc0Uo1+htjVyE8f15MhG8A7NttvzggbtyzmfLMPr7TilM+Mm7hC3pIk/TeBEdH8p+8qypnY0NzPntz5z1+6C6ZTjDXp6NxDwMz7th31r3B3u4xo/K4qMnXmrAFOIE5Lopk0uDGXfjKPCKE=
+example.com.   3600    IN      NS      ns.example.com.
+example.com.   3600    IN      RRSIG   NS 8 2 3600 20121126131826 20121029131826 64050 example.com. NgY7UAdkXprnCi/O6c5XoB82tqLBd1bY9LmDG9wwN0zEUR5aHQcOmX9waHyqXQI86SOFQbGCvO2wDLqdqWniw1IYf4S66Vf9KrpaH2gVbvHKiEpGJPeDYQcD5xkv50Lsp4ktcLyuO/dk8ORCP7E2yC5IQVNeFgUfaqttZcJoxuQ=
+SECTION ADDITIONAL
+ns.example.com.        3600    IN      A       1.2.3.4
+ns.example.com.        3600    IN      RRSIG   A 8 2 3600 20121126123249 20121029123249 64050 example.com. zxGyimwFsd39j8T7jJ+tSAQPwZ7tjk6HHmzosTMCRePM4k4newbLb5HbrpucSiW/plaEZvjRTDTJ6bPkw0msPXjPCI/22Zh236XO5vhGtMOlxDgAEazuhifVF6UsM7GZwONPBCvw705HgWQyCR1YlTK2w9ffH3GopU9f4oP7Pmk=
+ENTRY_END
+RANGE_END
+
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+start.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+start.example.com. IN A
+SECTION ANSWER
+start.example.com.     3600    IN      CNAME   x.y.z.wc.example.com.
+start.example.com.     3600    IN      RRSIG   CNAME 8 3 3600 20121126131853 20121029131853 64050 example.com. uN8+hg2b9kqpso4zTtpb8CdkGkgOdlbayH1Ui7NVSi1Y8un8FDG4NHy2gpCi0zIMpeAOa5bENe3cdTEwYZKHQdvnGjaI/zFWpFAzXsEFg0VlLxDQXSzRB6GtoFoUEYiZBHsmLIy3zWjuihlWK9fRzyPyVtBDDmqU8KK7+H3BYp0=
+x.y.z.wc.example.com.  3600    IN      CNAME   x.y.z.end.example.com.
+x.y.z.wc.example.com.  3600    IN      RRSIG   CNAME 8 3 3600 20121126131853 20121029131853 64050 example.com. NQTIY1uMK1jxVMHOaMB4shedyhdAERZuPiZXytfqSH36hDVMf1C8tSxdbCjJ90lOLEWNtMmT09l5kh14gp1XIaBHzLuDsYmZJVeudBGCaQRkbM5focd2VMd8V4hHQk4odwsRrSY6IETftHeqeFiRifru/rI3x5Dlv8awI6V5TZI=
+x.y.z.end.example.com. 3600    IN      A       1.2.3.5
+x.y.z.end.example.com. 3600    IN      RRSIG   A 8 3 3600 20121126131826 20121029131826 64050 example.com. iS1Pe45xt8SLGlmfmrSPTrnIAlwpIX8leTrsoLgpQJc98aA0XJmO/D32CbMTRZzAM1oBVggm80ht2RIQkX3W1NvN/prcu+Gp0Zrm0rtW+7Q7VwcSbo7jyHh5K8Mppp2OsCleexco5NVAKpDMvD0nyG+CsKtNMQpKK2DlumQsraE=
+SECTION AUTHORITY
+*.wc.example.com.      86400   IN      NSEC    www.example.com. CNAME RRSIG NSEC 
+*.wc.example.com.      86400   IN      RRSIG   NSEC 8 3 86400 20121126131853 20121029131853 64050 example.com. YrmCLu0uGgD2gcU4p12BGnUGYcrKmfg82MJHSF5OnVmmJxXiSbSBnZPahbJNGA/kPLt+SlDyBTcssZKXWxM6bW7WF57OwffOj7rMyr5vhx7J6OsuWKotPVqnUFDx9j/rOum24yCKqoBWvpW/RYUHLuX1Wm05WMCgNWhuN4wqwiU=
+*.end.example.com.     86400   IN      NSEC    escapedtext.example.com. A RRSIG NSEC 
+*.end.example.com.     86400   IN      RRSIG   NSEC 8 3 86400 20121126131826 20121029131826 64050 example.com. P6uJSImaee+5NHlTP06pMxgO69qxjJc0Uo1+htjVyE8f15MhG8A7NttvzggbtyzmfLMPr7TilM+Mm7hC3pIk/TeBEdH8p+8qypnY0NzPntz5z1+6C6ZTjDXp6NxDwMz7th31r3B3u4xo/K4qMnXmrAFOIE5Lopk0uDGXfjKPCKE=
+example.com.   3600    IN      NS      ns.example.com.
+example.com.   3600    IN      RRSIG   NS 8 2 3600 20121126131826 20121029131826 64050 example.com. NgY7UAdkXprnCi/O6c5XoB82tqLBd1bY9LmDG9wwN0zEUR5aHQcOmX9waHyqXQI86SOFQbGCvO2wDLqdqWniw1IYf4S66Vf9KrpaH2gVbvHKiEpGJPeDYQcD5xkv50Lsp4ktcLyuO/dk8ORCP7E2yC5IQVNeFgUfaqttZcJoxuQ=
+SECTION ADDITIONAL
+ns.example.com.        3600    IN      A       1.2.3.4
+ns.example.com.        3600    IN      RRSIG   A 8 2 3600 20121126123249 20121029123249 64050 example.com. zxGyimwFsd39j8T7jJ+tSAQPwZ7tjk6HHmzosTMCRePM4k4newbLb5HbrpucSiW/plaEZvjRTDTJ6bPkw0msPXjPCI/22Zh236XO5vhGtMOlxDgAEazuhifVF6UsM7GZwONPBCvw705HgWQyCR1YlTK2w9ffH3GopU9f4oP7Pmk=
+ENTRY_END
+
+SCENARIO_END
diff --git a/testdata/val_ds_cnamesub.rpl b/testdata/val_ds_cnamesub.rpl
new file mode 100644 (file)
index 0000000..a147b93
--- /dev/null
@@ -0,0 +1,275 @@
+; config options
+; The island of trust is at example.com
+server:
+       trust-anchor: "example.com.    3600    IN      DS      2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+       val-override-date: "20070916134226"
+       target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with CNAME response to DS in chain of trust
+; the CNAME is at a nonempty nonterminal name in the parent zone.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+       ADDRESS 193.0.14.129 
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS        K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET.    IN      A       193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com.   IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.    IN      A       192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net.   IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.    IN      A       192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+       ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com.    IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.     IN      A       192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.net. IN A
+SECTION AUTHORITY
+example.net. IN NS ns.example.net.
+SECTION ADDITIONAL
+ns.example.net. IN A 1.2.3.6
+ENTRY_END
+
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ns.example.com. IN AAAA
+SECTION ANSWER
+; not legal NOERROR/NODATA response, but leniently accepted (not validated)
+SECTION AUTHORITY
+example.com.    IN NS   ns.example.com.
+example.com.    3600    IN      RRSIG   NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+;example.com. IN SOA alfa.ns.example.com.cz. hostmaster.example.com. 2010030800 10800 86400 604800 86400
+;example.com.  3600    IN      RRSIG   SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. ADsxLOHjxFzwFmwIiGOubqD9nKWAp4RccRIXQ0+EAUGfSDZMCB0ZiFA= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com.         IN      A       1.2.3.4
+ns.example.com. 3600    IN      RRSIG   A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com.    IN NS   ns.example.com.
+example.com.    3600    IN      RRSIG   NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com.         IN      A       1.2.3.4
+ns.example.com. 3600    IN      RRSIG   A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com.    3600    IN      DNSKEY  256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com.    3600    IN      RRSIG   DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+example.com.    3600    IN      RRSIG   NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+ns.example.com. 3600    IN      RRSIG   A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to DS query for a.example.com, a CNAME
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.example.com. IN DS
+SECTION ANSWER
+a.example.com. IN CNAME zzz.example.net.
+a.example.com. 3600    IN      RRSIG   CNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AKM6/j6yowuwqbazKzi4fEsavcLwXo3PjglhH9KD68ANZOrdN9y1ZCc=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; response to DS query for sub.a.example.com.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.a.example.com. IN DS
+SECTION ANSWER
+sub.a.example.com.     3600    IN      DS      57024 7 1 e54100bff773a794854808694c5d217267a53649
+sub.a.example.com.     3600    IN      RRSIG   DS 3 4 3600 20070926134150 20070829134150 2854 example.com. ALHDGmpgZlXnAb54z4FbBKw/9nXVBdosG0UCEuh4qU7Lm/fs5Dv9aJw=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; delegation down
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub.a.example.com. IN NS
+SECTION ANSWER
+SECTION AUTHORITY
+sub.a.example.com.     3600    IN      DS      57024 7 1 e54100bff773a794854808694c5d217267a53649
+sub.a.example.com.     3600    IN      RRSIG   DS 3 4 3600 20070926134150 20070829134150 2854 example.com. ALHDGmpgZlXnAb54z4FbBKw/9nXVBdosG0UCEuh4qU7Lm/fs5Dv9aJw=
+sub.a.example.com. IN NS ns.sub.a.example.com.
+SECTION ADDITIONAL
+ns.sub.a.example.com. IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+; ns.sub.a.example.com.
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.5
+
+; DNSKEY query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub.a.example.com. IN DNSKEY
+SECTION ANSWER
+sub.a.example.com.     3600    IN      DNSKEY  257 3 7 AwEAAbvre/wK/WVeoj0SiwVkTD+NefvHPru9YIqLWY0m+0E5NYOpJZdc+PGQQYRzFNOlugVZtFirmv5Lmz7GNiASXtG/IFi//SlE30DxEKQOjt2F6qSZTZ1nZ5XOIMGTwWyp4OoI0egk5JavC5mQbyXqcj82ywt6F5Z3CmnThVl6MtOv ;{id = 57024 (ksk), size = 1024b}
+sub.a.example.com.     3600    IN      RRSIG   DNSKEY 7 4 3600 20070926134150 20070829134150 57024 sub.a.example.com. TB3rkkPBD/ESQR9WBpfq2aV+2howI+EJq2+om2EI6PiemQOdpN6ovLvKwCILb0LOsTEFfPpAvRCOuDzRC24sJqBgWpZ4xLxMTcQJ8hMvv7rIUfZotDPO2JYNHSRmpeQLuDGA6P+AtJLYIr7yfOltJmJ0aCJxy3Fm9RQxJxHVbEQ=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.sub.a.example.com. IN A
+SECTION ANSWER
+www.sub.a.example.com. IN A 10.20.30.40
+www.sub.a.example.com. 3600    IN      RRSIG   A 7 5 3600 20070926134150 20070829134150 57024 sub.a.example.com. az44R7VbfooRtaSOO65W+GP4K/fHlIcKMkF/z3LVvDXOdCK+zuYPJycBCYljH5cAhslMXgDeHMOWdcPhKIZ3EjykYUJIGlMckVIMobBieFKFhIX9r/bRpT0vlsCF2YKbmvyjpeRF/sIg2iSNMf/s6wxpZq02Kq6yuHtUEqgx7uA=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.6
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+zzz.example.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+example.net. IN SOA root. host. 1 2 3 4 5
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.sub.a.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+www.sub.a.example.com. IN A
+SECTION ANSWER
+www.sub.a.example.com.  3600    IN      A       10.20.30.40
+www.sub.a.example.com.  3600    IN      RRSIG   A 7 5 3600 20070926134150 20070829134150 57024 sub.a.example.com. az44R7VbfooRtaSOO65W+GP4K/fHlIcKMkF/z3LVvDXOdCK+zuYPJycBCYljH5cAhslMXgDeHMOWdcPhKIZ3EjykYUJIGlMckVIMobBieFKFhIX9r/bRpT0vlsCF2YKbmvyjpeRF/sIg2iSNMf/s6wxpZq02Kq6yuHtUEqgx7uA=
+ENTRY_END
+
+SCENARIO_END
diff --git a/testdata/val_nsec3_cnametocnamewctoposwc.rpl b/testdata/val_nsec3_cnametocnamewctoposwc.rpl
new file mode 100644 (file)
index 0000000..d6e92d8
--- /dev/null
@@ -0,0 +1,206 @@
+; config options
+; The island of trust is at example.com
+server:
+       trust-anchor: "example.com.    IN      DNSKEY  257 3 8 AwEAAdL6YJdvoKQJEt/SgB6MrbQ2RDwnrcQQb6bDE8FpGgLen6hvF31ntVsZ3RZzhCmwL6lvumOLFIRKaP9ZBEVutT9iMoF2dNRbT0TCUrv6uQNHcuCZ0BJhuDNBU42f3yOnfFv7PKxd0NP+yFHJkvDQAVLMB5GeUQuYnvgQGeZsf/3b"
+       val-override-date: "-1"
+       target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with a regular cname to wildcard cname to wildcard response
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+       ADDRESS 193.0.14.129 
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS        K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET.    IN      A       193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+start.example.com. IN A
+SECTION AUTHORITY
+com.   IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.    IN      A       192.5.6.30
+ENTRY_END
+
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+       ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com.    IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.     IN      A       192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+start.example.com. IN A
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.        120     IN      A       1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com.   3600    IN      NS      ns.example.com.
+example.com.   3600    IN      RRSIG   NS 8 2 3600 20121126123249 20121029123249 64050 example.com. cpLjgKPacNxVIGo59tYMZ98GVYpH28WHRWj3AeIHK0StYFcAlflGLdkae1LEgMwfUmzrayrA5GMe3AH8LyuTgA2Dn1oNFxGfuShQvK2MFQ+LxvQfiuoqlAlL5Aa94IWcSoU/wLrr66I1K8oSB2yK1Tyyv73c2N40D1mBbzIE70U=
+SECTION ADDITIONAL
+ns.example.com.        3600    IN      A       1.2.3.4
+ns.example.com.        3600    IN      RRSIG   A 8 2 3600 20121126123249 20121029123249 64050 example.com. zxGyimwFsd39j8T7jJ+tSAQPwZ7tjk6HHmzosTMCRePM4k4newbLb5HbrpucSiW/plaEZvjRTDTJ6bPkw0msPXjPCI/22Zh236XO5vhGtMOlxDgAEazuhifVF6UsM7GZwONPBCvw705HgWQyCR1YlTK2w9ffH3GopU9f4oP7Pmk=
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com.   3600    IN      DNSKEY  256 3 8 AwEAAdWzfjQD2bfQuoQGNYuS0ByosBxiTkoKcy9kMoWOQ/jx9rvTRhHImWxTxFtIyZOoRgn6E6mE71e5Y1q1nuyH544Em+4rNRMMW4bzecQmMmPk+B97MqW9aW6e4BwiCTt52IGfL++5GORYcaITw9UOlQLYH1oHHUNUC6ebHENofLTj ;{id = 64050 (zsk), size = 1024b}
+example.com.   3600    IN      DNSKEY  257 3 8 AwEAAdL6YJdvoKQJEt/SgB6MrbQ2RDwnrcQQb6bDE8FpGgLen6hvF31ntVsZ3RZzhCmwL6lvumOLFIRKaP9ZBEVutT9iMoF2dNRbT0TCUrv6uQNHcuCZ0BJhuDNBU42f3yOnfFv7PKxd0NP+yFHJkvDQAVLMB5GeUQuYnvgQGeZsf/3b ;{id = 46426 (ksk), size = 1024b}
+example.com.   3600    IN      RRSIG   DNSKEY 8 2 3600 20121126123249 20121029123249 46426 example.com. pisNb/A40XDEiMpcYtxc+yO6osISyfpqz+0UZ61pd70+TLXMF197zr9SqOVJHyRI6G2lSnFggxYrZDpxLbxOW0RY/KfjD3xlI14M/2DieJ1NdlQuYFGgTwxcoINUJ/wRd4YUxkF4JS0D4NBdQ0yQYR0KqDr84oyhnULEHX6WB7s=
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+start.example.com. IN A
+SECTION ANSWER
+start.example.com.     3600    IN      CNAME   x.y.z.wc.example.com.
+start.example.com.     3600    IN      RRSIG   CNAME 8 3 3600 20121126123316 20121029123316 64050 example.com. LHpx5n++Z0Jgjjalac+e7wdYSbfurqSDpLRAOI1PybTJkwrMvgDKfp0ycT4HwsLVy7spumZ/Ahg/5II9pai7jCiqv1Iyh6fx19ZVeClTFMOLotCK8xMHACYJIY39BhTwD2D3r9BxbK+RopUlXypwV02yzdY2xEnPCBJVDUn5d0g=
+x.y.z.wc.example.com.  3600    IN      CNAME   x.y.z.end.example.com.
+x.y.z.wc.example.com.  3600    IN      RRSIG   CNAME 8 3 3600 20121126123316 20121029123316 64050 example.com. BCnT6CIuqvF1U9LfiHIovgvXIVFJsCXqQWmnjHtbFvzUlTlfGj+56YBSOEpyCep4CBJ0CBgZ8gl5kWip8N+sTlveU/UWMv4FAkqLXRYjp4CZegslmJIuXU5uS+Q0GlLbWdSB9ZCZcbbO0qrOtUfrJ2ozcSTCS+D+oIZ+CkwvDlQ=
+x.y.z.end.example.com. 3600    IN      A       1.2.3.5
+x.y.z.end.example.com. 3600    IN      RRSIG   A 8 3 3600 20121126123249 20121029123249 64050 example.com. MyXXd3MvXtEYVNqWDepM3+Ra/j/b63QehzSHXZe5gL954WxW8KGHPYmeWyhDtruThpZS6s6jeARY2xt0lmEDnMgNyPJGA6UWwTIgvGD0u9Qw5kocCq3ZH4cSG4xu4rmZoi+h8OGrHxUb4jIKzipzAQDxhnAcp/wKF7e+p+OE+Fo=
+SECTION AUTHORITY
+; H(z.wc.example.com.) = isn85psesctb6afn2q105mv966tqqepi.
+isjq5aarcp8p5sukc56g961cccjus5u2.example.com.  86400   IN      NSEC3   1 0 1 abcd  isoaarjsq14bkqaamivn1t1milkv95lc A RRSIG 
+isjq5aarcp8p5sukc56g961cccjus5u2.example.com.  86400   IN      RRSIG   NSEC3 8 3 86400 20121126123259 20121029123259 64050 example.com. Cxwzq1DUQvhkTVHEJHlb92c511Y+uJy/C0yL9br6W/5lB/usuSiK2DjW58ibPh2kLH1P3SpGqd1Y7LigptdXoPBDFakcNcimPWCN93R3J80+vrHHPkPyIsBaywwYI3SNGgfnHfPF+wmH+tZ1vfEHbigOxqPFK+T0ntKq7dkSndg=
+; H(z.end.example.com.) = a62608t4becqb6233m87ar7a3648rj3b.
+a61sejfu6am5a36p628t4s089s309o44.example.com.  86400   IN      NSEC3   1 0 1 abcd  a64lt5ij9a1up15h5cdsn1u2071901hu A RRSIG 
+a61sejfu6am5a36p628t4s089s309o44.example.com.  86400   IN      RRSIG   NSEC3 8 3 86400 20121126123315 20121029123315 64050 example.com. gfBu4oqo9cVxJbqrw2Ly7mK638kGPOF8l8eh7ovalniwkU3F+PNYJyfSE9yGX8tMGbXrkEW9mAzAh39igr2+Bbzi9WPTRp4RDVM0qw+eyMmQRPWKt7FeanDtP+OcdVp0Hf2aPzsgmgTdS6s0AboUq1rX53H2M6F8xAiwPrBJXDQ=
+example.com.   3600    IN      NS      ns.example.com.
+example.com.   3600    IN      RRSIG   NS 8 2 3600 20121126123249 20121029123249 64050 example.com. cpLjgKPacNxVIGo59tYMZ98GVYpH28WHRWj3AeIHK0StYFcAlflGLdkae1LEgMwfUmzrayrA5GMe3AH8LyuTgA2Dn1oNFxGfuShQvK2MFQ+LxvQfiuoqlAlL5Aa94IWcSoU/wLrr66I1K8oSB2yK1Tyyv73c2N40D1mBbzIE70U=
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.y.z.wc.example.com. IN A
+SECTION ANSWER
+x.y.z.wc.example.com.  3600    IN      CNAME   x.y.z.end.example.com.
+x.y.z.wc.example.com.  3600    IN      RRSIG   CNAME 8 3 3600 20121126123316 20121029123316 64050 example.com. BCnT6CIuqvF1U9LfiHIovgvXIVFJsCXqQWmnjHtbFvzUlTlfGj+56YBSOEpyCep4CBJ0CBgZ8gl5kWip8N+sTlveU/UWMv4FAkqLXRYjp4CZegslmJIuXU5uS+Q0GlLbWdSB9ZCZcbbO0qrOtUfrJ2ozcSTCS+D+oIZ+CkwvDlQ=
+x.y.z.end.example.com. 3600    IN      A       1.2.3.5
+x.y.z.end.example.com. 3600    IN      RRSIG   A 8 3 3600 20121126123249 20121029123249 64050 example.com. MyXXd3MvXtEYVNqWDepM3+Ra/j/b63QehzSHXZe5gL954WxW8KGHPYmeWyhDtruThpZS6s6jeARY2xt0lmEDnMgNyPJGA6UWwTIgvGD0u9Qw5kocCq3ZH4cSG4xu4rmZoi+h8OGrHxUb4jIKzipzAQDxhnAcp/wKF7e+p+OE+Fo=
+SECTION AUTHORITY
+isjq5aarcp8p5sukc56g961cccjus5u2.example.com.  86400   IN      NSEC3   1 0 1 abcd  isoaarjsq14bkqaamivn1t1milkv95lc A RRSIG 
+isjq5aarcp8p5sukc56g961cccjus5u2.example.com.  86400   IN      RRSIG   NSEC3 8 3 86400 20121126123259 20121029123259 64050 example.com. Cxwzq1DUQvhkTVHEJHlb92c511Y+uJy/C0yL9br6W/5lB/usuSiK2DjW58ibPh2kLH1P3SpGqd1Y7LigptdXoPBDFakcNcimPWCN93R3J80+vrHHPkPyIsBaywwYI3SNGgfnHfPF+wmH+tZ1vfEHbigOxqPFK+T0ntKq7dkSndg=
+a61sejfu6am5a36p628t4s089s309o44.example.com.  86400   IN      NSEC3   1 0 1 abcd  a64lt5ij9a1up15h5cdsn1u2071901hu A RRSIG 
+a61sejfu6am5a36p628t4s089s309o44.example.com.  86400   IN      RRSIG   NSEC3 8 3 86400 20121126123315 20121029123315 64050 example.com. gfBu4oqo9cVxJbqrw2Ly7mK638kGPOF8l8eh7ovalniwkU3F+PNYJyfSE9yGX8tMGbXrkEW9mAzAh39igr2+Bbzi9WPTRp4RDVM0qw+eyMmQRPWKt7FeanDtP+OcdVp0Hf2aPzsgmgTdS6s0AboUq1rX53H2M6F8xAiwPrBJXDQ=
+example.com.   3600    IN      NS      ns.example.com.
+example.com.   3600    IN      RRSIG   NS 8 2 3600 20121126123249 20121029123249 64050 example.com. cpLjgKPacNxVIGo59tYMZ98GVYpH28WHRWj3AeIHK0StYFcAlflGLdkae1LEgMwfUmzrayrA5GMe3AH8LyuTgA2Dn1oNFxGfuShQvK2MFQ+LxvQfiuoqlAlL5Aa94IWcSoU/wLrr66I1K8oSB2yK1Tyyv73c2N40D1mBbzIE70U=
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGING
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+x.y.z.end.example.com. IN A
+SECTION ANSWER
+x.y.z.end.example.com. 3600    IN      A       1.2.3.5
+x.y.z.end.example.com. 3600    IN      RRSIG   A 8 3 3600 20121126123249 20121029123249 64050 example.com. MyXXd3MvXtEYVNqWDepM3+Ra/j/b63QehzSHXZe5gL954WxW8KGHPYmeWyhDtruThpZS6s6jeARY2xt0lmEDnMgNyPJGA6UWwTIgvGD0u9Qw5kocCq3ZH4cSG4xu4rmZoi+h8OGrHxUb4jIKzipzAQDxhnAcp/wKF7e+p+OE+Fo=
+SECTION AUTHORITY
+a61sejfu6am5a36p628t4s089s309o44.example.com.  86400   IN      NSEC3   1 0 1 abcd  a64lt5ij9a1up15h5cdsn1u2071901hu A RRSIG 
+a61sejfu6am5a36p628t4s089s309o44.example.com.  86400   IN      RRSIG   NSEC3 8 3 86400 20121126123315 20121029123315 64050 example.com. gfBu4oqo9cVxJbqrw2Ly7mK638kGPOF8l8eh7ovalniwkU3F+PNYJyfSE9yGX8tMGbXrkEW9mAzAh39igr2+Bbzi9WPTRp4RDVM0qw+eyMmQRPWKt7FeanDtP+OcdVp0Hf2aPzsgmgTdS6s0AboUq1rX53H2M6F8xAiwPrBJXDQ=
+example.com.   3600    IN      NS      ns.example.com.
+example.com.   3600    IN      RRSIG   NS 8 2 3600 20121126123249 20121029123249 64050 example.com. cpLjgKPacNxVIGo59tYMZ98GVYpH28WHRWj3AeIHK0StYFcAlflGLdkae1LEgMwfUmzrayrA5GMe3AH8LyuTgA2Dn1oNFxGfuShQvK2MFQ+LxvQfiuoqlAlL5Aa94IWcSoU/wLrr66I1K8oSB2yK1Tyyv73c2N40D1mBbzIE70U=
+SECTION ADDITIONAL
+ns.example.com.        3600    IN      A       1.2.3.4
+ns.example.com.        3600    IN      RRSIG   A 8 2 3600 20121126123249 20121029123249 64050 example.com. zxGyimwFsd39j8T7jJ+tSAQPwZ7tjk6HHmzosTMCRePM4k4newbLb5HbrpucSiW/plaEZvjRTDTJ6bPkw0msPXjPCI/22Zh236XO5vhGtMOlxDgAEazuhifVF6UsM7GZwONPBCvw705HgWQyCR1YlTK2w9ffH3GopU9f4oP7Pmk=
+ENTRY_END
+RANGE_END
+
+
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+start.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+start.example.com. IN A
+SECTION ANSWER
+start.example.com.     3600    IN      CNAME   x.y.z.wc.example.com.
+start.example.com.     3600    IN      RRSIG   CNAME 8 3 3600 20121126123316 20121029123316 64050 example.com. LHpx5n++Z0Jgjjalac+e7wdYSbfurqSDpLRAOI1PybTJkwrMvgDKfp0ycT4HwsLVy7spumZ/Ahg/5II9pai7jCiqv1Iyh6fx19ZVeClTFMOLotCK8xMHACYJIY39BhTwD2D3r9BxbK+RopUlXypwV02yzdY2xEnPCBJVDUn5d0g=
+x.y.z.wc.example.com.  3600    IN      CNAME   x.y.z.end.example.com.
+x.y.z.wc.example.com.  3600    IN      RRSIG   CNAME 8 3 3600 20121126123316 20121029123316 64050 example.com. BCnT6CIuqvF1U9LfiHIovgvXIVFJsCXqQWmnjHtbFvzUlTlfGj+56YBSOEpyCep4CBJ0CBgZ8gl5kWip8N+sTlveU/UWMv4FAkqLXRYjp4CZegslmJIuXU5uS+Q0GlLbWdSB9ZCZcbbO0qrOtUfrJ2ozcSTCS+D+oIZ+CkwvDlQ=
+x.y.z.end.example.com. 3600    IN      A       1.2.3.5
+x.y.z.end.example.com. 3600    IN      RRSIG   A 8 3 3600 20121126123249 20121029123249 64050 example.com. MyXXd3MvXtEYVNqWDepM3+Ra/j/b63QehzSHXZe5gL954WxW8KGHPYmeWyhDtruThpZS6s6jeARY2xt0lmEDnMgNyPJGA6UWwTIgvGD0u9Qw5kocCq3ZH4cSG4xu4rmZoi+h8OGrHxUb4jIKzipzAQDxhnAcp/wKF7e+p+OE+Fo=
+SECTION AUTHORITY
+isjq5aarcp8p5sukc56g961cccjus5u2.example.com.  86400   IN      NSEC3   1 0 1 abcd  isoaarjsq14bkqaamivn1t1milkv95lc A RRSIG 
+isjq5aarcp8p5sukc56g961cccjus5u2.example.com.  86400   IN      RRSIG   NSEC3 8 3 86400 20121126123259 20121029123259 64050 example.com. Cxwzq1DUQvhkTVHEJHlb92c511Y+uJy/C0yL9br6W/5lB/usuSiK2DjW58ibPh2kLH1P3SpGqd1Y7LigptdXoPBDFakcNcimPWCN93R3J80+vrHHPkPyIsBaywwYI3SNGgfnHfPF+wmH+tZ1vfEHbigOxqPFK+T0ntKq7dkSndg=
+a61sejfu6am5a36p628t4s089s309o44.example.com.  86400   IN      NSEC3   1 0 1 abcd  a64lt5ij9a1up15h5cdsn1u2071901hu A RRSIG 
+a61sejfu6am5a36p628t4s089s309o44.example.com.  86400   IN      RRSIG   NSEC3 8 3 86400 20121126123315 20121029123315 64050 example.com. gfBu4oqo9cVxJbqrw2Ly7mK638kGPOF8l8eh7ovalniwkU3F+PNYJyfSE9yGX8tMGbXrkEW9mAzAh39igr2+Bbzi9WPTRp4RDVM0qw+eyMmQRPWKt7FeanDtP+OcdVp0Hf2aPzsgmgTdS6s0AboUq1rX53H2M6F8xAiwPrBJXDQ=
+example.com.   3600    IN      NS      ns.example.com.
+example.com.   3600    IN      RRSIG   NS 8 2 3600 20121126123249 20121029123249 64050 example.com. cpLjgKPacNxVIGo59tYMZ98GVYpH28WHRWj3AeIHK0StYFcAlflGLdkae1LEgMwfUmzrayrA5GMe3AH8LyuTgA2Dn1oNFxGfuShQvK2MFQ+LxvQfiuoqlAlL5Aa94IWcSoU/wLrr66I1K8oSB2yK1Tyyv73c2N40D1mBbzIE70U=
+SECTION ADDITIONAL
+ns.example.com.        3600    IN      A       1.2.3.4
+ns.example.com.        3600    IN      RRSIG   A 8 2 3600 20121126123249 20121029123249 64050 example.com. zxGyimwFsd39j8T7jJ+tSAQPwZ7tjk6HHmzosTMCRePM4k4newbLb5HbrpucSiW/plaEZvjRTDTJ6bPkw0msPXjPCI/22Zh236XO5vhGtMOlxDgAEazuhifVF6UsM7GZwONPBCvw705HgWQyCR1YlTK2w9ffH3GopU9f4oP7Pmk=
+ENTRY_END
+
+SCENARIO_END
diff --git a/testdata/val_nsec3_entnodata_optout.rpl b/testdata/val_nsec3_entnodata_optout.rpl
new file mode 100644 (file)
index 0000000..56ed195
--- /dev/null
@@ -0,0 +1,200 @@
+; config options
+; The island of trust is at example.com
+server:
+       trust-anchor: "example.com.    3600    IN      DS      2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+       val-override-date: "20070916134226"
+       target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with NSEC3 response for NODATA ENT with optout. 
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+       ADDRESS 193.0.14.129 
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS        K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET.    IN      A       193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com.   IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.    IN      A       192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+       ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com.    IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.     IN      A       192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN A
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com.    IN NS   ns.example.com.
+example.com.    3600    IN      RRSIG   NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com.         IN      A       1.2.3.4
+ns.example.com. 3600    IN      RRSIG   A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com.    3600    IN      DNSKEY  256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com.    3600    IN      RRSIG   DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+example.com.    3600    IN      RRSIG   NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+ns.example.com. 3600    IN      RRSIG   A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com.   IN SOA  ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
+example.com.    3600    IN      RRSIG   SOA 3 2 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCM6lsu9byZIQ1yYjJmyYfFWM2RWAIUcR5t84r2La824oWCkLjmHXRQlco= ;{id = 2854}
+
+; NODATA response. H(www.example.com.) = s1unhcti19bkdr98fegs0v46mbu3t4m3
+s1unhcti19bkdr98fegs0v46mbu3t4m3.example.com. IN NSEC3  1 1 123 aabb00123456bbccdd s1unhcti19bkdr98fegs0v46mbu3t4m4 MX RRSIG
+s1unhcti19bkdr98fegs0v46mbu3t4m3.example.com.   3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MCwCFE/a24nsY2luhQmZjY/ObAIgNSMkAhQWd4MUOUVK55bD6AbMHWrDA0yvEA== ;{id = 2854}
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ent.example.com. IN DS
+SECTION AUTHORITY
+; example.com. -> b6fuorg741ufili49mg9j4328ig53sqg.
+; OPTOUT
+b6fuorg741ufili49mg9j4328ig53sqg.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd b6fuorg741ufili49mg9j4328ig54sqg NS SOA DNSKEY RRSIG
+b6fuorg741ufili49mg9j4328ig53sqg.example.com.  3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AHNLlpOM8cBFBBdzUO9nQC/O6mw3rDUrqcdiSwMKAIckd3k5WZvoP78=
+
+; ent.example.com. -> 2kekcu37chvrqjb272ptidu9jhk8oqag.
+; OPTOUT SPAN around it
+2kekcu37chvrqjb272ptidu9jhk7oqag.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 2kekcu37chvrqjb272ptidu9jhk9oqag
+2kekcu37chvrqjb272ptidu9jhk7oqag.example.com.  3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AFgtC3UEm/Tu4HIjfDHIDmZkvgwHF0kWKcD3wP2hs+/wOfaILtXBr4c=
+ENTRY_END
+
+; refer to server one down
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ent.example.com. IN A
+SECTION AUTHORITY
+; example.com. -> b6fuorg741ufili49mg9j4328ig53sqg.
+; OPTOUT
+b6fuorg741ufili49mg9j4328ig53sqg.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd b6fuorg741ufili49mg9j4328ig54sqg NS SOA DNSKEY RRSIG
+b6fuorg741ufili49mg9j4328ig53sqg.example.com.  3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AHNLlpOM8cBFBBdzUO9nQC/O6mw3rDUrqcdiSwMKAIckd3k5WZvoP78=
+
+; ent.example.com. -> 2kekcu37chvrqjb272ptidu9jhk8oqag.
+; OPTOUT SPAN around it
+2kekcu37chvrqjb272ptidu9jhk7oqag.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 2kekcu37chvrqjb272ptidu9jhk9oqag
+2kekcu37chvrqjb272ptidu9jhk7oqag.example.com.  3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AFgtC3UEm/Tu4HIjfDHIDmZkvgwHF0kWKcD3wP2hs+/wOfaILtXBr4c=
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+ent.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+ent.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+b6fuorg741ufili49mg9j4328ig53sqg.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd b6fuorg741ufili49mg9j4328ig54sqg NS SOA DNSKEY RRSIG
+b6fuorg741ufili49mg9j4328ig53sqg.example.com.  3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AHNLlpOM8cBFBBdzUO9nQC/O6mw3rDUrqcdiSwMKAIckd3k5WZvoP78=
+2kekcu37chvrqjb272ptidu9jhk7oqag.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 2kekcu37chvrqjb272ptidu9jhk9oqag
+2kekcu37chvrqjb272ptidu9jhk7oqag.example.com.  3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AFgtC3UEm/Tu4HIjfDHIDmZkvgwHF0kWKcD3wP2hs+/wOfaILtXBr4c=
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/testdata/val_nsec3_entnodata_optout_badopt.rpl b/testdata/val_nsec3_entnodata_optout_badopt.rpl
new file mode 100644 (file)
index 0000000..d1548f5
--- /dev/null
@@ -0,0 +1,196 @@
+; config options
+; The island of trust is at example.com
+server:
+       trust-anchor: "example.com.    3600    IN      DS      2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+       val-override-date: "20070916134226"
+       target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with NSEC3 response for NODATA ENT with optout. 
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+       ADDRESS 193.0.14.129 
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS        K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET.    IN      A       193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com.   IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.    IN      A       192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+       ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com.    IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.     IN      A       192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN A
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com.    IN NS   ns.example.com.
+example.com.    3600    IN      RRSIG   NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com.         IN      A       1.2.3.4
+ns.example.com. 3600    IN      RRSIG   A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com.    3600    IN      DNSKEY  256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com.    3600    IN      RRSIG   DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+example.com.    3600    IN      RRSIG   NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+ns.example.com. 3600    IN      RRSIG   A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com.   IN SOA  ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
+example.com.    3600    IN      RRSIG   SOA 3 2 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCM6lsu9byZIQ1yYjJmyYfFWM2RWAIUcR5t84r2La824oWCkLjmHXRQlco= ;{id = 2854}
+
+; NODATA response. H(www.example.com.) = s1unhcti19bkdr98fegs0v46mbu3t4m3
+s1unhcti19bkdr98fegs0v46mbu3t4m3.example.com. IN NSEC3  1 1 123 aabb00123456bbccdd s1unhcti19bkdr98fegs0v46mbu3t4m4 MX RRSIG
+s1unhcti19bkdr98fegs0v46mbu3t4m3.example.com.   3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MCwCFE/a24nsY2luhQmZjY/ObAIgNSMkAhQWd4MUOUVK55bD6AbMHWrDA0yvEA== ;{id = 2854}
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ent.example.com. IN DS
+SECTION AUTHORITY
+; example.com. -> b6fuorg741ufili49mg9j4328ig53sqg.
+; OPTOUT
+b6fuorg741ufili49mg9j4328ig53sqg.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd b6fuorg741ufili49mg9j4328ig54sqg NS SOA DNSKEY RRSIG
+b6fuorg741ufili49mg9j4328ig53sqg.example.com.  3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AHNLlpOM8cBFBBdzUO9nQC/O6mw3rDUrqcdiSwMKAIckd3k5WZvoP78=
+
+; ent.example.com. -> 2kekcu37chvrqjb272ptidu9jhk8oqag.
+; the span does not have OPTOUT
+2kekcu37chvrqjb272ptidu9jhk7oqag.example.com. IN NSEC3 1 0 123 aabb00123456bbccdd 2kekcu37chvrqjb272ptidu9jhk9oqag
+2kekcu37chvrqjb272ptidu9jhk7oqag.example.com.  3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AAaGjBrmbElksOWsOAU0vdNwbRKsbsQgOwhFkONaynSk9M+2QpJQ6+k=
+ENTRY_END
+
+; refer to server one down
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ent.example.com. IN A
+SECTION AUTHORITY
+; example.com. -> b6fuorg741ufili49mg9j4328ig53sqg.
+; OPTOUT
+b6fuorg741ufili49mg9j4328ig53sqg.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd b6fuorg741ufili49mg9j4328ig54sqg NS SOA DNSKEY RRSIG
+b6fuorg741ufili49mg9j4328ig53sqg.example.com.  3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AHNLlpOM8cBFBBdzUO9nQC/O6mw3rDUrqcdiSwMKAIckd3k5WZvoP78=
+
+; ent.example.com. -> 2kekcu37chvrqjb272ptidu9jhk8oqag.
+; the span does not have OPTOUT
+2kekcu37chvrqjb272ptidu9jhk7oqag.example.com. IN NSEC3 1 0 123 aabb00123456bbccdd 2kekcu37chvrqjb272ptidu9jhk9oqag
+2kekcu37chvrqjb272ptidu9jhk7oqag.example.com.  3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AAaGjBrmbElksOWsOAU0vdNwbRKsbsQgOwhFkONaynSk9M+2QpJQ6+k=
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+ent.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO SERVFAIL
+SECTION QUESTION
+ent.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
diff --git a/testdata/val_nsec3_entnodata_optout_match.rpl b/testdata/val_nsec3_entnodata_optout_match.rpl
new file mode 100644 (file)
index 0000000..329db5f
--- /dev/null
@@ -0,0 +1,200 @@
+; config options
+; The island of trust is at example.com
+server:
+       trust-anchor: "example.com.    3600    IN      DS      2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+       val-override-date: "20070916134226"
+       target-fetch-policy: "0 0 0 0 0"
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator NODATA ENT with nsec3 optout matches the ent. 
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+       ADDRESS 193.0.14.129 
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS        K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET.    IN      A       193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com.   IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.    IN      A       192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+       ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com.    IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.     IN      A       192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN A
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com.    IN NS   ns.example.com.
+example.com.    3600    IN      RRSIG   NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com.         IN      A       1.2.3.4
+ns.example.com. 3600    IN      RRSIG   A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com.    3600    IN      DNSKEY  256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com.    3600    IN      RRSIG   DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+example.com.    3600    IN      RRSIG   NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+ns.example.com. 3600    IN      RRSIG   A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com.   IN SOA  ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
+example.com.    3600    IN      RRSIG   SOA 3 2 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCM6lsu9byZIQ1yYjJmyYfFWM2RWAIUcR5t84r2La824oWCkLjmHXRQlco= ;{id = 2854}
+
+; NODATA response. H(www.example.com.) = s1unhcti19bkdr98fegs0v46mbu3t4m3
+s1unhcti19bkdr98fegs0v46mbu3t4m3.example.com. IN NSEC3  1 1 123 aabb00123456bbccdd s1unhcti19bkdr98fegs0v46mbu3t4m4 MX RRSIG
+s1unhcti19bkdr98fegs0v46mbu3t4m3.example.com.   3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MCwCFE/a24nsY2luhQmZjY/ObAIgNSMkAhQWd4MUOUVK55bD6AbMHWrDA0yvEA== ;{id = 2854}
+
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+ent.example.com. IN DS
+SECTION AUTHORITY
+; example.com. -> b6fuorg741ufili49mg9j4328ig53sqg.
+; OPTOUT
+b6fuorg741ufili49mg9j4328ig53sqg.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd b6fuorg741ufili49mg9j4328ig54sqg NS SOA DNSKEY RRSIG
+b6fuorg741ufili49mg9j4328ig53sqg.example.com.  3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AHNLlpOM8cBFBBdzUO9nQC/O6mw3rDUrqcdiSwMKAIckd3k5WZvoP78=
+
+; ent.example.com. -> 2kekcu37chvrqjb272ptidu9jhk8oqag.
+; OPTOUT
+2kekcu37chvrqjb272ptidu9jhk8oqag.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 2kekcu37chvrqjb272ptidu9jhk9oqag
+2kekcu37chvrqjb272ptidu9jhk8oqag.example.com.  3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AJl6kanB5RTIcTJysEzDUNqQAr0ftIqzGzQw2+v8RLEbn3Yhi1bEfOQ=
+ENTRY_END
+
+; refer to server one down
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+ent.example.com. IN A
+SECTION AUTHORITY
+; example.com. -> b6fuorg741ufili49mg9j4328ig53sqg.
+; OPTOUT
+b6fuorg741ufili49mg9j4328ig53sqg.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd b6fuorg741ufili49mg9j4328ig54sqg NS SOA DNSKEY RRSIG
+b6fuorg741ufili49mg9j4328ig53sqg.example.com.  3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AHNLlpOM8cBFBBdzUO9nQC/O6mw3rDUrqcdiSwMKAIckd3k5WZvoP78=
+
+; ent.example.com. -> 2kekcu37chvrqjb272ptidu9jhk8oqag.
+; OPTOUT
+2kekcu37chvrqjb272ptidu9jhk8oqag.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 2kekcu37chvrqjb272ptidu9jhk9oqag
+2kekcu37chvrqjb272ptidu9jhk8oqag.example.com.  3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AJl6kanB5RTIcTJysEzDUNqQAr0ftIqzGzQw2+v8RLEbn3Yhi1bEfOQ=
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+ent.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+ent.example.com. IN A
+SECTION ANSWER
+SECTION AUTHORITY
+b6fuorg741ufili49mg9j4328ig53sqg.example.com.   3600    IN      NSEC3   1 1 123 aabb00123456bbccdd  b6fuorg741ufili49mg9j4328ig54sqg NS SOA RRSIG DNSKEY 
+b6fuorg741ufili49mg9j4328ig53sqg.example.com.   3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AHNLlpOM8cBFBBdzUO9nQC/O6mw3rDUrqcdiSwMKAIckd3k5WZvoP78=
+2kekcu37chvrqjb272ptidu9jhk8oqag.example.com.   3600    IN      NSEC3   1 1 123 aabb00123456bbccdd  2kekcu37chvrqjb272ptidu9jhk9oqag
+2kekcu37chvrqjb272ptidu9jhk8oqag.example.com.   3600    IN      RRSIG   NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AJl6kanB5RTIcTJysEzDUNqQAr0ftIqzGzQw2+v8RLEbn3Yhi1bEfOQ=
+SECTION ADDITIONAL
+ENTRY_END
+
+SCENARIO_END
index b21b3d7d61498e47ff451bf7e8452f4a714bf873..cca2d8f594da29eced590b77edf383d8e19ae89f 100644 (file)
@@ -1091,9 +1091,9 @@ cfg_convert_timeval(const char* str)
 int 
 cfg_count_numbers(const char* s)
 {
-       /* format ::= (sp num)+ sp      */
-       /* num ::= [-](0-9)+        */
-       /* sp ::= (space|tab)*    */
+       /* format ::= (sp num)+ sp  */
+       /* num ::= [-](0-9)+        */
+       /* sp ::= (space|tab)*      */
        int num = 0;
        while(*s) {
                while(*s && isspace((int)*s))
index 0b910e61241878b59a3edacdf6d1c8b982b64abb..d6d2ceedf0895e27f28a30cb281859700a1d2bf8 100644 (file)
 4486,
 4488,
 4500,
+4534,
 4535,
 4536,
 4537,
 4743,
 4744,
 4745,
+4747,
 4749,
 4750,
 4751,
 5050,
 5051,
 5052,
+5053,
 5055,
 5056,
 5057,
 5632,
 5633,
 5634,
+5670,
 5671,
 5672,
 5673,
 6769,
 6770,
 6771,
+6784,
 6785,
 6786,
 6787,
 8763,
 8764,
 8765,
+8766,
 8770,
 8786,
 8787,
 9217,
 9222,
 9255,
+9277,
 9278,
 9279,
 9280,
 10805,
 10810,
 10860,
+10880,
 10990,
 11000,
 11001,
 13929,
 14000,
 14001,
+14002,
 14033,
 14034,
 14141,
 19539,
 19540,
 19541,
+19788,
 19999,
 20000,
 20001,
 24242,
 24249,
 24321,
+24322,
 24386,
 24465,
 24554,
 27999,
 28000,
 28119,
+28200,
 28240,
 29167,
 30001,
 42508,
 42509,
 42510,
+43000,
 43188,
 43189,
 43190,
 43441,
 44321,
 44322,
-44323,
 44544,
 44553,
 44600,
 45966,
 46999,
 47000,
+47100,
 47557,
 47624,
 47806,
index 46077b516e14cd6a5d68b2cf55e265f7acda5bd6..460233fbbcddb308e0d476ce6cba55b52bcda116 100644 (file)
@@ -778,9 +778,12 @@ void ub_openssl_lock_delete(void)
        int i;
        if(!ub_openssl_locks)
                return;
+       CRYPTO_set_id_callback(NULL);
+       CRYPTO_set_locking_callback(NULL);
        for(i=0; i<CRYPTO_num_locks(); i++) {
                lock_basic_destroy(&ub_openssl_locks[i]);
        }
+       free(ub_openssl_locks);
 #endif /* OPENSSL_THREADS */
 }
 
index 38a79662239a1595d4bbe7f7c5cfc1fbaddaa90a..139511c5d437968bcf4ed4c78745d246116a57ea 100644 (file)
@@ -1023,6 +1023,13 @@ validate_cname_response(struct module_env* env, struct val_env* ve,
                        chase_reply->security = sec_status_bogus;
                        return;
                }
+
+               /* If we have found a CNAME, stop looking for one.
+                * The iterator has placed the CNAME chain in correct
+                * order. */
+               if (ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME) {
+                       break;
+               }
        }
 
        /* AUTHORITY section */