ldns: Update vendor branch to 1.6.11
authorJan Lentfer <Jan.Lentfer@web.de>
Mon, 28 Nov 2011 09:57:30 +0000 (10:57 +0100)
committerJan Lentfer <Jan.Lentfer@web.de>
Mon, 28 Nov 2011 09:57:30 +0000 (10:57 +0100)
This fixes a severe bug (CVE-2011-3581)

36 files changed:
contrib/ldns/Changelog
contrib/ldns/README
contrib/ldns/dnssec.c
contrib/ldns/dnssec_sign.c
contrib/ldns/dnssec_verify.c
contrib/ldns/dnssec_zone.c
contrib/ldns/drill/dnssec.c
contrib/ldns/drill/securetrace.c
contrib/ldns/error.c
contrib/ldns/higher.c
contrib/ldns/host2str.c
contrib/ldns/host2wire.c
contrib/ldns/keys.c
contrib/ldns/ldns/buffer.h
contrib/ldns/ldns/common.h
contrib/ldns/ldns/dnssec.h
contrib/ldns/ldns/dnssec_sign.h
contrib/ldns/ldns/dnssec_verify.h
contrib/ldns/ldns/dnssec_zone.h
contrib/ldns/ldns/error.h
contrib/ldns/ldns/host2str.h
contrib/ldns/ldns/keys.h
contrib/ldns/ldns/rr.h
contrib/ldns/ldns/sha2.h
contrib/ldns/ldns/zone.h
contrib/ldns/net.c
contrib/ldns/parse.c
contrib/ldns/resolver.c
contrib/ldns/rr.c
contrib/ldns/rr_functions.c
contrib/ldns/sha2.c
contrib/ldns/str2host.c
contrib/ldns/tsig.c
contrib/ldns/update.c
contrib/ldns/util.c
contrib/ldns/zone.c

index ffbcb3f..240acde 100644 (file)
@@ -1,3 +1,80 @@
+1.6.11 2011-09-29
+       * bugfix #394: Fix socket leak on errors
+       * bugfix #392: Apex only and percentage checks for ldns-verify-zone 
+         (thanks Miek Gieben)
+       * bugfix #398: Allow NSEC RRSIGs before the NSEC3 in ldns-verify-zone
+       * Fix python site package path from sitelib to sitearch for pyldns.
+       * Fix python api to support python2 and python3 (thanks Karel Slany).
+       * bugfix #401: Correction of date/time functions algorithm and 
+         prevention of an infinite loop therein
+       * bugfix #402: Correct the minimum and maximum number of rdata fields
+         in TSIG. (thanks David Keeler)
+       * bugfix #403: Fix heap overflow (thanks David Keeler)
+       * bugfix #404: Make parsing APL strings more robust
+         (thanks David Keeler)
+       * bugfix #391: Complete library assessment to prevent assertion errors
+                 through ldns_rdf_size usage.
+       * Slightly more specific error messaging on wrong number of rdata
+         fields with the LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG and
+         LDNS_STATUS_MISSING_RDATA_FIELDS_KEY result codes.
+       * bugfix #406: More rigorous openssl result code handling to prevent
+         future crashes within openssl.
+       * Fix ldns_fetch_valid_domain_keys to search deeper than just one level
+          for a DNSKEY that signed a DS RR. (this function was used in the
+         check_dnssec_trace nagios module)
+       * bugfix #407: Canonicalize TSIG dnames and algorithm fields
+       * A new output specifier to accommodate configuration of what to show
+         in comment texts when converting host and/or wire-format data to
+         string. All conversion to string and printing functions have a new
+         version that have such a format specifier as an extra argument.
+         The default is changed so that only DNSKEY RR's are annotated with 
+         an comment show the Key Tag of the DNSKEY.
+       * Fixed the ldns resolver to not mark a nameserver unreachable when
+         edns0 is tried unsuccessfully with size 4096 (no return packet came),
+         but to still try TCP. A big UDP packet might have been corrupted by 
+         fragments dropping firewalls.
+       * Update of libdns.vim (thanks Miek Gieben)
+       * Added the ldnsx Python module to our contrib section, which adds even
+         more pythonisticism to the usage of ldns with  Python. (Many thanks 
+         to Christpher Olah and Paul Wouters)
+         The ldnsx module is automatically installed when --with-pyldns is
+         used with configuring, but may explicitly be excluded with the
+         --without-pyldnsx option to configure.
+       * bugfix #410: Fix clearing out temporary data on stack in sha2.c
+       * bugfix #411: Don't let empty non-terminal NSEC3s cause assertion failure.
+
+1.6.10 2011-05-31
+       * New example tool added: ldns-gen-zone.
+       * bugfix #359: Serial-arithmetic for the inception and expiration
+         fields of a RRSIG and correctly converting them to broken-out time
+         information.
+       * bugfix #364: Slight performance increase of ldns-verifyzone.
+       * bugfix #367: Fix to allow glue records with the same name as the
+         delegation.
+       * Fix ldns-verifyzone to allow NSEC3-less records for NS rrsets *and* 
+         glue when the zone is opt-out.
+       * bugfix #376: Adapt ldns_nsec3_salt, ldns_nsec3_iterations, 
+         ldns_nsec3_flags and ldns_nsec3_algorithm to work for NSEC3PARAMS too.
+       * pyldns memory leaks fixed by Bedrich Kosata (at the cost of a bit
+         performance)
+       * Better handling of reference variables in ldns_rr_new_frm_fp_l from
+         pyldns, with a very nice generator function by Bedrich Kosata.
+       * Decoupling of the rdfs in rrs in the python wrappers to enable
+         the python garbage collector by Bedrich Kosata.
+       * bugfix #380: Minimizing effect of discrepancies in sizeof(bool) at
+         build time and when used.
+       * bugfix #383: Fix detection of empty nonterminals of multiple labels.
+       * Fixed the ommission of rrsets in nsec(3)s and rrsigs to all occluded
+         names (in stead of just the ones that contain glue only) and all
+         occluded records on the delegation points (in stead of just the glue).
+       * Clarify the operation of ldns_dnssec_mark_glue and the usage of
+         ldns_dnssec_node_next_nonglue functions in the documentation.
+       * Added function ldns_dnssec_mark_and_get_glue as an real fast
+         alternative for ldns_zone_glue_rr_list.
+       * Fix parse buffer overflow for max length domain names.
+       * Fix Makefile for U in environment, since wrong U is more common than
+         deansification necessity.
+
 1.6.9  2011-03-16
        * Fix creating NSEC(3) bitmaps: make array size 65536,
          don't add doubles.
index 74e470a..70eb3dc 100644 (file)
@@ -8,6 +8,8 @@ Contents:
        INFORMATION FOR SPECIFIC OPERATING SYSTEMS
                Mac OS X
                Solaris
+       KNOWN ISSUES
+               pyldns
         Your Support
 
 Project page:
@@ -65,6 +67,7 @@ commands may be a little bit different on your machine. Most notable, you'll nee
 * Developers
 ldns is developed by the ldns team at NLnet Labs. This team currently
 consists of:
+  o Willem Toorop
   o Wouter Wijngaards
   o Matthijs Mekking
 
@@ -74,6 +77,7 @@ Former main developers:
 
 * Credits
 We have received patches from the following people, thanks!
+  o Bedrich Kosata
   o Erik Rozendaal
   o Håkan Olsson
   o Jakob Schlyter
@@ -82,7 +86,7 @@ We have received patches from the following people, thanks!
   o Ondřej Surý
 
 
-IFORMATION FOR SPECIFIC OPERATING SYSTEMS
+INFORMATION FOR SPECIFIC OPERATING SYSTEMS
 
 MAC OS X
 
@@ -103,6 +107,17 @@ compile in 64-bit mode. Jakob Schlyter has kindly contributed a build
 script that sets the right build and link options. You can find it in
 contrib/build-solaris.sh
 
+KNOWN ISSUES
+
+A complete list of currently known open issues can be found here:
+http://www.nlnetlabs.nl/projects/ldns/bugs
+
+* pyldns
+Compiling pyldns produces many ``unused parameter'' warnings.  Those are
+harmless and may safely be ignored.
+Also when building with Swig which version is before 2.0.4, compiling
+pyldns produces many ``missing initializer'' warnings. Those are harmless
+too.
 
 Your Support
 NLnet Labs offers all of its software products as open source, most are
index ce02ef3..b36e3f3 100644 (file)
@@ -536,6 +536,9 @@ ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
                return NULL;
 #endif
 #ifdef USE_ECDSA
+               /* Make similar ``not implemented'' construct as above when 
+                  draft-hoffman-dnssec-ecdsa-04 becomes a standard
+                */
        case LDNS_SHA384:
                digest = LDNS_XMALLOC(uint8_t, SHA384_DIGEST_LENGTH);
                if (!digest) {
@@ -543,10 +546,6 @@ ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
                        return NULL;
                }
                 break;
-#else
-               /* not implemented */
-               ldns_rr_free(ds);
-               return NULL;
 #endif
        }
 
@@ -565,7 +564,14 @@ ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
        ldns_rr_push_rdf(ds, tmp);
 
        /* copy the algorithm field */
-       ldns_rr_push_rdf(ds, ldns_rdf_clone( ldns_rr_rdf(key, 2))); 
+       if ((tmp = ldns_rr_rdf(key, 2)) == NULL) {
+               LDNS_FREE(digest);
+               ldns_buffer_free(data_buf);
+               ldns_rr_free(ds);
+               return NULL;
+       } else {
+               ldns_rr_push_rdf(ds, ldns_rdf_clone( tmp )); 
+       }
 
        /* digest hash type */
        sha1hash = (uint8_t)h;
@@ -764,20 +770,6 @@ ldns_dnssec_rrsets_contains_type(ldns_dnssec_rrsets *rrsets,
        return 0;
 }
 
-/* returns true if the current dnssec_rrset from the given list of rrsets
- * is glue */
-static int
-is_glue(ldns_dnssec_rrsets *cur_rrsets, ldns_dnssec_rrsets *orig_rrsets)
-{
-       /* only glue if a or aaaa if there are no ns, unless there is soa */
-       return (cur_rrsets->type == LDNS_RR_TYPE_A ||
-               cur_rrsets->type ==  LDNS_RR_TYPE_AAAA) &&
-               (ldns_dnssec_rrsets_contains_type(orig_rrsets,
-                     LDNS_RR_TYPE_NS) &&
-               !ldns_dnssec_rrsets_contains_type(orig_rrsets,
-                     LDNS_RR_TYPE_SOA));
-}
-
 ldns_rr *
 ldns_dnssec_create_nsec(ldns_dnssec_name *from,
                         ldns_dnssec_name *to,
@@ -787,9 +779,9 @@ ldns_dnssec_create_nsec(ldns_dnssec_name *from,
        ldns_rr_type types[65536];
        size_t type_count = 0;
        ldns_dnssec_rrsets *cur_rrsets;
+       int on_delegation_point;
 
-       if (!from || !to || (nsec_type != LDNS_RR_TYPE_NSEC &&
-                                        nsec_type != LDNS_RR_TYPE_NSEC3)) {
+       if (!from || !to || (nsec_type != LDNS_RR_TYPE_NSEC)) {
                return NULL;
        }
 
@@ -798,14 +790,22 @@ ldns_dnssec_create_nsec(ldns_dnssec_name *from,
        ldns_rr_set_owner(nsec_rr, ldns_rdf_clone(ldns_dnssec_name_name(from)));
        ldns_rr_push_rdf(nsec_rr, ldns_rdf_clone(ldns_dnssec_name_name(to)));
 
+       on_delegation_point = ldns_dnssec_rrsets_contains_type(
+                       from->rrsets, LDNS_RR_TYPE_NS)
+               && !ldns_dnssec_rrsets_contains_type(
+                       from->rrsets, LDNS_RR_TYPE_SOA);
+
        cur_rrsets = from->rrsets;
        while (cur_rrsets) {
-               if (is_glue(cur_rrsets, from->rrsets)) {
-                       cur_rrsets = cur_rrsets->next;
-                       continue;
-               }
-               if (cur_rrsets->type != LDNS_RR_TYPE_RRSIG &&
-                   cur_rrsets->type != LDNS_RR_TYPE_NSEC) {
+               /* Do not include non-authoritative rrsets on the delegation point
+                * in the type bitmap */
+               if ((on_delegation_point && (
+                               cur_rrsets->type == LDNS_RR_TYPE_NS 
+                            || cur_rrsets->type == LDNS_RR_TYPE_DS))
+                       || (!on_delegation_point &&
+                               cur_rrsets->type != LDNS_RR_TYPE_RRSIG
+                            && cur_rrsets->type != LDNS_RR_TYPE_NSEC)) {
+
                        types[type_count] = cur_rrsets->type;
                        type_count++;
                }
@@ -839,6 +839,7 @@ ldns_dnssec_create_nsec3(ldns_dnssec_name *from,
        size_t type_count = 0;
        ldns_dnssec_rrsets *cur_rrsets;
        ldns_status status;
+       int on_delegation_point;
 
        flags = flags;
 
@@ -865,13 +866,24 @@ ldns_dnssec_create_nsec3(ldns_dnssec_name *from,
                                  salt_length,
                                  salt);
 
+       on_delegation_point = ldns_dnssec_rrsets_contains_type(
+                       from->rrsets, LDNS_RR_TYPE_NS)
+               && !ldns_dnssec_rrsets_contains_type(
+                       from->rrsets, LDNS_RR_TYPE_SOA);
        cur_rrsets = from->rrsets;
        while (cur_rrsets) {
-               if (is_glue(cur_rrsets, from->rrsets)) {
-                       cur_rrsets = cur_rrsets->next;
-                       continue;
-               }
-               if (cur_rrsets->type != LDNS_RR_TYPE_RRSIG) {
+               /* Do not include non-authoritative rrsets on the delegation point
+                * in the type bitmap. Potentionally not skipping insecure
+                * delegation should have been done earlier, in function
+                * ldns_dnssec_zone_create_nsec3s, or even earlier in:
+                * ldns_dnssec_zone_sign_nsec3_flg .
+                */
+               if ((on_delegation_point && (
+                               cur_rrsets->type == LDNS_RR_TYPE_NS
+                            || cur_rrsets->type == LDNS_RR_TYPE_DS))
+                       || (!on_delegation_point &&
+                               cur_rrsets->type != LDNS_RR_TYPE_RRSIG)) {
+
                        types[type_count] = cur_rrsets->type;
                        type_count++;
                }
@@ -1199,9 +1211,11 @@ ldns_create_nsec3(ldns_rdf *cur_owner,
 uint8_t
 ldns_nsec3_algorithm(const ldns_rr *nsec3_rr)
 {
-       if (nsec3_rr && ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 &&
-           ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 0)) > 0
-           ) {
+       if (nsec3_rr && 
+             (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
+              ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
+           && (ldns_rr_rdf(nsec3_rr, 0) != NULL)
+           && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 0)) > 0) {
                return ldns_rdf2native_int8(ldns_rr_rdf(nsec3_rr, 0));
        }
        return 0;
@@ -1210,9 +1224,11 @@ ldns_nsec3_algorithm(const ldns_rr *nsec3_rr)
 uint8_t
 ldns_nsec3_flags(const ldns_rr *nsec3_rr)
 {
-       if (nsec3_rr && ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 &&
-           ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 1)) > 0
-           ) {
+       if (nsec3_rr && 
+             (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
+              ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
+           && (ldns_rr_rdf(nsec3_rr, 1) != NULL)
+           && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 1)) > 0) {
                return ldns_rdf2native_int8(ldns_rr_rdf(nsec3_rr, 1));
        }
        return 0;
@@ -1227,9 +1243,11 @@ ldns_nsec3_optout(const ldns_rr *nsec3_rr)
 uint16_t
 ldns_nsec3_iterations(const ldns_rr *nsec3_rr)
 {
-       if (nsec3_rr && ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 &&
-           ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 2)) > 0
-           ) {
+       if (nsec3_rr &&
+             (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
+              ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
+           && (ldns_rr_rdf(nsec3_rr, 2) != NULL)
+           && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 2)) > 0) {
                return ldns_rdf2native_int16(ldns_rr_rdf(nsec3_rr, 2));
        }
        return 0;
@@ -1239,7 +1257,10 @@ ldns_nsec3_iterations(const ldns_rr *nsec3_rr)
 ldns_rdf *
 ldns_nsec3_salt(const ldns_rr *nsec3_rr)
 {
-       if (nsec3_rr && ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3) {
+       if (nsec3_rr && 
+             (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
+              ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
+           ) {
                return ldns_rr_rdf(nsec3_rr, 3);
        }
        return NULL;
@@ -1326,8 +1347,12 @@ ldns_nsec_bitmap_covers_type(const ldns_rdf *nsec_bitmap, ldns_rr_type type)
        uint16_t cur_type;
        uint16_t pos = 0;
        uint16_t bit_pos;
-       uint8_t *data = ldns_rdf_data(nsec_bitmap);
+       uint8_t *data;
 
+       if (nsec_bitmap == NULL) {
+               return false;
+       }
+       data = ldns_rdf_data(nsec_bitmap);
        while(pos < ldns_rdf_size(nsec_bitmap)) {
                window_block_nr = data[pos];
                bitmap_length = data[pos + 1];
@@ -1359,7 +1384,11 @@ ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name)
        bool result;
 
        if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC) {
-               nsec_next = ldns_rdf_clone(ldns_rr_rdf(nsec, 0));
+               if (ldns_rr_rdf(nsec, 0) != NULL) {
+                       nsec_next = ldns_rdf_clone(ldns_rr_rdf(nsec, 0));
+               } else {
+                       return false;
+               }
        } else if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC3) {
                hash_next = ldns_nsec3_next_owner(nsec);
                next_hash_str = ldns_rdf2str(hash_next);
index b210944..8e65d22 100644 (file)
@@ -522,59 +522,148 @@ ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
 }
 #endif /* HAVE_SSL */
 
-static int
-ldns_dnssec_name_has_only_a(ldns_dnssec_name *cur_name)
+/**
+ * Pushes all rrs from the rrsets of type A and AAAA on gluelist.
+ */
+static ldns_status
+ldns_dnssec_addresses_on_glue_list(
+               ldns_dnssec_rrsets *cur_rrset,
+               ldns_rr_list *glue_list)
 {
-       ldns_dnssec_rrsets *cur_rrset;
-       cur_rrset = cur_name->rrsets;
+       ldns_dnssec_rrs *cur_rrs;
        while (cur_rrset) {
-               if (cur_rrset->type != LDNS_RR_TYPE_A &&
-                       cur_rrset->type != LDNS_RR_TYPE_AAAA) {
-                       return 0;
-               } else {
-                       cur_rrset = cur_rrset->next;
+               if (cur_rrset->type == LDNS_RR_TYPE_A 
+                               || cur_rrset->type == LDNS_RR_TYPE_AAAA) {
+                       for (cur_rrs = cur_rrset->rrs; 
+                                       cur_rrs; 
+                                       cur_rrs = cur_rrs->next) {
+                               if (cur_rrs->rr) {
+                                       if (!ldns_rr_list_push_rr(glue_list, 
+                                                       cur_rrs->rr)) {
+                                               return LDNS_STATUS_MEM_ERR; 
+                                               /* ldns_rr_list_push_rr()
+                                                * returns false when unable
+                                                * to increase the capacity
+                                                * of the ldsn_rr_list
+                                                */
+                                       }
+                               }
+                       }
                }
+               cur_rrset = cur_rrset->next;
        }
-       return 1;
+       return LDNS_STATUS_OK;
 }
 
+/**
+ * Marks the names in the zone that are occluded. Those names will be skipped
+ * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
+ * function. But watch out! Names that are partially occluded (like glue with
+ * the same name as the delegation) will not be marked and should specifically 
+ * be taken into account seperately.
+ *
+ * When glue_list is given (not NULL), in the process of marking the names, all
+ * glue resource records will be pushed to that list, even glue at delegation names.
+ *
+ * \param[in] zone the zone in which to mark the names
+ * \param[in] glue_list the list to which to push the glue rrs
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
 ldns_status
-ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
+ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone, 
+       ldns_rr_list *glue_list)
 {
-       ldns_rbnode_t *cur_node;
-       ldns_dnssec_name *cur_name;
-       ldns_rdf *cur_owner, *cur_parent;
+       ldns_rbnode_t    *node;
+       ldns_dnssec_name *name;
+       ldns_rdf         *owner;
+       ldns_rdf         *cut = NULL; /* keeps track of zone cuts */
+       /* When the cut is caused by a delegation, below_delegation will be 1.
+        * When caused by a DNAME, below_delegation will be 0.
+        */
+       int below_delegation = -1; /* init suppresses comiler warning */
+       ldns_status s;
 
-       cur_node = ldns_rbtree_first(zone->names);
-       while (cur_node != LDNS_RBTREE_NULL) {
-               cur_name = (ldns_dnssec_name *) cur_node->data;
-               cur_node = ldns_rbtree_next(cur_node);
-               if (ldns_dnssec_name_has_only_a(cur_name)) {
-                       /* assume glue XXX check for zone cur */
-                       cur_owner = ldns_rdf_clone(ldns_rr_owner(
-                                             cur_name->rrsets->rrs->rr));
-                       while (ldns_dname_label_count(cur_owner) >
-                                 ldns_dname_label_count(zone->soa->name)) {
-                               if (ldns_dnssec_zone_find_rrset(zone,
-                                                                                 cur_owner,
-                                                                                 LDNS_RR_TYPE_NS)) {
-                                       /*
-                                       fprintf(stderr, "[XX] Marking as glue: ");
-                                       ldns_rdf_print(stderr, cur_name->name);
-                                       fprintf(stderr, "\n");
-                                       */
-                                       cur_name->is_glue = true;
+       if (!zone || !zone->names) {
+               return LDNS_STATUS_NULL;
+       }
+       for (node = ldns_rbtree_first(zone->names); 
+                       node != LDNS_RBTREE_NULL; 
+                       node = ldns_rbtree_next(node)) {
+               name = (ldns_dnssec_name *) node->data;
+               owner = ldns_dnssec_name_name(name);
+
+               if (cut) { 
+                       /* The previous node was a zone cut, or a subdomain
+                        * below a zone cut. Is this node (still) a subdomain
+                        * below the cut? Then the name is occluded. Unless
+                        * the name contains a SOA, after which we are 
+                        * authoritative again.
+                        *
+                        * FIXME! If there are labels in between the SOA and
+                        * the cut, going from the authoritative space (below
+                        * the SOA) up into occluded space again, will not be
+                        * detected with the contruct below!
+                        */
+                       if (ldns_dname_is_subdomain(owner, cut) &&
+                                       !ldns_dnssec_rrsets_contains_type(
+                                       name->rrsets, LDNS_RR_TYPE_SOA)) {
+
+                               if (below_delegation && glue_list) {
+                                       s = ldns_dnssec_addresses_on_glue_list(
+                                               name->rrsets, glue_list);
+                                       if (s != LDNS_STATUS_OK) {
+                                               return s;
+                                       }
+                               }
+                               name->is_glue = true; /* Mark occluded name! */
+                               continue;
+                       } else {
+                               cut = NULL;
+                       }
+               }
+
+               /* The node is not below a zone cut. Is it a zone cut itself?
+                * Everything below a SOA is authoritative of course; Except
+                * when the name also contains a DNAME :).
+                */
+               if (ldns_dnssec_rrsets_contains_type(
+                               name->rrsets, LDNS_RR_TYPE_NS)
+                           && !ldns_dnssec_rrsets_contains_type(
+                               name->rrsets, LDNS_RR_TYPE_SOA)) {
+                       cut = owner;
+                       below_delegation = 1;
+                       if (glue_list) { /* record glue on the zone cut */
+                               s = ldns_dnssec_addresses_on_glue_list(
+                                       name->rrsets, glue_list);
+                               if (s != LDNS_STATUS_OK) {
+                                       return s;
                                }
-                               cur_parent = ldns_dname_left_chop(cur_owner);
-                               ldns_rdf_deep_free(cur_owner);
-                               cur_owner = cur_parent;
                        }
-                       ldns_rdf_deep_free(cur_owner);
+               } else if (ldns_dnssec_rrsets_contains_type(
+                               name->rrsets, LDNS_RR_TYPE_DNAME)) {
+                       cut = owner;
+                       below_delegation = 0;
                }
        }
        return LDNS_STATUS_OK;
 }
 
+/**
+ * Marks the names in the zone that are occluded. Those names will be skipped
+ * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
+ * function. But watch out! Names that are partially occluded (like glue with
+ * the same name as the delegation) will not be marked and should specifically 
+ * be taken into account seperately.
+ *
+ * \param[in] zone the zone in which to mark the names
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status
+ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
+{
+       return ldns_dnssec_zone_mark_and_get_glue(zone, NULL);
+}
+
 ldns_rbnode_t *
 ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
 {
@@ -620,9 +709,9 @@ ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
        /* did the caller actually set it? if not,
         * fall back to default ttl
         */
-       if (soa && soa->rrs && soa->rrs->rr) {
-               nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(
-                                                    soa->rrs->rr, 6));
+       if (soa && soa->rrs && soa->rrs->rr
+                       && (ldns_rr_rdf(soa->rrs->rr, 6) != NULL)) {
+               nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
        } else {
                nsec_ttl = LDNS_DEFAULT_TTL;
        }
@@ -676,14 +765,18 @@ ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
 }
 
 #ifdef HAVE_SSL
+/* in dnssec_zone.c */
+extern int ldns_dname_compare_v(const void *a, const void *b);
+
 ldns_status
-ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
-                                                ldns_rr_list *new_rrs,
-                                                uint8_t algorithm,
-                                                uint8_t flags,
-                                                uint16_t iterations,
-                                                uint8_t salt_length,
-                                                uint8_t *salt)
+ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
+               ldns_rr_list *new_rrs,
+               uint8_t algorithm,
+               uint8_t flags,
+               uint16_t iterations,
+               uint8_t salt_length,
+               uint8_t *salt,
+               ldns_rbtree_t **map)
 {
        ldns_rbnode_t *first_name_node;
        ldns_rbnode_t *current_name_node;
@@ -693,6 +786,7 @@ ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
        ldns_rr_list *nsec3_list;
        uint32_t nsec_ttl;
        ldns_dnssec_rrsets *soa;
+       ldns_rbnode_t *hashmap_node;
 
        if (!zone || !new_rrs || !zone->names) {
                return LDNS_STATUS_ERR;
@@ -706,13 +800,19 @@ ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
        /* did the caller actually set it? if not,
         * fall back to default ttl
         */
-       if (soa && soa->rrs && soa->rrs->rr) {
-               nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(
-                                                    soa->rrs->rr, 6));
+       if (soa && soa->rrs && soa->rrs->rr
+                       && ldns_rr_rdf(soa->rrs->rr, 6) != NULL) {
+               nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
        } else {
                nsec_ttl = LDNS_DEFAULT_TTL;
        }
 
+       if (map) {
+               if ((*map = ldns_rbtree_create(ldns_dname_compare_v)) 
+                               == NULL) {
+                       map = NULL;
+               };
+       }
        nsec3_list = ldns_rr_list_new();
 
        first_name_node = ldns_dnssec_name_node_next_nonglue(
@@ -740,6 +840,18 @@ ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
                result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
                ldns_rr_list_push_rr(new_rrs, nsec_rr);
                ldns_rr_list_push_rr(nsec3_list, nsec_rr);
+               if (map) {
+                       hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
+                       if (hashmap_node && ldns_rr_owner(nsec_rr)) {
+                               hashmap_node->key = ldns_dname_label(
+                                       ldns_rr_owner(nsec_rr), 0);
+                               if (hashmap_node->key) {
+                                       hashmap_node->data = current_name->name;
+                                       (void) ldns_rbtree_insert(
+                                                       *map, hashmap_node);
+                               }
+                       }
+               }
                current_name_node = ldns_dnssec_name_node_next_nonglue(
                                   ldns_rbtree_next(current_name_node));
        }
@@ -756,6 +868,20 @@ ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
        ldns_rr_list_free(nsec3_list);
        return result;
 }
+
+ldns_status
+ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
+               ldns_rr_list *new_rrs,
+               uint8_t algorithm,
+               uint8_t flags,
+               uint16_t iterations,
+               uint8_t salt_length,
+               uint8_t *salt)
+{
+       return ldns_dnssec_zone_create_nsec3s_mkmap(zone, new_rrs, algorithm,
+                       flags, iterations, salt_length, salt, NULL);
+
+}
 #endif /* HAVE_SSL */
 
 ldns_dnssec_rrs *
@@ -915,6 +1041,8 @@ ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
 
        size_t i;
 
+       int on_delegation_point = 0; /* handle partially occluded names */
+
        ldns_rr_list *pubkey_list = ldns_rr_list_new();
        zone = zone;
        new_rrs = new_rrs;
@@ -930,6 +1058,10 @@ ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
                cur_name = (ldns_dnssec_name *) cur_node->data;
 
                if (!cur_name->is_glue) {
+                       on_delegation_point = ldns_dnssec_rrsets_contains_type(
+                                       cur_name->rrsets, LDNS_RR_TYPE_NS)
+                               && !ldns_dnssec_rrsets_contains_type(
+                                       cur_name->rrsets, LDNS_RR_TYPE_SOA);
                        cur_rrset = cur_name->rrsets;
                        while (cur_rrset) {
                                /* reset keys to use */
@@ -959,20 +1091,15 @@ ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
                                }
 
                                /* only sign non-delegation RRsets */
-                               /* (glue should have been marked earlier) */
-                               if ((ldns_rr_list_type(rr_list) != LDNS_RR_TYPE_NS ||
-                                       ldns_dname_compare(ldns_rr_list_owner(rr_list),
-                                       zone->soa->name) == 0) &&
-                                       /* OK, there is also the possibility that the record
-                                        * is glue, but at the same owner name as other records that
-                                        * are not NS nor A/AAAA. Bleh, our current data structure
-                                        * doesn't really support that... */
-                                       !((ldns_rr_list_type(rr_list) == LDNS_RR_TYPE_A ||
-                                        ldns_rr_list_type(rr_list) == LDNS_RR_TYPE_AAAA) &&
-                                        !ldns_dname_compare(ldns_rr_list_owner(rr_list), zone->soa->name) == 0 &&
-                                        ldns_dnssec_zone_find_rrset(zone, ldns_rr_list_owner(rr_list), LDNS_RR_TYPE_NS)
-                                        )) {
-
+                               /* (glue should have been marked earlier, 
+                                *  except on the delegation points itself) */
+                               if (!on_delegation_point ||
+                                               ldns_rr_list_type(rr_list) 
+                                                       == LDNS_RR_TYPE_DS ||
+                                               ldns_rr_list_type(rr_list) 
+                                                       == LDNS_RR_TYPE_NSEC ||
+                                               ldns_rr_list_type(rr_list) 
+                                                       == LDNS_RR_TYPE_NSEC3) {
                                        siglist = ldns_sign_public(rr_list, key_list);
                                        for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
                                                if (cur_rrset->signatures) {
@@ -1092,24 +1219,26 @@ ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
                                           uint8_t salt_length,
                                           uint8_t *salt)
 {
-       return ldns_dnssec_zone_sign_nsec3_flg(zone, new_rrs, key_list,
-               func, arg, algorithm, flags, iterations, salt_length, salt, 0);
+       return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
+               func, arg, algorithm, flags, iterations, salt_length, salt, 0,
+               NULL);
 }
 
 ldns_status
-ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
-                                          ldns_rr_list *new_rrs,
-                                          ldns_key_list *key_list,
-                                          int (*func)(ldns_rr *, void *),
-                                          void *arg,
-                                          uint8_t algorithm,
-                                          uint8_t flags,
-                                          uint16_t iterations,
-                                          uint8_t salt_length,
-                                          uint8_t *salt,
-                                          int signflags)
+ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
+               ldns_rr_list *new_rrs,
+               ldns_key_list *key_list,
+               int (*func)(ldns_rr *, void *),
+               void *arg,
+               uint8_t algorithm,
+               uint8_t flags,
+               uint16_t iterations,
+               uint8_t salt_length,
+               uint8_t *salt,
+               int signflags,
+               ldns_rbtree_t **map)
 {
-       ldns_rr *nsec3, *nsec3params;
+       ldns_rr *nsec3, *nsec3param;
        ldns_status result = LDNS_STATUS_OK;
 
        /* zone is already sorted */
@@ -1134,13 +1263,13 @@ ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
                } else {
                        if (!ldns_dnssec_zone_find_rrset(zone,
                                                                           zone->soa->name,
-                                                                          LDNS_RR_TYPE_NSEC3PARAMS)) {
-                               /* create and add the nsec3params rr */
-                               nsec3params =
-                                       ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAMS);
-                               ldns_rr_set_owner(nsec3params,
+                                                                          LDNS_RR_TYPE_NSEC3PARAM)) {
+                               /* create and add the nsec3param rr */
+                               nsec3param =
+                                       ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAM);
+                               ldns_rr_set_owner(nsec3param,
                                                           ldns_rdf_clone(zone->soa->name));
-                               ldns_nsec3_add_param_rdfs(nsec3params,
+                               ldns_nsec3_add_param_rdfs(nsec3param,
                                                                         algorithm,
                                                                         flags,
                                                                         iterations,
@@ -1148,20 +1277,21 @@ ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
                                                                         salt);
                                /* always set bit 7 of the flags to zero, according to
                                 * rfc5155 section 11 */
-                               ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3params, 1)), 7, 0);
-                               result = ldns_dnssec_zone_add_rr(zone, nsec3params);
+                               ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3param, 1)), 7, 0);
+                               result = ldns_dnssec_zone_add_rr(zone, nsec3param);
                                if (result != LDNS_STATUS_OK) {
                                        return result;
                                }
-                               ldns_rr_list_push_rr(new_rrs, nsec3params);
+                               ldns_rr_list_push_rr(new_rrs, nsec3param);
                        }
-                       result = ldns_dnssec_zone_create_nsec3s(zone,
+                       result = ldns_dnssec_zone_create_nsec3s_mkmap(zone,
                                                                                        new_rrs,
                                                                                        algorithm,
                                                                                        flags,
                                                                                        iterations,
                                                                                        salt_length,
-                                                                                       salt);
+                                                                                       salt,
+                                                                                       map);
                        if (result != LDNS_STATUS_OK) {
                                return result;
                        }
@@ -1178,6 +1308,23 @@ ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
        return result;
 }
 
+ldns_status
+ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
+               ldns_rr_list *new_rrs,
+               ldns_key_list *key_list,
+               int (*func)(ldns_rr *, void *),
+               void *arg,
+               uint8_t algorithm,
+               uint8_t flags,
+               uint16_t iterations,
+               uint8_t salt_length,
+               uint8_t *salt,
+               int signflags)
+{
+       return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
+               func, arg, algorithm, flags, iterations, salt_length, salt,
+               signflags, NULL);
+}
 
 ldns_zone *
 ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
@@ -1267,3 +1414,4 @@ ldns_zone_sign_nsec3(ldns_zone *zone, ldns_key_list *key_list, uint8_t algorithm
 }
 #endif /* HAVE_SSL */
 
+
index 352e440..4e51df7 100644 (file)
 ldns_dnssec_data_chain *
 ldns_dnssec_data_chain_new()
 {
-       ldns_dnssec_data_chain *nc = LDNS_XMALLOC(ldns_dnssec_data_chain, 1);
+       ldns_dnssec_data_chain *nc = LDNS_CALLOC(ldns_dnssec_data_chain, 1);
         if(!nc) return NULL;
+       /* 
+        * not needed anymore because CALLOC initalizes everything to zero.
+
        nc->rrset = NULL;
        nc->parent_type = 0;
        nc->parent = NULL;
@@ -27,6 +30,8 @@ ldns_dnssec_data_chain_new()
        nc->packet_rcode = 0;
        nc->packet_qtype = 0;
        nc->packet_nodata = false;
+
+        */
        return nc;
 }
 
@@ -48,12 +53,13 @@ ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain)
 }
 
 void
-ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain)
+ldns_dnssec_data_chain_print_fmt(FILE *out, const ldns_output_format *fmt,
+               const ldns_dnssec_data_chain *chain)
 {
        ldns_lookup_table *rcode;
        const ldns_rr_descriptor *rr_descriptor;
        if (chain) {
-               ldns_dnssec_data_chain_print(out, chain->parent);
+               ldns_dnssec_data_chain_print_fmt(out, fmt, chain->parent);
                if (ldns_rr_list_rr_count(chain->rrset) > 0) {
                        rcode = ldns_lookup_by_id(ldns_rcodes,
                                                                 (int) chain->packet_rcode);
@@ -72,15 +78,22 @@ ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain)
                                fprintf(out, ";; NODATA response\n");
                        }
                        fprintf(out, "rrset:\n");
-                       ldns_rr_list_print(out, chain->rrset);
+                       ldns_rr_list_print_fmt(out, fmt, chain->rrset);
                        fprintf(out, "sigs:\n");
-                       ldns_rr_list_print(out, chain->signatures);
+                       ldns_rr_list_print_fmt(out, fmt, chain->signatures);
                        fprintf(out, "---\n");
                } else {
                        fprintf(out, "<no data>\n");
                }
        }
 }
+void
+ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain)
+{
+       ldns_dnssec_data_chain_print_fmt(
+                       out, ldns_output_format_default, chain);
+}
+
 
 static void
 ldns_dnssec_build_data_chain_dnskey(ldns_resolver *res,
@@ -482,12 +495,13 @@ print_tabs(FILE *out, size_t nr, uint8_t *map, size_t treedepth)
 }
 
 void
-ldns_dnssec_trust_tree_print_sm(FILE *out,
-                                                 ldns_dnssec_trust_tree *tree,
-                                                 size_t tabs,
-                                                 bool extended,
-                                                 uint8_t *sibmap,
-                                                 size_t treedepth)
+ldns_dnssec_trust_tree_print_sm_fmt(FILE *out, 
+               const ldns_output_format *fmt,
+               ldns_dnssec_trust_tree *tree,
+               size_t tabs,
+               bool extended,
+               uint8_t *sibmap,
+               size_t treedepth)
 {
        size_t i;
        const ldns_rr_descriptor *descriptor;
@@ -583,18 +597,22 @@ ldns_dnssec_trust_tree_print_sm(FILE *out,
                                                        ERR_print_errors_fp(stdout);
                                                        printf("\n");
                                                }
-                                               ldns_rr_print(out, tree->parent_signature[i]);
+                                               ldns_rr_print_fmt(out, fmt, 
+                                                       tree->
+                                                       parent_signature[i]);
                                                printf("For RRset:\n");
-                                               ldns_rr_list_print(out, tree->rrset);
+                                               ldns_rr_list_print_fmt(out, fmt,
+                                                               tree->rrset);
                                                printf("With key:\n");
-                                               ldns_rr_print(out, tree->parents[i]->rr);
+                                               ldns_rr_print_fmt(out, fmt,
+                                                       tree->parents[i]->rr);
                                        }
-                               ldns_dnssec_trust_tree_print_sm(out,
-                                                                                 tree->parents[i],
-                                                                                 tabs+1,
-                                                                                 extended,
-                                                                                 sibmap,
-                                                                                 treedepth);
+                               ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
+                                               tree->parents[i],
+                                               tabs+1,
+                                               extended,
+                                               sibmap,
+                                               treedepth);
                        }
                } else {
                        print_tabs(out, tabs, sibmap, treedepth);
@@ -609,15 +627,39 @@ ldns_dnssec_trust_tree_print_sm(FILE *out,
        }
 }
 
+void
+ldns_dnssec_trust_tree_print_sm(FILE *out, 
+               ldns_dnssec_trust_tree *tree,
+               size_t tabs,
+               bool extended,
+               uint8_t *sibmap,
+               size_t treedepth)
+{
+       ldns_dnssec_trust_tree_print_sm_fmt(out, ldns_output_format_default, 
+                       tree, tabs, extended, sibmap, treedepth);
+}
+
+void
+ldns_dnssec_trust_tree_print_fmt(FILE *out, const ldns_output_format *fmt,
+               ldns_dnssec_trust_tree *tree,
+               size_t tabs,
+               bool extended)
+{
+       ldns_dnssec_trust_tree_print_sm_fmt(out, fmt, 
+                       tree, tabs, extended, NULL, 0);
+}
+
 void
 ldns_dnssec_trust_tree_print(FILE *out,
-                                           ldns_dnssec_trust_tree *tree,
-                                           size_t tabs,
-                                           bool extended)
+               ldns_dnssec_trust_tree *tree,
+               size_t tabs,
+               bool extended)
 {
-       ldns_dnssec_trust_tree_print_sm(out, tree, tabs, extended, NULL, 0);
+       ldns_dnssec_trust_tree_print_fmt(out, ldns_output_format_default, 
+                       tree, tabs, extended);
 }
 
+
 ldns_status
 ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree,
                                   const ldns_dnssec_trust_tree *parent,
@@ -1075,6 +1117,9 @@ ldns_fetch_valid_domain_keys(const ldns_resolver *res,
 {
        ldns_rr_list * trusted_keys = NULL;
        ldns_rr_list * ds_keys = NULL;
+       ldns_rdf * prev_parent_domain;
+       ldns_rdf *      parent_domain;
+       ldns_rr_list * parent_keys = NULL;
 
        if (res && domain && keys) {
 
@@ -1085,11 +1130,10 @@ ldns_fetch_valid_domain_keys(const ldns_resolver *res,
                } else {
                        /* No trusted keys in this domain, we'll have to find some in the parent domain */
                        *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
-      
-                       if (ldns_rdf_size(domain) > 1) {
+
+                       parent_domain = ldns_dname_left_chop(domain);
+                       while (ldns_rdf_size(parent_domain) > 0) {
                                /* Fail if we are at the root */
-                               ldns_rr_list * parent_keys;
-                               ldns_rdf * parent_domain = ldns_dname_left_chop(domain);
        
                                if ((parent_keys = 
                                        ldns_fetch_valid_domain_keys(res,
@@ -1112,9 +1156,16 @@ ldns_fetch_valid_domain_keys(const ldns_resolver *res,
                                                *status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DS ;
                                        }
                                        ldns_rr_list_deep_free(parent_keys);
+                                       break;
+                               } else {
+                                       parent_domain = ldns_dname_left_chop((
+                                               prev_parent_domain 
+                                                       = parent_domain
+                                               ));
+                                       ldns_rdf_deep_free(prev_parent_domain);
                                }
-                               ldns_rdf_deep_free(parent_domain);
                        }
+                       ldns_rdf_deep_free(parent_domain);
                }
        }
        return trusted_keys;
@@ -1303,12 +1354,7 @@ ldns_verify_trusted(ldns_resolver *res,
                                        }
                                        ldns_rr_list_deep_free(trusted_keys);
                                        return LDNS_STATUS_OK;
-                               } else {
-                                       ldns_rr_list_print(stdout, rrset);
-                                       ldns_rr_print(stdout, cur_sig);
-                                       ldns_rr_print(stdout, cur_key);
-               
-                               }
+                               } 
                        }
                }
        }
@@ -1398,12 +1444,13 @@ ldns_dnssec_verify_denial(ldns_rr *rr,
 
 #ifdef HAVE_SSL
 ldns_status
-ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
+ldns_dnssec_verify_denial_nsec3_match(ldns_rr *rr,
                                                  ldns_rr_list *nsecs,
                                                  ldns_rr_list *rrsigs,
                                                  ldns_pkt_rcode packet_rcode,
                                                  ldns_rr_type packet_qtype,
-                                                 bool packet_nodata)
+                                                 bool packet_nodata,
+                                                 ldns_rr **match)
 {
        ldns_rdf *closest_encloser;
        ldns_rdf *wildcard;
@@ -1416,6 +1463,10 @@ ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
 
        rrsigs = rrsigs;
 
+       if (match) {
+               *match = NULL;
+       }
+
        zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
 
        /* section 8.4 */
@@ -1442,6 +1493,9 @@ ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
                        if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
                                                                 hashed_wildcard_name)) {
                                wildcard_covered = true;
+                               if (match) {
+                                       *match = ldns_rr_list_rr(nsecs, i);
+                               }
                        }
                        ldns_rdf_deep_free(hashed_wildcard_name);
                }
@@ -1474,6 +1528,9 @@ ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
                                            ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
                                            LDNS_RR_TYPE_CNAME)) {
                                        result = LDNS_STATUS_OK;
+                                       if (match) {
+                                               *match = ldns_rr_list_rr(nsecs, i);
+                                       }
                                        goto done;
                                }
                        }
@@ -1500,6 +1557,9 @@ ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
                                            ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
                                            LDNS_RR_TYPE_CNAME)) {
                                        result = LDNS_STATUS_OK;
+                                       if (match) {
+                                               *match = ldns_rr_list_rr(nsecs, i);
+                                       }
                                        goto done;
                                }
                        }
@@ -1513,6 +1573,22 @@ ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
        ldns_rdf_deep_free(zone_name);
        return result;
 }
+
+ldns_status
+ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
+                                                 ldns_rr_list *nsecs,
+                                                 ldns_rr_list *rrsigs,
+                                                 ldns_pkt_rcode packet_rcode,
+                                                 ldns_rr_type packet_qtype,
+                                                 bool packet_nodata)
+{
+       return ldns_dnssec_verify_denial_nsec3_match(
+                               rr, nsecs, rrsigs, packet_rcode,
+                               packet_qtype, packet_nodata, NULL
+              );
+}
+
+
 #endif /* HAVE_SSL */
 
 #ifdef USE_GOST
@@ -1594,7 +1670,11 @@ ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
                 EC_KEY_free(ec);
                 return NULL;
         }
-        EVP_PKEY_assign_EC_KEY(evp_key, ec);
+        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
+               EVP_PKEY_free(evp_key);
+               EC_KEY_free(ec);
+               return NULL;
+       }
         return evp_key;
 }
 
@@ -1714,6 +1794,10 @@ ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
        ldns_rdf *wildcard_name;
        ldns_rdf *wildcard_chopped;
        ldns_rdf *wildcard_chopped_tmp;
+       
+       if ((rrsig == NULL) || ldns_rr_rd_count(rrsig) < 4) {
+               return;
+       }
 
        orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
        label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
@@ -1753,7 +1837,15 @@ ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
 static ldns_status
 ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
 {
-       uint8_t sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
+       uint8_t sig_algo;
+       
+       if (rrsig == NULL) {
+               return LDNS_STATUS_CRYPTO_NO_RRSIG;
+       }
+       if (ldns_rr_rdf(rrsig, 1) == NULL) {
+               return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
+       }
+       sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
        /* check for known and implemented algo's now (otherwise 
         * the function could return a wrong error
         */
@@ -1772,16 +1864,23 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
 #ifdef USE_GOST
        case LDNS_ECC_GOST:
 #endif
-               if (ldns_rdf2buffer_wire(rawsig_buf, 
-                   ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
+               if (ldns_rr_rdf(rrsig, 8) == NULL) {
+                       return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
+               }
+               if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8))
+                               != LDNS_STATUS_OK) {
                        return LDNS_STATUS_MEM_ERR;
                }
                break;
        case LDNS_DSA:
        case LDNS_DSA_NSEC3:
                /* EVP takes rfc2459 format, which is a tad longer than dns format */
-               if (ldns_convert_dsa_rrsig_rdf2asn1(rawsig_buf, 
-                       ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
+               if (ldns_rr_rdf(rrsig, 8) == NULL) {
+                       return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
+               }
+               if (ldns_convert_dsa_rrsig_rdf2asn1(
+                                       rawsig_buf, ldns_rr_rdf(rrsig, 8)) 
+                               != LDNS_STATUS_OK) {
                        /*
                          if (ldns_rdf2buffer_wire(rawsig_buf,
                          ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
@@ -1794,8 +1893,12 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
         case LDNS_ECDSAP384SHA384:
                 /* EVP produces an ASN prefix on the signature, which is
                  * not used in the DNS */
-               if (ldns_convert_ecdsa_rrsig_rdf2asn1(rawsig_buf, 
-                       ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
+               if (ldns_rr_rdf(rrsig, 8) == NULL) {
+                       return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
+               }
+               if (ldns_convert_ecdsa_rrsig_rdf2asn1(
+                                       rawsig_buf, ldns_rr_rdf(rrsig, 8))
+                               != LDNS_STATUS_OK) {
                        return LDNS_STATUS_MEM_ERR;
                 }
                 break;
@@ -1901,7 +2004,15 @@ static ldns_status
 ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 
        ldns_rr* rrsig, ldns_rr* key)
 {
-       uint8_t sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
+       uint8_t sig_algo;
+       
+       if (rrsig == NULL) {
+               return LDNS_STATUS_CRYPTO_NO_RRSIG;
+       }
+       if (ldns_rr_rdf(rrsig, 1) == NULL) {
+               return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
+       }
+       sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
 
        /* before anything, check if the keytags match */
        if (ldns_calc_keytag(key)
@@ -1913,8 +2024,12 @@ ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
 
                /* put the key-data in a buffer, that's the third rdf, with
                 * the base64 encoded key data */
-               if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3)) 
-                       != LDNS_STATUS_OK) {
+               if (ldns_rr_rdf(key, 3) == NULL) {
+                       ldns_buffer_free(key_buf);
+                       return LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
+               }
+               if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3))
+                               != LDNS_STATUS_OK) {
                        ldns_buffer_free(key_buf); 
                        /* returning is bad might screw up
                           good keys later in the list
@@ -1922,7 +2037,11 @@ ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
                        return LDNS_STATUS_ERR;
                }
 
-               if (sig_algo == ldns_rdf2native_int8(ldns_rr_rdf(key, 2))) {
+               if (ldns_rr_rdf(key, 2) == NULL) {
+                       result = LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
+               }
+               else if (sig_algo == ldns_rdf2native_int8(
+                                       ldns_rr_rdf(key, 2))) {
                        result = ldns_verify_rrsig_buffers(rawsig_buf, 
                                verify_buf, key_buf, sig_algo);
                } else {
@@ -2183,12 +2302,15 @@ ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
        ldns_status result;
 
        evp_key = EVP_PKEY_new();
-       EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen));
-       result = ldns_verify_rrsig_evp_raw(sig,
+       if (EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen))) {
+               result = ldns_verify_rrsig_evp_raw(sig,
                                                                siglen,
                                                                rrset,
                                                                evp_key,
                                                                EVP_dss1());
+       } else {
+               result = LDNS_STATUS_SSL_ERR;
+       }
        EVP_PKEY_free(evp_key);
        return result;
 
@@ -2202,12 +2324,15 @@ ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen,
        ldns_status result;
 
        evp_key = EVP_PKEY_new();
-       EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
-       result = ldns_verify_rrsig_evp_raw(sig,
+       if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
+               result = ldns_verify_rrsig_evp_raw(sig,
                                                                siglen,
                                                                rrset,
                                                                evp_key,
                                                                EVP_sha1());
+       } else {
+               result = LDNS_STATUS_SSL_ERR;
+       }
        EVP_PKEY_free(evp_key);
 
        return result;
@@ -2225,12 +2350,15 @@ ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
        ldns_status result;
 
        evp_key = EVP_PKEY_new();
-       EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
-       result = ldns_verify_rrsig_evp_raw(sig,
+       if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
+               result = ldns_verify_rrsig_evp_raw(sig,
                                                                siglen,
                                                                rrset,
                                                                evp_key,
                                                                EVP_sha256());
+       } else {
+               result = LDNS_STATUS_SSL_ERR;
+       }
        EVP_PKEY_free(evp_key);
 
        return result;
@@ -2257,12 +2385,15 @@ ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
        ldns_status result;
 
        evp_key = EVP_PKEY_new();
-       EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
-       result = ldns_verify_rrsig_evp_raw(sig,
+       if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
+               result = ldns_verify_rrsig_evp_raw(sig,
                                                                siglen,
                                                                rrset,
                                                                evp_key,
                                                                EVP_sha512());
+       } else {
+               result = LDNS_STATUS_SSL_ERR;
+       }
        EVP_PKEY_free(evp_key);
 
        return result;
@@ -2289,12 +2420,15 @@ ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
        ldns_status result;
 
        evp_key = EVP_PKEY_new();
-       EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
-       result = ldns_verify_rrsig_evp_raw(sig,
+       if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
+               result = ldns_verify_rrsig_evp_raw(sig,
                                                                siglen,
                                                                rrset,
                                                                evp_key,
                                                                EVP_md5());
+       } else {
+               result = LDNS_STATUS_SSL_ERR;
+       }
        EVP_PKEY_free(evp_key);
 
        return result;
index e2a5fce..89bdf8d 100644 (file)
@@ -78,20 +78,29 @@ ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr)
 }
 
 void
-ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs)
+ldns_dnssec_rrs_print_fmt(FILE *out, const ldns_output_format *fmt,
+              ldns_dnssec_rrs *rrs)
 {
        if (!rrs) {
-               fprintf(out, "<void>");
+               if ((fmt->flags & LDNS_COMMENT_LAYOUT))
+                       fprintf(out, "; <void>");
        } else {
                if (rrs->rr) {
-                       ldns_rr_print(out, rrs->rr);
+                       ldns_rr_print_fmt(out, fmt, rrs->rr);
                }
                if (rrs->next) {
-                       ldns_dnssec_rrs_print(out, rrs->next);
+                       ldns_dnssec_rrs_print_fmt(out, fmt, rrs->next);
                }
        }
 }
 
+void
+ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs)
+{
+       ldns_dnssec_rrs_print_fmt(out, ldns_output_format_default, rrs);
+}
+
+
 ldns_dnssec_rrsets *
 ldns_dnssec_rrsets_new()
 {
@@ -262,34 +271,57 @@ ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr)
 }
 
 void
-ldns_dnssec_rrsets_print_soa(FILE *out,
-                                           ldns_dnssec_rrsets *rrsets,
-                                           bool follow,
-                                           bool show_soa)
+ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
+               ldns_dnssec_rrsets *rrsets,
+               bool follow,
+               bool show_soa)
 {
        if (!rrsets) {
-               fprintf(out, "<void>\n");
+               if ((fmt->flags & LDNS_COMMENT_LAYOUT))
+                       fprintf(out, "; <void>\n");
        } else {
                if (rrsets->rrs &&
                    (show_soa ||
                        ldns_rr_get_type(rrsets->rrs->rr) != LDNS_RR_TYPE_SOA
                    )
                   ) {
-                       ldns_dnssec_rrs_print(out, rrsets->rrs);
+                       ldns_dnssec_rrs_print_fmt(out, fmt, rrsets->rrs);
                        if (rrsets->signatures) {
-                               ldns_dnssec_rrs_print(out, rrsets->signatures);
+                               ldns_dnssec_rrs_print_fmt(out, fmt, 
+                                               rrsets->signatures);
                        }
                }
                if (follow && rrsets->next) {
-                       ldns_dnssec_rrsets_print_soa(out, rrsets->next, follow, show_soa);
+                       ldns_dnssec_rrsets_print_soa_fmt(out, fmt, 
+                                       rrsets->next, follow, show_soa);
                }
        }
 }
 
+void
+ldns_dnssec_rrsets_print_soa(FILE *out,
+               ldns_dnssec_rrsets *rrsets,
+               bool follow,
+               bool show_soa)
+{
+       ldns_dnssec_rrsets_print_soa_fmt(out, ldns_output_format_default,
+                       rrsets, follow, show_soa);
+}
+
+
+void
+ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt,
+               ldns_dnssec_rrsets *rrsets, 
+               bool follow)
+{
+       ldns_dnssec_rrsets_print_soa_fmt(out, fmt, rrsets, follow, true);
+}
+
 void
 ldns_dnssec_rrsets_print(FILE *out, ldns_dnssec_rrsets *rrsets, bool follow)
 {
-       ldns_dnssec_rrsets_print_soa(out, rrsets, follow, true);
+       ldns_dnssec_rrsets_print_fmt(out, ldns_output_format_default, 
+                       rrsets, follow);
 }
 
 ldns_dnssec_name *
@@ -297,10 +329,12 @@ ldns_dnssec_name_new()
 {
        ldns_dnssec_name *new_name;
 
-       new_name = LDNS_MALLOC(ldns_dnssec_name);
+       new_name = LDNS_CALLOC(ldns_dnssec_name, 1);
        if (!new_name) {
                return NULL;
        }
+       /*
+        * not needed anymore because CALLOC initalizes everything to zero.
 
        new_name->name = NULL;
        new_name->rrsets = NULL;
@@ -311,6 +345,7 @@ ldns_dnssec_name_new()
        new_name->is_glue = false;
        new_name->hashed_name = NULL;
 
+        */
        return new_name;
 }
 
@@ -375,6 +410,15 @@ ldns_dnssec_name_name(ldns_dnssec_name *name)
        return NULL;
 }
 
+bool
+ldns_dnssec_name_is_glue(ldns_dnssec_name *name)
+{
+       if (name) {
+               return name->is_glue;
+       }
+       return false;
+}
+
 void
 ldns_dnssec_name_set_name(ldns_dnssec_name *rrset,
                                         ldns_rdf *dname)
@@ -520,33 +564,52 @@ ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
 }
 
 void
-ldns_dnssec_name_print_soa(FILE *out, ldns_dnssec_name *name, bool show_soa)
+ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
+               ldns_dnssec_name *name, 
+               bool show_soa)
 {
        if (name) {
                if(name->rrsets) {
-                       ldns_dnssec_rrsets_print_soa(out, name->rrsets, true, show_soa);
-               } else {
+                       ldns_dnssec_rrsets_print_soa_fmt(out, fmt, 
+                                       name->rrsets, true, show_soa);
+               } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
                        fprintf(out, ";; Empty nonterminal: ");
                        ldns_rdf_print(out, name->name);
                        fprintf(out, "\n");
                }
                if(name->nsec) {
-                       ldns_rr_print(out, name->nsec);
+                       ldns_rr_print_fmt(out, fmt, name->nsec);
                }
                if (name->nsec_signatures) {
-                       ldns_dnssec_rrs_print(out, name->nsec_signatures);
+                       ldns_dnssec_rrs_print_fmt(out, fmt, 
+                                       name->nsec_signatures);
                }
-       } else {
-               fprintf(out, "<void>\n");
+       } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
+               fprintf(out, "<void>\n");
        }
 }
 
+void
+ldns_dnssec_name_print_soa(FILE *out, ldns_dnssec_name *name, bool show_soa)
+{
+       ldns_dnssec_name_print_soa_fmt(out, ldns_output_format_default,
+                      name, show_soa);
+}
+
+void
+ldns_dnssec_name_print_fmt(FILE *out, const ldns_output_format *fmt,
+               ldns_dnssec_name *name)
+{
+       ldns_dnssec_name_print_soa_fmt(out, fmt, name, true);
+}
+
 void
 ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name)
 {
-       ldns_dnssec_name_print_soa(out, name, true);
+       ldns_dnssec_name_print_fmt(out, ldns_output_format_default, name);
 }
 
+
 ldns_dnssec_zone *
 ldns_dnssec_zone_new()
 {
@@ -701,7 +764,9 @@ ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
 #endif /* HAVE_SSL */
 
 void
-ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa)
+ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
+               ldns_rbtree_t *tree, 
+               bool print_soa)
 {
        ldns_rbnode_t *node;
        ldns_dnssec_name *name;
@@ -709,34 +774,54 @@ ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa)
        node = ldns_rbtree_first(tree);
        while (node != LDNS_RBTREE_NULL) {
                name = (ldns_dnssec_name *) node->data;
-               ldns_dnssec_name_print_soa(out, name, print_soa);
-               fprintf(out, ";\n");
+               ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa);
+               if ((fmt->flags & LDNS_COMMENT_LAYOUT))
+                       fprintf(out, ";\n");
                node = ldns_rbtree_next(node);
        }
 }
 
 void
-ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone)
+ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa)
+{
+       ldns_dnssec_zone_names_print_fmt(out, ldns_output_format_default,
+                      tree, print_soa);
+}
+
+void
+ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt,
+              ldns_dnssec_zone *zone)
 {
        if (zone) {
                if (zone->soa) {
-                       fprintf(out, ";; Zone: ");
-                       ldns_rdf_print(out, ldns_dnssec_name_name(zone->soa));
-                       fprintf(out, "\n;\n");
-                       ldns_dnssec_rrsets_print(
-                           out,
-                           ldns_dnssec_name_find_rrset(zone->soa,
-                                                                         LDNS_RR_TYPE_SOA),
-                           false);
-                       fprintf(out, ";\n");
+                       if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
+                               fprintf(out, ";; Zone: ");
+                               ldns_rdf_print(out, ldns_dnssec_name_name(
+                                                       zone->soa));
+                               fprintf(out, "\n;\n");
+                       }
+                       ldns_dnssec_rrsets_print_fmt(out, fmt,
+                                       ldns_dnssec_name_find_rrset(
+                                               zone->soa, 
+                                               LDNS_RR_TYPE_SOA), 
+                                       false);
+                       if ((fmt->flags & LDNS_COMMENT_LAYOUT))
+                               fprintf(out, ";\n");
                }
 
                if (zone->names) {
-                       ldns_dnssec_zone_names_print(out, zone->names, false);
+                       ldns_dnssec_zone_names_print_fmt(out, fmt, 
+                                       zone->names, false);
                }
        }
 }
 
+void
+ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone)
+{
+       ldns_dnssec_zone_print_fmt(out, ldns_output_format_default, zone);
+}
+
 ldns_status
 ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
 {
@@ -789,11 +874,11 @@ ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
                for (i = 1; i < next_label_count - soa_label_count; i++) {
                        lpos = (int)cur_label_count - (int)next_label_count + (int)i;
                        if (lpos >= 0) {
-                               l1 = ldns_dname_label(cur_name, (uint8_t)lpos);
+                               l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos);
                        } else {
                                l1 = NULL;
                        }
-                       l2 = ldns_dname_label(next_name, i);
+                       l2 = ldns_dname_clone_from(next_name, i);
 
                        if (!l1 || ldns_dname_compare(l1, l2) != 0) {
                                /* We have an empty nonterminal, add it to the
@@ -805,7 +890,7 @@ ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
                                }
                                new_name->name = ldns_dname_clone_from(next_name,
                                                                       i);
-                               if (!new_name) {
+                               if (!new_name->name) {
                                        ldns_dnssec_name_free(new_name);
                                        return LDNS_STATUS_MEM_ERR;
                                }
index 930ac7c..030aa3b 100644 (file)
@@ -215,6 +215,7 @@ ldns_verify_denial(ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type, ldns_rr_lis
        } else if( (nsecs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_NSEC3, LDNS_SECTION_ANY_NOQUESTION)) ) {
                 ldns_rr_list* sigs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_RRSIG, LDNS_SECTION_ANY_NOQUESTION);
                 ldns_rr* q = ldns_rr_new();
+               ldns_rr* match = NULL;
                 if(!sigs) return LDNS_STATUS_MEM_ERR;
                 if(!q) return LDNS_STATUS_MEM_ERR;
                 ldns_rr_set_question(q, 1);
@@ -223,7 +224,11 @@ ldns_verify_denial(ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type, ldns_rr_lis
                 if(!ldns_rr_owner(q)) return LDNS_STATUS_MEM_ERR;
                 ldns_rr_set_type(q, type);
                 
-                result = ldns_dnssec_verify_denial_nsec3(q, nsecs, sigs, ldns_pkt_get_rcode(pkt), type, ldns_pkt_ancount(pkt) == 0);
+                /* result = ldns_dnssec_verify_denial_nsec3(q, nsecs, sigs, ldns_pkt_get_rcode(pkt), type, ldns_pkt_ancount(pkt) == 0); */
+                result = ldns_dnssec_verify_denial_nsec3_match(q, nsecs, sigs, ldns_pkt_get_rcode(pkt), type, ldns_pkt_ancount(pkt) == 0, &match);
+               if (result == LDNS_STATUS_OK && match && nsec_rrs && nsec_rr_sigs) {
+                       (void) get_dnssec_rr(pkt, ldns_rr_owner(match), LDNS_RR_TYPE_NSEC3, nsec_rrs, nsec_rr_sigs);
+               }
                 ldns_rr_free(q);
                ldns_rr_list_deep_free(nsecs);
                ldns_rr_list_deep_free(sigs);
index ecc21fd..c08b040 100644 (file)
@@ -263,11 +263,6 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
        for(i = 2 ; i < (ssize_t)labels_count + 2; i++) {
                labels[i] = ldns_dname_left_chop(labels[i - 1]);
        }
-       /* if no servers is given with @, start by asking local resolver */
-       /* first part todo :) */
-       for (i = 0; i < (ssize_t) ldns_resolver_nameserver_count(local_res); i++) {
-               (void) ldns_resolver_push_nameserver(res, ldns_resolver_nameservers(local_res)[i]);
-       }
 
        /* get the nameserver for the label
         * ask: dnskey and ds for the label
index ff240dc..a619502 100644 (file)
@@ -88,6 +88,8 @@ ldns_lookup_table ldns_error_str[] = {
        { LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED, "RR not covered by the given NSEC RRs" },
        { LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED, "wildcard not covered by the given NSEC RRs" },
        { LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND, "original of NSEC3 hashed name could not be found" },
+       { LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG, "The RRSIG has to few rdata fields" },
+       { LDNS_STATUS_MISSING_RDATA_FIELDS_KEY, "The DNSKEY has to few rdata fields" },
        { 0, NULL }
 };
 
index 1563e82..c9eb173 100644 (file)
@@ -310,7 +310,12 @@ ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t)
         uint16_t pos = 0;
         uint16_t bit_pos;
        ldns_rdf *nsec_type_list = ldns_rr_rdf(nsec, 1); 
-       uint8_t *data = ldns_rdf_data(nsec_type_list);
+       uint8_t *data;
+       
+       if (nsec_type_list == NULL) {
+               return false;
+       }
+       data  = ldns_rdf_data(nsec_type_list);
 
        while(pos < ldns_rdf_size(nsec_type_list)) {
                window_block_nr = data[pos];
index 6942f6a..eff1216 100644 (file)
@@ -113,6 +113,22 @@ ldns_lookup_table ldns_opcodes[] = {
         { 0, NULL }
 };
 
+const ldns_output_format   ldns_output_format_nocomments_record = { 0, NULL };
+const ldns_output_format  *ldns_output_format_nocomments 
+                       = &ldns_output_format_nocomments_record;
+const ldns_output_format   ldns_output_format_onlykeyids_record = {
+       LDNS_COMMENT_KEY, NULL
+};
+const ldns_output_format  *ldns_output_format_onlykeyids
+                       = &ldns_output_format_onlykeyids_record;
+const ldns_output_format  *ldns_output_format_default
+                       = &ldns_output_format_onlykeyids_record;
+const ldns_output_format   ldns_output_format_bubblebabble_record = { 
+       LDNS_COMMENT_KEY | LDNS_COMMENT_BUBBLEBABBLE | LDNS_COMMENT_FLAGS, NULL
+};
+const ldns_output_format  *ldns_output_format_bubblebabble 
+                       = &ldns_output_format_bubblebabble_record;
+
 ldns_status
 ldns_pkt_opcode2buffer_str(ldns_buffer *output, ldns_pkt_opcode opcode)
 {
@@ -330,13 +346,12 @@ ldns_status
 ldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf)
 {
        /* create a YYYYMMDDHHMMSS string if possible */
-       time_t data_time = (time_t) ldns_read_uint32(ldns_rdf_data(rdf));
        struct tm tm;
        char date_buf[16];
 
        memset(&tm, 0, sizeof(tm));
-
-       if (gmtime_r(&data_time, &tm) && strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) {
+       if (ldns_serial_arithmitics_gmtime_r(ldns_rdf2native_int32(rdf), time(NULL), &tm)
+           && strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) {
                ldns_buffer_printf(output, "%s", date_buf);
        }
        return ldns_buffer_status(output);
@@ -1140,120 +1155,258 @@ ldns_rdf2buffer_str(ldns_buffer *buffer, const ldns_rdf *rdf)
        return res;
 }
 
+ldns_rdf *
+ldns_b32_ext2dname(const ldns_rdf *rdf)
+{
+       size_t size;
+       char *b32;
+       ldns_rdf *out;
+       if(ldns_rdf_size(rdf) == 0)
+               return NULL;
+        /* remove -1 for the b32-hash-len octet */
+       size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
+        /* add one for the end nul for the string */
+       b32 = LDNS_XMALLOC(char, size + 2);
+       if (b32) {
+               if (ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1, 
+                               ldns_rdf_size(rdf) - 1, b32, size+1) > 0) {
+                       b32[size] = '.';
+                       b32[size+1] = '\0';
+                       if (ldns_str2rdf_dname(&out, b32) == LDNS_STATUS_OK) {
+                               LDNS_FREE(b32);
+                               return out;
+                       }
+               }
+               LDNS_FREE(b32);
+       }
+       return NULL;
+}
+
 ldns_status
-ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
+ldns_rr2buffer_str_fmt(ldns_buffer *output, 
+               const ldns_output_format *fmt, const ldns_rr *rr)
 {
        uint16_t i, flags;
        ldns_status status = LDNS_STATUS_OK;
+
+       if (fmt == NULL) {
+               fmt = ldns_output_format_default;
+       }
        if (!rr) {
-               ldns_buffer_printf(output, "(null)\n");
-       } else {
-               if (ldns_rr_owner(rr)) {
-                       status = ldns_rdf2buffer_str_dname(output, ldns_rr_owner(rr));
-               }
-               if (status != LDNS_STATUS_OK) {
-                       return status;
+               if (LDNS_COMMENT_NULLS & fmt->flags) {
+                       ldns_buffer_printf(output, "; (null)\n");
                }
+               return ldns_buffer_status(output);
+       }
+       if (ldns_rr_owner(rr)) {
+               status = ldns_rdf2buffer_str_dname(output, ldns_rr_owner(rr));
+       }
+       if (status != LDNS_STATUS_OK) {
+               return status;
+       }
 
-               /* TTL should NOT be printed if it is a question */
-               if (!ldns_rr_is_question(rr)) {
-                       ldns_buffer_printf(output, "\t%d", ldns_rr_ttl(rr));
-               }
+       /* TTL should NOT be printed if it is a question */
+       if (!ldns_rr_is_question(rr)) {
+               ldns_buffer_printf(output, "\t%d", ldns_rr_ttl(rr));
+       }
 
-               ldns_buffer_printf(output, "\t");
-               status = ldns_rr_class2buffer_str(output, ldns_rr_get_class(rr));
-               if (status != LDNS_STATUS_OK) {
-                       return status;
-               }
-               ldns_buffer_printf(output, "\t");
+       ldns_buffer_printf(output, "\t");
+       status = ldns_rr_class2buffer_str(output, ldns_rr_get_class(rr));
+       if (status != LDNS_STATUS_OK) {
+               return status;
+       }
+       ldns_buffer_printf(output, "\t");
 
-               status = ldns_rr_type2buffer_str(output, ldns_rr_get_type(rr));
-               if (status != LDNS_STATUS_OK) {
-                       return status;
-               }
+       status = ldns_rr_type2buffer_str(output, ldns_rr_get_type(rr));
+       if (status != LDNS_STATUS_OK) {
+               return status;
+       }
 
-               if (ldns_rr_rd_count(rr) > 0) {
-                       ldns_buffer_printf(output, "\t");
-               } else if (!ldns_rr_is_question(rr)) {
-                       ldns_buffer_printf(output, "\t\\# 0");
-               }
+       if (ldns_rr_rd_count(rr) > 0) {
+               ldns_buffer_printf(output, "\t");
+       } else if (!ldns_rr_is_question(rr)) {
+               ldns_buffer_printf(output, "\t\\# 0");
+       }
 
-               for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-                       status = ldns_rdf2buffer_str(output, ldns_rr_rdf(rr, i));
-                        if(status != LDNS_STATUS_OK)
-                                return status;
-                       if (i < ldns_rr_rd_count(rr) - 1) {
-                               ldns_buffer_printf(output, " ");
-                       }
+       for (i = 0; i < ldns_rr_rd_count(rr); i++) {
+               /* ldns_rdf2buffer_str handles NULL input fine! */
+               status = ldns_rdf2buffer_str(output, ldns_rr_rdf(rr, i));
+               if(status != LDNS_STATUS_OK)
+                       return status;
+               if (i < ldns_rr_rd_count(rr) - 1) {
+                       ldns_buffer_printf(output, " ");
                }
-               /* per RR special comments - handy for DNSSEC types */
-               /* check to prevent question sec. rr from
-                * getting here */
-               if (ldns_rr_rd_count(rr) > 0) {
-                       switch (ldns_rr_get_type(rr)) {
-                               case LDNS_RR_TYPE_DNSKEY:
-                                       if (ldns_rr_rdf(rr, 0)) {
-                                               flags = ldns_rdf2native_int16(ldns_rr_rdf(rr, 0));
-                                               if (flags == 256 || flags == 384) {
-                                                       ldns_buffer_printf(output,
-                                                                       " ;{id = %u (zsk), size = %db}",
-                                                                       (unsigned int) ldns_calc_keytag(rr),
-                                                                       ldns_rr_dnskey_key_size(rr));
-                                                       break;
-                                               }
-                                               if (flags == 257 || flags == 385) {
-                                                       ldns_buffer_printf(output,
-                                                                       " ;{id = %u (ksk), size = %db}",
-                                                                       (unsigned int) ldns_calc_keytag(rr),
-                                                                       ldns_rr_dnskey_key_size(rr));
-                                                       break;
-                                               }
-                                               ldns_buffer_printf(output, " ;{id = %u, size = %db}",
-                                                               (unsigned int) ldns_calc_keytag(rr),
-                                                               ldns_rr_dnskey_key_size(rr));
-                                       }
-                                       break;
-                               case LDNS_RR_TYPE_RRSIG:
-                                       ldns_buffer_printf(output, " ;{id = %d}",
-                                                       ldns_rdf2native_int16(ldns_rr_rdf(rr, 6)));
+       }
+       /* per RR special comments - handy for DNSSEC types */
+       /* check to prevent question sec. rr from
+        * getting here */
+       if (ldns_rr_rd_count(rr) > 0) {
+               switch (ldns_rr_get_type(rr)) {
+                       case LDNS_RR_TYPE_DNSKEY:
+                               /* if ldns_rr_rd_count(rr) > 0
+                                  then ldns_rr_rdf(rr, 0) exists! */
+                               if (! (fmt->flags & LDNS_COMMENT_KEY)) {
                                        break;
-                               case LDNS_RR_TYPE_DS:
-                                       {
-                                               uint8_t *data = ldns_rdf_data(ldns_rr_rdf(rr, 3));
-                                               size_t len = ldns_rdf_size(ldns_rr_rdf(rr, 3));
-                                               char *babble = ldns_bubblebabble(data, len);
-                                               if(babble)
-                                                 ldns_buffer_printf(output, " ; %s", babble);
-                                               LDNS_FREE(babble);
+                               }
+                               flags = ldns_rdf2native_int16(
+                                               ldns_rr_rdf(rr, 0));
+                               ldns_buffer_printf(output, " ;{");
+                               if (fmt->flags & LDNS_COMMENT_KEY_ID) {
+                                       ldns_buffer_printf(output, "id = %u",
+                                                       (unsigned int)
+                                                       ldns_calc_keytag(rr));
+                               }
+                               if ((fmt->flags & LDNS_COMMENT_KEY_TYPE)
+                                               && (flags & LDNS_KEY_ZONE_KEY)){
+                                       if (flags & LDNS_KEY_SEP_KEY) {
+                                               ldns_buffer_printf(
+                                                       output, " (ksk)");
+                                       }
+                                       else {
+                                               ldns_buffer_printf(
+                                                       output, " (zsk)");
+                                       }
+                                       if (fmt->flags & LDNS_COMMENT_KEY_SIZE){
+                                               ldns_buffer_printf(
+                                                       output, ", ");
                                        }
+                               } else if (fmt->flags
+                                               & (LDNS_COMMENT_KEY_ID
+                                                 |LDNS_COMMENT_KEY_SIZE)) {
+                                       ldns_buffer_printf( output, ", ");
+                               }
+                               if (fmt->flags & LDNS_COMMENT_KEY_SIZE) {
+                                       ldns_buffer_printf(output, "size = %db",
+                                               ldns_rr_dnskey_key_size(rr));
+                               }
+                               ldns_buffer_printf(output, "}");
+                               break;
+                       case LDNS_RR_TYPE_RRSIG:
+                               if ((fmt->flags & LDNS_COMMENT_KEY)
+                                               && (fmt->flags 
+                                                       & LDNS_COMMENT_RRSIGS)
+                                               && ldns_rr_rdf(rr, 6) != NULL) {
+                                       ldns_buffer_printf(output
+                                               , " ;{id = %d}"
+                                               , ldns_rdf2native_int16(
+                                                       ldns_rr_rdf(rr, 6)));
+                               }
+                               break;
+                       case LDNS_RR_TYPE_DS:
+                               if ((fmt->flags & LDNS_COMMENT_BUBBLEBABBLE)
+                                               && ldns_rr_rdf(rr, 3) != NULL) {
+                                       uint8_t *data = ldns_rdf_data(
+                                                       ldns_rr_rdf(rr, 3));
+                                       size_t len = ldns_rdf_size(
+                                                       ldns_rr_rdf(rr, 3));
+                                       char *babble = ldns_bubblebabble(
+                                                       data, len);
+                                       if(babble) {
+                                               ldns_buffer_printf(output
+                                                       , " ;{%s}", babble);
+                                       }
+                                       LDNS_FREE(babble);
+                               }
+                               break;
+                       case LDNS_RR_TYPE_NSEC3:
+                               if (! (fmt->flags & LDNS_COMMENT_FLAGS) &&
+                                   ! (fmt->flags & LDNS_COMMENT_NSEC3_CHAIN)) {
                                        break;
-                               case LDNS_RR_TYPE_NSEC3:
+                               }
+                               ldns_buffer_printf(output, " ;{");
+                               if ((fmt->flags & LDNS_COMMENT_FLAGS)) {
                                        if (ldns_nsec3_optout(rr)) {
-                                               ldns_buffer_printf(output, " ; flags: optout");
+                                               ldns_buffer_printf(output,
+                                                       " flags: optout");
+                                       } else {
+                                               ldns_buffer_printf(output,
+                                                       " flags: -");
                                        }
-                                       break;
-                               default:
-                                       break;
+                                       if (fmt->flags & LDNS_COMMENT_NSEC3_CHAIN
+                                                       && fmt->data != NULL) {
+                                               ldns_buffer_printf(output, ", ");
+                                       }
+                               }
+                               if (fmt->flags & LDNS_COMMENT_NSEC3_CHAIN
+                                               && fmt->data != NULL) {
+                                       ldns_rbnode_t *node;
+                                       ldns_rdf *key = ldns_dname_label(
+                                                       ldns_rr_owner(rr), 0);
+                                       if (key) {
+                                               node = ldns_rbtree_search(
+                                                       (ldns_rbtree_t *)
+                                                               fmt->data,
+                                                       (void *) key);
+                                               if (node->data) {
+                                                       ldns_buffer_printf(
+                                                               output,
+                                                               "from: ");
+                                                       (void)
+                                                       ldns_rdf2buffer_str(
+                                                               output, 
+                                                               (ldns_rdf *)
+                                                               node->data);
+                                               }
+                                               ldns_rdf_free(key);
+                                       }
+                                       key = ldns_b32_ext2dname(
+                                               ldns_nsec3_next_owner(rr));
+                                       if (key) {
+                                               node = ldns_rbtree_search(
+                                                       (ldns_rbtree_t *)
+                                                               fmt->data,
+                                                       (void *) key);
+                                               if (node->data) {
+                                                       ldns_buffer_printf(
+                                                               output,
+                                                               " to: ");
+                                                       (void)
+                                                       ldns_rdf2buffer_str(
+                                                               output, 
+                                                               (ldns_rdf *)
+                                                               node->data);
+                                               }
+                                               ldns_rdf_free(key);
+                                       }
+                               }
+                               ldns_buffer_printf(output, "}");
+                               break;
+                       default:
+                               break;
 
-                       }
                }
-               /* last */
-               ldns_buffer_printf(output, "\n");
        }
+       /* last */
+       ldns_buffer_printf(output, "\n");
        return ldns_buffer_status(output);
 }
 
 ldns_status
-ldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list)
+ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
+{
+       return ldns_rr2buffer_str_fmt(output, ldns_output_format_default, rr);
+}
+
+ldns_status
+ldns_rr_list2buffer_str_fmt(ldns_buffer *output, 
+               const ldns_output_format *fmt, const ldns_rr_list *list)
 {
        uint16_t i;
 
        for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
-               (void) ldns_rr2buffer_str(output, ldns_rr_list_rr(list, i));
+               (void) ldns_rr2buffer_str_fmt(output, fmt, 
+                               ldns_rr_list_rr(list, i));
        }
        return ldns_buffer_status(output);
 }
 
+ldns_status
+ldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list)
+{
+       return ldns_rr_list2buffer_str_fmt(
+                       output, ldns_output_format_default, list);
+}
+
 ldns_status
 ldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
 {
@@ -1307,7 +1460,8 @@ ldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
 }
 
 ldns_status
-ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
+ldns_pkt2buffer_str_fmt(ldns_buffer *output, 
+               const ldns_output_format *fmt, const ldns_pkt *pkt)
 {
        uint16_t i;
        ldns_status status = LDNS_STATUS_OK;
@@ -1332,8 +1486,9 @@ ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
 
 
                for (i = 0; i < ldns_pkt_qdcount(pkt); i++) {
-                       status = ldns_rr2buffer_str(output,
-                                      ldns_rr_list_rr(ldns_pkt_question(pkt), i));
+                       status = ldns_rr2buffer_str_fmt(output, fmt,
+                                      ldns_rr_list_rr(
+                                              ldns_pkt_question(pkt), i));
                        if (status != LDNS_STATUS_OK) {
                                return status;
                        }
@@ -1342,8 +1497,9 @@ ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
 
                ldns_buffer_printf(output, ";; ANSWER SECTION:\n");
                for (i = 0; i < ldns_pkt_ancount(pkt); i++) {
-                       status = ldns_rr2buffer_str(output,
-                                      ldns_rr_list_rr(ldns_pkt_answer(pkt), i));
+                       status = ldns_rr2buffer_str_fmt(output, fmt,
+                                      ldns_rr_list_rr(
+                                              ldns_pkt_answer(pkt), i));
                        if (status != LDNS_STATUS_OK) {
                                return status;
                        }
@@ -1354,8 +1510,9 @@ ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
                ldns_buffer_printf(output, ";; AUTHORITY SECTION:\n");
 
                for (i = 0; i < ldns_pkt_nscount(pkt); i++) {
-                       status = ldns_rr2buffer_str(output,
-                                      ldns_rr_list_rr(ldns_pkt_authority(pkt), i));
+                       status = ldns_rr2buffer_str_fmt(output, fmt,
+                                      ldns_rr_list_rr(
+                                              ldns_pkt_authority(pkt), i));
                        if (status != LDNS_STATUS_OK) {
                                return status;
                        }
@@ -1364,8 +1521,9 @@ ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
 
                ldns_buffer_printf(output, ";; ADDITIONAL SECTION:\n");
                for (i = 0; i < ldns_pkt_arcount(pkt); i++) {
-                       status = ldns_rr2buffer_str(output,
-                                      ldns_rr_list_rr(ldns_pkt_additional(pkt), i));
+                       status = ldns_rr2buffer_str_fmt(output, fmt,
+                                      ldns_rr_list_rr(
+                                              ldns_pkt_additional(pkt), i));
                        if (status != LDNS_STATUS_OK) {
                                return status;
                        }
@@ -1400,7 +1558,8 @@ ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
                }
                if (ldns_pkt_tsig(pkt)) {
                        ldns_buffer_printf(output, ";; TSIG:\n;; ");
-                       (void) ldns_rr2buffer_str(output, ldns_pkt_tsig(pkt));
+                       (void) ldns_rr2buffer_str_fmt(
+                                       output, fmt, ldns_pkt_tsig(pkt));
                        ldns_buffer_printf(output, "\n");
                }
                if (ldns_pkt_answerfrom(pkt)) {
@@ -1421,6 +1580,13 @@ ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
        return status;
 }
 
+ldns_status
+ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
+{
+       return ldns_pkt2buffer_str_fmt(output, ldns_output_format_default, pkt);
+}
+
+
 #ifdef HAVE_SSL
 static ldns_status
 ldns_hmac_key2buffer_str(ldns_buffer *output, const ldns_key *k)
@@ -1891,7 +2057,7 @@ ldns_rdf2str(const ldns_rdf *rdf)
 }
 
 char *
-ldns_rr2str(const ldns_rr *rr)
+ldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr)
 {
        char *result = NULL;
        ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
@@ -1899,7 +2065,8 @@ ldns_rr2str(const ldns_rr *rr)
        if (!tmp_buffer) {
                return NULL;
        }
-       if (ldns_rr2buffer_str(tmp_buffer, rr) == LDNS_STATUS_OK) {
+       if (ldns_rr2buffer_str_fmt(tmp_buffer, fmt, rr)
+                       == LDNS_STATUS_OK) {
                /* export and return string, destroy rest */
                result = ldns_buffer2str(tmp_buffer);
        }
@@ -1908,7 +2075,13 @@ ldns_rr2str(const ldns_rr *rr)
 }
 
 char *
-ldns_pkt2str(const ldns_pkt *pkt)
+ldns_rr2str(const ldns_rr *rr)
+{
+       return ldns_rr2str_fmt(ldns_output_format_default, rr);
+}
+
+char *
+ldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt)
 {
        char *result = NULL;
        ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
@@ -1916,7 +2089,8 @@ ldns_pkt2str(const ldns_pkt *pkt)
        if (!tmp_buffer) {
                return NULL;
        }
-       if (ldns_pkt2buffer_str(tmp_buffer, pkt) == LDNS_STATUS_OK) {
+       if (ldns_pkt2buffer_str_fmt(tmp_buffer, fmt, pkt)
+                       == LDNS_STATUS_OK) {
                /* export and return string, destroy rest */
                result = ldns_buffer2str(tmp_buffer);
        }
@@ -1925,6 +2099,12 @@ ldns_pkt2str(const ldns_pkt *pkt)
        return result;
 }
 
+char *
+ldns_pkt2str(const ldns_pkt *pkt)
+{
+       return ldns_pkt2str_fmt(ldns_output_format_default, pkt);
+}
+
 char *
 ldns_key2str(const ldns_key *k)
 {
@@ -1943,7 +2123,7 @@ ldns_key2str(const ldns_key *k)
 }
 
 char *
-ldns_rr_list2str(const ldns_rr_list *list)
+ldns_rr_list2str_fmt(const ldns_output_format *fmt, const ldns_rr_list *list)
 {
        char *result = NULL;
        ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
@@ -1952,10 +2132,17 @@ ldns_rr_list2str(const ldns_rr_list *list)
                return NULL;
        }
        if (list) {
-               if (ldns_rr_list2buffer_str(tmp_buffer, list) == LDNS_STATUS_OK) {
+               if (ldns_rr_list2buffer_str_fmt(
+                                  tmp_buffer, fmt, list)
+                               == LDNS_STATUS_OK) {
                }
        } else {
-               ldns_buffer_printf(tmp_buffer, "(null)\n");
+               if (fmt == NULL) {
+                       fmt = ldns_output_format_default;
+               }
+               if (fmt->flags & LDNS_COMMENT_NULLS) {
+                       ldns_buffer_printf(tmp_buffer, "; (null)\n");
+               }
        }
 
        /* export and return string, destroy rest */
@@ -1964,6 +2151,12 @@ ldns_rr_list2str(const ldns_rr_list *list)
        return result;
 }
 
+char *
+ldns_rr_list2str(const ldns_rr_list *list)
+{
+       return ldns_rr_list2str_fmt(ldns_output_format_default, list);
+}
+
 void
 ldns_rdf_print(FILE *output, const ldns_rdf *rdf)
 {
@@ -1977,9 +2170,10 @@ ldns_rdf_print(FILE *output, const ldns_rdf *rdf)
 }
 
 void
-ldns_rr_print(FILE *output, const ldns_rr *rr)
+ldns_rr_print_fmt(FILE *output, 
+               const ldns_output_format *fmt, const ldns_rr *rr)
 {
-       char *str = ldns_rr2str(rr);
+       char *str = ldns_rr2str_fmt(fmt, rr);
        if (str) {
                fprintf(output, "%s", str);
        } else {
@@ -1989,9 +2183,16 @@ ldns_rr_print(FILE *output, const ldns_rr *rr)
 }
 
 void
-ldns_pkt_print(FILE *output, const ldns_pkt *pkt)
+ldns_rr_print(FILE *output, const ldns_rr *rr)
+{
+       ldns_rr_print_fmt(output, ldns_output_format_default, rr);
+}
+
+void
+ldns_pkt_print_fmt(FILE *output, 
+               const ldns_output_format *fmt, const ldns_pkt *pkt)
 {
-       char *str = ldns_pkt2str(pkt);
+       char *str = ldns_pkt2str_fmt(fmt, pkt);
        if (str) {
                fprintf(output, "%s", str);
        } else {
@@ -2001,16 +2202,30 @@ ldns_pkt_print(FILE *output, const ldns_pkt *pkt)
 }
 
 void
-ldns_rr_list_print(FILE *output, const ldns_rr_list *lst)
+ldns_pkt_print(FILE *output, const ldns_pkt *pkt)
+{
+       ldns_pkt_print_fmt(output, ldns_output_format_default, pkt);
+}
+
+void
+ldns_rr_list_print_fmt(FILE *output, 
+               const ldns_output_format *fmt, const ldns_rr_list *lst)
 {
        size_t i;
        for (i = 0; i < ldns_rr_list_rr_count(lst); i++) {
-               ldns_rr_print(output, ldns_rr_list_rr(lst, i));
+               ldns_rr_print_fmt(output, fmt, ldns_rr_list_rr(lst, i));
        }
 }
 
 void
-ldns_resolver_print(FILE *output, const ldns_resolver *r)
+ldns_rr_list_print(FILE *output, const ldns_rr_list *lst)
+{
+       ldns_rr_list_print_fmt(output, ldns_output_format_default, lst);
+}
+
+void
+ldns_resolver_print_fmt(FILE *output, 
+               const ldns_output_format *fmt, const ldns_resolver *r)
 {
        uint16_t i;
        ldns_rdf **n;
@@ -2040,7 +2255,7 @@ ldns_resolver_print(FILE *output, const ldns_resolver *r)
        fprintf(output, "dnssec cd: %d\n", ldns_resolver_dnssec_cd(r));
        fprintf(output, "trust anchors (%d listed):\n",
                (int)ldns_rr_list_rr_count(ldns_resolver_dnssec_anchors(r)));
-       ldns_rr_list_print(output, ldns_resolver_dnssec_anchors(r));
+       ldns_rr_list_print_fmt(output, fmt, ldns_resolver_dnssec_anchors(r));
        fprintf(output, "tsig: %s %s\n",
                 ldns_resolver_tsig_keyname(r)?ldns_resolver_tsig_keyname(r):"-",
                 ldns_resolver_tsig_algorithm(r)?ldns_resolver_tsig_algorithm(r):"-");
@@ -2076,9 +2291,21 @@ ldns_resolver_print(FILE *output, const ldns_resolver *r)
 }
 
 void
-ldns_zone_print(FILE *output, const ldns_zone *z)
+ldns_resolver_print(FILE *output, const ldns_resolver *r)
+{
+       ldns_resolver_print_fmt(output, ldns_output_format_default, r);
+}
+
+void
+ldns_zone_print_fmt(FILE *output, 
+               const ldns_output_format *fmt, const ldns_zone *z)
 {
        if(ldns_zone_soa(z))
-               ldns_rr_print(output, ldns_zone_soa(z));
-       ldns_rr_list_print(output, ldns_zone_rrs(z));
+               ldns_rr_print_fmt(output, fmt, ldns_zone_soa(z));
+       ldns_rr_list_print_fmt(output, fmt, ldns_zone_rrs(z));
+}
+void
+ldns_zone_print(FILE *output, const ldns_zone *z)
+{
+       ldns_zone_print_fmt(output, ldns_output_format_default, z);
 }
index 1ffb0f5..ca28dba 100644 (file)
@@ -138,10 +138,11 @@ ldns_rr2buffer_wire_canonical(ldns_buffer *buffer,
 
                for (i = 0; i < ldns_rr_rd_count(rr); i++) {
                        if (pre_rfc3597) {
-                               (void) ldns_rdf2buffer_wire_canonical(buffer,
-                                                                                          ldns_rr_rdf(rr, i));
+                               (void) ldns_rdf2buffer_wire_canonical(
+                                               buffer, ldns_rr_rdf(rr, i));
                        } else {
-                               (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
+                               (void) ldns_rdf2buffer_wire(
+                                               buffer, ldns_rr_rdf(rr, i));
                        }
                }
                
@@ -178,7 +179,8 @@ ldns_rr2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr, int section)
                }       
 
                for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-                       (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
+                       (void) ldns_rdf2buffer_wire(
+                                       buffer, ldns_rr_rdf(rr, i));
                }
                
                if (rdl_pos != 0) {
@@ -203,9 +205,7 @@ ldns_rrsig2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
        /* Convert all the rdfs, except the actual signature data
         * rdf number 8  - the last, hence: -1 */
        for (i = 0; i < ldns_rr_rd_count(rr) - 1; i++) {
-               if (ldns_rr_rdf(rr, i)) {
-                       (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
-               }
+               (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
        }
 
        return ldns_buffer_status(buffer);
index c224cd6..2d7f62a 100644 (file)
@@ -278,8 +278,11 @@ ldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr)
                 EC_KEY_free(ec);
                 return NULL;
         }
-        EVP_PKEY_assign_EC_KEY(evp_key, ec);
-
+        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
+               EVP_PKEY_free(evp_key);
+                EC_KEY_free(ec);
+                return NULL;
+       }
         return evp_key;
 }
 #endif
@@ -839,7 +842,6 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
                                ldns_key_free(k);
                                return NULL;
                        }
-
                        ldns_key_set_rsa_key(k, r);
 #endif /* HAVE_SSL */
                        break;
@@ -929,7 +931,11 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
                                 EC_KEY_free(ec);
                                 return NULL;
                         }
-                        EVP_PKEY_assign_EC_KEY(k->_key.key, ec);
+                        if (!EVP_PKEY_assign_EC_KEY(k->_key.key, ec)) {
+                                ldns_key_free(k);
+                                EC_KEY_free(ec);
+                                return NULL;
+                       }
 #endif /* splint */
                        break;
 #endif
index 65b8bdc..03df14c 100644 (file)
@@ -607,8 +607,8 @@ ldns_buffer_status_ok(ldns_buffer *buffer)
 
 /**
  * prints to the buffer, increasing the capacity if required using
- * buffer_reserve(). The buffer's position is set to the terminating
- * '\\0'. Returns the number of characters written (not including the
+ * buffer_reserve(). The buffer's position is set to the terminating '\\0'
+ * Returns the number of characters written (not including the
  * terminating '\\0') or -1 on failure.
  */
 int ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...);
index cc7dd89..e69de29 100644 (file)
@@ -1,52 +0,0 @@
-/**
- * \file common.h
- *
- * Common definitions for LDNS
- */
-
-/**
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-
-#ifndef LDNS_COMMON_H
-#define LDNS_COMMON_H
-
-#if !defined(__cplusplus) && !defined(__bool_true_false_are_defined)
-
-#if defined(HAVE_STDBOOL_H)
-#include <stdbool.h>
-#else
-
-/*@ignore@*/
-/* splint barfs on this construct */
-typedef unsigned int bool;
-#define bool bool
-#define false 0
-#define true  1
-#define __bool_true_false_are_defined 1
-/*@end@*/
-
-#endif
-
-#endif
-
-#ifdef HAVE_ATTR_FORMAT
-#define ATTR_FORMAT(archetype, string_index, first_to_check) \
-    __attribute__ ((format (archetype, string_index, first_to_check)))
-#else /* !HAVE_ATTR_FORMAT */
-#define ATTR_FORMAT(archetype, string_index, first_to_check) /* empty */
-#endif /* !HAVE_ATTR_FORMAT */
-
-#if defined(__cplusplus)
-#define ATTR_UNUSED(x)
-#elif defined(HAVE_ATTR_UNUSED)
-#define ATTR_UNUSED(x)  x __attribute__((unused))
-#else /* !HAVE_ATTR_UNUSED */
-#define ATTR_UNUSED(x)  x
-#endif /* !HAVE_ATTR_UNUSED */
-
-#endif /* LDNS_COMMON_H */
index 7bfc70b..7863551 100644 (file)
 #ifndef LDNS_DNSSEC_H
 #define LDNS_DNSSEC_H
 
-#ifdef HAVE_SSL
+#include <ldns/common.h>
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 #include <openssl/ssl.h>
 #include <openssl/evp.h>
-#endif /* HAVE_SSL */
-#include <ldns/common.h>
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 #include <ldns/packet.h>
 #include <ldns/keys.h>
 #include <ldns/zone.h>
@@ -127,7 +127,7 @@ uint16_t ldns_calc_keytag(const ldns_rr *key);
  */
 uint16_t ldns_calc_keytag_raw(uint8_t* key, size_t keysize);
 
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 /**
  * converts a buffer holding key material to a DSA key in openssl.
  *
@@ -173,9 +173,9 @@ EVP_PKEY* ldns_gost2pkey_raw(unsigned char* key, size_t keylen);
  */
 EVP_PKEY* ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo);
 
-#endif /* HAVE_SSL */
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 /**
  * converts a buffer holding key material to a RSA key in openssl.
  *
@@ -191,7 +191,7 @@ RSA *ldns_key_buf2rsa(ldns_buffer *key);
  * \return a RSA * structure with the key material
  */
 RSA *ldns_key_buf2rsa_raw(unsigned char* key, size_t len);
-#endif /* HAVE_SSL */
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 
 /** 
  * returns a new DS rr that represents the given key rr.
@@ -210,6 +210,16 @@ ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[],
                                                 size_t size,
                                                 ldns_rr_type nsec_type);
 
+/**
+ * returns whether a rrset of the given type is found in the rrsets.
+ *
+ * \param[in] rrsets the rrsets to be tested
+ * \param[in] type the type to test for
+ * \return int 1 if the type was found, 0 otherwise.
+ */
+int
+ldns_dnssec_rrsets_contains_type (ldns_dnssec_rrsets *rrsets, ldns_rr_type type);
+
 /**
  * Creates NSEC
  */
@@ -372,7 +382,7 @@ bool ldns_nsec_bitmap_covers_type(const ldns_rdf *nsec_bitmap, ldns_rr_type type
  */
 bool ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name);
 
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 /**
  * verify a packet 
  * \param[in] p the packet
@@ -438,7 +448,7 @@ int ldns_dnssec_default_delete_signatures(ldns_rr *sig, void *n);
  */
 int ldns_dnssec_default_replace_signatures(ldns_rr *sig, void *n);
 
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 /**
  * Converts the DSA signature from ASN1 representation (RFC2459, as 
  * used by OpenSSL) to raw signature data as used in DNS (rfc2536)
@@ -488,7 +498,7 @@ ldns_status
 ldns_convert_ecdsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
         const ldns_rdf *sig_rdf);
 
-#endif /* HAVE_SSL */
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 
 #ifdef __cplusplus
 }
index 5b3921a..e77cb69 100644 (file)
@@ -42,7 +42,7 @@ ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *key);
  */
 ldns_rr_list *ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys);
 
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 /**
  * Sign a buffer with the DSA key (hash with SHA1)
  * \param[in] to_sign buffer with the data
@@ -80,11 +80,42 @@ ldns_rdf *ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key);
  * \return a ldns_rdf with the signed data
  */
 ldns_rdf *ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key);
-#endif /* HAVE_SSL */
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 
 /**
- * Finds the first dnssec_name node in the rbtree that has not been marked
- * as glue, starting at the given node
+ * Marks the names in the zone that are occluded. Those names will be skipped
+ * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
+ * function. But watch out! Names that are partially occluded (like glue with
+ * the same name as the delegation) will not be marked and should specifically 
+ * be taken into account seperately.
+ *
+ * When glue_list is given (not NULL), in the process of marking the names, all
+ * glue resource records will be pushed to that list, even glue at the delegation name.
+ *
+ * \param[in] zone the zone in which to mark the names
+ * \param[in] glue_list the list to which to push the glue rrs
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status
+ldns_dnssec_zone_mark_and_get_glue(
+               ldns_dnssec_zone *zone, ldns_rr_list *glue_list);
+
+/**
+ * Marks the names in the zone that are occluded. Those names will be skipped
+ * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
+ * function. But watch out! Names that are partially occluded (like glue with
+ * the same name as the delegation) will not be marked and should specifically 
+ * be taken into account seperately.
+ *
+ * \param[in] zone the zone in which to mark the names
+ * \return LDNS_STATUS_OK on succesful completion
+ */
+ldns_status
+ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone);
+
+/**
+ * Finds the first dnssec_name node in the rbtree that is not occluded.
+ * It *does* return names that are partially occluded.
  *
  * \param[in] node the first node to check
  * \return the first node that has not been marked as glue, or NULL
@@ -238,6 +269,40 @@ ldns_status ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
                                uint8_t *salt,
                                int signflags);
 
+/**
+ * signs the given zone with the given new zone, with NSEC3
+ *
+ * \param[in] zone the zone to sign
+ * \param[in] key_list the list of keys to sign the zone with
+ * \param[in] new_rrs newly created resource records are added to this list, to free them later
+ * \param[in] func callback function that decides what to do with old signatures
+ * \param[in] arg optional argument for the callback function
+ * \param[in] algorithm the NSEC3 hashing algorithm to use
+ * \param[in] flags NSEC3 flags
+ * \param[in] iterations the number of NSEC3 hash iterations to use
+ * \param[in] salt_length the length (in octets) of the NSEC3 salt
+ * \param[in] salt the NSEC3 salt data
+ * \param[in] signflags option flags for signing process. 0 is the default.
+ * \param[out] map a referenced rbtree pointer variable. The newly created 
+ *                 rbtree will contain mappings from hashed owner names to the 
+ *                 unhashed name.
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
+                               ldns_rr_list *new_rrs,
+                               ldns_key_list *key_list,
+                               int (*func)(ldns_rr *, void *),
+                               void *arg,
+                               uint8_t algorithm,
+                               uint8_t flags,
+                               uint16_t iterations,
+                               uint8_t salt_length,
+                               uint8_t *salt,
+                               int signflags,
+                               ldns_rbtree_t **map
+                               );
+
+
 /**
  * signs the given zone with the given keys
  * 
index 8d380f9..13b3fa3 100644 (file)
@@ -6,6 +6,7 @@
 #define LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS 10
 
 #include <ldns/dnssec.h>
+#include <ldns/host2str.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -56,6 +57,17 @@ void ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain);
  */
 void ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain);
 
+/**
+ * Prints the dnssec_data_chain to the given file stream
+ * 
+ * \param[in] *out The file stream to print to
+ * \param[in] *fmt The format of the textual representation
+ * \param[in] *chain The dnssec_data_chain to print
+ */
+void ldns_dnssec_data_chain_print_fmt(FILE *out, 
+               const ldns_output_format *fmt,
+               const ldns_dnssec_data_chain *chain);
+
 /**
  * Build an ldns_dnssec_data_chain, which contains all
  * DNSSEC data that is needed to derive the trust tree later
@@ -158,9 +170,28 @@ size_t ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree);
  * \param[in] extended If true, add little explanation lines to the output
  */
 void ldns_dnssec_trust_tree_print(FILE *out,
-                                                   ldns_dnssec_trust_tree *tree,
-                                                   size_t tabs,
-                                                   bool extended);
+               ldns_dnssec_trust_tree *tree,
+               size_t tabs,
+               bool extended);
+
+/**
+ * Prints the dnssec_trust_tree structure to the given file
+ * stream.
+ *
+ * If a link status is not LDNS_STATUS_OK; the status and
+ * relevant signatures are printed too
+ *
+ * \param[in] *out The file stream to print to
+ * \param[in] *fmt The format of the textual representation
+ * \param[in] tree The trust tree to print
+ * \param[in] tabs Prepend each line with tabs*2 spaces
+ * \param[in] extended If true, add little explanation lines to the output
+ */
+void ldns_dnssec_trust_tree_print_fmt(FILE *out,
+               const ldns_output_format *fmt,
+               ldns_dnssec_trust_tree *tree,
+               size_t tabs,
+               bool extended);
 
 /**
  * Adds a trust tree as a parent for the given trust tree
@@ -193,8 +224,7 @@ ldns_dnssec_trust_tree *ldns_dnssec_derive_trust_tree(
                                           ldns_rr *rr);
 
 /**
- * Sub function for derive_trust_tree that is used for a
- * 'normal' rrset
+ * Sub function for derive_trust_tree that is used for a 'normal' rrset
  *
  * \param[in] new_tree The trust tree that we are building
  * \param[in] data_chain The data chain containing the data for the trust tree
@@ -389,6 +419,31 @@ ldns_status ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
                                                                    ldns_rr_type packet_qtype,
                                                                    bool packet_nodata);
 
+/**
+ * Same as ldns_status ldns_dnssec_verify_denial_nsec3 but also returns
+ * the nsec rr that matched.
+ *
+ * \param[in] rr The (query) RR to check the denial of existence for
+ * \param[in] nsecs The list of NSEC3 RRs that are supposed to deny the
+ *                  existence of the RR
+ * \param[in] rrsigs The RRSIG rr covering the NSEC RRs
+ * \param[in] packet_rcode The RCODE value of the packet that provided the
+ *                         NSEC3 RRs
+ * \param[in] packet_qtype The original query RR type
+ * \param[in] packet_nodata True if the providing packet had an empty ANSWER
+ *                          section
+ * \param[in] match On match, the given (reference to a) pointer will be set 
+ *                  to point to the matching nsec resource record.
+ * \return LDNS_STATUS_OK if the NSEC3 RRs deny the existence, error code
+ *                        containing the reason they do not otherwise
+ */
+ldns_status ldns_dnssec_verify_denial_nsec3_match(ldns_rr *rr,
+                                                 ldns_rr_list *nsecs,
+                                                 ldns_rr_list *rrsigs,
+                                                 ldns_pkt_rcode packet_rcode,
+                                                 ldns_rr_type packet_qtype,
+                                                 bool packet_nodata,
+                                                 ldns_rr **match);
 /**
  * Verifies the already processed data in the buffers
  * This function should probably not be used directly.
@@ -465,6 +520,7 @@ ldns_status ldns_verify_rrsig(ldns_rr_list *rrset,
                                                ldns_rr *rrsig,
                                                ldns_rr *key);
 
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 /**
  * verifies a buffer with signature data for a buffer with rrset data 
  * with an EVP_PKEY
@@ -474,12 +530,10 @@ ldns_status ldns_verify_rrsig(ldns_rr_list *rrset,
  * \param[in] key the EVP key structure
  * \param[in] digest_type The digest type of the signature
  */
-#ifdef HAVE_SSL
 ldns_status ldns_verify_rrsig_evp(ldns_buffer *sig,
                                                    ldns_buffer *rrset,
                                                    EVP_PKEY *key,
                                                    const EVP_MD *digest_type);
-#endif
 
 /**
  * Like ldns_verify_rrsig_evp, but uses raw signature data.
@@ -489,7 +543,6 @@ ldns_status ldns_verify_rrsig_evp(ldns_buffer *sig,
  * \param[in] key the EVP key structure
  * \param[in] digest_type The digest type of the signature
  */
-#ifdef HAVE_SSL
 ldns_status ldns_verify_rrsig_evp_raw(unsigned char *sig,
                                                           size_t siglen,
                                                           ldns_buffer *rrset,
index 88117da..e2dd402 100644 (file)
@@ -10,6 +10,7 @@
  
 #include <ldns/ldns.h>
 #include <ldns/rbtree.h>
+#include <ldns/host2str.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -70,8 +71,13 @@ struct ldns_struct_dnssec_name
         */
        ldns_dnssec_rrs *nsec_signatures;
        /**
-        * Set to true if this name is glue
-        * (as marked by ldns_dnssec_zone_mark_glue())
+        * Unlike what the name is_glue suggests, this field is set to true by
+        * ldns_dnssec_zone_mark_glue() or ldns_dnssec_zone_mark_and_get_glue()
+        * when the name, this dnssec_name struct represents, is occluded.
+        * Names that contain other occluded rrsets and records with glue on
+        * the delegation point will NOT have this bool set to true.
+        * This field should NOT be read directly, but only via the 
+        * ldns_dnssec_name_is_glue() function!
         */
        bool is_glue;
        /**
@@ -130,6 +136,16 @@ ldns_status ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr);
  */
 void ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs);
 
+/**
+ * Prints the given rrs to the file descriptor
+ *
+ * \param[in] out the file descriptor to print to
+ * \param[in] fmt the format of the textual representation
+ * \param[in] rrs the list of RRs to print
+ */
+void ldns_dnssec_rrs_print_fmt(FILE *out, 
+               const ldns_output_format *fmt, ldns_dnssec_rrs *rrs);
+
 /**
  * Creates a new list (entry) of RRsets
  * \return the newly allocated structure
@@ -188,8 +204,22 @@ ldns_status ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr);
  * \param[in] follow if set to false, only print the first RRset
  */ 
 void ldns_dnssec_rrsets_print(FILE *out,
-                                               ldns_dnssec_rrsets *rrsets,
-                                               bool follow);
+               ldns_dnssec_rrsets *rrsets,
+               bool follow);
+
+/**
+ * Print the given list of rrsets to the fiven file descriptor
+ * 
+ * \param[in] out the file descriptor to print to
+ * \param[in] fmt the format of the textual representation
+ * \param[in] rrsets the list of RRsets to print
+ * \param[in] follow if set to false, only print the first RRset
+ */ 
+void ldns_dnssec_rrsets_print_fmt(FILE *out,
+               const ldns_output_format *fmt,
+               ldns_dnssec_rrsets *rrsets,
+               bool follow);
+
 
 /**
  * Create a new data structure for a dnssec name
@@ -237,6 +267,18 @@ ldns_rdf *ldns_dnssec_name_name(ldns_dnssec_name *name);
  */
 void ldns_dnssec_name_set_name(ldns_dnssec_name *name,
                                                 ldns_rdf *dname);
+/**
+ * Returns if dnssec_name structure is marked as glue.
+ * The ldns_dnssec_zone_mark_glue() function has to be called on a zone before
+ * using this function.
+ * Only names that have only glue rrsets will be marked.
+ * Names that have other occluded rrsets and names containing glue on the 
+ * delegation point will NOT be marked!
+ *
+ * \param[in] name the dnssec name to get the domain name from
+ * \return true if the structure is marked as glue, false otherwise.
+ */
+bool ldns_dnssec_name_is_glue(ldns_dnssec_name *name);
 
 /**
  * Sets the NSEC(3) RR of the given dnssec_name structure
@@ -300,6 +342,17 @@ ldns_dnssec_rrsets *ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
  */
 void ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name);
 
+/**
+ * Prints the RRs in the  dnssec name structure to the given
+ * file descriptor
+ *
+ * \param[in] out the file descriptor to print to
+ * \param[in] fmt the format of the textual representation
+ * \param[in] name the name structure to print the contents of
+ */
+void ldns_dnssec_name_print_fmt(FILE *out, 
+               const ldns_output_format *fmt, ldns_dnssec_name *name);
+
 /**
  * Creates a new dnssec_zone structure
  * \return the allocated structure
@@ -342,6 +395,17 @@ ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone,
  */
 void ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa);
 
+/**
+ * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
+ *
+ * \param[in] out the file descriptor to print the names to
+ * \param[in] fmt the format of the textual representation
+ * \param[in] tree the tree of ldns_dnssec_name structures to print
+ * \param[in] print_soa if true, print SOA records, if false, skip them
+ */
+void ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
+               ldns_rbtree_t *tree, bool print_soa);
+
 /**
  * Prints the complete zone to the given file descriptor
  *
@@ -350,6 +414,16 @@ void ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa
  */
 void ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone);
 
+/**
+ * Prints the complete zone to the given file descriptor
+ *
+ * \param[in] out the file descriptor to print to
+ * \param[in] fmt the format of the textual representation
+ * \param[in] zone the dnssec_zone to print
+ */
+void ldns_dnssec_zone_print_fmt(FILE *out, 
+               const ldns_output_format *fmt, ldns_dnssec_zone *zone);
+
 /**
  * Adds explicit dnssec_name structures for the empty nonterminals
  * in this zone. (this is needed for NSEC3 generation)
index e17846f..99d4f0b 100644 (file)
@@ -98,7 +98,9 @@ enum ldns_enum_status {
        LDNS_STATUS_DNSSEC_EXISTENCE_DENIED,
        LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED,
        LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED,
-       LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND
+       LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND,
+       LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG,
+       LDNS_STATUS_MISSING_RDATA_FIELDS_KEY
 };
 typedef enum ldns_enum_status ldns_status;
 
index 07180bb..f0a14a4 100644 (file)
@@ -39,6 +39,72 @@ extern "C" {
 #define LDNS_APL_MASK           0x7f
 #define LDNS_APL_NEGATION       0x80
 
+/** 
+ * Represent a NULL pointer (in stead of a pointer to a ldns_rr as "; (null)" 
+ * as opposed to outputting nothing at all in such a case.
+ */
+#define LDNS_COMMENT_NULLS             0x0001
+/** Show key id with DNSKEY RR's as comment */
+#define LDNS_COMMENT_KEY_ID            0x0002
+/** Show if a DNSKEY is a ZSK or KSK as comment */
+#define LDNS_COMMENT_KEY_TYPE          0x0004
+/** Show DNSKEY key size as comment */
+#define LDNS_COMMENT_KEY_SIZE          0x0008
+/** Show key id, type and size as comment for DNSKEY RR's */
+#define LDNS_COMMENT_KEY               (LDNS_COMMENT_KEY_ID  \
+                                       |LDNS_COMMENT_KEY_TYPE\
+                                       |LDNS_COMMENT_KEY_SIZE)
+/** Provide bubblebabble representation for DS RR's as comment */
+#define LDNS_COMMENT_BUBBLEBABBLE      0x0010
+/** Show when a NSEC3 RR has the optout flag set as comment */
+#define LDNS_COMMENT_FLAGS             0x0020
+/** Show the unhashed owner and next owner names for NSEC3 RR's as comment */
+#define LDNS_COMMENT_NSEC3_CHAIN       0x0040
+/** Print mark up */
+#define LDNS_COMMENT_LAYOUT            0x0080
+/** Also comment KEY_ID with RRSIGS **/
+#define LDNS_COMMENT_RRSIGS            0x0100
+
+/**
+ * Output format specifier
+ *
+ * Determines how Packets, Resource Records and Resource record data fiels are
+ * formatted when printing or converting to string.
+ * Currently it is only used to specify what aspects of a Resource Record are
+ * annotated in the comment section of the textual representation the record.
+ * This is speciefed with flags and potential exra data (such as for example
+ * a lookup map of hashes to real names for annotation NSEC3 records).
+ */
+struct ldns_struct_output_format
+{
+       /** Specification of how RR's should be formatted in text */
+       int   flags;
+       /** Potential extra data to be used with formatting RR's in text */
+       void *data;
+};
+typedef struct ldns_struct_output_format ldns_output_format;
+
+/**
+ * Standard output format record that disables commenting in the textual 
+ * representation of Resource Records completely.
+ */
+extern const ldns_output_format *ldns_output_format_nocomments;
+/**
+ * Standard output format record that annotated only DNSKEY RR's with commenti
+ * text.
+ */
+extern const ldns_output_format *ldns_output_format_onlykeyids;
+/**
+ * The default output format record. Same as ldns_output_format_onlykeyids.
+ */
+extern const ldns_output_format *ldns_output_format_default;
+/**
+ * Standard output format record that shows all DNSKEY related information in
+ * the comment text, plus the optout flag when set with NSEC3's, plus the
+ * bubblebabble representation of DS RR's.
+ */
+extern const ldns_output_format *ldns_output_format_bubblebabble;
+
 /**
  * Converts an ldns packet opcode value to its mnemonic, and adds that
  * to the output buffer
@@ -352,7 +418,9 @@ ldns_status ldns_rdf2buffer_str(ldns_buffer *output, const ldns_rdf *rdf);
 
 /**
  * Converts the data in the resource record to presentation
- * format (as char *) and appends it to the given buffer
+ * format (as char *) and appends it to the given buffer.
+ * The presentation format of DNSKEY record is annotated with comments giving
+ * the id, type and size of the key.
  *
  * \param[in] output pointer to the buffer to append the data to
  * \param[in] rr the pointer to the rr field to convert
@@ -360,6 +428,21 @@ ldns_status ldns_rdf2buffer_str(ldns_buffer *output, const ldns_rdf *rdf);
  */
 ldns_status ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr);
 
+/**
+ * Converts the data in the resource record to presentation
+ * format (as char *) and appends it to the given buffer.
+ * The presentation format is annotated with comments giving
+ * additional information on the record.
+ *
+ * \param[in] output pointer to the buffer to append the data to
+ * \param[in] fmt how to format the textual representation of the 
+ *            resource record.
+ * \param[in] rr the pointer to the rr field to convert
+ * \return status
+ */
+ldns_status ldns_rr2buffer_str_fmt(ldns_buffer *output, 
+               const ldns_output_format *fmt, const ldns_rr *rr);
+
 /**
  * Converts the data in the DNS packet to presentation
  * format (as char *) and appends it to the given buffer
@@ -370,6 +453,18 @@ ldns_status ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr);
  */
 ldns_status ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt);
 
+/**
+ * Converts the data in the DNS packet to presentation
+ * format (as char *) and appends it to the given buffer
+ *
+ * \param[in] output pointer to the buffer to append the data to
+ * \param[in] fmt how to format the textual representation of the packet
+ * \param[in] pkt the pointer to the packet to convert
+ * \return status
+ */
+ldns_status ldns_pkt2buffer_str_fmt(ldns_buffer *output,
+               const ldns_output_format *fmt, const ldns_pkt *pkt);
+
 /** 
  * Converts an LDNS_RDF_TYPE_NSEC3_SALT rdata element to string format and adds it to the output buffer 
  * \param[in] *rdf The rdata to convert
@@ -441,6 +536,17 @@ char *ldns_rdf2str(const ldns_rdf *rdf);
  */
 char *ldns_rr2str(const ldns_rr *rr);
 
+/**
+ * Converts the data in the resource record to presentation format and
+ * returns that as a char *.
+ * Remember to free it.
+ *
+ * \param[in] fmt how to format the resource record
+ * \param[in] rr The rdata field to convert
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr);
+
 /**
  * Converts the data in the DNS packet to presentation format and
  * returns that as a char *.
@@ -451,6 +557,17 @@ char *ldns_rr2str(const ldns_rr *rr);
  */
 char *ldns_pkt2str(const ldns_pkt *pkt);
 
+/**
+ * Converts the data in the DNS packet to presentation format and
+ * returns that as a char *.
+ * Remember to free it.
+ *
+ * \param[in] fmt how to format the packet
+ * \param[in] pkt The rdata field to convert
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt);
+
 /**
  * Converts a private key to the test presentation fmt and
  * returns that as a char *.
@@ -471,6 +588,18 @@ char *ldns_key2str(const ldns_key *k);
  */
 char *ldns_rr_list2str(const ldns_rr_list *rr_list);
 
+/**
+ * Converts a list of resource records to presentation format
+ * and returns that as a char *.
+ * Remember to free it.
+ *
+ * \param[in] fmt how to format the list of resource records
+ * \param[in] rr_list the rr_list to convert to text
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_rr_list2str_fmt(
+               const ldns_output_format *fmt, const ldns_rr_list *rr_list);
+
 /**
  * Returns the data in the buffer as a null terminated char * string
  * Buffer data must be char * type, and must be freed by the caller
@@ -500,6 +629,18 @@ void ldns_rdf_print(FILE *output, const ldns_rdf *rdf);
  */
 void ldns_rr_print(FILE *output, const ldns_rr *rr);
 
+/**
+ * Prints the data in the resource record to the given file stream
+ * (in presentation format)
+ *
+ * \param[in] output the file stream to print to
+ * \param[in] fmt format of the textual representation
+ * \param[in] rr the resource record to print
+ * \return void
+ */
+void ldns_rr_print_fmt(FILE *output, 
+               const ldns_output_format *fmt, const ldns_rr *rr);
+
 /**
  * Prints the data in the DNS packet to the given file stream
  * (in presentation format)
@@ -510,6 +651,18 @@ void ldns_rr_print(FILE *output, const ldns_rr *rr);
  */
 void ldns_pkt_print(FILE *output, const ldns_pkt *pkt);
 
+/**
+ * Prints the data in the DNS packet to the given file stream
+ * (in presentation format)
+ *
+ * \param[in] output the file stream to print to
+ * \param[in] fmt format of the textual representation
+ * \param[in] pkt the packet to print
+ * \return void
+ */
+void ldns_pkt_print_fmt(FILE *output, 
+               const ldns_output_format *fmt, const ldns_pkt *pkt);
+
 /**
  * Converts a rr_list to presentation format and appends it to
  * the output buffer
@@ -519,6 +672,17 @@ void ldns_pkt_print(FILE *output, const ldns_pkt *pkt);
  */
 ldns_status ldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list);
 
+/**
+ * Converts a rr_list to presentation format and appends it to
+ * the output buffer
+ * \param[in] output the buffer to append output to
+ * \param[in] fmt format of the textual representation
+ * \param[in] list the ldns_rr_list to print
+ * \return ldns_status
+ */
+ldns_status ldns_rr_list2buffer_str_fmt(ldns_buffer *output, 
+               const ldns_output_format *fmt, const ldns_rr_list *list);
+
 /**
  * Converts the header of a packet to presentation format and appends it to
  * the output buffer
@@ -530,11 +694,20 @@ ldns_status ldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt);
 
 /**
  * print a rr_list to output
- * param[in] output the fd to print to
- * param[in] list the rr_list to print
+ * \param[in] output the fd to print to
+ * \param[in] list the rr_list to print
  */
 void ldns_rr_list_print(FILE *output, const ldns_rr_list *list);
 
+/**
+ * print a rr_list to output
+ * \param[in] output the fd to print to
+ * \param[in] fmt format of the textual representation
+ * \param[in] list the rr_list to print
+ */
+void ldns_rr_list_print_fmt(FILE *output, 
+               const ldns_output_format *fmt, const ldns_rr_list *list);
+
 /**
  * Print a resolver (in sofar that is possible) state
  * to output.
@@ -543,6 +716,16 @@ void ldns_rr_list_print(FILE *output, const ldns_rr_list *list);
  */
 void ldns_resolver_print(FILE *output, const ldns_resolver *r);
 
+/**
+ * Print a resolver (in sofar that is possible) state
+ * to output.
+ * \param[in] output the fd to print to
+ * \param[in] fmt format of the textual representation
+ * \param[in] r the resolver to print
+ */
+void ldns_resolver_print_fmt(FILE *output, 
+               const ldns_output_format *fmt, const ldns_resolver *r);
+
 /**
  * Print a zone structure * to output. Note the SOA record
  * is included in this output
@@ -551,6 +734,16 @@ void ldns_resolver_print(FILE *output, const ldns_resolver *r);
  */
 void ldns_zone_print(FILE *output, const ldns_zone *z);
 
+/**
+ * Print a zone structure * to output. Note the SOA record
+ * is included in this output
+ * \param[in] output the fd to print to
+ * \param[in] fmt format of the textual representation
+ * \param[in] z the zone to print
+ */
+void ldns_zone_print_fmt(FILE *output, 
+               const ldns_output_format *fmt, const ldns_zone *z);
+
 /**
  * Print the ldns_rdf containing a dname to the buffer
  * \param[in] output the buffer to print to
index e0f568d..ae5d474 100644 (file)
 #ifndef LDNS_KEYS_H
 #define LDNS_KEYS_H
 
-#ifdef HAVE_SSL
+#include <ldns/common.h>
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 #include <openssl/ssl.h>
-#endif /* HAVE_SSL */
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 #include <ldns/dnssec.h>
 #include <ldns/util.h>
 #include <errno.h>
@@ -53,7 +54,7 @@ enum ldns_enum_algorithm
         LDNS_RSASHA256          = 8,   /* RFC 5702 */
         LDNS_RSASHA512          = 10,  /* RFC 5702 */
         LDNS_ECC_GOST           = 12,  /* RFC 5933 */
-#ifdef USE_ECDSA
+#if LDNS_BUILD_CONFIG_USE_ECDSA
        /* this ifdef has to be removed once it is no longer experimental,
         * to be able to use these values outside of the ldns library itself */
         LDNS_ECDSAP256SHA256    = 13,  /* draft-hoffman-dnssec-ecdsa */
@@ -73,7 +74,7 @@ enum ldns_enum_hash
         LDNS_SHA1               = 1,  /* RFC 4034 */
         LDNS_SHA256             = 2,  /* RFC 4509 */
         LDNS_HASH_GOST          = 3   /* RFC 5933 */
-#ifdef USE_ECDSA
+#if LDNS_BUILD_CONFIG_USE_ECDSA
        /* this ifdef has to be removed once it is no longer experimental,
         * to be able to use these values outside of the ldns library itself */
         ,LDNS_SHA384             = 4   /* draft-hoffman-dnssec-ecdsa EXPERIMENTAL */
@@ -94,7 +95,7 @@ enum ldns_enum_signing_algorithm
        LDNS_SIGN_RSASHA512      = LDNS_RSASHA512,
        LDNS_SIGN_DSA_NSEC3      = LDNS_DSA_NSEC3,
        LDNS_SIGN_ECC_GOST       = LDNS_ECC_GOST,
-#ifdef USE_ECDSA
+#if LDNS_BUILD_CONFIG_USE_ECDSA
        /* this ifdef has to be removed once it is no longer experimental,
         * to be able to use these values outside of the ldns library itself */
         LDNS_SIGN_ECDSAP256SHA256 = LDNS_ECDSAP256SHA256,
@@ -123,13 +124,13 @@ struct ldns_struct_key {
        /** Storage pointers for the types of keys supported */
        /* TODO remove unions? */
        struct {
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 #ifndef S_SPLINT_S
                /* The key can be an OpenSSL EVP Key
                 */
                EVP_PKEY *key;
 #endif
-#endif /* HAVE_SSL */
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
                /**
                 * The key can be an HMAC key
                 */
@@ -220,7 +221,7 @@ ldns_status ldns_key_new_frm_fp(ldns_key **k, FILE *fp);
  */
 ldns_status ldns_key_new_frm_fp_l(ldns_key **k, FILE *fp, int *line_nr);
 
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 /**
  * Read the key with the given id from the given engine and store it
  * in the given ldns_key structure. The algorithm type is set
@@ -235,9 +236,9 @@ ldns_status ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldn
  * \return NULL on failure otherwise a RSA structure
  */
 RSA *ldns_key_new_frm_fp_rsa(FILE *fp);
-#endif /* HAVE_SSL */
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 /**
  * frm_fp helper function. This function parses the
  * remainder of the (RSA) priv. key file generated from bind9
@@ -246,9 +247,9 @@ RSA *ldns_key_new_frm_fp_rsa(FILE *fp);
  * \return NULL on failure otherwise a RSA structure
  */
 RSA *ldns_key_new_frm_fp_rsa_l(FILE *fp, int *line_nr);
-#endif /* HAVE_SSL */
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 /**
  * frm_fp helper function. This function parses the
  * remainder of the (DSA) priv. key file
@@ -256,9 +257,9 @@ RSA *ldns_key_new_frm_fp_rsa_l(FILE *fp, int *line_nr);
  * \return NULL on failure otherwise a RSA structure
  */
 DSA *ldns_key_new_frm_fp_dsa(FILE *fp);
-#endif /* HAVE_SSL */
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 /**
  * frm_fp helper function. This function parses the
  * remainder of the (DSA) priv. key file
@@ -267,9 +268,9 @@ DSA *ldns_key_new_frm_fp_dsa(FILE *fp);
  * \return NULL on failure otherwise a RSA structure
  */
 DSA *ldns_key_new_frm_fp_dsa_l(FILE *fp, int *line_nr);
-#endif /* HAVE_SSL */
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 /**
  * frm_fp helper function. This function parses the
  * remainder of the (HMAC-MD5) key file
@@ -281,7 +282,7 @@ DSA *ldns_key_new_frm_fp_dsa_l(FILE *fp, int *line_nr);
 unsigned char *ldns_key_new_frm_fp_hmac(FILE *fp, size_t *hmac_size);
 #endif
 
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 /**
  * frm_fp helper function. This function parses the
  * remainder of the (HMAC-MD5) key file
@@ -292,7 +293,7 @@ unsigned char *ldns_key_new_frm_fp_hmac(FILE *fp, size_t *hmac_size);
  * \return NULL on failure otherwise a newly allocated char buffer
  */
 unsigned char *ldns_key_new_frm_fp_hmac_l(FILE *fp, int *line_nr, size_t *hmac_size);
-#endif /* HAVE_SSL */
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 
 /* acces write functions */
 /**
@@ -301,7 +302,7 @@ unsigned char *ldns_key_new_frm_fp_hmac_l(FILE *fp, int *line_nr, size_t *hmac_s
  * \param[in] l the algorithm
  */
 void ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l);
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 /**
  * Set the key's evp key
  * \param[in] k the key
@@ -331,7 +332,7 @@ int ldns_key_EVP_load_gost_id(void);
 
 /** Release the engine reference held for the GOST engine. */
 void ldns_key_EVP_unload_gost(void);
-#endif /* HAVE_SSL */
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 
 /**
  * Set the key's hmac data
@@ -424,7 +425,7 @@ size_t ldns_key_list_key_count(const ldns_key_list *key_list);
  */
 ldns_key *ldns_key_list_key(const ldns_key_list *key, size_t nr);
 
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 /**
  * returns the (openssl) RSA struct contained in the key
  * \param[in] k the key to look in
@@ -437,14 +438,14 @@ RSA *ldns_key_rsa_key(const ldns_key *k);
  * \return the RSA * structure in the key
  */
 EVP_PKEY *ldns_key_evp_key(const ldns_key *k);
-#endif /* HAVE_SSL */
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 
 /**
  * returns the (openssl) DSA struct contained in the key
  */
-#ifdef HAVE_SSL
+#if LDNS_BUILD_CONFIG_HAVE_SSL
 DSA *ldns_key_dsa_key(const ldns_key *k);
-#endif /* HAVE_SSL */
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
 
 /**
  * return the signing alg of the key
index 86e31de..2e1dd76 100644 (file)
@@ -176,6 +176,7 @@ enum ldns_enum_rr_type
        LDNS_RR_TYPE_DHCID = 49,
 
        LDNS_RR_TYPE_NSEC3 = 50,
+       LDNS_RR_TYPE_NSEC3PARAM = 51,
        LDNS_RR_TYPE_NSEC3PARAMS = 51,
 
         /** draft-ietf-dnsop-trust-history */
index beb0b6f..238767a 100644 (file)
@@ -55,17 +55,14 @@ extern "C" {
  * Import u_intXX_t size_t type definitions from system headers.  You
  * may need to change this, or define these things yourself in this
  * file.
- *
- * (include ldns/config.h so HAVE_INTTYPES is defined (or not, depending
- * on the system))
  */
 #include <sys/types.h>
 
-#ifdef HAVE_INTTYPES_H
+#if LDNS_BUILD_CONFIG_HAVE_INTTYPES_H
 
 #include <inttypes.h>
 
-#endif /* HAVE_INTTYPES_H */
+#endif /* LDNS_BUILD_CONFIG_HAVE_INTTYPES_H */
 
 
 /*** SHA-256/384/512 Various Length Definitions ***********************/
index a683ea8..0d129a0 100644 (file)
@@ -117,7 +117,8 @@ bool ldns_zone_push_rr(ldns_zone *z, ldns_rr *rr);
  *
  * Due to the current zone implementation (as a list of rr's), this
  * function is extremely slow. Another (probably better) way to do this
- * is to use an ldns_dnssec_zone structure and the mark_glue function 
+ * is to use an ldns_dnssec_zone structure and the 
+ * ldns_dnssec_mark_and_get_glue() function.
  *
  * \param[in] z the zone to look for glue
  * \return the rr_list with the glue
index bf8766b..4407e4a 100644 (file)
@@ -341,6 +341,11 @@ ldns_udp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t
        }
 
        if (ldns_udp_send_query(qbin, sockfd, to, tolen) == 0) {
+#ifndef USE_WINSOCK
+               close(sockfd);
+#else
+               closesocket(sockfd);
+#endif
                return 0;
        }
        return sockfd;
@@ -678,6 +683,11 @@ ldns_tcp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t
        }
        
        if (ldns_tcp_send_query(qbin, sockfd, to, tolen) == 0) {
+#ifndef USE_WINSOCK
+               close(sockfd);
+#else
+               closesocket(sockfd);
+#endif
                return 0;
        }
        
index 0487873..2011081 100644 (file)
@@ -132,13 +132,15 @@ ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *li
                        }
                }
                if (c != '\0' && c != '\n') {
-                       *t++ = c;
                        i++;
                }
                if (limit > 0 && i >= limit) {
                        *t = '\0';
                        return -1;
                }
+               if (c != '\0' && c != '\n') {
+                       *t++ = c;
+               }
                if (c == '\\' && prev_c == '\\')
                        prev_c = 0;
                else    prev_c = c;
@@ -302,12 +304,12 @@ ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
                         }
                }
 
-               *t++ = c;
                i++;
                if (limit > 0 && i >= limit) {
                        *t = '\0';
                        return -1;
                }
+               *t++ = c;
 
                if (c == '\\' && lc == '\\') {
                        lc = 0;
index 735e6f1..732f2a8 100644 (file)
@@ -1031,12 +1031,41 @@ ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name,
        return pkt;
 }
 
+static size_t *
+ldns_resolver_backup_rtt(ldns_resolver *r)
+{
+       size_t *new_rtt;
+       size_t *old_rtt = ldns_resolver_rtt(r);
+
+       if (old_rtt && ldns_resolver_nameserver_count(r)) {
+               new_rtt = LDNS_XMALLOC(size_t
+                               , ldns_resolver_nameserver_count(r));
+               memcpy(new_rtt, old_rtt, sizeof(size_t)
+                               * ldns_resolver_nameserver_count(r));
+               ldns_resolver_set_rtt(r, new_rtt);
+               return old_rtt;
+       }
+       return NULL;
+}
+
+static void
+ldns_resolver_restore_rtt(ldns_resolver *r, size_t *old_rtt)
+{
+       size_t *cur_rtt = ldns_resolver_rtt(r);
+
+       if (cur_rtt) {
+               LDNS_FREE(cur_rtt);
+       }
+       ldns_resolver_set_rtt(r, old_rtt);
+}
+
 ldns_status
 ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r,
                                   ldns_pkt *query_pkt)
 {
        ldns_pkt *answer_pkt = NULL;
        ldns_status stat = LDNS_STATUS_OK;
+       size_t *rtt;
 
        stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt);
        if (stat != LDNS_STATUS_OK) {
@@ -1051,9 +1080,21 @@ ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r,
                        if (ldns_pkt_tc(answer_pkt)) {
                                /* was EDNS0 set? */
                                if (ldns_pkt_edns_udp_size(query_pkt) == 0) {
-                                       ldns_pkt_set_edns_udp_size(query_pkt, 4096);
+                                       ldns_pkt_set_edns_udp_size(query_pkt
+                                                       , 4096);
                                        ldns_pkt_free(answer_pkt);
-                                       stat = ldns_send(&answer_pkt, r, query_pkt);
+                                       /* Nameservers should not become 
+                                        * unreachable because fragments are
+                                        * dropped (network error). We might
+                                        * still have success with TCP.
+                                        * Therefore maintain reachability
+                                        * statuses of the nameservers by
+                                        * backup and restore the rtt list.
+                                        */
+                                       rtt = ldns_resolver_backup_rtt(r);
+                                       stat = ldns_send(&answer_pkt, r
+                                                       , query_pkt);
+                                       ldns_resolver_restore_rtt(r, rtt);
                                }
                                /* either way, if it is still truncated, use TCP */
                                if (stat != LDNS_STATUS_OK ||
index 7b799b9..2caed50 100644 (file)
@@ -431,7 +431,19 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                                                cur_hex_data_size = 0;
                                                while(cur_hex_data_size < 2 * hex_data_size) {
                                                        c = ldns_bget_token(rd_buf, rd, delimiters, LDNS_MAX_RDFLEN);
-                                                       rd_strlen = strlen(rd);
+                                                       if (c != -1) {
+                                                               rd_strlen = strlen(rd);
+                                                       }
+                                                       if (c == -1 || (size_t)cur_hex_data_size + rd_strlen > 2 * (size_t)hex_data_size) {
+                                                               LDNS_FREE(hex_data_str);
+                                                               LDNS_FREE(rd);
+                                                               LDNS_FREE(b64);
+                                                               ldns_buffer_free(rd_buf);
+                                                               ldns_buffer_free(rr_buf);
+                                                               LDNS_FREE(rdata);
+                                                               ldns_rr_free(new);
+                                                               return LDNS_STATUS_SYNTAX_RDATA_ERR;
+                                                       }
                                                        strncpy(hex_data_str + cur_hex_data_size, rd, rd_strlen);
                                                        cur_hex_data_size += rd_strlen;
                                                }
@@ -826,7 +838,7 @@ ldns_rr_pop_rdf(ldns_rr *rr)
 ldns_rdf *
 ldns_rr_rdf(const ldns_rr *rr, size_t nr)
 {
-       if (nr < ldns_rr_rd_count(rr)) {
+       if (rr && nr < ldns_rr_rd_count(rr)) {
                return rr->_rdata_fields[nr];
        } else {
                return NULL;
@@ -1626,7 +1638,10 @@ ldns_rr_compare_ds_dnskey(ldns_rr *ds,
                return false;
        }
 
-algo = ldns_rdf2native_int8(ldns_rr_rdf(ds, 2));
+       if (ldns_rr_rdf(ds, 2) == NULL) {
+               return false;
+       }
+       algo = ldns_rdf2native_int8(ldns_rr_rdf(ds, 2));
 
        ds_gen = ldns_key_rr2ds(dnskey, algo);
        if (ds_gen) {
@@ -1900,7 +1915,7 @@ static const ldns_rdf_type type_nsec3_wireformat[] = {
        LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_NSEC3_SALT, LDNS_RDF_TYPE_NSEC3_NEXT_OWNER, LDNS_RDF_TYPE_NSEC
 };
 
-static const ldns_rdf_type type_nsec3params_wireformat[] = {
+static const ldns_rdf_type type_nsec3param_wireformat[] = {
 /*     LDNS_RDF_TYPE_NSEC3_PARAMS_VARS*/
        LDNS_RDF_TYPE_INT8,
        LDNS_RDF_TYPE_INT8,
@@ -2034,7 +2049,7 @@ static ldns_rr_descriptor rdata_field_descriptors[] = {
        /* 50 */
        {LDNS_RR_TYPE_NSEC3, "NSEC3", 5, 6, type_nsec3_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
        /* 51 */
-{LDNS_RR_TYPE_NSEC3PARAMS, "NSEC3PARAM", 4, 4, type_nsec3params_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NSEC3PARAM, "NSEC3PARAM", 4, 4, type_nsec3param_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
        /* 52 */
 {LDNS_RR_TYPE_NULL, "TYPE52", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 {LDNS_RR_TYPE_NULL, "TYPE53", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
@@ -2234,7 +2249,11 @@ static ldns_rr_descriptor rdata_field_descriptors[] = {
 {LDNS_RR_TYPE_NULL, "TYPE247", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 {LDNS_RR_TYPE_NULL, "TYPE248", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 {LDNS_RR_TYPE_NULL, "TYPE249", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_TSIG, "TSIG", 8, 9, type_tsig_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+/* LDNS_RDF_TYPE_INT16_DATA essentially takes two fields (length and data) and
+ * makes them into one. So, while in rfc 2845 is specified that a TSIG may have 
+ * 8 or 9 rdata fields, by this implementation, the min/max are 7 each. 
+ */
+{LDNS_RR_TYPE_TSIG, "TSIG", 7, 7, type_tsig_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 /* split in array, no longer contiguous */
 {LDNS_RR_TYPE_DLV, "DLV", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 }
 };
index 700372b..9dca09e 100644 (file)
@@ -331,7 +331,8 @@ ldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
 size_t 
 ldns_rr_dnskey_key_size(const ldns_rr *key) 
 {
-       if (!key) {
+       if (!key || !ldns_rr_dnskey_key(key) 
+                       || !ldns_rr_dnskey_algorithm(key)) {
                return 0;
        }
        return ldns_rr_dnskey_key_size_raw((unsigned char*)ldns_rdf_data(ldns_rr_dnskey_key(key)),
index 26b7716..6ba4ab5 100644 (file)
@@ -605,7 +605,7 @@ void ldns_sha256_final(sha2_byte digest[], ldns_sha256_CTX* context) {
        }
 
        /* Clean up state data: */
-       MEMSET_BZERO(context, sizeof(context));
+       MEMSET_BZERO(context, sizeof(ldns_sha256_CTX));
        usedspace = 0;
 }
 
@@ -915,7 +915,7 @@ void ldns_sha512_final(sha2_byte digest[], ldns_sha512_CTX* context) {
        }
 
        /* Zero out state data */
-       MEMSET_BZERO(context, sizeof(context));
+       MEMSET_BZERO(context, sizeof(ldns_sha512_CTX));
 }
 
 unsigned char *
@@ -968,7 +968,7 @@ void ldns_sha384_final(sha2_byte digest[], ldns_sha384_CTX* context) {
        }
 
        /* Zero out state data */
-       MEMSET_BZERO(context, sizeof(context));
+       MEMSET_BZERO(context, sizeof(ldns_sha384_CTX));
 }
 
 unsigned char *
index 2eda2f8..4ec9d37 100644 (file)
@@ -460,7 +460,10 @@ ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
        size_t i = 0;
 
        /* [!]afi:address/prefix */
-       if (strlen(my_str) < 2) {
+       if (strlen(my_str) < 2
+                       || strchr(my_str, ':') == NULL
+                       || strchr(my_str, '/') == NULL
+                       || strchr(my_str, ':') > strchr(my_str, '/')) {
                return LDNS_STATUS_INVALID_STR;
        }
 
index 7fcf21d..90c20a0 100644 (file)
@@ -66,9 +66,9 @@ ldns_tsig_prepare_pkt_wire(uint8_t *wire, size_t wire_len, size_t *result_len)
 
        ldns_status status;
 
-        if(wire_len < LDNS_HEADER_SIZE) {
-                return NULL;
-        }
+       if(wire_len < LDNS_HEADER_SIZE) {
+               return NULL;
+       }
        /* fake parse the wire */
        qd_count = LDNS_QDCOUNT(wire);
        an_count = LDNS_ANCOUNT(wire);
@@ -118,9 +118,9 @@ ldns_tsig_prepare_pkt_wire(uint8_t *wire, size_t wire_len, size_t *result_len)
 
        *result_len = pos;
        wire2 = LDNS_XMALLOC(uint8_t, *result_len);
-        if(!wire2) {
-                return NULL;
-        }
+       if(!wire2) {
+               return NULL;
+       }
        memcpy(wire2, wire, *result_len);
 
        ldns_write_uint16(wire2 + LDNS_ARCOUNT_OFF, ar_count);
@@ -134,19 +134,23 @@ ldns_digest_function(char *name)
 {
        /* these are the mandatory algorithms from RFC4635 */
        /* The optional algorithms are not yet implemented */
-       if (strlen(name) == 12 && strncasecmp(name, "hmac-sha256.", 11) == 0) {
+       if (strlen(name) == 12 
+                       && strncasecmp(name, "hmac-sha256.", 11) == 0) {
 #ifdef HAVE_EVP_SHA256
                return EVP_sha256();
 #else
                return NULL;
 #endif
-       } else if (strlen(name) == 10 && strncasecmp(name, "hmac-sha1.", 9) == 0)
+       } else if (strlen(name) == 10
+                       && strncasecmp(name, "hmac-sha1.", 9) == 0) {
                return EVP_sha1();
-       else if (strlen(name) == 25 && strncasecmp(name,
-                    "hmac-md5.sig-alg.reg.int.", 25) == 0)
+       } else if (strlen(name) == 25 
+                       && strncasecmp(name, "hmac-md5.sig-alg.reg.int.", 25) 
+                       == 0) {
                return EVP_md5();
-       else
+       } else {
                return NULL;
+       }
 }
 #endif
 
@@ -157,23 +161,37 @@ ldns_tsig_mac_new(ldns_rdf **tsig_mac, uint8_t *pkt_wire, size_t pkt_wire_size,
                ldns_rdf *algorithm_rdf, ldns_rdf *time_signed_rdf, ldns_rdf *error_rdf,
                ldns_rdf *other_data_rdf, ldns_rdf *orig_mac_rdf, int tsig_timers_only)
 {
+       ldns_status status;
        char *wireformat;
        int wiresize;
-       unsigned char *mac_bytes;
-       unsigned char *key_bytes;
+       unsigned char *mac_bytes = NULL;
+       unsigned char *key_bytes = NULL;
        int key_size;
        const EVP_MD *digester;
-       char *algorithm_name;
+       char *algorithm_name = NULL;
        unsigned int md_len = EVP_MAX_MD_SIZE;
        ldns_rdf *result = NULL;
        ldns_buffer *data_buffer = NULL;
+       ldns_rdf *canonical_key_name_rdf = NULL;
+       ldns_rdf *canonical_algorithm_rdf = NULL;
+       
+       if (key_name_rdf == NULL || algorithm_rdf == NULL) {
+               return LDNS_STATUS_NULL;
+       }
+       canonical_key_name_rdf  = ldns_rdf_clone(key_name_rdf);
+       canonical_algorithm_rdf = ldns_rdf_clone(algorithm_rdf);
 
+       if (canonical_key_name_rdf == NULL 
+                       || canonical_algorithm_rdf  == NULL) {
+               return LDNS_STATUS_MEM_ERR;
+       }
        /*
         * prepare the digestable information
         */
        data_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-       if(!data_buffer) {
-               return LDNS_STATUS_MEM_ERR;
+       if (!data_buffer) {
+               status = LDNS_STATUS_MEM_ERR;
+               goto clean;
        }
        /* if orig_mac is not NULL, add it too */
        if (orig_mac_rdf) {
@@ -181,10 +199,14 @@ ldns_tsig_mac_new(ldns_rdf **tsig_mac, uint8_t *pkt_wire, size_t pkt_wire_size,
        }
        ldns_buffer_write(data_buffer, pkt_wire, pkt_wire_size);
        if (!tsig_timers_only) {
-               (void)ldns_rdf2buffer_wire(data_buffer, key_name_rdf);
+               ldns_dname2canonical(canonical_key_name_rdf);
+               (void)ldns_rdf2buffer_wire(data_buffer, 
+                               canonical_key_name_rdf);
                ldns_buffer_write_u16(data_buffer, LDNS_RR_CLASS_ANY);
                ldns_buffer_write_u32(data_buffer, 0);
-               (void)ldns_rdf2buffer_wire(data_buffer, algorithm_rdf);
+               ldns_dname2canonical(canonical_algorithm_rdf);
+               (void)ldns_rdf2buffer_wire(data_buffer, 
+                               canonical_algorithm_rdf);
        }
        (void)ldns_rdf2buffer_wire(data_buffer, time_signed_rdf);
        (void)ldns_rdf2buffer_wire(data_buffer, fudge_rdf);
@@ -198,35 +220,29 @@ ldns_tsig_mac_new(ldns_rdf **tsig_mac, uint8_t *pkt_wire, size_t pkt_wire_size,
 
        algorithm_name = ldns_rdf2str(algorithm_rdf);
        if(!algorithm_name) {
-               ldns_buffer_free(data_buffer);
-               return LDNS_STATUS_MEM_ERR;
+               status = LDNS_STATUS_MEM_ERR;
+               goto clean;
        }
 
        /* prepare the key */
        key_bytes = LDNS_XMALLOC(unsigned char,
                        ldns_b64_pton_calculate_size(strlen(key_data)));
        if(!key_bytes) {
-               LDNS_FREE(algorithm_name);
-               ldns_buffer_free(data_buffer);
-               return LDNS_STATUS_MEM_ERR;
+               status = LDNS_STATUS_MEM_ERR;
+               goto clean;
        }
        key_size = ldns_b64_pton(key_data, key_bytes,
-                ldns_b64_pton_calculate_size(strlen(key_data)));
+       ldns_b64_pton_calculate_size(strlen(key_data)));
        if (key_size < 0) {
-               LDNS_FREE(algorithm_name);
-               LDNS_FREE(key_bytes);
-               ldns_buffer_free(data_buffer);
-               /* LDNS_STATUS_INVALID_B64 */
-               return LDNS_STATUS_INVALID_B64;
+               status = LDNS_STATUS_INVALID_B64;
+               goto clean;
        }
        /* hmac it */
        /* 2 spare bytes for the length */
        mac_bytes = LDNS_XMALLOC(unsigned char, md_len+2);
        if(!mac_bytes) {
-               LDNS_FREE(algorithm_name);
-               LDNS_FREE(key_bytes);
-               ldns_buffer_free(data_buffer);
-               return LDNS_STATUS_MEM_ERR;
+               status = LDNS_STATUS_MEM_ERR;
+               goto clean;
        }
        memset(mac_bytes, 0, md_len+2);
 
@@ -240,21 +256,19 @@ ldns_tsig_mac_new(ldns_rdf **tsig_mac, uint8_t *pkt_wire, size_t pkt_wire_size,
                result = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT16_DATA, md_len + 2,
                                mac_bytes);
        } else {
-               LDNS_FREE(algorithm_name);
-               LDNS_FREE(mac_bytes);
-               LDNS_FREE(key_bytes);
-               ldns_buffer_free(data_buffer);
-               return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
+               status = LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
+               goto clean;
        }
-
-       LDNS_FREE(algorithm_name);
+       *tsig_mac = result;
+       status = LDNS_STATUS_OK;
+  clean:
        LDNS_FREE(mac_bytes);
        LDNS_FREE(key_bytes);
+       LDNS_FREE(algorithm_name);
        ldns_buffer_free(data_buffer);
-
-       *tsig_mac = result;
-
-       return LDNS_STATUS_OK;
+       ldns_rdf_free(canonical_algorithm_rdf);
+       ldns_rdf_free(canonical_key_name_rdf);
+       return status;
 }
 #endif /*  HAVE_SSL */
 
@@ -288,7 +302,7 @@ ldns_pkt_tsig_verify_next(ldns_pkt *pkt, uint8_t *wire, size_t wirelen, const ch
 
        ldns_rr *orig_tsig = ldns_pkt_tsig(pkt);
 
-       if (!orig_tsig) {
+       if (!orig_tsig || ldns_rr_rd_count(orig_tsig) <= 6) {
                ldns_rdf_deep_free(key_name_rdf);
                return false;
        }
@@ -366,19 +380,19 @@ ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_dat
        ldns_rdf *time_signed_rdf = NULL;
 
        algorithm_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, algorithm_name);
-        if(!key_name_rdf || !algorithm_rdf) {
-                status = LDNS_STATUS_MEM_ERR;
-                goto clean;
-        }
+       if(!key_name_rdf || !algorithm_rdf) {
+               status = LDNS_STATUS_MEM_ERR;
+               goto clean;
+       }
 
        /* eww don't have create tsigtime rdf yet :( */
        /* bleh :p */
        if (gettimeofday(&tv_time_signed, NULL) == 0) {
                time_signed = LDNS_XMALLOC(uint8_t, 6);
-                if(!time_signed) {
-                        status = LDNS_STATUS_MEM_ERR;
-                        goto clean;
-                }
+               if(!time_signed) {
+                       status = LDNS_STATUS_MEM_ERR;
+                       goto clean;
+               }
                ldns_write_uint64_as_uint48(time_signed,
                                (uint64_t)tv_time_signed.tv_sec);
        } else {
@@ -387,11 +401,11 @@ ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_dat
        }
 
        time_signed_rdf = ldns_rdf_new(LDNS_RDF_TYPE_TSIGTIME, 6, time_signed);
-        if(!time_signed_rdf) {
-                LDNS_FREE(time_signed);
-                status = LDNS_STATUS_MEM_ERR;
-                goto clean;
-        }
+       if(!time_signed_rdf) {
+               LDNS_FREE(time_signed);
+               status = LDNS_STATUS_MEM_ERR;
+               goto clean;
+       }
 
        fudge_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, fudge);
 
@@ -401,10 +415,10 @@ ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_dat
 
        other_data_rdf = ldns_native2rdf_int16_data(0, NULL);
 
-        if(!fudge_rdf || !orig_id_rdf || !error_rdf || !other_data_rdf) {
-                status = LDNS_STATUS_MEM_ERR;
-                goto clean;
-        }
+       if(!fudge_rdf || !orig_id_rdf || !error_rdf || !other_data_rdf) {
+               status = LDNS_STATUS_MEM_ERR;
+               goto clean;
+       }
 
        if (ldns_pkt2wire(&pkt_wire, pkt, &pkt_wire_len) != LDNS_STATUS_OK) {
                status = LDNS_STATUS_ERR;
@@ -423,10 +437,10 @@ ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_dat
 
        /* Create the TSIG RR */
        tsig_rr = ldns_rr_new();
-        if(!tsig_rr) {
-                status = LDNS_STATUS_MEM_ERR;
-                goto clean;
-        }
+       if(!tsig_rr) {
+               status = LDNS_STATUS_MEM_ERR;
+               goto clean;
+       }
        ldns_rr_set_owner(tsig_rr, key_name_rdf);
        ldns_rr_set_class(tsig_rr, LDNS_RR_CLASS_ANY);
        ldns_rr_set_type(tsig_rr, LDNS_RR_TYPE_TSIG);
index 01e67aa..96f72ce 100644 (file)
@@ -113,7 +113,8 @@ ldns_update_soa_mname(ldns_rdf *zone, ldns_resolver *r,
        /* Expect a SOA answer. */
        *mname = NULL;
        while ((soa_rr = ldns_rr_list_pop_rr(ldns_pkt_answer(resp)))) {
-               if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA)
+               if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
+                               || ldns_rr_rdf(soa_rr, 0) == NULL)
                        continue;
                /* [RFC1035 3.3.13] */
                *mname = ldns_rdf_clone(ldns_rr_rdf(soa_rr, 0));
@@ -161,7 +162,8 @@ ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r,
 
        /* XXX Is it safe to only look in authority section here? */
        while ((soa_rr = ldns_rr_list_pop_rr(ldns_pkt_authority(resp)))) {
-               if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA)
+               if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
+                               || ldns_rr_rdf(soa_rr, 0) == NULL)
                        continue;
                /* [RFC1035 3.3.13] */
                soa_mname = ldns_rdf_clone(ldns_rr_rdf(soa_rr, 0));
@@ -244,7 +246,8 @@ ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r,
 
        /* XXX Is it safe to only look in authority section here, too? */
        while ((soa_rr = ldns_rr_list_pop_rr(ldns_pkt_authority(resp)))) {
-               if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA)
+               if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
+                               || ldns_rr_rdf(soa_rr, 0) == NULL)
                        continue;
                /* [RFC1035 3.3.13] */
                soa_mname = ldns_rdf_clone(ldns_rr_rdf(soa_rr, 0));
index eb24f81..01d29c1 100644 (file)
@@ -199,10 +199,14 @@ static const int mdays[] = {
        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
 };
 
+#define LDNS_MOD(x,y) (((x) % (y) < 0) ? ((x) % (y) + (y)) : ((x) % (y)))
+#define LDNS_DIV(x,y) (((x) % (y) < 0) ? ((x) / (y) -  1 ) : ((x) / (y)))
+
 static int
 is_leap_year(int year)
 {
-       return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
+       return LDNS_MOD(year,   4) == 0 && (LDNS_MOD(year, 100) != 0 
+           || LDNS_MOD(year, 400) == 0);
 }
 
 static int
@@ -210,7 +214,9 @@ leap_days(int y1, int y2)
 {
        --y1;
        --y2;
-       return (y2/4 - y1/4) - (y2/100 - y1/100) + (y2/400 - y1/400);
+       return (LDNS_DIV(y2,   4) - LDNS_DIV(y1,   4)) - 
+              (LDNS_DIV(y2, 100) - LDNS_DIV(y1, 100)) +
+              (LDNS_DIV(y2, 400) - LDNS_DIV(y1, 400));
 }
 
 /*
@@ -241,6 +247,100 @@ mktime_from_utc(const struct tm *tm)
        return seconds;
 }
 
+#if SIZEOF_TIME_T <= 4
+
+static void
+ldns_year_and_yday_from_days_since_epoch(int64_t days, struct tm *result)
+{
+       int year = 1970;
+       int new_year;
+
+       while (days < 0 || days >= (int64_t) (is_leap_year(year) ? 366 : 365)) {
+               new_year = year + (int) LDNS_DIV(days, 366);
+               if (year == new_year) {
+                       year += days < 0 ? -1 : 1;
+               }
+               days -= (new_year - year) * 365;
+               days -= leap_days(year, new_year);
+               year  = new_year;
+       }
+       result->tm_year = year;
+       result->tm_yday = (int) days;
+}
+
+/* Number of days per month in a leap year. */
+static const int leap_year_mdays[] = {
+       31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+static void
+ldns_mon_and_mday_from_year_and_yday(struct tm *result)
+{
+       int idays = result->tm_yday;
+       const int *mon_lengths = is_leap_year(result->tm_year) ? 
+                                       leap_year_mdays : mdays;
+
+       result->tm_mon = 0;
+       while  (idays >= mon_lengths[result->tm_mon]) {
+               idays -= mon_lengths[result->tm_mon++];
+       }
+       result->tm_mday = idays + 1;
+}
+
+static void
+ldns_wday_from_year_and_yday(struct tm *result)
+{
+       result->tm_wday = 4 /* 1-1-1970 was a thursday */
+                       + LDNS_MOD((result->tm_year - 1970), 7) * LDNS_MOD(365, 7)
+                       + leap_days(1970, result->tm_year)
+                       + result->tm_yday;
+       result->tm_wday = LDNS_MOD(result->tm_wday, 7);
+       if (result->tm_wday < 0) {
+               result->tm_wday += 7;
+       }
+}
+
+static struct tm *
+ldns_gmtime64_r(int64_t clock, struct tm *result)
+{
+       result->tm_isdst = 0;
+       result->tm_sec   = (int) LDNS_MOD(clock, 60);
+       clock            =       LDNS_DIV(clock, 60);
+       result->tm_min   = (int) LDNS_MOD(clock, 60);
+       clock            =       LDNS_DIV(clock, 60);
+       result->tm_hour  = (int) LDNS_MOD(clock, 24);
+       clock            =       LDNS_DIV(clock, 24);
+
+       ldns_year_and_yday_from_days_since_epoch(clock, result);
+       ldns_mon_and_mday_from_year_and_yday(result);
+       ldns_wday_from_year_and_yday(result);
+       result->tm_year -= 1900;
+
+       return result;
+}
+
+#endif /* SIZEOF_TIME_T <= 4 */
+
+static int64_t
+ldns_serial_arithmitics_time(int32_t time, time_t now)
+{
+       int32_t offset = time - (int32_t) now;
+       return (int64_t) now + offset;
+}
+
+
+struct tm *
+ldns_serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result)
+{
+#if SIZEOF_TIME_T <= 4
+       int64_t secs_since_epoch = ldns_serial_arithmitics_time(time, now);
+       return  ldns_gmtime64_r(secs_since_epoch, result);
+#else
+       time_t  secs_since_epoch = ldns_serial_arithmitics_time(time, now);
+       return  gmtime_r(&secs_since_epoch, result);
+#endif
+}
+
 /**
  * Init the random source
  * applications should call this if they need entropy data within ldns
index 917af8b..0616a14 100644 (file)
@@ -228,7 +228,8 @@ ldns_zone_glue_rr_list(const ldns_zone *z)
                        a = ldns_rr_list_rr(addr, j);
                        dname_a = ldns_rr_owner(a);
 
-                       if (ldns_dname_is_subdomain(dname_a, ns_owner)) {
+                       if (ldns_dname_is_subdomain(dname_a, ns_owner) ||
+                               ldns_dname_compare(dname_a, ns_owner) == 0) {
                                /* GLUE! */
                                if (!ldns_rr_list_push_rr(glue, a)) goto memory_error;
                        }