Update to ldns-1.6.7
authorJan Lentfer <Jan.Lentfer@web.de>
Thu, 30 Dec 2010 00:30:02 +0000 (01:30 +0100)
committerJan Lentfer <Jan.Lentfer@web.de>
Thu, 30 Dec 2010 22:05:30 +0000 (23:05 +0100)
67 files changed:
contrib/ldns/Changelog
contrib/ldns/README
contrib/ldns/README.DELETED [deleted file]
contrib/ldns/README.DRAGONFLY [deleted file]
contrib/ldns/buffer.c
contrib/ldns/compat/b32_ntop.c
contrib/ldns/compat/b32_pton.c
contrib/ldns/compat/b64_ntop.c
contrib/ldns/compat/b64_pton.c
contrib/ldns/compat/fake-rfc2553.h
contrib/ldns/compat/snprintf.c
contrib/ldns/dname.c
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/drill.1
contrib/ldns/drill/drill.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/config.h.in [deleted file]
contrib/ldns/ldns/dname.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/higher.h
contrib/ldns/ldns/host2str.h
contrib/ldns/ldns/host2wire.h
contrib/ldns/ldns/keys.h
contrib/ldns/ldns/ldns.h [deleted file]
contrib/ldns/ldns/net.h.in [deleted file]
contrib/ldns/ldns/packet.h
contrib/ldns/ldns/parse.h
contrib/ldns/ldns/rbtree.h
contrib/ldns/ldns/rdata.h
contrib/ldns/ldns/resolver.h
contrib/ldns/ldns/rr.h
contrib/ldns/ldns/rr_functions.h
contrib/ldns/ldns/sha1.h
contrib/ldns/ldns/str2host.h
contrib/ldns/ldns/tsig.h
contrib/ldns/ldns/update.h
contrib/ldns/ldns/util.h.in [deleted file]
contrib/ldns/ldns/wire2host.h
contrib/ldns/ldns/zone.h
contrib/ldns/net.c
contrib/ldns/packet.c
contrib/ldns/parse.c
contrib/ldns/rbtree.c
contrib/ldns/rdata.c
contrib/ldns/resolver.c
contrib/ldns/rr.c
contrib/ldns/rr_functions.c
contrib/ldns/str2host.c
contrib/ldns/tsig.c
contrib/ldns/util.c
contrib/ldns/wire2host.c
contrib/ldns/zone.c

index 5ad466a..e999567 100644 (file)
@@ -1,3 +1,91 @@
+1.6.7  2010-11-08
+       * EXPERIMENTAL ecdsa implementation, please do not enable on real
+         servers.
+       * GOST code enabled by default (RFC 5933).
+       * bugfix #326: ignore whitespace between directives and their values.
+       * Header comment to advertise ldns_axfr_complete to check for
+         successfully completed zone transfers.
+       * read resolv.conf skips interface labels, e.g. %eth0.
+       * Fix drill verify NSEC3 denials.
+       * Use closesocket() on windows.
+       * Add ldns_get_signing_algorithm_by_name that understand aliases,
+         names changed to RFC names and aliases for compatibility added.
+       * bugfix: don't print final dot if the domain is relative.
+       * bugfix: resolver search continue when packet rcode != NOERROR.
+       * bugfix: resolver push all domains in search directive to list.
+       * bugfix: resolver search by default includes the root domain.
+       * bugfix: tcp read could fail on single octet recv.
+       * bugfix: read of RR in unknown syntax with missing fields.
+       * added ldns_pkt_tsig_sign_next() and ldns_pkt_tsig_verify_next()
+         to sign and verify TSIG RRs on subsequent messages
+         (section 4.4, RFC 2845).
+       * bugfix: signer sigs nsecs with zsks only.
+       * bugfix #333: fix ldns_dname_absolute for name ending with backslash.
+
+1.6.6  2010-08-09
+       * Fix ldns_rr_clone to copy question rrs properly.
+       * Fix ldns_sign_zone(_nsec3) to clone the soa for the new zone.
+       * Fix ldns_wire2dname size check from reading 1 byte beyond buffer end.
+       * Fix ldns_wire2dname from reading 1 byte beyond end for pointer.
+       * Fix crash using GOST for particular platform configurations.
+       * extern C declarations used in the header file.
+       * Removed debug fprintf from resolver.c.
+       * ldns-signzone checks if public key file is for the right zone.
+       * NETLDNS, .NET port of ldns functionality, by Alex Nicoll, in contrib.
+       * Fix handling of comments in resolv.conf parse.
+       * GOST code enabled if SSL recent, RFC 5933.
+       * bugfix #317: segfault util.c ldns_init_random() fixed.
+       * Fix ldns_tsig_mac_new: allocate enough memory for the hash, fix use of
+         b64_pton_calculate_size.
+       * Fix ldns_dname_cat: size calculation and handling of realloc().
+       * Fix ldns_rr_pop_rdf: fix handling of realloc().
+       * Fix ldns-signzone for single type key scheme: sign whole zone if there
+         are only KSKs.
+       * Fix ldns_resolver: also close socket if AXFR failed (if you don't,
+          it would block subsequent transfers (thanks Roland van Rijswijk).
+        * Fix drill: allow for a secure trace if you use DS records as trust
+         anchors (thanks Jan Komissar).
+
+1.6.5  2010-06-15
+       * Catch \X where X is a digit as an error.
+       * Fix segfault when ip6 ldns resolver only has ip4 servers.
+       * Fix NSEC record after DNSKEY at zone apex not properly signed.
+       * Fix syntax error if last label too long and no dot at end of domain. 
+       * Fix parse of \# syntax with space for type LOC.
+       * Fix ldns_dname_absolute for escape sequences, fixes some parse errs.
+       * bugfix #297: linking ssl, bug due to patch submitted as #296.
+       * bugfix #299: added missing declarations to host2str.h
+       * ldns-compare-zones -s to not exclude SOA record from comparison.
+       * --disable-rpath fix
+       * fix ldns_pkt_empty(), reported by Alex Nicoll.
+       * fix ldns_resolver_new_frm_fp not ignore lines after a comment.
+       * python code for ldns_rr.new_question_frm_str()
+       * Fix ldns_dnssec_verify_denial: the signature selection routine.
+       * Type TALINK parsed (draft-ietf-dnsop-trust-history).
+       * bugfix #304: fixed dead loop in ldns_tcp_read_wire() and
+         ldns_tcp_read_wire_timeout().
+       * GOST support with correct algorithm numbers.  The plan is to make it
+         enabled if openssl support is detected, but it is disabled by
+         default in this release because the RFC is not ready.
+       * Fixed comment in rbtree.h about being first member and data ptr.
+       * Fixed possibly leak in case of out of memory in ldns_native2rdf...
+       * ldns_dname_is_wildcard added.
+       * Fixed: signatures over wildcards had the wrong labelcount.
+       * Fixed ldns_verify() inconsistent return values.
+       * Fixed ldns_resolver to copy and free tsig name, data and algorithm.
+       * Fixed ldns_resolver to push search onto searchlist.
+       * A ldns resolver now defaults to a non-recursive resolver that handles
+         the TC bit.
+       * ldns_resolver_print() prints more details.
+       * Fixed ldns_rdf2buffer_str_time(), which did not print timestamps
+         on 64bit systems.
+       * Make ldns_resolver_nameservers_randomize() more random.
+       * bugfix #310: POSIX specifies NULL second argument of gettimeofday.
+       * fix compiler warnings from llvm clang compiler.
+       * bugfix #309: ldns_pkt_clone did not clone the tsig_rr.
+       * Fix gentoo ebuild for drill, 'no m4 directory'.
+       * bugfix #313: drill trace on an empty nonterminal continuation.
+
 1.6.4  2010-01-20
        * Imported pyldns contribution by Zdenek Vasicek and Karel Slany.
          Changed its configure and Makefile to fit into ldns.
index 3a93c41..74e470a 100644 (file)
@@ -8,6 +8,7 @@ Contents:
        INFORMATION FOR SPECIFIC OPERATING SYSTEMS
                Mac OS X
                Solaris
+        Your Support
 
 Project page:
 http://www.nlnetlabs.nl/ldns/
@@ -64,10 +65,11 @@ 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 Jelte Jansen
   o Wouter Wijngaards
+  o Matthijs Mekking
 
 Former main developers:
+  o Jelte Jansen
   o Miek Gieben
 
 * Credits
@@ -101,3 +103,27 @@ 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
 
+
+Your Support
+NLnet Labs offers all of its software products as open source, most are
+published under a BDS license. You can download them, not only from the
+NLnet Labs website but also through the various OS distributions for
+which NSD, ldns, and Unbound are packaged. We therefore have little idea
+who uses our software in production environments and have no direct ties
+with 'our customers'.
+
+Therefore, we ask you to contact us at users@NLnetLabs.nl and tell us
+whether you use one of our products in your production environment,
+what that environment looks like, and maybe even share some praise.
+We would like to refer to the fact that your organization is using our
+products. We will only do that if you explicitly allow us. In all other
+cases we will keep the information you share with us to ourselves.
+
+In addition to the moral support you can also support us
+financially. NLnet Labs is a recognized not-for-profit charity foundation
+that is chartered to develop open-source software and open-standards
+for the Internet. If you use our software to satisfaction please express
+that by giving us a donation. For small donations PayPal can be used. For
+larger and regular donations please contact us at users@NLnetLabs.nl. Also
+see http://www.nlnetlabs.nl/labs/contributors/.
+
diff --git a/contrib/ldns/README.DELETED b/contrib/ldns/README.DELETED
deleted file mode 100644 (file)
index 142e158..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-Makefile.in
-ac_pkg_swig.m4
-aclocal.m4
-acx_nlnetlabs.m4
-acx_python.m4
-config.guess
-config.sub
-configure
-configure.ac
-contrib/
-doc/
-drill/Makefile.in
-drill/config.h.in
-drill/configure
-drill/configure.ac
-drill/drill.h.in
-drill/install-sh
-examples/
-install-sh
-ldns_symbols.def
-libdns.doxygen
-libdns.vim
-ltmain.sh
-packaging/
diff --git a/contrib/ldns/README.DRAGONFLY b/contrib/ldns/README.DRAGONFLY
deleted file mode 100644 (file)
index 2d896ef..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-Original source can be downloaded from:
-http://www.nlnetlabs.nl/projects/ldns/
-
-    MD5 (ldns-1.6.4.tar.gz) = 6747d7bd96552ee5d8943f3abb24815f
-    SHA1 (ldns-1.6.4.tar.gz) = 9015968ad3ddd015c750c15b60e60b9cccd393ec
-
-A list of deleted files is in README.DELETED.
-
-When Upgrading please stick to development(7).
index c6259b4..5a6b0ba 100644 (file)
@@ -44,9 +44,13 @@ ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size)
 
        buffer->_position = 0; 
        buffer->_limit = buffer->_capacity = size;
+       buffer->_fixed = 0;
        buffer->_data = LDNS_XMALLOC(uint8_t, size);
+       if(!buffer->_data) {
+               buffer->_status = LDNS_STATUS_MEM_ERR;
+               return;
+       }
        memcpy(buffer->_data, data, size);
-       buffer->_fixed = 0;
        buffer->_status = LDNS_STATUS_OK;
        
        ldns_buffer_invariant(buffer);
index ec4104f..038ebdc 100644 (file)
@@ -41,8 +41,6 @@
  */
 #include <ldns/config.h>
 
-#include <ldns/ldns.h>
-
 #include <sys/types.h>
 #include <sys/param.h>
 #ifdef HAVE_SYS_SOCKET_H
@@ -256,41 +254,56 @@ ldns_b32_ntop_ar(uint8_t const *src, size_t srclength, char *target, size_t targ
                }
                target[datalength++] = B32_ar[output[0]];
                if (srclength >= 1) {
+                       if (datalength + 1 > targsize) { return (-2); }
                        target[datalength++] = B32_ar[output[1]];
                        if (srclength == 1 && output[2] == 0) {
+                               if (datalength + 1 > targsize) { return (-2); }
                                target[datalength++] = Pad32;
                        } else {
+                               if (datalength + 1 > targsize) { return (-2); }
                                target[datalength++] = B32_ar[output[2]];
                        }
                } else {
+                       if (datalength + 1 > targsize) { return (-2); }
                        target[datalength++] = Pad32;
+                       if (datalength + 1 > targsize) { return (-2); }
                        target[datalength++] = Pad32;
                }
                if (srclength >= 2) {
+                       if (datalength + 1 > targsize) { return (-2); }
                        target[datalength++] = B32_ar[output[3]];
                } else {
+                       if (datalength + 1 > targsize) { return (-2); }
                        target[datalength++] = Pad32;
                }
                if (srclength >= 3) {
+                       if (datalength + 1 > targsize) { return (-2); }
                        target[datalength++] = B32_ar[output[4]];
                        if (srclength == 3 && output[5] == 0) {
+                               if (datalength + 1 > targsize) { return (-2); }
                                target[datalength++] = Pad32;
                        } else {
+                               if (datalength + 1 > targsize) { return (-2); }
                                target[datalength++] = B32_ar[output[5]];
                        }
                } else {
+                       if (datalength + 1 > targsize) { return (-2); }
                        target[datalength++] = Pad32;
+                       if (datalength + 1 > targsize) { return (-2); }
                        target[datalength++] = Pad32;
                }
                if (srclength >= 4) {
+                       if (datalength + 1 > targsize) { return (-2); }
                        target[datalength++] = B32_ar[output[6]];
                } else {
+                       if (datalength + 1 > targsize) { return (-2); }
                        target[datalength++] = Pad32;
                }
+               if (datalength + 1 > targsize) { return (-2); }
                target[datalength++] = Pad32;
        }
-       if (datalength > targsize) {
-               return (-3);
+       if (datalength+1 > targsize) {
+               return (int) (datalength);
        }
        target[datalength] = '\0';      /* Returned value doesn't count \0. */
        return (int) (datalength);
index 5a3c2ea..9c261e6 100644 (file)
@@ -41,8 +41,6 @@
  */
 #include <ldns/config.h>
 
-#include <ldns/ldns.h>
-
 #include <sys/types.h>
 #include <sys/param.h>
 #ifdef HAVE_SYS_SOCKET_H
index 93c209a..d0b52b5 100644 (file)
@@ -41,8 +41,6 @@
  */
 #include <ldns/config.h>
 
-#include <ldns/ldns.h>
-
 #include <sys/types.h>
 #include <sys/param.h>
 #ifdef HAVE_SYS_SOCKET_H
index a4babea..aa637d2 100644 (file)
@@ -41,8 +41,6 @@
  */
 #include <ldns/config.h>
 
-#include <ldns/ldns.h>
-
 #include <sys/types.h>
 #include <sys/param.h>
 #ifdef HAVE_SYS_SOCKET_H
index 1e9add1..4c277ee 100644 (file)
 #include <netdb.h>
 #include <limits.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * First, socket and INET6 related definitions 
  */
@@ -171,5 +175,9 @@ int getnameinfo(const struct sockaddr *, size_t, char *, size_t,
     char *, size_t, int);
 #endif /* !HAVE_GETNAMEINFO */
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* !_FAKE_RFC2553_H */
 
index c668dae..b744511 100644 (file)
@@ -671,15 +671,15 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
    */
   dopr_outch (buffer, currlen, maxlen, '.');
 
-  while (fplace > 0) 
-    dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
-
   while (zpadlen > 0)
   {
     dopr_outch (buffer, currlen, maxlen, '0');
     --zpadlen;
   }
 
+  while (fplace > 0) 
+    dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
+
   while (padlen < 0) 
   {
     dopr_outch (buffer, currlen, maxlen, ' ');
index e5c8031..0e63ef2 100644 (file)
@@ -73,6 +73,7 @@ ldns_dname_cat(ldns_rdf *rd1, ldns_rdf *rd2)
 {
        uint16_t left_size;
        uint16_t size;
+       uint8_t* newd;
 
        if (ldns_rdf_get_type(rd1) != LDNS_RDF_TYPE_DNAME ||
                        ldns_rdf_get_type(rd2) != LDNS_RDF_TYPE_DNAME) {
@@ -86,10 +87,17 @@ ldns_dname_cat(ldns_rdf *rd1, ldns_rdf *rd2)
        if (left_size > 0 &&ldns_rdf_data(rd1)[left_size - 1] == 0) {
                left_size--;
        }
+        if(left_size == 0) {
+                return LDNS_STATUS_OK;
+        }
 
        size = left_size + ldns_rdf_size(rd2);
+       newd = LDNS_XREALLOC(ldns_rdf_data(rd1), uint8_t, size);
+       if(!newd) {
+               return LDNS_STATUS_MEM_ERR;
+       }
 
-       ldns_rdf_set_data(rd1, LDNS_XREALLOC(ldns_rdf_data(rd1), uint8_t, size));
+       ldns_rdf_set_data(rd1, newd);
        memcpy(ldns_rdf_data(rd1) + left_size, ldns_rdf_data(rd2),
                        ldns_rdf_size(rd2));
        ldns_rdf_set_size(rd1, size);
@@ -108,10 +116,17 @@ ldns_dname_reverse(const ldns_rdf *d)
        d_tmp = ldns_rdf_clone(d);
 
        new = ldns_dname_new_frm_str(".");
+        if(!new)
+                return NULL;
 
        while(ldns_dname_label_count(d_tmp) > 0) {
                tmp = ldns_dname_label(d_tmp, 0);
                status = ldns_dname_cat(tmp, new);
+                if(status != LDNS_STATUS_OK) {
+                        ldns_rdf_deep_free(new);
+                       ldns_rdf_deep_free(d_tmp);
+                        return NULL;
+                }
                ldns_rdf_deep_free(new);
                new = tmp;
                tmp = ldns_dname_left_chop(d_tmp);
@@ -417,14 +432,20 @@ ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
 }
 
 int
+ldns_dname_is_wildcard(const ldns_rdf* dname)
+{
+       return ( ldns_dname_label_count(dname) > 0 &&
+                ldns_rdf_data(dname)[0] == 1 &&
+                ldns_rdf_data(dname)[1] == '*');
+}
+
+int
 ldns_dname_match_wildcard(const ldns_rdf *dname, const ldns_rdf *wildcard)
 {
        ldns_rdf *wc_chopped;
        int result;
        /* check whether it really is a wildcard */
-       if (ldns_dname_label_count(wildcard) > 0 &&
-           ldns_rdf_data(wildcard)[0] == 1 &&
-           ldns_rdf_data(wildcard)[1] == '*') {
+       if (ldns_dname_is_wildcard(wildcard)) {
                /* ok, so the dname needs to be a subdomain of the wildcard
                 * without the *
                 */
@@ -475,12 +496,30 @@ ldns_dname_interval(const ldns_rdf *prev, const ldns_rdf *middle,
 bool
 ldns_dname_str_absolute(const char *dname_str)
 {
+        const char* s;
        if(dname_str && strcmp(dname_str, ".") == 0)
                return 1;
-       return (dname_str &&
-               strlen(dname_str) > 1 &&
-               dname_str[strlen(dname_str) - 1] == '.' &&
-               dname_str[strlen(dname_str) - 2] != '\\');
+        if(!dname_str || strlen(dname_str) < 2)
+                return 0;
+        if(dname_str[strlen(dname_str) - 1] != '.')
+                return 0;
+        if(dname_str[strlen(dname_str) - 2] != '\\')
+                return 1; /* ends in . and no \ before it */
+        /* so we have the case of ends in . and there is \ before it */
+        for(s=dname_str; *s; s++) {
+                if(*s == '\\') {
+                        if(s[1] && s[2] && s[3] /* check length */
+                                && isdigit(s[1]) && isdigit(s[2]) && 
+                                isdigit(s[3]))
+                                s += 3;
+                        else if(!s[1] || isdigit(s[1])) /* escape of nul,0-9 */
+                                return 0; /* parse error */
+                        else s++; /* another character escaped */
+                }
+                else if(!*(s+1) && *s == '.')
+                        return 1; /* trailing dot, unescaped */
+        }
+        return 0;
 }
 
 ldns_rdf *
index c39985f..5d394d1 100644 (file)
@@ -42,7 +42,7 @@ ldns_dnssec_get_rrsig_for_name_and_type(const ldns_rdf *name,
                if (ldns_rr_get_type(candidate) == LDNS_RR_TYPE_RRSIG) {
                        if (ldns_dname_compare(ldns_rr_owner(candidate),
                                               name) == 0 &&
-                           ldns_rdf2native_int8(ldns_rr_rrsig_typecovered(candidate))
+                           ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(candidate))
                            == type
                            ) {
                                return candidate;
@@ -148,6 +148,12 @@ ldns_dnssec_nsec3_closest_encloser(ldns_rdf *qname,
                                                                         salt);
 
                status = ldns_dname_cat(hashed_sname, zone_name);
+                if(status != LDNS_STATUS_OK) {
+                       LDNS_FREE(salt);
+                       ldns_rdf_deep_free(zone_name);
+                       ldns_rdf_deep_free(sname);
+                        return NULL;
+                }
 
                for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsec3s); nsec_i++) {
                        nsec = ldns_rr_list_rr(nsec3s, nsec_i);
@@ -506,7 +512,7 @@ ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
                        return NULL;
                }
                break;
-       case LDNS_HASH_GOST94:
+       case LDNS_HASH_GOST:
 #ifdef USE_GOST
                (void)ldns_key_EVP_load_gost_id();
                md = EVP_get_digestbyname("md_gost94");
@@ -519,12 +525,25 @@ ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
                        ldns_rr_free(ds);
                        return NULL;
                }
+                break;
+#else
+               /* not implemented */
+               ldns_rr_free(ds);
+               return NULL;
+#endif
+#ifdef USE_ECDSA
+       case LDNS_SHA384:
+               digest = LDNS_XMALLOC(uint8_t, SHA384_DIGEST_LENGTH);
+               if (!digest) {
+                       ldns_rr_free(ds);
+                       return NULL;
+               }
+                break;
 #else
                /* not implemented */
                ldns_rr_free(ds);
                return NULL;
 #endif
-               break;
        }
 
        data_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
@@ -593,7 +612,7 @@ ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
                                            digest);
                ldns_rr_push_rdf(ds, tmp);
                break;
-       case LDNS_HASH_GOST94:
+       case LDNS_HASH_GOST:
 #ifdef USE_GOST
                if(!ldns_digest_evp((unsigned char *) ldns_buffer_begin(data_buf),
                                (unsigned int) ldns_buffer_position(data_buf),
@@ -609,6 +628,17 @@ ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
                ldns_rr_push_rdf(ds, tmp);
 #endif
                break;
+#ifdef USE_ECDSA
+       case LDNS_SHA384:
+               (void) SHA384((unsigned char *) ldns_buffer_begin(data_buf),
+                                (unsigned int) ldns_buffer_position(data_buf),
+                                (unsigned char *) digest);
+               tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
+                                           SHA384_DIGEST_LENGTH,
+                                           digest);
+               ldns_rr_push_rdf(ds, tmp);
+               break;
+#endif
        }
 
        LDNS_FREE(digest);
@@ -807,6 +837,10 @@ ldns_dnssec_create_nsec3(ldns_dnssec_name *from,
                          salt_length,
                          salt));
        status = ldns_dname_cat(ldns_rr_owner(nsec_rr), zone_name);
+        if(status != LDNS_STATUS_OK) {
+                ldns_rr_free(nsec_rr);
+                return NULL;
+        }
        ldns_nsec3_add_param_rdfs(nsec_rr,
                                  algorithm,
                                  flags,
@@ -960,7 +994,7 @@ ldns_nsec3_hash_name(ldns_rdf *name,
                 (uint8_t *) hashed_owner_str,
                 hashed_owner_str_len,
                 hashed_owner_b32,
-                ldns_b32_ntop_calculate_size(hashed_owner_str_len));
+                ldns_b32_ntop_calculate_size(hashed_owner_str_len)+1);
        if (hashed_owner_b32_len < 1) {
                fprintf(stderr, "Error in base32 extended hex encoding ");
                fprintf(stderr, "of hashed owner name (name: ");
@@ -970,7 +1004,6 @@ ldns_nsec3_hash_name(ldns_rdf *name,
                LDNS_FREE(hashed_owner_b32);
                return NULL;
        }
-       hashed_owner_str_len = hashed_owner_b32_len;
        hashed_owner_b32[hashed_owner_b32_len] = '\0';
 
        status = ldns_str2rdf_dname(&hashed_owner, hashed_owner_b32);
@@ -1075,8 +1108,12 @@ ldns_create_nsec3(ldns_rdf *cur_owner,
                                                                 salt_length,
                                                                 salt);
        status = ldns_dname_cat(hashed_owner, cur_zone);
+        if(status != LDNS_STATUS_OK)
+                return NULL;
 
        nsec = ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3);
+        if(!nsec)
+                return NULL;
        ldns_rr_set_type(nsec, LDNS_RR_TYPE_NSEC3);
        ldns_rr_set_owner(nsec, hashed_owner);
 
@@ -1530,14 +1567,14 @@ ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
                                                  const ldns_rdf *sig_rdf)
 {
        /* the EVP api wants the DER encoding of the signature... */
-       uint8_t t;
        BIGNUM *R, *S;
        DSA_SIG *dsasig;
        unsigned char *raw_sig = NULL;
        int raw_sig_len;
 
+        if(ldns_rdf_size(sig_rdf) < 1 + 2*SHA_DIGEST_LENGTH)
+                return LDNS_STATUS_SYNTAX_RDATA_ERR;
        /* extract the R and S field from the sig buffer */
-       t = ldns_rdf_data(sig_rdf)[0];
        R = BN_new();
        if(!R) return LDNS_STATUS_MEM_ERR;
        (void) BN_bin2bn((unsigned char *) ldns_rdf_data(sig_rdf) + 1,
@@ -1575,4 +1612,65 @@ ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
 
        return ldns_buffer_status(target_buffer);
 }
+
+#ifdef USE_ECDSA
+ldns_rdf *
+ldns_convert_ecdsa_rrsig_asn12rdf(const ldns_buffer *sig, const long sig_len)
+{
+        ECDSA_SIG* ecdsa_sig;
+       unsigned char *data = (unsigned char*)ldns_buffer_begin(sig);
+        ldns_rdf* rdf;
+       ecdsa_sig = d2i_ECDSA_SIG(NULL, (const unsigned char **)&data, sig_len);
+        if(!ecdsa_sig) return NULL;
+
+        /* "r | s". */
+        data = LDNS_XMALLOC(unsigned char,
+                BN_num_bytes(ecdsa_sig->r) + BN_num_bytes(ecdsa_sig->s));
+        if(!data) {
+                ECDSA_SIG_free(ecdsa_sig);
+                return NULL;
+        }
+        BN_bn2bin(ecdsa_sig->r, data);
+        BN_bn2bin(ecdsa_sig->s, data+BN_num_bytes(ecdsa_sig->r));
+       rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64,
+                BN_num_bytes(ecdsa_sig->r) + BN_num_bytes(ecdsa_sig->s), data);
+        ECDSA_SIG_free(ecdsa_sig);
+        return rdf;
+}
+
+ldns_status
+ldns_convert_ecdsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
+        const ldns_rdf *sig_rdf)
+{
+        ECDSA_SIG* sig;
+       int raw_sig_len;
+        long bnsize = ldns_rdf_size(sig_rdf) / 2;
+        /* if too short, or not even length, do not bother */
+        if(bnsize < 16 || (size_t)bnsize*2 != ldns_rdf_size(sig_rdf))
+                return LDNS_STATUS_ERR;
+        
+        /* use the raw data to parse two evenly long BIGNUMs, "r | s". */
+        sig = ECDSA_SIG_new();
+        if(!sig) return LDNS_STATUS_MEM_ERR;
+        sig->r = BN_bin2bn((const unsigned char*)ldns_rdf_data(sig_rdf),
+                bnsize, sig->r);
+        sig->s = BN_bin2bn((const unsigned char*)ldns_rdf_data(sig_rdf)+bnsize,
+                bnsize, sig->s);
+        if(!sig->r || !sig->s) {
+                ECDSA_SIG_free(sig);
+                return LDNS_STATUS_MEM_ERR;
+        }
+
+       raw_sig_len = i2d_ECDSA_SIG(sig, NULL);
+       if (ldns_buffer_reserve(target_buffer, (size_t) raw_sig_len)) {
+                unsigned char* pp = ldns_buffer_current(target_buffer);
+               raw_sig_len = i2d_ECDSA_SIG(sig, &pp);
+                ldns_buffer_skip(target_buffer, (size_t) raw_sig_len);
+       }
+        ECDSA_SIG_free(sig);
+
+       return ldns_buffer_status(target_buffer);
+}
+
+#endif /* USE_ECDSA */
 #endif /* HAVE_SSL */
index 2b5cad9..d571c93 100644 (file)
@@ -31,35 +31,38 @@ ldns_create_empty_rrsig(ldns_rr_list *rrset,
 
        label_count = ldns_dname_label_count(ldns_rr_owner(ldns_rr_list_rr(rrset,
                                                           0)));
-       
+        /* RFC4035 2.2: not counting the leftmost label if it is a wildcard */
+        if(ldns_dname_is_wildcard(ldns_rr_owner(ldns_rr_list_rr(rrset, 0))))
+                label_count --;
+
        current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
-       
+
        /* set the type on the new signature */
        orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
        orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0));
 
        ldns_rr_set_ttl(current_sig, orig_ttl);
        ldns_rr_set_class(current_sig, orig_class);
-       ldns_rr_set_owner(current_sig, 
+       ldns_rr_set_owner(current_sig,
                          ldns_rdf_clone(
                               ldns_rr_owner(
                                    ldns_rr_list_rr(rrset,
                                                    0))));
 
        /* fill in what we know of the signature */
-       
+
        /* set the orig_ttl */
        (void)ldns_rr_rrsig_set_origttl(
-                  current_sig, 
+                  current_sig,
                   ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
                                         orig_ttl));
        /* the signers name */
        (void)ldns_rr_rrsig_set_signame(
-                       current_sig, 
+                       current_sig,
                        ldns_rdf_clone(ldns_key_pubkey_owner(current_key)));
        /* label count - get it from the first rr in the rr_list */
        (void)ldns_rr_rrsig_set_labels(
-                       current_sig, 
+                       current_sig,
                        ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
                                             label_count));
        /* inception, expiration */
@@ -68,7 +71,7 @@ ldns_create_empty_rrsig(ldns_rr_list *rrset,
                (void)ldns_rr_rrsig_set_inception(
                                current_sig,
                                ldns_native2rdf_int32(
-                                   LDNS_RDF_TYPE_TIME, 
+                                   LDNS_RDF_TYPE_TIME,
                                    ldns_key_inception(current_key)));
        } else {
                (void)ldns_rr_rrsig_set_inception(
@@ -79,25 +82,25 @@ ldns_create_empty_rrsig(ldns_rr_list *rrset,
                (void)ldns_rr_rrsig_set_expiration(
                                current_sig,
                                ldns_native2rdf_int32(
-                                   LDNS_RDF_TYPE_TIME, 
+                                   LDNS_RDF_TYPE_TIME,
                                    ldns_key_expiration(current_key)));
        } else {
                (void)ldns_rr_rrsig_set_expiration(
                             current_sig,
                                ldns_native2rdf_int32(
-                                   LDNS_RDF_TYPE_TIME, 
+                                   LDNS_RDF_TYPE_TIME,
                                    now + LDNS_DEFAULT_EXP_TIME));
        }
 
        (void)ldns_rr_rrsig_set_keytag(
                   current_sig,
-                  ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, 
+                  ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
                                         ldns_key_keytag(current_key)));
 
        (void)ldns_rr_rrsig_set_algorithm(
                        current_sig,
                        ldns_native2rdf_int8(
-                           LDNS_RDF_TYPE_ALG, 
+                           LDNS_RDF_TYPE_ALG,
                            ldns_key_algorithm(current_key)));
 
        (void)ldns_rr_rrsig_set_typecovered(
@@ -145,13 +148,27 @@ ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
                break;
 #endif /* USE_SHA2 */
 #ifdef USE_GOST
-       case LDNS_SIGN_GOST:
+       case LDNS_SIGN_ECC_GOST:
                b64rdf = ldns_sign_public_evp(
                                   sign_buf,
                                   ldns_key_evp_key(current_key),
                                   EVP_get_digestbyname("md_gost94"));
                break;
 #endif /* USE_GOST */
+#ifdef USE_ECDSA
+        case LDNS_SIGN_ECDSAP256SHA256:
+                       b64rdf = ldns_sign_public_evp(
+                                  sign_buf,
+                                  ldns_key_evp_key(current_key),
+                                  EVP_sha256());
+                break;
+        case LDNS_SIGN_ECDSAP384SHA384:
+                       b64rdf = ldns_sign_public_evp(
+                                  sign_buf,
+                                  ldns_key_evp_key(current_key),
+                                  EVP_sha384());
+                break;
+#endif
        case LDNS_SIGN_RSAMD5:
                b64rdf = ldns_sign_public_evp(
                                   sign_buf,
@@ -164,7 +181,7 @@ ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
                printf("is the one used available on this system?\n");
                break;
        }
-       
+
        return b64rdf;
 }
 
@@ -188,10 +205,9 @@ ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
        if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
                return NULL;
        }
-       
+
        new_owner = NULL;
 
-       key_count = 0;
        signatures = ldns_rr_list_new();
 
        /* prepare a signature and add all the know data
@@ -209,7 +225,7 @@ ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
        }
        /* sort */
        ldns_rr_list_sort(rrset_clone);
-       
+
        for (key_count = 0;
                key_count < ldns_key_list_key_count(keys);
                key_count++) {
@@ -228,12 +244,7 @@ ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
                current_key = ldns_key_list_key(keys, key_count);
                /* sign all RRs with keys that have ZSKbit, !SEPbit.
                   sign DNSKEY RRs with keys that have ZSKbit&SEPbit */
-               if (
-                   ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY &&
-                   (!(ldns_key_flags(current_key) & LDNS_KEY_SEP_KEY)
-                       || ldns_rr_get_type(ldns_rr_list_rr(rrset, 0))
-                       == LDNS_RR_TYPE_DNSKEY)
-                   ) {
+               if (ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY) {
                        current_sig = ldns_create_empty_rrsig(rrset_clone,
                                                              current_key);
 
@@ -300,7 +311,7 @@ ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
        if (!b64sig) {
                return NULL;
        }
-       
+
        sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
                                  ldns_buffer_position(to_sign), NULL);
        if (!sha1_hash) {
@@ -336,6 +347,32 @@ ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
        return sigdata_rdf;
 }
 
+#ifdef USE_ECDSA
+static int
+ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
+{
+        EC_KEY* ec;
+        const EC_GROUP* g;
+        if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC)
+                return 0;
+        ec = EVP_PKEY_get1_EC_KEY(pkey);
+        g = EC_KEY_get0_group(ec);
+        if(!g) {
+                EC_KEY_free(ec);
+                return 0;
+        }
+        if(EC_GROUP_get_curve_name(g) == NID_secp224r1 ||
+                EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1 ||
+                EC_GROUP_get_curve_name(g) == NID_secp384r1) {
+                EC_KEY_free(ec);
+                return 1;
+        }
+        /* downref the eckey, the original is still inside the pkey */
+        EC_KEY_free(ec);
+        return 0;
+}
+#endif /* USE_ECDSA */
+
 ldns_rdf *
 ldns_sign_public_evp(ldns_buffer *to_sign,
                                 EVP_PKEY *key,
@@ -366,7 +403,7 @@ ldns_sign_public_evp(ldns_buffer *to_sign,
        r = EVP_SignInit(&ctx, md_type);
        if(r == 1) {
                r = EVP_SignUpdate(&ctx, (unsigned char*)
-                                           ldns_buffer_begin(to_sign), 
+                                           ldns_buffer_begin(to_sign),
                                            ldns_buffer_position(to_sign));
        } else {
                ldns_buffer_free(b64sig);
@@ -387,6 +424,11 @@ ldns_sign_public_evp(ldns_buffer *to_sign,
        /* unfortunately, OpenSSL output is differenct from DNS DSA format */
        if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
                sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
+#ifdef USE_ECDSA
+        } else if(EVP_PKEY_type(key->type) == EVP_PKEY_EC &&
+                ldns_pkey_is_ecdsa(key)) {
+                sigdata_rdf = ldns_convert_ecdsa_rrsig_asn12rdf(b64sig, siglen);
+#endif
        } else {
                /* ok output for other types is the same */
                sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
@@ -448,7 +490,7 @@ ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
        if (!b64sig) {
                return NULL;
        }
-       
+
        md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
                                ldns_buffer_position(to_sign), NULL);
        if (!md5_hash) {
@@ -460,7 +502,7 @@ ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
                    (unsigned char*)ldns_buffer_begin(b64sig),
                    &siglen, key);
 
-       sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, 
+       sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
                                                                 ldns_buffer_begin(b64sig));
        ldns_buffer_free(b64sig);
        return sigdata_rdf;
@@ -556,12 +598,12 @@ ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
        ldns_rr *nsec_rr;
        uint32_t nsec_ttl;
        ldns_dnssec_rrsets *soa;
-       
+
        /* the TTL of NSEC rrs should be set to the minimum TTL of
         * the zone SOA (RFC4035 Section 2.3)
         */
        soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
-       
+
        /* did the caller actually set it? if not,
         * fall back to default ttl
         */
@@ -571,7 +613,7 @@ ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
        } else {
                nsec_ttl = LDNS_DEFAULT_TTL;
        }
-       
+
        first_node = ldns_dnssec_name_node_next_nonglue(
                               ldns_rbtree_first(zone->names));
        cur_node = first_node;
@@ -632,16 +674,16 @@ ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
        ldns_rr_list *nsec3_list;
        uint32_t nsec_ttl;
        ldns_dnssec_rrsets *soa;
-       
+
        if (!zone || !new_rrs || !zone->names) {
                return LDNS_STATUS_ERR;
        }
-       
+
        /* the TTL of NSEC rrs should be set to the minimum TTL of
         * the zone SOA (RFC4035 Section 2.3)
         */
        soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
-       
+
        /* did the caller actually set it? if not,
         * fall back to default ttl
         */
@@ -656,7 +698,7 @@ ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
 
        first_name_node = ldns_dnssec_name_node_next_nonglue(
                                          ldns_rbtree_first(zone->names));
-       
+
        current_name_node = first_name_node;
 
        while (current_name_node &&
@@ -688,7 +730,7 @@ ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
        if (result != LDNS_STATUS_OK) {
                return result;
        }
-       
+
        ldns_rr_list_free(nsec3_list);
        return result;
 }
@@ -707,7 +749,6 @@ ldns_dnssec_remove_signatures(ldns_dnssec_rrs *signatures,
 
        uint16_t keytag;
        size_t i;
-       int v;
 
        key_list = key_list;
 
@@ -726,11 +767,11 @@ ldns_dnssec_remove_signatures(ldns_dnssec_rrs *signatures,
                }
                return NULL;
        }
-       v = func(cur_rr->rr, arg);
+       (void)func(cur_rr->rr, arg);
 
        while (cur_rr) {
                next_rr = cur_rr->next;
-               
+
                switch (func(cur_rr->rr, arg)) {
                case  LDNS_SIGNATURE_LEAVE_ADD_NEW:
                        prev_rr = cur_rr;
@@ -790,7 +831,7 @@ ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
                                int (*func)(ldns_rr *, void*),
                                void *arg)
 {
-       return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list, 
+       return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list,
                func, arg, 0);
 }
 
@@ -812,6 +853,25 @@ ldns_key_list_filter_for_dnskey(ldns_key_list *key_list)
                        ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
 }
 
+/** If there are no ZSKs use KSK as ZSK */
+static void
+ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list)
+{
+       int saw_zsk = 0;
+       size_t i;
+       for(i=0; i<ldns_key_list_key_count(key_list); i++)
+               if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
+                       saw_zsk = 1;
+                       break;
+               }
+       if(!saw_zsk)
+               return;
+       /* else filter all KSKs */
+       for(i=0; i<ldns_key_list_key_count(key_list); i++)
+               if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
+                       ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
+}
+
 ldns_status
 ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
                                ldns_rr_list *new_rrs,
@@ -830,7 +890,7 @@ ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
        ldns_dnssec_rrs *cur_rr;
 
        ldns_rr_list *siglist;
-       
+
        size_t i;
 
        ldns_rr_list *pubkey_list = ldns_rr_list_new();
@@ -852,7 +912,7 @@ ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
                        while (cur_rrset) {
                                /* reset keys to use */
                                ldns_key_list_set_use(key_list, true);
-                               
+
                                /* walk through old sigs, remove the old,
                                   and mark which keys (not) to use) */
                                cur_rrset->signatures =
@@ -863,16 +923,19 @@ ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
                                if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) &&
                                        cur_rrset->type == LDNS_RR_TYPE_DNSKEY)
                                        ldns_key_list_filter_for_dnskey(key_list);
-                               
+
+                               if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY)
+                                       ldns_key_list_filter_for_non_dnskey(key_list);
+
                                /* TODO: just set count to zero? */
                                rr_list = ldns_rr_list_new();
-                               
+
                                cur_rr = cur_rrset->rrs;
                                while (cur_rr) {
                                        ldns_rr_list_push_rr(rr_list, cur_rr->rr);
                                        cur_rr = cur_rr->next;
                                }
-                               
+
                                /* only sign non-delegation RRsets */
                                /* (glue should have been marked earlier) */
                                if ((ldns_rr_list_type(rr_list) != LDNS_RR_TYPE_NS ||
@@ -905,23 +968,25 @@ ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
                                        }
                                        ldns_rr_list_free(siglist);
                                }
-                               
+
                                ldns_rr_list_free(rr_list);
-                               
+
                                cur_rrset = cur_rrset->next;
                        }
-                       
+
                        /* sign the nsec */
+                       ldns_key_list_set_use(key_list, true);
                        cur_name->nsec_signatures =
                                ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
                                                                                key_list,
                                                                                func,
                                                                                arg);
-                       
+                       ldns_key_list_filter_for_non_dnskey(key_list);
+
                        rr_list = ldns_rr_list_new();
                        ldns_rr_list_push_rr(rr_list, cur_name->nsec);
                        siglist = ldns_sign_public(rr_list, key_list);
-                       
+
                        for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
                                if (cur_name->nsec_signatures) {
                                        ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
@@ -934,7 +999,7 @@ ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
                                                                         ldns_rr_list_rr(siglist, i));
                                }
                        }
-                       
+
                        ldns_rr_list_free(siglist);
                        ldns_rr_list_free(rr_list);
                }
@@ -971,7 +1036,7 @@ ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
 
        /* zone is already sorted */
        ldns_dnssec_zone_mark_glue(zone);
-       
+
        /* check whether we need to add nsecs */
        if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
                result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
@@ -1075,7 +1140,7 @@ ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
                                                arg,
                                                signflags);
        }
-       
+
        return result;
 }
 
@@ -1092,13 +1157,13 @@ ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
        dnssec_zone = ldns_dnssec_zone_new();
 
        (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
-       ldns_zone_set_soa(signed_zone, ldns_zone_soa(zone));
-       
+       ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
+
        for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
                (void) ldns_dnssec_zone_add_rr(dnssec_zone,
                                                                 ldns_rr_list_rr(ldns_zone_rrs(zone),
                                                                                          i));
-               ldns_zone_push_rr(signed_zone, 
+               ldns_zone_push_rr(signed_zone,
                                           ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
                                                                                           i)));
        }
@@ -1133,8 +1198,8 @@ ldns_zone_sign_nsec3(ldns_zone *zone, ldns_key_list *key_list, uint8_t algorithm
        dnssec_zone = ldns_dnssec_zone_new();
 
        (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
-       ldns_zone_set_soa(signed_zone, ldns_zone_soa(zone));
-       
+       ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
+
        for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
                (void) ldns_dnssec_zone_add_rr(dnssec_zone,
                                                                 ldns_rr_list_rr(ldns_zone_rrs(zone),
index c7cd268..d979c58 100644 (file)
@@ -635,7 +635,6 @@ ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
        ldns_rr_list *cur_sigs;
        ldns_rr *cur_rr = NULL;
        ldns_rr *cur_sig_rr;
-       uint16_t cur_keytag;
        size_t i, j;
 
        ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
@@ -668,9 +667,6 @@ ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
                                for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
                                        /* find the appropriate key in the parent list */
                                        cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
-                                       cur_keytag = 
-                                               ldns_rdf2native_int16(
-                                                   ldns_rr_rrsig_keytag(cur_sig_rr));
 
                                        if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
                                                if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
@@ -869,7 +865,6 @@ ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree *new_tree,
                                                /*ldns_rr_print(stdout, cur_parent_rr);*/
                                        }
                                }
-                               cur_rr = ldns_rr_list_rr(cur_rrset, 0);
                        }
                }
        }
@@ -1111,7 +1106,6 @@ ldns_validate_domain_dnskey(const ldns_resolver * res,
                                           const ldns_rdf * domain,
                                           const ldns_rr_list * keys)
 {
-       ldns_status status;
        ldns_pkt * keypkt;
        ldns_rr * cur_key;
        uint16_t key_i; uint16_t key_j; uint16_t key_k;
@@ -1154,10 +1148,9 @@ ldns_validate_domain_dnskey(const ldns_resolver * res,
                                                if (ldns_rdf2native_int16(
                                                           ldns_rr_rrsig_keytag(cur_sig))
                                                    == ldns_calc_keytag(cur_key)) {
-                                                       if ((status =
-                                                               ldns_verify_rrsig(domain_keys,
+                                                       if (ldns_verify_rrsig(domain_keys,
                                                                                           cur_sig,
-                                                                                          cur_key))
+                                                                                          cur_key)
                                                            == LDNS_STATUS_OK) {
                 
                                                                /* Push the whole rrset 
@@ -1194,7 +1187,7 @@ ldns_validate_domain_dnskey(const ldns_resolver * res,
                ldns_pkt_free(keypkt);
 
        } else {
-               status = LDNS_STATUS_CRYPTO_NO_DNSKEY;
+               /* LDNS_STATUS_CRYPTO_NO_DNSKEY */
        }
     
        return trusted_keys;
@@ -1205,7 +1198,6 @@ ldns_validate_domain_ds(const ldns_resolver *res,
                                    const ldns_rdf * domain,
                                    const ldns_rr_list * keys)
 {
-       ldns_status status;
        ldns_pkt * dspkt;
        uint16_t key_i;
        ldns_rr_list * rrset = NULL;
@@ -1227,8 +1219,7 @@ ldns_validate_domain_ds(const ldns_resolver *res,
                                                                  LDNS_SECTION_ANSWER);
 
                /* Validate sigs */
-               if ((status = ldns_verify(rrset, sigs, keys, NULL))
-                   == LDNS_STATUS_OK) {
+               if (ldns_verify(rrset, sigs, keys, NULL) == LDNS_STATUS_OK) {
                        trusted_keys = ldns_rr_list_new();
                        for (key_i=0; key_i<ldns_rr_list_rr_count(rrset); key_i++) {
                                ldns_rr_list_push_rr(trusted_keys,
@@ -1244,7 +1235,7 @@ ldns_validate_domain_ds(const ldns_resolver *res,
                ldns_pkt_free(dspkt);
 
        } else {
-               status = LDNS_STATUS_CRYPTO_NO_DS;
+               /* LDNS_STATUS_CRYPTO_NO_DS */
        }
 
        return trusted_keys;
@@ -1420,6 +1411,10 @@ ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
                                                   ldns_rr_owner(rr),
                                                   ldns_rr_get_type(rr),
                                                   nsecs);
+                if(!closest_encloser) {
+                        result = LDNS_STATUS_NSEC3_ERR;
+                        goto done;
+                }
 
                wildcard = ldns_dname_new_frm_str("*");
                (void) ldns_dname_cat(wildcard, closest_encloser);
@@ -1498,11 +1493,6 @@ ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
                }
 
                /* XXX see note above */
-               closest_encloser =
-                       ldns_dnssec_nsec3_closest_encloser(ldns_rr_owner(rr),
-                                                                               ldns_rr_get_type(rr),
-                                                                               nsecs);
-
                result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
        }
 
@@ -1523,18 +1513,14 @@ ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
                0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
        unsigned char encoded[37+64];
        const unsigned char* pp;
-       if(keylen != 66) {
+       if(keylen != 64) {
                /* key wrong size */
                return NULL;
        }
-       if(key[0] != 0 || key[1] != 0) {
-               /* unsupported GOST algo or digest paramset */
-               return NULL;
-       }
 
        /* create evp_key */
        memmove(encoded, asn, 37);
-       memmove(encoded+37, key+2, 64);
+       memmove(encoded+37, key, 64);
        pp = (unsigned char*)&encoded[0];
 
        return d2i_PUBKEY(NULL, &pp, sizeof(encoded));
@@ -1563,6 +1549,63 @@ ldns_verify_rrsig_gost_raw(unsigned char* sig, size_t siglen,
 }
 #endif
 
+#ifdef USE_ECDSA
+EVP_PKEY*
+ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
+{
+       unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
+        const unsigned char* pp = buf;
+        EVP_PKEY *evp_key;
+        EC_KEY *ec;
+       /* check length, which uncompressed must be 2 bignums */
+        if(algo == LDNS_ECDSAP256SHA256) {
+               if(keylen != 2*256/8) return NULL;
+                ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+        } else if(algo == LDNS_ECDSAP384SHA384) {
+               if(keylen != 2*384/8) return NULL;
+                ec = EC_KEY_new_by_curve_name(NID_secp384r1);
+        } else    ec = NULL;
+        if(!ec) return NULL;
+       if(keylen+1 > sizeof(buf))
+               return NULL; /* sanity check */
+       /* prepend the 0x02 (from docs) (or actually 0x04 from implementation
+        * of openssl) for uncompressed data */
+       buf[0] = POINT_CONVERSION_UNCOMPRESSED;
+       memmove(buf+1, key, keylen);
+        if(!o2i_ECPublicKey(&ec, &pp, keylen+1)) {
+                EC_KEY_free(ec);
+                return NULL;
+        }
+        evp_key = EVP_PKEY_new();
+        if(!evp_key) {
+                EC_KEY_free(ec);
+                return NULL;
+        }
+        EVP_PKEY_assign_EC_KEY(evp_key, ec);
+        return evp_key;
+}
+
+static ldns_status
+ldns_verify_rrsig_ecdsa_raw(unsigned char* sig, size_t siglen, 
+       ldns_buffer* rrset, unsigned char* key, size_t keylen, uint8_t algo)
+{
+        EVP_PKEY *evp_key;
+        ldns_status result;
+        const EVP_MD *d;
+
+        evp_key = ldns_ecdsa2pkey_raw(key, keylen, algo);
+        if(!evp_key) {
+               /* could not convert key */
+               return LDNS_STATUS_CRYPTO_BOGUS;
+        }
+        if(algo == LDNS_ECDSAP256SHA256)
+                d = EVP_sha256();
+        else    d = EVP_sha384(); /* LDNS_ECDSAP384SHA384 */
+       result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, d);
+       EVP_PKEY_free(evp_key);
+       return result;
+}
+#endif
 
 ldns_status
 ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf, 
@@ -1616,11 +1659,18 @@ ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
                break;
 #endif
 #ifdef USE_GOST
-       case LDNS_GOST:
+       case LDNS_ECC_GOST:
                return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf,
                        key, keylen);
                break;
 #endif
+#ifdef USE_ECDSA
+        case LDNS_ECDSAP256SHA256:
+        case LDNS_ECDSAP384SHA384:
+               return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf,
+                       key, keylen, algo);
+               break;
+#endif
        case LDNS_RSAMD5:
                return ldns_verify_rrsig_rsamd5_raw(sig,
                                                                         siglen,
@@ -1707,7 +1757,7 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
        case LDNS_RSASHA512:
 #endif
 #ifdef USE_GOST
-       case LDNS_GOST:
+       case LDNS_ECC_GOST:
 #endif
                if (ldns_rdf2buffer_wire(rawsig_buf, 
                    ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
@@ -1726,6 +1776,17 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
                        return LDNS_STATUS_MEM_ERR;
                }
                break;
+#ifdef USE_ECDSA
+        case LDNS_ECDSAP256SHA256:
+        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) {
+                       return LDNS_STATUS_MEM_ERR;
+                }
+                break;
+#endif
        case LDNS_DH:
        case LDNS_ECC:
        case LDNS_INDIRECT:
@@ -1941,8 +2002,8 @@ ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
                ldns_rr_list_free(validkeys);
                return result;
        }
-       result = LDNS_STATUS_ERR;
 
+       result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
        for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
                status = ldns_verify_test_sig_key(rawsig_buf, verify_buf, 
                        rrsig, ldns_rr_list_rr(keys, i));
@@ -1960,10 +2021,11 @@ ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
                                ldns_rr_list_free(validkeys);
                                return LDNS_STATUS_MEM_ERR;
                        }
-                       /* reset no keytag match error */
-                       result = LDNS_STATUS_ERR;
+
+                       result = status;
                }
-               if (result == LDNS_STATUS_ERR) {
+
+               if (result == LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
                        result = status;
                }
        }
index bb28362..91e5651 100644 (file)
@@ -58,7 +58,7 @@ ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr)
        /* should we error on equal? */
        if (cmp <= 0) {
                if (rrs->next) {
-                       ldns_dnssec_rrs_add_rr(rrs->next, rr);
+                       return ldns_dnssec_rrs_add_rr(rrs->next, rr);
                } else {
                        new_rrs = ldns_dnssec_rrs_new();
                        new_rrs->rr = rr;
@@ -421,7 +421,7 @@ ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
        ldns_status result = LDNS_STATUS_OK;
        ldns_rdf *name_name;
        bool hashed_name = false;
-       ldns_rr_type rr_type = ldns_rr_get_type(rr);
+       ldns_rr_type rr_type;
        ldns_rr_type typecovered = 0;
 
        /* special handling for NSEC3 and NSECX covering RRSIGS */
index 2201953..930ac7c 100644 (file)
@@ -212,7 +212,22 @@ ldns_verify_denial(ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type, ldns_rr_lis
                        }
                }
                ldns_rr_list_deep_free(nsecs);
-       }
+       } 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();
+                if(!sigs) return LDNS_STATUS_MEM_ERR;
+                if(!q) return LDNS_STATUS_MEM_ERR;
+                ldns_rr_set_question(q, 1);
+                ldns_rr_set_ttl(q, 0);
+                ldns_rr_set_owner(q, ldns_rdf_clone(name));
+                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);
+                ldns_rr_free(q);
+               ldns_rr_list_deep_free(nsecs);
+               ldns_rr_list_deep_free(sigs);
+        }
        return result;
 }
 
index 64e850c..24cfd6d 100644 (file)
@@ -159,7 +159,7 @@ Use TCP/IP when querying a server
 Use this file to read a (trusted) key from. When this options is
 given \fBdrill\fR tries to validate the current answer with this
 key. No chasing is done. When \fBdrill\fR is doing a secure trace, this
-key will be used as trust anchor.
+key will be used as trust anchor. Can contain a DNSKEY or a DS record.
 
 .TP
 \fB\-o \fImnemonic\fR
index 13d09f7..bae04db 100644 (file)
@@ -48,7 +48,7 @@ usage(FILE *stream, const char *progname)
        fprintf(stream, "\t-a\t\tfallback to EDNS0 and TCP if the answer is truncated\n");
        fprintf(stream, "\t-b <bufsize>\tuse <bufsize> as the buffer size (defaults to 512 b)\n");
        fprintf(stream, "\t-c <file>\t\tuse file for rescursive nameserver configuration (/etc/resolv.conf)\n");
-       fprintf(stream, "\t-k <file>\tspecify a file that contains a trusted DNSSEC key [**]\n");
+       fprintf(stream, "\t-k <file>\tspecify a file that contains a trusted DNSSEC key (DNSKEY|DS) [**]\n");
        fprintf(stream, "\t\t\tused to verify any signatures in the current answer\n");
        fprintf(stream, "\t-o <mnemonic>\tset flags to: [QR|qr][AA|aa][TC|tc][RD|rd][CD|cd][RA|ra][AD|ad]\n");
        fprintf(stream, "\t\t\tlowercase: unset bit, uppercase: set bit\n");
@@ -912,9 +912,7 @@ main(int argc, char *argv[])
        ldns_rr_list_deep_free(cmdline_rr_list);
        ldns_rdf_deep_free(trace_start_name);
        xfree(progname);
-/*
        xfree(tsig_name);
-*/
        xfree(tsig_data);
        xfree(tsig_algorithm);
 
index b05e2da..ecc21fd 100644 (file)
@@ -134,7 +134,7 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
        ldns_rr_list *new_nss;
        ldns_rr_list *ns_addr;
        uint16_t loop_count;
-       ldns_rdf *pop; 
+       ldns_rdf *pop;
        ldns_rdf **labels = NULL;
        ldns_status status, st;
        ssize_t i;
@@ -157,7 +157,7 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
 
        ldns_rr_list *nsec_rrs = NULL;
        ldns_rr_list *nsec_rr_sigs = NULL;
-       
+
        /* empty non-terminal check */
        bool ent;
 
@@ -165,9 +165,9 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
        ldns_rr_list *new_ns_addr;
        ldns_rr_list *old_ns_addr;
        ldns_rr *ns_rr;
-       
+
        int result = 0;
-       
+
        /* printing niceness */
        const ldns_rr_descriptor *descriptor;
 
@@ -187,13 +187,13 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
        res = ldns_resolver_new();
        key_sig_list = NULL;
        ds_sig_list = NULL;
-       
+
        if (!res) {
                error("Memory allocation failed");
                result = -1;
                return result;
        }
-       
+
        correct_key_list = ldns_rr_list_new();
        if (!correct_key_list) {
                error("Memory allocation failed");
@@ -202,25 +202,31 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
        }
 
        trusted_ds_rrs = ldns_rr_list_new();
-
        if (!trusted_ds_rrs) {
                error("Memory allocation failed");
                result = -1;
                return result;
        }
+        /* Add all preset trusted DS signatures to the list of trusted DS RRs. */
+        for (j = 0; j < ldns_rr_list_rr_count(trusted_keys); j++) {
+            ldns_rr* one_rr = ldns_rr_list_rr(trusted_keys, j);
+            if (ldns_rr_get_type(one_rr)  == LDNS_RR_TYPE_DS) {
+                ldns_rr_list_push_rr(trusted_ds_rrs, ldns_rr_clone(one_rr));
+            }
+        }
 
        /* transfer some properties of local_res to res */
-       ldns_resolver_set_ip6(res, 
+       ldns_resolver_set_ip6(res,
                        ldns_resolver_ip6(local_res));
-       ldns_resolver_set_port(res, 
+       ldns_resolver_set_port(res,
                        ldns_resolver_port(local_res));
-       ldns_resolver_set_debug(res, 
+       ldns_resolver_set_debug(res,
                        ldns_resolver_debug(local_res));
-       ldns_resolver_set_fail(res, 
+       ldns_resolver_set_fail(res,
                        ldns_resolver_fail(local_res));
-       ldns_resolver_set_usevc(res, 
+       ldns_resolver_set_usevc(res,
                        ldns_resolver_usevc(local_res));
-       ldns_resolver_set_random(res, 
+       ldns_resolver_set_random(res,
                        ldns_resolver_random(local_res));
        ldns_resolver_set_recursive(local_res, true);
 
@@ -264,7 +270,7 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
        }
 
        /* get the nameserver for the label
-        * ask: dnskey and ds for the label 
+        * ask: dnskey and ds for the label
         */
        for(i = (ssize_t)labels_count + 1; i > 0; i--) {
                status = ldns_resolver_send(&local_p, res, labels[i], LDNS_RR_TYPE_NS, c, 0);
@@ -313,14 +319,14 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
                                ldns_rr_list_deep_free(new_ns_addr);
                        }
                        ldns_rr_list_deep_free(new_nss);
-                       
+
                        if (ns_addr) {
                                remove_resolver_nameservers(res);
 
-                               if (ldns_resolver_push_nameserver_rr_list(res, ns_addr) != 
+                               if (ldns_resolver_push_nameserver_rr_list(res, ns_addr) !=
                                                LDNS_STATUS_OK) {
                                        error("Error adding new nameservers");
-                                       ldns_pkt_free(local_p); 
+                                       ldns_pkt_free(local_p);
                                        goto done;
                                }
                                ldns_rr_list_deep_free(ns_addr);
@@ -336,7 +342,7 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
                                        printf("correct keys:\n");
                                        ldns_rr_list_print(stdout, correct_key_list);
                                }
-                               
+
                                if (status == LDNS_STATUS_OK) {
                                        if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, trusted_keys, NULL)) == LDNS_STATUS_OK) {
                                                fprintf(stdout, "%s ", TRUST);
@@ -382,7 +388,7 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
                                        ldns_rdf_print(stdout, labels[i]);
                                        printf("NS: %s\n", ldns_get_errorstr_by_id(status));
                                }
-                               
+
                                /* there might be an empty non-terminal, in which case we need to continue */
                                ent = false;
                                for (j = 0; j < ldns_rr_list_rr_count(nsec_rrs); j++) {
@@ -397,10 +403,11 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
                                        goto done;
                                } else {
                                        printf(";; There is an empty non-terminal here, continue\n");
+                                       continue;
                                }
                                goto done;
                        }
-                       
+
                        if (ldns_resolver_nameserver_count(res) == 0) {
                                error("No nameservers found for this node");
                                goto done;
@@ -414,7 +421,7 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
 
                /* retrieve keys for current domain, and verify them
                   if they match an already trusted DS, or if one of the
-                  keys used to sign these is trusted, add the keys to 
+                  keys used to sign these is trusted, add the keys to
                   the trusted list */
                p = get_dnssec_pkt(res, labels[i], LDNS_RR_TYPE_DNSKEY);
                pt = get_key(p, labels[i], &key_list, &key_sig_list);
@@ -428,9 +435,9 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
                                        for (j = 0; j < ldns_rr_list_rr_count(key_list); j++) {
                                                ldns_rr_list_push_rr(correct_key_list, ldns_rr_clone(ldns_rr_list_rr(key_list, j)));
                                        }
-                                       
+
                                        /* check whether these keys were signed
-                                        * by a trusted keys. if so, these 
+                                        * by a trusted keys. if so, these
                                         * keys are also trusted */
                                        new_keys_trusted = false;
                                        for (k = 0; k < ldns_rr_list_rr_count(current_correct_keys); k++) {
index 7867c2a..ff240dc 100644 (file)
@@ -56,7 +56,7 @@ ldns_lookup_table ldns_error_str[] = {
         { LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION, "DNSSEC signature has expiration date earlier than inception date" },
        { LDNS_STATUS_ENGINE_KEY_NOT_LOADED, "Unable to load private key from engine" },
         { LDNS_STATUS_NSEC3_ERR, "Error in NSEC3 denial of existence proof" },
-       { LDNS_STATUS_RES_NO_NS, "No nameservers defined in the resolver" },
+       { LDNS_STATUS_RES_NO_NS, "No (valid) nameservers defined in the resolver" },
        { LDNS_STATUS_RES_QUERY, "No correct query given to resolver" },
        { LDNS_STATUS_WIRE_INCOMPLETE_HEADER, "header section incomplete" },
        { LDNS_STATUS_WIRE_INCOMPLETE_QUESTION, "question section incomplete" },
@@ -68,6 +68,7 @@ ldns_lookup_table ldns_error_str[] = {
        { LDNS_STATUS_SYNTAX_TYPE_ERR, "Syntax error, could not parse the RR's type" },
        { LDNS_STATUS_SYNTAX_CLASS_ERR, "Syntax error, could not parse the RR's class" },
        { LDNS_STATUS_SYNTAX_TTL_ERR, "Syntax error, could not parse the RR's TTL" },
+       { LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL, "Syntax error, $INCLUDE not implemented" },
        { LDNS_STATUS_SYNTAX_RDATA_ERR, "Syntax error, could not parse the RR's rdata" },
        { LDNS_STATUS_SYNTAX_DNAME_ERR, "Syntax error, could not parse the RR's dname(s)" },
        { LDNS_STATUS_SYNTAX_VERSION_ERR, "Syntax error, version mismatch" },
@@ -77,6 +78,7 @@ ldns_lookup_table ldns_error_str[] = {
        { LDNS_STATUS_SYNTAX_EMPTY, "Empty line was returned" },
        { LDNS_STATUS_SYNTAX_TTL, "$TTL directive was seen in the zone" },
        { LDNS_STATUS_SYNTAX_ORIGIN, "$ORIGIN directive was seen in the zone" },
+       { LDNS_STATUS_SYNTAX_INCLUDE, "$INCLUDE directive was seen in the zone" },
        { LDNS_STATUS_SYNTAX_ITERATIONS_OVERFLOW, "Iterations count for NSEC3 record higher than maximum" },
        { LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR, "Syntax error, value expected" },
        { LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW, "Syntax error, integer value too large" },
index de1523f..a4ab06f 100644 (file)
@@ -110,9 +110,7 @@ ldns_get_rr_list_name_by_addr(ldns_resolver *res, ldns_rdf *addr, ldns_rr_class
        ldns_pkt *pkt;
        ldns_rr_list *names;
        ldns_rdf *name;
-       size_t i;
 
-       i = 0; 
        names = NULL;
 
        if (!res || !addr) {
@@ -166,6 +164,14 @@ ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
        ip6 = false;
        list = ldns_rr_list_new();
        rr = NULL;
+       if(!line || !word || !addr || !rr_str || !list) {
+               LDNS_FREE(line);
+               LDNS_FREE(word);
+               LDNS_FREE(addr);
+               LDNS_FREE(rr_str);
+               ldns_rr_list_free(list);
+               return NULL;
+       }
 
        for(i = ldns_fget_token_l(fp, line, "\n", 0, line_nr);
                        i > 0; i = ldns_fget_token_l(fp, line, "\n", 0, line_nr)) {
@@ -175,6 +181,14 @@ ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
                }
                /* put it in a buffer for further processing */
                linebuf = LDNS_MALLOC(ldns_buffer);
+               if(!linebuf) {
+                       LDNS_FREE(line);
+                       LDNS_FREE(word);
+                       LDNS_FREE(addr);
+                       LDNS_FREE(rr_str);
+                       ldns_rr_list_deep_free(list);
+                       return NULL;
+               }
 
                ldns_buffer_new_frm_data(linebuf, line, (size_t) i);
                for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, 0);
index 7ef5e39..32ef8a5 100644 (file)
@@ -51,7 +51,11 @@ ldns_lookup_table ldns_algorithms[] = {
        { LDNS_RSASHA512, "RSASHA512"},
 #endif
 #ifdef USE_GOST
-       { LDNS_GOST, "GOST"},
+       { LDNS_ECC_GOST, "ECC-GOST"},
+#endif
+#ifdef USE_ECDSA
+        { LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"},
+        { LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"},
 #endif
         { LDNS_INDIRECT, "INDIRECT" },
         { LDNS_PRIVATEDNS, "PRIVATEDNS" },
@@ -270,8 +274,10 @@ ldns_rdf2buffer_str_dname(ldns_buffer *output, const ldns_rdf *dname)
                                src_pos++;
                        }
 
+                       if (src_pos < ldns_rdf_size(dname)) {
+                               ldns_buffer_printf(output, ".");
+                       }
                        len = data[src_pos];
-                       ldns_buffer_printf(output, ".");
                }
        }
        return ldns_buffer_status(output);
@@ -305,14 +311,10 @@ ldns_status
 ldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf)
 {
        /* create a YYYYMMDDHHMMSS string if possible */
-       uint32_t data = ldns_read_uint32(ldns_rdf_data(rdf));
-       time_t data_time;
+       time_t data_time = (time_t) ldns_read_uint32(ldns_rdf_data(rdf));
        struct tm tm;
        char date_buf[16];
 
-       data_time = 0;
-       memcpy(&data_time, &data, sizeof(uint32_t));
-
        memset(&tm, 0, sizeof(tm));
 
        if (gmtime_r(&data_time, &tm) && strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) {
@@ -372,6 +374,7 @@ ldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf)
 {
        size_t size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf));
        char *b64 = LDNS_XMALLOC(char, size);
+       if(!b64) return LDNS_STATUS_MEM_ERR;
        if (ldns_b64_ntop(ldns_rdf_data(rdf), ldns_rdf_size(rdf), b64, size)) {
                ldns_buffer_printf(output, "%s", b64);
        }
@@ -382,11 +385,17 @@ ldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf)
 ldns_status
 ldns_rdf2buffer_str_b32_ext(ldns_buffer *output, const ldns_rdf *rdf)
 {
-       size_t size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
-       char *b32 = LDNS_XMALLOC(char, size + 1);
+       size_t size;
+       char *b32;
+       if(ldns_rdf_size(rdf) == 0)
+               return LDNS_STATUS_OK;
+        /* 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 + 1);
+       if(!b32) return LDNS_STATUS_MEM_ERR;
        size = (size_t) ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1,
-                                                                          ldns_rdf_size(rdf) - 1,
-                                                                          b32, size);
+               ldns_rdf_size(rdf) - 1, b32, size+1);
        if (size > 0) {
                ldns_buffer_printf(output, "%s", b32);
        }
@@ -455,19 +464,7 @@ ldns_rdf2buffer_str_alg(ldns_buffer *output, const ldns_rdf *rdf)
        /* don't use algorithm mnemonics in the presentation format
           this kind of got sneaked into the rfc's */
         uint8_t data = ldns_rdf_data(rdf)[0];
-/*
-
-       ldns_lookup_table *lt;
-
-       lt = ldns_lookup_by_id(ldns_algorithms, (int) data);
-       if (lt) {
-               ldns_buffer_printf(output, "%s", lt->name);
-       } else {
-*/
                ldns_buffer_printf(output, "%d", data);
-/*
-       }
-*/
        return ldns_buffer_status(output);
 }
 
@@ -648,7 +645,7 @@ ldns_rdf2buffer_str_loc(ldns_buffer *output, const ldns_rdf *rdf)
 
                loc_cm_print(output, (vertical_precision & 0xf0) >> 4,
                        vertical_precision & 0x0f);
-               ldns_buffer_printf(output, "m ");
+               ldns_buffer_printf(output, "m");
 
                return ldns_buffer_status(output);
        } else {
@@ -763,18 +760,14 @@ ldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf)
        uint8_t salt_pos;
 
        uint8_t *data = ldns_rdf_data(rdf);
-       size_t pos;
 
        salt_length = data[0];
-       /* todo: length check needed/possible? */
        /* from now there are variable length entries so remember pos */
-       pos = 1;
-       if (salt_length == 0) {
+       if (salt_length == 0 || ((size_t)salt_length)+1 > ldns_rdf_size(rdf)) {
                ldns_buffer_printf(output, "- ");
        } else {
                for (salt_pos = 0; salt_pos < salt_length; salt_pos++) {
                        ldns_buffer_printf(output, "%02x", data[1 + salt_pos]);
-                       pos++;
                }
                ldns_buffer_printf(output, " ");
        }
@@ -816,14 +809,16 @@ ldns_status
 ldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf)
 {
        uint8_t *data = ldns_rdf_data(rdf);
-       uint16_t address_family = ldns_read_uint16(data);
-       uint8_t prefix = data[2];
+       uint16_t address_family;
+       uint8_t prefix;
        bool negation;
        uint8_t adf_length;
        unsigned short i;
        unsigned int pos = 0;
 
        while (pos < (unsigned int) ldns_rdf_size(rdf)) {
+                if(pos + 3 >= ldns_rdf_size(rdf))
+                        return LDNS_STATUS_SYNTAX_RDATA_ERR;
                address_family = ldns_read_uint16(&data[pos]);
                prefix = data[pos + 2];
                negation = data[pos + 3] & LDNS_APL_NEGATION;
@@ -840,6 +835,8 @@ ldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf)
                                        ldns_buffer_printf(output, ".");
                                }
                                if (i < (unsigned short) adf_length) {
+                                        if(pos+i+4 >= ldns_rdf_size(rdf))
+                                                return LDNS_STATUS_SYNTAX_RDATA_ERR;
                                        ldns_buffer_printf(output, "%d",
                                                           data[pos + i + 4]);
                                } else {
@@ -859,6 +856,8 @@ ldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf)
                                        ldns_buffer_printf(output, ":");
                                }
                                if (i < (unsigned short) adf_length) {
+                                        if(pos+i+4 >= ldns_rdf_size(rdf))
+                                                return LDNS_STATUS_SYNTAX_RDATA_ERR;
                                        ldns_buffer_printf(output, "%02x",
                                                           data[pos + i + 4]);
                                } else {
@@ -872,6 +871,8 @@ ldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf)
                        ldns_buffer_printf(output, "Unknown address family: %u data: ",
                                        address_family);
                        for (i = 1; i < (unsigned short) (4 + adf_length); i++) {
+                                if(pos+i >= ldns_rdf_size(rdf))
+                                        return LDNS_STATUS_SYNTAX_RDATA_ERR;
                                ldns_buffer_printf(output, "%02x", data[i]);
                        }
                }
@@ -944,6 +945,8 @@ ldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf)
                        break;
                case 3:
                        status = ldns_wire2dname(&gateway, data, ldns_rdf_size(rdf), &offset);
+                        if(status != LDNS_STATUS_OK)
+                                return status;
                        break;
                default:
                        /* error? */
@@ -980,7 +983,7 @@ ldns_rdf2buffer_str_tsig(ldns_buffer *output, const ldns_rdf *rdf)
 ldns_status
 ldns_rdf2buffer_str(ldns_buffer *buffer, const ldns_rdf *rdf)
 {
-       ldns_status res;
+       ldns_status res = LDNS_STATUS_OK;
 
        /*ldns_buffer_printf(buffer, "%u:", ldns_rdf_get_type(rdf));*/
        if (rdf) {
@@ -1078,8 +1081,9 @@ ldns_rdf2buffer_str(ldns_buffer *buffer, const ldns_rdf *rdf)
                }
        } else {
                ldns_buffer_printf(buffer, "(null) ");
+               res = ldns_buffer_status(buffer);
        }
-       return LDNS_STATUS_OK;
+       return res;
 }
 
 ldns_status
@@ -1122,6 +1126,8 @@ ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
 
                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, " ");
                        }
@@ -1162,7 +1168,8 @@ ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
                                                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);
-                                               ldns_buffer_printf(output, " ; %s", babble);
+                                               if(babble)
+                                                 ldns_buffer_printf(output, " ; %s", babble);
                                                LDNS_FREE(babble);
                                        }
                                        break;
@@ -1693,14 +1700,41 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
                                        printf("(Not available)\n");
                                }
                                break;
-                       case LDNS_SIGN_GOST:
+                       case LDNS_SIGN_ECC_GOST:
                                /* no format defined, use blob */
 #if defined(HAVE_SSL) && defined(USE_GOST)
                                ldns_buffer_printf(output, "Private-key-format: v1.2\n");
-                               ldns_buffer_printf(output, "Algorithm: %d (GOST)\n", LDNS_SIGN_GOST);
+                               ldns_buffer_printf(output, "Algorithm: %d (ECC-GOST)\n", LDNS_SIGN_ECC_GOST);
                                status = ldns_gost_key2buffer_str(output, k->_key.key);
 #endif
                                break;
+#ifdef USE_ECDSA
+                       case LDNS_SIGN_ECDSAP256SHA256:
+                       case LDNS_SIGN_ECDSAP384SHA384:
+                                ldns_buffer_printf(output, "Private-key-format: v1.2\n");
+                               ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
+                                ldns_algorithm2buffer_str(output, ldns_key_algorithm(k));
+                               ldns_buffer_printf(output, ")\n");
+                                if(k->_key.key) {
+                                        EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
+                                        const BIGNUM* b = EC_KEY_get0_private_key(ec);
+                                        ldns_buffer_printf(output, "PrivateKey: ");
+                                        i = (uint16_t)BN_bn2bin(b, bignum);
+                                        if (i > LDNS_MAX_KEYLEN) {
+                                                goto error;
+                                        }
+                                        b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+                                        if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+                                                goto error;
+                                        }
+                                        ldns_rdf_deep_free(b64_bignum);
+                                       ldns_buffer_printf(output, "\n");
+                                        /* down reference count in EC_KEY
+                                         * its still assigned to the PKEY */
+                                        EC_KEY_free(ec);
+                                }
+                                break;
+#endif
                        case LDNS_SIGN_HMACMD5:
                                /* there's not much of a format defined for TSIG */
                                /* It's just a binary blob, Same for all algorithms */
@@ -1771,7 +1805,7 @@ char *
 ldns_rdf2str(const ldns_rdf *rdf)
 {
        char *result = NULL;
-       ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MIN_BUFLEN);
+       ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
 
        if (ldns_rdf2buffer_str(tmp_buffer, rdf) == LDNS_STATUS_OK) {
                /* export and return string, destroy rest */
@@ -1786,7 +1820,7 @@ char *
 ldns_rr2str(const ldns_rr *rr)
 {
        char *result = NULL;
-       ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MIN_BUFLEN);
+       ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
 
        if (ldns_rr2buffer_str(tmp_buffer, rr) == LDNS_STATUS_OK) {
                /* export and return string, destroy rest */
@@ -1815,7 +1849,7 @@ char *
 ldns_key2str(const ldns_key *k)
 {
        char *result = NULL;
-       ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MIN_BUFLEN);
+       ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
        if (ldns_key2buffer_str(tmp_buffer, k) == LDNS_STATUS_OK) {
                /* export and return string, destroy rest */
                result = ldns_buffer2str(tmp_buffer);
@@ -1828,7 +1862,7 @@ char *
 ldns_rr_list2str(const ldns_rr_list *list)
 {
        char *result = NULL;
-       ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MIN_BUFLEN);
+       ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
 
        if (list) {
                if (ldns_rr_list2buffer_str(tmp_buffer, list) == LDNS_STATUS_OK) {
@@ -1911,20 +1945,32 @@ ldns_resolver_print(FILE *output, const ldns_resolver *r)
        fprintf(output, "igntc: %d\n", ldns_resolver_igntc(r));
        fprintf(output, "fail: %d\n", ldns_resolver_fail(r));
        fprintf(output, "retry: %d\n", (int)ldns_resolver_retry(r));
+       fprintf(output, "retrans: %d\n", (int)ldns_resolver_retrans(r));
+       fprintf(output, "fallback: %d\n", ldns_resolver_fallback(r));
+       fprintf(output, "random: %d\n", ldns_resolver_random(r));
        fprintf(output, "timeout: %d\n", (int)ldns_resolver_timeout(r).tv_sec);
+       fprintf(output, "dnssec: %d\n", ldns_resolver_dnssec(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));
+       fprintf(output, "tsig: %s %s\n", ldns_resolver_tsig_keyname(r), ldns_resolver_tsig_algorithm(r));
+       fprintf(output, "debug: %d\n", ldns_resolver_debug(r));
 
        fprintf(output, "default domain: ");
        ldns_rdf_print(output, ldns_resolver_domain(r));
        fprintf(output, "\n");
+       fprintf(output, "apply default domain: %d\n", ldns_resolver_defnames(r));
 
-       fprintf(output, "searchlist:\n");
+       fprintf(output, "searchlist (%d listed):\n",  (int)ldns_resolver_searchlist_count(r));
        for (i = 0; i < ldns_resolver_searchlist_count(r); i++) {
                fprintf(output, "\t");
                ldns_rdf_print(output, s[i]);
                fprintf(output, "\n");
        }
+       fprintf(output, "apply search list: %d\n", ldns_resolver_dnsrch(r));
 
-       fprintf(output, "nameservers:\n");
+       fprintf(output, "nameservers (%d listed):\n", (int)ldns_resolver_nameserver_count(r));
        for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
                fprintf(output, "\t");
                ldns_rdf_print(output, n[i]);
index c1f0f0d..93b017d 100644 (file)
@@ -75,7 +75,7 @@ ldns_rr_list2buffer_wire(ldns_buffer *buffer,const ldns_rr_list *rr_list)
 
        rr_count = ldns_rr_list_rr_count(rr_list);
        for(i = 0; i < rr_count; i++) {
-               (void)ldns_rr2buffer_wire(buffer, ldns_rr_list_rr(rr_list, i), 
+               ldns_rr2buffer_wire(buffer, ldns_rr_list_rr(rr_list, i), 
                                          LDNS_SECTION_ANY);
        }
        return ldns_buffer_status(buffer);
@@ -308,6 +308,7 @@ ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
        /* add EDNS to additional if it is needed */
        if (ldns_pkt_edns(packet)) {
                edns_rr = ldns_rr_new();
+               if(!edns_rr) return LDNS_STATUS_MEM_ERR;
                ldns_rr_set_owner(edns_rr,
                                ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "."));
                ldns_rr_set_type(edns_rr, LDNS_RR_TYPE_OPT);
@@ -343,17 +344,23 @@ ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *result_size)
        ldns_status status;
        *result_size = 0;
        *dest = NULL;
+       if(!buffer) return LDNS_STATUS_MEM_ERR;
        
        status = ldns_rdf2buffer_wire(buffer, rdf);
        if (status == LDNS_STATUS_OK) {
                *result_size =  ldns_buffer_position(buffer);
                result = (uint8_t *) ldns_buffer_export(buffer);
        } else {
+               ldns_buffer_free(buffer);
                return status;
        }
        
        if (result) {
                *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
+               if(!*dest) {
+                       ldns_buffer_free(buffer);
+                       return LDNS_STATUS_MEM_ERR;
+               }
                memcpy(*dest, result, ldns_buffer_position(buffer));
        }
        
@@ -369,17 +376,23 @@ ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *result_size
        ldns_status status;
        *result_size = 0;
        *dest = NULL;
+       if(!buffer) return LDNS_STATUS_MEM_ERR;
        
        status = ldns_rr2buffer_wire(buffer, rr, section);
        if (status == LDNS_STATUS_OK) {
                *result_size =  ldns_buffer_position(buffer);
                result = (uint8_t *) ldns_buffer_export(buffer);
        } else {
+               ldns_buffer_free(buffer);
                return status;
        }
        
        if (result) {
                *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
+               if(!*dest) {
+                       ldns_buffer_free(buffer);
+                       return LDNS_STATUS_MEM_ERR;
+               }
                memcpy(*dest, result, ldns_buffer_position(buffer));
        }
        
@@ -395,17 +408,23 @@ ldns_pkt2wire(uint8_t **dest, const ldns_pkt *packet, size_t *result_size)
        ldns_status status;
        *result_size = 0;
        *dest = NULL;
+       if(!buffer) return LDNS_STATUS_MEM_ERR;
        
        status = ldns_pkt2buffer_wire(buffer, packet);
        if (status == LDNS_STATUS_OK) {
                *result_size =  ldns_buffer_position(buffer);
                result = (uint8_t *) ldns_buffer_export(buffer);
        } else {
+               ldns_buffer_free(buffer);
                return status;
        }
        
        if (result) {
                *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
+               if(!*dest) {
+                       ldns_buffer_free(buffer);
+                       return LDNS_STATUS_MEM_ERR;
+               }
                memcpy(*dest, result, ldns_buffer_position(buffer));
        }
        
index 4d03542..e0fffc7 100644 (file)
 ldns_lookup_table ldns_signing_algorithms[] = {
         { LDNS_SIGN_RSAMD5, "RSAMD5" },
         { LDNS_SIGN_RSASHA1, "RSASHA1" },
-        { LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" },
+        { LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
 #ifdef USE_SHA2
         { LDNS_SIGN_RSASHA256, "RSASHA256" },
         { LDNS_SIGN_RSASHA512, "RSASHA512" },
 #endif
 #ifdef USE_GOST
-        { LDNS_SIGN_GOST, "GOST" },
+        { LDNS_SIGN_ECC_GOST, "ECC-GOST" },
+#endif
+#ifdef USE_ECDSA
+        { LDNS_SIGN_ECDSAP256SHA256, "ECDSAP256SHA256" },
+        { LDNS_SIGN_ECDSAP384SHA384, "ECDSAP384SHA384" },
 #endif
         { LDNS_SIGN_DSA, "DSA" },
-        { LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" },
+        { LDNS_SIGN_DSA_NSEC3, "DSA-NSEC3-SHA1" },
         { LDNS_SIGN_HMACMD5, "hmac-md5.sig-alg.reg.int" },
         { LDNS_SIGN_HMACSHA1, "hmac-sha1" },
         { LDNS_SIGN_HMACSHA256, "hmac-sha256" },
@@ -103,6 +107,9 @@ ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm
 #endif
 
 #ifdef USE_GOST
+/** store GOST engine reference loaded into OpenSSL library */
+ENGINE* ldns_gost_engine = NULL;
+
 int
 ldns_key_EVP_load_gost_id(void)
 {
@@ -138,15 +145,27 @@ ldns_key_EVP_load_gost_id(void)
        }
 
        meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
-       ENGINE_finish(e);
-       ENGINE_free(e);
        if(!meth) {
                /* algo not found */
+               ENGINE_finish(e);
+               ENGINE_free(e);
                return 0;
        }
+        /* Note: do not ENGINE_finish and ENGINE_free the acquired engine
+         * on some platforms this frees up the meth and unloads gost stuff */
+        ldns_gost_engine = e;
        
        EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
        return gost_id;
+} 
+
+void ldns_key_EVP_unload_gost(void)
+{
+        if(ldns_gost_engine) {
+                ENGINE_finish(ldns_gost_engine);
+                ENGINE_free(ldns_gost_engine);
+                ldns_gost_engine = NULL;
+        }
 }
 
 /** read GOST private key */
@@ -181,6 +200,83 @@ ldns_key_new_frm_fp_gost_l(FILE* fp, int* line_nr)
 }
 #endif
 
+#ifdef USE_ECDSA
+/** calculate public key from private key */
+static int
+ldns_EC_KEY_calc_public(EC_KEY* ec)
+{
+        EC_POINT* pub_key;
+        const EC_GROUP* group;
+        group = EC_KEY_get0_group(ec);
+        pub_key = EC_POINT_new(group);
+        if(!pub_key) return 0;
+        if(!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
+                EC_POINT_free(pub_key);
+                return 0;
+        }
+        if(!EC_POINT_mul(group, pub_key, EC_KEY_get0_private_key(ec),
+                NULL, NULL, NULL)) {
+                EC_POINT_free(pub_key);
+                return 0;
+        }
+        if(EC_KEY_set_public_key(ec, pub_key) == 0) {
+                EC_POINT_free(pub_key);
+                return 0;
+        }
+        EC_POINT_free(pub_key);
+        return 1;
+}
+
+/** read ECDSA private key */
+static EVP_PKEY*
+ldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr)
+{
+       char token[16384];
+        ldns_rdf* b64rdf = NULL;
+        unsigned char* pp;
+        BIGNUM* bn;
+        EVP_PKEY* evp_key;
+        EC_KEY* ec;
+       if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", 
+               sizeof(token), line_nr) == -1)
+               return NULL;
+       if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
+               return NULL;
+        pp = (unsigned char*)ldns_rdf_data(b64rdf);
+
+        if(alg == LDNS_ECDSAP256SHA256)
+                ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+        else if(alg == LDNS_ECDSAP384SHA384)
+                ec = EC_KEY_new_by_curve_name(NID_secp384r1);
+        else    ec = NULL;
+        if(!ec) {
+               ldns_rdf_deep_free(b64rdf);
+                return NULL;
+        }
+       bn = BN_bin2bn(pp, ldns_rdf_size(b64rdf), NULL);
+       ldns_rdf_deep_free(b64rdf);
+        if(!bn) {
+                EC_KEY_free(ec);
+                return NULL;
+        }
+        EC_KEY_set_private_key(ec, bn);
+        BN_free(bn);
+        if(!ldns_EC_KEY_calc_public(ec)) {
+                EC_KEY_free(ec);
+                return NULL;
+        }
+
+        evp_key = EVP_PKEY_new();
+        if(!evp_key) {
+                EC_KEY_free(ec);
+                return NULL;
+        }
+        EVP_PKEY_assign_EC_KEY(evp_key, ec);
+
+        return evp_key;
+}
+#endif
+       
 ldns_status
 ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
 {
@@ -266,14 +362,22 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
                fprintf(stderr, "version of ldns\n");
 #endif
        }
-       if (strncmp(d, "249 GOST", 4) == 0) {
+       if (strncmp(d, "12 ECC-GOST", 3) == 0) {
 #ifdef USE_GOST
-               alg = LDNS_SIGN_GOST;
+               alg = LDNS_SIGN_ECC_GOST;
 #else
-               fprintf(stderr, "Warning: GOST not compiled into this ");
-               fprintf(stderr, "version of ldns\n");
+               fprintf(stderr, "Warning: ECC-GOST not compiled into this ");
+               fprintf(stderr, "version of ldns, use --enable-gost\n");
 #endif
        }
+#ifdef USE_ECDSA
+       if (strncmp(d, "13 ECDSAP256SHA256", 3) == 0) {
+                alg = LDNS_ECDSAP256SHA256;
+        }
+       if (strncmp(d, "14 ECDSAP384SHA384", 3) == 0) {
+                alg = LDNS_ECDSAP384SHA384;
+        }
+#endif
        if (strncmp(d, "157 HMAC-MD5", 4) == 0) {
                alg = LDNS_SIGN_HMACMD5;
        }
@@ -332,9 +436,13 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
                        ldns_key_set_hmac_key(k, hmac);
 #endif /* HAVE_SSL */
                        break;
-               case LDNS_SIGN_GOST:
+               case LDNS_SIGN_ECC_GOST:
                        ldns_key_set_algorithm(k, alg);
 #if defined(HAVE_SSL) && defined(USE_GOST)
+                        if(!ldns_key_EVP_load_gost_id()) {
+                               ldns_key_free(k);
+                                return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
+                        }
                        ldns_key_set_evp_key(k, 
                                ldns_key_new_frm_fp_gost_l(fp, line_nr));
                        if(!k->_key.key) {
@@ -343,10 +451,21 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
                        }
 #endif
                        break;
+#ifdef USE_ECDSA
+               case LDNS_SIGN_ECDSAP256SHA256:
+               case LDNS_SIGN_ECDSAP384SHA384:
+                        ldns_key_set_algorithm(k, alg);
+                        ldns_key_set_evp_key(k,
+                                ldns_key_new_frm_fp_ecdsa_l(fp, alg, line_nr));
+                       if(!k->_key.key) {
+                               ldns_key_free(k);
+                               return LDNS_STATUS_ERR;
+                       }
+                       break;
+#endif
                case 0:
                default:
                        return LDNS_STATUS_SYNTAX_ALG_ERR;
-                       break;
        }
        key_rr = ldns_key2rr(k);
        ldns_key_set_keytag(k, ldns_calc_keytag(key_rr));
@@ -664,6 +783,9 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
 #ifdef HAVE_SSL
        DSA *d;
        RSA *r;
+#  ifdef USE_ECDSA
+        EC_KEY *ec = NULL;
+#  endif
 #else
        int i;
        uint16_t offset = 0;
@@ -733,11 +855,31 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
 
                        ldns_key_set_flags(k, 0);
                        break;
-               case LDNS_SIGN_GOST:
+               case LDNS_SIGN_ECC_GOST:
 #if defined(HAVE_SSL) && defined(USE_GOST)
                        ldns_key_set_evp_key(k, ldns_gen_gost_key());
 #endif /* HAVE_SSL and USE_GOST */
+                        break;
+#ifdef USE_ECDSA
+                case LDNS_ECDSAP256SHA256:
+                case LDNS_ECDSAP384SHA384:
+                        if(alg == LDNS_ECDSAP256SHA256)
+                                ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+                        else if(alg == LDNS_ECDSAP384SHA384)
+                                ec = EC_KEY_new_by_curve_name(NID_secp384r1);
+                        if(!ec) return NULL;
+                        if(!EC_KEY_generate_key(ec)) {
+                                EC_KEY_free(ec);
+                                return NULL;
+                        }
+                        k->_key.key = EVP_PKEY_new();
+                        if(!k->_key.key) {
+                                EC_KEY_free(ec);
+                                return NULL;
+                        }
+                        EVP_PKEY_assign_EC_KEY(k->_key.key, ec);
                        break;
+#endif
        }
        ldns_key_set_algorithm(k, alg);
        return k;
@@ -994,7 +1136,6 @@ ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key)
         ldns_key **keys;
 
         key_count = ldns_key_list_key_count(key_list);
-        keys = key_list->_keys;
 
         /* grow the array */
         keys = LDNS_XREALLOC(
@@ -1111,13 +1252,10 @@ ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
                return false;
        }
        /* omit ASN header */
-       /* insert parameters */
-       data[0] = 0;
-       data[1] = 0;
        for(i=0; i<64; i++)
-               data[i+2] = pp[i+37];
+               data[i] = pp[i+37];
        CRYPTO_free(pp);
-       *size = 66;
+       *size = 64;
        return true;
 }
 #endif /* USE_GOST */
@@ -1139,6 +1277,9 @@ ldns_key2rr(const ldns_key *k)
        RSA *rsa = NULL;
        DSA *dsa = NULL;
 #endif /* HAVE_SSL */
+#ifdef USE_ECDSA
+        EC_KEY* ec;
+#endif
        int internal_data = 0;
 
        pubkey = ldns_rr_new();
@@ -1229,7 +1370,7 @@ ldns_key2rr(const ldns_key *k)
                        }
 #endif /* HAVE_SSL */
                        break;
-               case LDNS_SIGN_GOST:
+               case LDNS_SIGN_ECC_GOST:
                        ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
                                LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
 #if defined(HAVE_SSL) && defined(USE_GOST)
@@ -1240,8 +1381,34 @@ ldns_key2rr(const ldns_key *k)
                                return NULL;
                        }
                        internal_data = 1;
-                       break;
 #endif /* HAVE_SSL and USE_GOST */
+                       break;
+#ifdef USE_ECDSA
+                case LDNS_SIGN_ECDSAP256SHA256:
+                case LDNS_SIGN_ECDSAP384SHA384:
+                       ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
+                               LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
+                        bin = NULL;
+                        ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
+                        EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
+                        size = i2o_ECPublicKey(ec, NULL);
+                        if(!i2o_ECPublicKey(ec, &bin))
+                                return NULL;
+                       if(size > 1) {
+                               /* move back one byte to shave off the 0x02
+                                * 'uncompressed' indicator that openssl made
+                                * Actually its 0x04 (from implementation).
+                                */
+                               assert(bin[0] == POINT_CONVERSION_UNCOMPRESSED);
+                               size -= 1;
+                               memmove(bin, bin+1, size);
+                       }
+                        /* down the reference count for ec, its still assigned
+                         * to the pkey */
+                        EC_KEY_free(ec);
+                       internal_data = 1;
+                        break;
+#endif
                case LDNS_SIGN_HMACMD5:
                case LDNS_SIGN_HMACSHA1:
                case LDNS_SIGN_HMACSHA256:
@@ -1371,3 +1538,41 @@ int ldns_key_algo_supported(int algo)
        }
        return 0;
 }
+
+ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name)
+{
+        /* list of (signing algorithm id, alias_name) */
+        ldns_lookup_table aliases[] = {
+                /* from bind dnssec-keygen */
+                {LDNS_SIGN_HMACMD5, "HMAC-MD5"},
+                {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"},
+                {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"},
+                /* old ldns usage, now RFC names */
+                {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" },
+                {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" },
+#ifdef USE_GOST
+                {LDNS_SIGN_ECC_GOST, "GOST"},
+#endif
+                /* compat with possible output */
+                {LDNS_DH, "DH"},
+                {LDNS_ECC, "ECC"},
+                {LDNS_INDIRECT, "INDIRECT"},
+                {LDNS_PRIVATEDNS, "PRIVATEDNS"},
+                {LDNS_PRIVATEOID, "PRIVATEOID"},
+                {0, NULL}};
+        ldns_lookup_table* lt = ldns_signing_algorithms;
+        while(lt->name) {
+                if(strcasecmp(lt->name, name) == 0)
+                        return lt->id;
+                lt++;
+        }
+        lt = aliases;
+        while(lt->name) {
+                if(strcasecmp(lt->name, name) == 0)
+                        return lt->id;
+                lt++;
+        }
+        if(atoi(name) != 0)
+                return atoi(name);
+        return 0;
+}
index 4e5f9fe..65b8bdc 100644 (file)
 
 #include "ldns/util.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * number of initial bytes in buffer of
  * which we cannot tell the size before hand
@@ -633,4 +637,8 @@ void *ldns_buffer_export(ldns_buffer *buffer);
  */
 void ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_BUFFER_H */
index 8e09f3b..cc7dd89 100644 (file)
@@ -23,7 +23,7 @@
 
 /*@ignore@*/
 /* splint barfs on this construct */
-typedef unsigned char bool;
+typedef unsigned int bool;
 #define bool bool
 #define false 0
 #define true  1
diff --git a/contrib/ldns/ldns/config.h.in b/contrib/ldns/ldns/config.h.in
deleted file mode 100644 (file)
index 9db7843..0000000
+++ /dev/null
@@ -1,443 +0,0 @@
-/* ldns/config.h.in.  Generated from configure.ac by autoheader.  */
-
-/* Define if building universal (internal helper macro) */
-#undef AC_APPLE_UNIVERSAL_BUILD
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#undef HAVE_ARPA_INET_H
-
-/* Whether the C compiler accepts the "format" attribute */
-#undef HAVE_ATTR_FORMAT
-
-/* Whether the C compiler accepts the "unused" attribute */
-#undef HAVE_ATTR_UNUSED
-
-/* Define to 1 if you have the `b32_ntop' function. */
-#undef HAVE_B32_NTOP
-
-/* Define to 1 if you have the `b32_pton' function. */
-#undef HAVE_B32_PTON
-
-/* Define to 1 if you have the `b64_ntop' function. */
-#undef HAVE_B64_NTOP
-
-/* Define to 1 if you have the `b64_pton' function. */
-#undef HAVE_B64_PTON
-
-/* Define to 1 if you have the `ctime_r' function. */
-#undef HAVE_CTIME_R
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#undef HAVE_DLFCN_H
-
-/* Define to 1 if you have the `endprotoent' function. */
-#undef HAVE_ENDPROTOENT
-
-/* Define to 1 if you have the `endservent' function. */
-#undef HAVE_ENDSERVENT
-
-/* Define to 1 if you have the `EVP_sha256' function. */
-#undef HAVE_EVP_SHA256
-
-/* Define to 1 if you have the `fcntl' function. */
-#undef HAVE_FCNTL
-
-/* Whether getaddrinfo is available */
-#undef HAVE_GETADDRINFO
-
-/* Define to 1 if you have the <getopt.h> header file. */
-#undef HAVE_GETOPT_H
-
-/* Define to 1 if you have the `gmtime_r' function. */
-#undef HAVE_GMTIME_R
-
-/* If you have HMAC_CTX_init */
-#undef HAVE_HMAC_CTX_INIT
-
-/* Define to 1 if you have the `inet_aton' function. */
-#undef HAVE_INET_ATON
-
-/* Define to 1 if you have the `inet_ntop' function. */
-#undef HAVE_INET_NTOP
-
-/* Define to 1 if you have the `inet_pton' function. */
-#undef HAVE_INET_PTON
-
-/* define if you have inttypes.h */
-#undef HAVE_INTTYPES_H
-
-/* if the function 'ioctlsocket' is available */
-#undef HAVE_IOCTLSOCKET
-
-/* Define to 1 if you have the `isblank' function. */
-#undef HAVE_ISBLANK
-
-/* Define to 1 if you have the `crypto' library (-lcrypto). */
-#undef HAVE_LIBCRYPTO
-
-/* Define to 1 if you have the `nsl' library (-lnsl). */
-#undef HAVE_LIBNSL
-
-/* Define to 1 if you have the `socket' library (-lsocket). */
-#undef HAVE_LIBSOCKET
-
-/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
-   to 0 otherwise. */
-#undef HAVE_MALLOC
-
-/* Define to 1 if you have the `memmove' function. */
-#undef HAVE_MEMMOVE
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#undef HAVE_NETDB_H
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#undef HAVE_NETINET_IN_H
-
-/* Define to 1 if you have the <openssl/err.h> header file. */
-#undef HAVE_OPENSSL_ERR_H
-
-/* Define to 1 if you have the <openssl/rand.h> header file. */
-#undef HAVE_OPENSSL_RAND_H
-
-/* Define to 1 if you have the <openssl/ssl.h> header file. */
-#undef HAVE_OPENSSL_SSL_H
-
-/* Define if you have Python libraries and header files. */
-#undef HAVE_PYTHON
-
-/* Define to 1 if you have the `random' function. */
-#undef HAVE_RANDOM
-
-/* Define to 1 if your system has a GNU libc compatible `realloc' function,
-   and to 0 otherwise. */
-#undef HAVE_REALLOC
-
-/* Define to 1 if you have the `sleep' function. */
-#undef HAVE_SLEEP
-
-/* Define to 1 if you have the `snprintf' function. */
-#undef HAVE_SNPRINTF
-
-/* Define if you have the SSL libraries installed. */
-#undef HAVE_SSL
-
-/* Define to 1 if you have the <stdarg.h> header file. */
-#undef HAVE_STDARG_H
-
-/* Define to 1 if you have the <stdbool.h> header file. */
-#undef HAVE_STDBOOL_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the `strlcpy' function. */
-#undef HAVE_STRLCPY
-
-/* Define if you have Swig libraries and header files. */
-#undef HAVE_SWIG
-
-/* Define to 1 if you have the <sys/mount.h> header file. */
-#undef HAVE_SYS_MOUNT_H
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#undef HAVE_SYS_PARAM_H
-
-/* define if you have sys/socket.h */
-#undef HAVE_SYS_SOCKET_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the `timegm' function. */
-#undef HAVE_TIMEGM
-
-/* Define to 1 if you have the <time.h> header file. */
-#undef HAVE_TIME_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to 1 if you have the <winsock2.h> header file. */
-#undef HAVE_WINSOCK2_H
-
-/* Define to 1 if you have the <ws2tcpip.h> header file. */
-#undef HAVE_WS2TCPIP_H
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
-   */
-#undef LT_OBJDIR
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* System configuration dir */
-#undef SYSCONFDIR
-
-/* Define this to enable GOST support. */
-#undef USE_GOST
-
-/* Define this to enable SHA256 and SHA512 support. */
-#undef USE_SHA2
-
-/* Enable extensions on AIX 3, Interix.  */
-#ifndef _ALL_SOURCE
-# undef _ALL_SOURCE
-#endif
-/* Enable GNU extensions on systems that have them.  */
-#ifndef _GNU_SOURCE
-# undef _GNU_SOURCE
-#endif
-/* Enable threading extensions on Solaris.  */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# undef _POSIX_PTHREAD_SEMANTICS
-#endif
-/* Enable extensions on HP NonStop.  */
-#ifndef _TANDEM_SOURCE
-# undef _TANDEM_SOURCE
-#endif
-/* Enable general extensions on Solaris.  */
-#ifndef __EXTENSIONS__
-# undef __EXTENSIONS__
-#endif
-
-
-/* Whether the windows socket API is used */
-#undef USE_WINSOCK
-
-/* the version of the windows API enabled */
-#undef WINVER
-
-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
-   significant byte first (like Motorola and SPARC, unlike Intel). */
-#if defined AC_APPLE_UNIVERSAL_BUILD
-# if defined __BIG_ENDIAN__
-#  define WORDS_BIGENDIAN 1
-# endif
-#else
-# ifndef WORDS_BIGENDIAN
-#  undef WORDS_BIGENDIAN
-# endif
-#endif
-
-/* Define to 1 if on MINIX. */
-#undef _MINIX
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
-   this defined. */
-#undef _POSIX_1_SOURCE
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-#undef _POSIX_SOURCE
-
-/* Define to empty if `const' does not conform to ANSI C. */
-#undef const
-
-/* in_addr_t */
-#undef in_addr_t
-
-/* in_port_t */
-#undef in_port_t
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-#undef inline
-#endif
-
-/* Define to `short' if <sys/types.h> does not define. */
-#undef int16_t
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef int32_t
-
-/* Define to `long long' if <sys/types.h> does not define. */
-#undef int64_t
-
-/* Define to `char' if <sys/types.h> does not define. */
-#undef int8_t
-
-/* Define to rpl_malloc if the replacement function should be used. */
-#undef malloc
-
-/* Define to rpl_realloc if the replacement function should be used. */
-#undef realloc
-
-/* Define to 'int' if not defined */
-#undef socklen_t
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef ssize_t
-
-/* Define to `unsigned short' if <sys/types.h> does not define. */
-#undef uint16_t
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-#undef uint32_t
-
-/* Define to `unsigned long long' if <sys/types.h> does not define. */
-#undef uint64_t
-
-/* Define to `unsigned char' if <sys/types.h> does not define. */
-#undef uint8_t
-
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <assert.h>
-
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
-#endif
-
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
-#endif
-
-#ifndef BYTE_ORDER
-#ifdef WORDS_BIGENDIAN
-#define BYTE_ORDER BIG_ENDIAN
-#else
-#define BYTE_ORDER LITTLE_ENDIAN
-#endif /* WORDS_BIGENDIAN */
-#endif /* BYTE_ORDER */
-
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#ifdef HAVE_WINSOCK2_H
-#include <winsock2.h>
-#endif
-
-#ifdef HAVE_WS2TCPIP_H
-#include <ws2tcpip.h>
-#endif
-
-
-/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */
-#ifdef HAVE_WINSOCK2_H
-#define FD_SET_T (u_int)
-#else
-#define FD_SET_T 
-#endif
-
-
-
-
-#ifndef B64_PTON
-int ldns_b64_ntop(uint8_t const *src, size_t srclength,
-                 char *target, size_t targsize);
-/**
- * calculates the size needed to store the result of b64_ntop
- */
-/*@unused@*/
-static inline size_t ldns_b64_ntop_calculate_size(size_t srcsize)
-{
-       return ((((srcsize + 2) / 3) * 4) + 1);
-}
-#endif /* !B64_PTON */
-#ifndef B64_NTOP
-int ldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
-/**
- * calculates the size needed to store the result of ldns_b64_pton
- */
-/*@unused@*/
-static inline size_t ldns_b64_pton_calculate_size(size_t srcsize)
-{
-       return ((((srcsize / 4) * 3) - 2) + 2);
-}
-#endif /* !B64_NTOP */
-
-#ifndef HAVE_SLEEP
-/* use windows sleep, in millisecs, instead */
-#define sleep(x) Sleep((x)*1000)
-#endif
-
-#ifndef HAVE_RANDOM
-#define srandom(x) srand(x)
-#define random(x) rand(x)
-#endif
-
-#ifndef HAVE_TIMEGM
-#include <time.h>
-time_t timegm (struct tm *tm);
-#endif /* !TIMEGM */
-#ifndef HAVE_GMTIME_R
-struct tm *gmtime_r(const time_t *timep, struct tm *result);
-#endif
-#ifndef HAVE_ISBLANK
-int isblank(int c);
-#endif /* !HAVE_ISBLANK */
-#ifndef HAVE_SNPRINTF
-#include <stdarg.h>
-int snprintf (char *str, size_t count, const char *fmt, ...);
-int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
-#endif /* HAVE_SNPRINTF */
-#ifndef HAVE_INET_PTON
-int inet_pton(int af, const char* src, void* dst);
-#endif /* HAVE_INET_PTON */
-#ifndef HAVE_INET_NTOP
-const char *inet_ntop(int af, const void *src, char *dst, size_t size);
-#endif
-#ifndef HAVE_INET_ATON
-int inet_aton(const char *cp, struct in_addr *addr);
-#endif
-#ifndef HAVE_MEMMOVE
-void *memmove(void *dest, const void *src, size_t n);
-#endif
-#ifndef HAVE_STRLCPY
-size_t strlcpy(char *dst, const char *src, size_t siz);
-#endif
-#ifndef HAVE_GETADDRINFO
-#include "compat/fake-rfc2553.h"
-#endif
-
index b144b4c..a91f075 100644 (file)
@@ -31,7 +31,7 @@
  *
  * Domain names are stored in \ref ldns_rdf structures, with the type
  * \ref LDNS_RDF_TYPE_DNAME
- * 
+ *
  * This module is *NOT* about the RR type called DNAME.
  */
 
 #include <ldns/common.h>
 #include <ldns/rdata.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define LDNS_DNAME_NORMALIZE        tolower
 
 /**
@@ -74,14 +78,14 @@ ldns_rdf *ldns_dname_reverse(const ldns_rdf *d);
  * \param[in] n the label nr to clone from, if this is 0, the complete
  *              dname is cloned
  * \return A newly allocated *rdf structure, containing the cloned dname,
- *         or NULL if either d was NULL, not a dname, or if n >= 
+ *         or NULL if either d was NULL, not a dname, or if n >=
  *         label_count
  */
 ldns_rdf *
 ldns_dname_clone_from(const ldns_rdf *d, uint16_t n);
 
 /**
- * chop one label off the left side of a dname. so 
+ * chop one label off the left side of a dname. so
  * wwww.nlnetlabs.nl, becomes nlnetlabs.nl
  * This new name is a clone and must be freed with ldns_deep_free()
  * \param[in] d the dname to chop
@@ -93,7 +97,7 @@ ldns_rdf *ldns_dname_left_chop(const ldns_rdf *d);
  * count the number of labels inside a LDNS_RDF_DNAME type rdf.
  * \param[in] *r the rdf
  * \return the number of labels
- */     
+ */
 uint8_t  ldns_dname_label_count(const ldns_rdf *r);
 
 /**
@@ -105,7 +109,7 @@ ldns_rdf *ldns_dname_new_frm_str(const char *str);
 
 /**
  * Create a new dname rdf from a string
- * \param[in] s the size of the new dname 
+ * \param[in] s the size of the new dname
  * \param[in] *data pointer to the actual data
  * \return ldns_rdf*
  */
@@ -183,4 +187,15 @@ bool ldns_dname_str_absolute(const char *dname_str);
  */
 ldns_rdf * ldns_dname_label(const ldns_rdf *rdf, uint8_t labelpos);
 
+/**
+ * Check if dname is a wildcard, starts with *.
+ * \param[in] dname: the rdf to look in
+ * \return true if a wildcard, false if not.
+ */
+int ldns_dname_is_wildcard(const ldns_rdf* dname);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_DNAME_H */
index c95b32b..7bfc70b 100644 (file)
 #include <ldns/resolver.h>
 #include <ldns/dnssec_zone.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define LDNS_MAX_KEYLEN                2048
 #define LDNS_DNSSEC_KEYPROTO   3
 /* default time before sigs expire */
@@ -159,6 +163,16 @@ int ldns_digest_evp(unsigned char* data, unsigned int len,
  */
 EVP_PKEY* ldns_gost2pkey_raw(unsigned char* key, size_t keylen);
 
+/**
+ * Converts a holding buffer with key material to EVP PKEY in openssl.
+ * Only available if ldns was compiled with ECDSA.
+ * \param[in] key data to convert
+ * \param[in] keylen length of the key data
+ * \param[in] algo precise algorithm to initialize ECC group values.
+ * \return the key or NULL on error.
+ */
+EVP_PKEY* ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo);
+
 #endif /* HAVE_SSL */
 
 #ifdef HAVE_SSL
@@ -363,7 +377,7 @@ bool ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name);
  * verify a packet 
  * \param[in] p the packet
  * \param[in] t the rr set type to check
- * \param[in] o the rr set name to ckeck
+ * \param[in] o the rr set name to check
  * \param[in] k list of keys
  * \param[in] s list of sigs (may be null)
  * \param[out] good_keys keys which validated the packet
@@ -449,6 +463,35 @@ ldns_status
 ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
                                                  const ldns_rdf *sig_rdf);
 
+/**
+ * Converts the ECDSA signature from ASN1 representation (as 
+ * used by OpenSSL) to raw signature data as used in DNS
+ * This routine is only present if ldns is compiled with ecdsa support.
+ *
+ * \param[in] sig The signature in ASN1 format
+ * \param[in] sig_len The length of the signature
+ * \return a new rdf with the signature
+ */
+ldns_rdf *
+ldns_convert_ecdsa_rrsig_asn12rdf(const ldns_buffer *sig, const long sig_len);
+
+/**
+ * Converts the RRSIG signature RDF (from DNS) to a buffer with the 
+ * signature in ASN1 format as openssl uses it.
+ * This routine is only present if ldns is compiled with ecdsa support.
+ *
+ * \param[out] target_buffer buffer to place the signature data in ASN1.
+ * \param[in] sig_rdf The signature rdf to convert
+ * \return LDNS_STATUS_OK on success, error code otherwise
+ */
+ldns_status
+ldns_convert_ecdsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
+        const ldns_rdf *sig_rdf);
+
 #endif /* HAVE_SSL */
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_DNSSEC_H */
index 64683c0..5b3921a 100644 (file)
@@ -5,6 +5,10 @@
 
 #include <ldns/dnssec.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* sign functions */
 
 /** Sign flag that makes DNSKEY type signed by all keys, not only by SEP keys*/
@@ -307,6 +311,8 @@ ldns_zone *ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list);
  */
 ldns_zone *ldns_zone_sign_nsec3(ldns_zone *zone, ldns_key_list *key_list, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt);
  
-
+#ifdef __cplusplus
+}
+#endif
 
 #endif
index 58e7467..8d380f9 100644 (file)
@@ -7,6 +7,10 @@
 
 #include <ldns/dnssec.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * Chain structure that contains all DNSSEC data needed to
  * verify an rrset
@@ -258,7 +262,7 @@ ldns_status ldns_dnssec_trust_tree_contains_keys(
  * \param[in] rrset the rrset to verify
  * \param[in] rrsig a list of signatures to check
  * \param[in] keys a list of keys to check with
- * \param[out] good_keys  if this is a (initialized) list, the keys
+ * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
  *                        from keys that validate one of the signatures
  *                        are added to it
  * \return status LDNS_STATUS_OK if there is at least one correct key
@@ -275,7 +279,7 @@ ldns_status ldns_verify(ldns_rr_list *rrset,
  * \param[in] rrset the rrset to verify
  * \param[in] rrsig a list of signatures to check
  * \param[in] keys a list of keys to check with
- * \param[out] good_keys  if this is a (initialized) list, the keys
+ * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
  *                        from keys that validate one of the signatures
  *                        are added to it
  * \return status LDNS_STATUS_OK if there is at least one correct key
@@ -337,7 +341,7 @@ ldns_rr_list *ldns_validate_domain_ds(const ldns_resolver *res,
  * \param[in] res the current resolver
  * \param[in] rrset the rrset to verify
  * \param[in] rrsigs a list of signatures to check
- * \param[out] validating_keys  if this is a (initialized) list, the 
+ * \param[out] validating_keys  if this is a (initialized) list, the
  *                              keys from keys that validate one of
  *                              the signatures are added to it
  * \return status LDNS_STATUS_OK if there is at least one correct key
@@ -423,7 +427,7 @@ ldns_status ldns_verify_rrsig_buffers_raw(unsigned char* sig,
  * \param[in] rrset the rrset to check
  * \param[in] rrsig the signature of the rrset
  * \param[in] keys the keys to try
- * \param[out] good_keys  if this is a (initialized) list, the keys 
+ * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
  *                        from keys that validate one of the signatures
  *                        are added to it
  * \return a list of keys which validate the rrsig + rrset. Returns
@@ -439,7 +443,7 @@ ldns_status ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
  * \param[in] rrset the rrset to check
  * \param[in] rrsig the signature of the rrset
  * \param[in] keys the keys to try
- * \param[out] good_keys  if this is a (initialized) list, the keys 
+ * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
  *                        from keys that validate one of the signatures
  *                        are added to it
  * \return a list of keys which validate the rrsig + rrset. Returns
@@ -600,5 +604,9 @@ ldns_status ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
                                                                 unsigned char* key,
                                                                 size_t keylen);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
 
index 196f193..88117da 100644 (file)
 #include <ldns/ldns.h>
 #include <ldns/rbtree.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * Singly linked list of rrs
  */
@@ -355,4 +359,8 @@ void ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone);
  */
 ldns_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
index 73dbb2b..e17846f 100644 (file)
 
 #include <ldns/util.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 enum ldns_enum_status {
        LDNS_STATUS_OK, 
        LDNS_STATUS_EMPTY_LABEL,
@@ -75,6 +79,7 @@ enum ldns_enum_status {
        LDNS_STATUS_SYNTAX_TYPE_ERR,
        LDNS_STATUS_SYNTAX_CLASS_ERR,
        LDNS_STATUS_SYNTAX_TTL_ERR,
+       LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL,
        LDNS_STATUS_SYNTAX_RDATA_ERR,
        LDNS_STATUS_SYNTAX_DNAME_ERR,
        LDNS_STATUS_SYNTAX_VERSION_ERR,
@@ -82,6 +87,7 @@ enum ldns_enum_status {
        LDNS_STATUS_SYNTAX_KEYWORD_ERR,
        LDNS_STATUS_SYNTAX_TTL,
        LDNS_STATUS_SYNTAX_ORIGIN,
+       LDNS_STATUS_SYNTAX_INCLUDE,
        LDNS_STATUS_SYNTAX_EMPTY,
        LDNS_STATUS_SYNTAX_ITERATIONS_OVERFLOW,
        LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR,
@@ -106,4 +112,8 @@ extern ldns_lookup_table ldns_error_str[];
  */
 const char *ldns_get_errorstr_by_id(ldns_status err);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_ERROR_H */
index c98d013..597e134 100644 (file)
 #include <ldns/host2str.h>
 #include <ldns/tsig.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * Ask the resolver about name
  * and return all address records
@@ -102,4 +106,8 @@ bool ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t);
  */
 void ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_HIGHER_H */
index 727ab05..07180bb 100644 (file)
 
 #include "ldns/util.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define LDNS_APL_IP4            1
 #define LDNS_APL_IP6            2
 #define LDNS_APL_MASK           0x7f
@@ -151,6 +155,14 @@ ldns_status ldns_rdf2buffer_str_str(ldns_buffer *output, const ldns_rdf *rdf);
 ldns_status ldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf);
 
 /** 
+ * Converts an LDNS_RDF_TYPE_B32_EXT rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_b32_ext(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
  * Converts an LDNS_RDF_TYPE_HEX rdata element to string format and adds it to the output buffer 
  * \param[in] *rdf The rdata to convert
  * \param[in] *output The buffer to add the data to
@@ -256,6 +268,14 @@ ldns_status ldns_rdf2buffer_str_unknown(ldns_buffer *output, const ldns_rdf *rdf
 ldns_status ldns_rdf2buffer_str_nsap(ldns_buffer *output, const ldns_rdf *rdf);
 
 /** 
+ * Converts an LDNS_RDF_TYPE_ATMA rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_atma(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
  * Converts an LDNS_RDF_TYPE_WKS rdata element to string format and adds it to the output buffer 
  * \param[in] *rdf The rdata to convert
  * \param[in] *output The buffer to add the data to
@@ -350,6 +370,15 @@ 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 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
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf);
+
+
 /**
  * Converts the data in the DNS packet to presentation
  * format (as char *) and appends it to the given buffer
@@ -361,16 +390,38 @@ ldns_status ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt);
 ldns_status ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k);
 
 /**
- * Converts the data in the int16 typed rdata field 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] rdf the pointer to the rdafa field containing the data
- * \return status
+ * Converts an LDNS_RDF_TYPE_INT8 rdata element to string format and adds it to the output buffer
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_int8(ldns_buffer *output, const ldns_rdf *rdf);
+
+/**
+ * Converts an LDNS_RDF_TYPE_INT16 rdata element to string format and adds it to the output buffer
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
  */
 ldns_status ldns_rdf2buffer_str_int16(ldns_buffer *output, const ldns_rdf *rdf);
 
 /**
+ * Converts an LDNS_RDF_TYPE_INT32 rdata element to string format and adds it to the output buffer
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_int32(ldns_buffer *output, const ldns_rdf *rdf);
+
+/**
+ * Converts an LDNS_RDF_TYPE_TIME rdata element to string format and adds it to the output buffer
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf);
+
+/**
  * Converts the data in the rdata field to presentation format and
  * returns that as a char *.
  * Remember to free it.
@@ -508,5 +559,8 @@ void ldns_zone_print(FILE *output, const ldns_zone *z);
  */
 ldns_status ldns_rdf2buffer_str_dname(ldns_buffer *output, const ldns_rdf *dname);
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* LDNS_HOST2STR_H */
index 5101111..5eafe9d 100644 (file)
 
 #include "ldns/util.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * Copies the dname data to the buffer in wire format
  * \param[out] *buffer buffer to append the result to
@@ -153,4 +157,8 @@ ldns_status ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int, size_t *size);
  */
 ldns_status ldns_pkt2wire(uint8_t **dest, const ldns_pkt *p, size_t *size);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_HOST2WIRE_H */
index a84f503..e0f568d 100644 (file)
 #include <ldns/util.h>
 #include <errno.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 extern ldns_lookup_table ldns_signing_algorithms[];
 
 #define LDNS_KEY_ZONE_KEY 0x0100   /* rfc 4034 */
@@ -48,7 +52,13 @@ enum ldns_enum_algorithm
         LDNS_RSASHA1_NSEC3      = 7,
         LDNS_RSASHA256          = 8,   /* RFC 5702 */
         LDNS_RSASHA512          = 10,  /* RFC 5702 */
-        LDNS_GOST               = 249, /* not official */
+        LDNS_ECC_GOST           = 12,  /* RFC 5933 */
+#ifdef 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 */
+        LDNS_ECDSAP384SHA384    = 14,  /* EXPERIMENTAL */
+#endif
         LDNS_INDIRECT           = 252,
         LDNS_PRIVATEDNS         = 253,
         LDNS_PRIVATEOID         = 254
@@ -62,7 +72,12 @@ enum ldns_enum_hash
 {
         LDNS_SHA1               = 1,  /* RFC 4034 */
         LDNS_SHA256             = 2,  /* RFC 4509 */
-        LDNS_HASH_GOST94        = 203 /* not official */
+        LDNS_HASH_GOST          = 3   /* RFC 5933 */
+#ifdef 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 */
+#endif
 };
 typedef enum ldns_enum_hash ldns_hash;
 
@@ -78,7 +93,13 @@ enum ldns_enum_signing_algorithm
        LDNS_SIGN_RSASHA256      = LDNS_RSASHA256,
        LDNS_SIGN_RSASHA512      = LDNS_RSASHA512,
        LDNS_SIGN_DSA_NSEC3      = LDNS_DSA_NSEC3,
-       LDNS_SIGN_GOST           = LDNS_GOST,
+       LDNS_SIGN_ECC_GOST       = LDNS_ECC_GOST,
+#ifdef 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,
+        LDNS_SIGN_ECDSAP384SHA384 = LDNS_ECDSAP384SHA384,
+#endif
        LDNS_SIGN_HMACMD5        = 157, /* not official! This type is for TSIG, not DNSSEC */
        LDNS_SIGN_HMACSHA1       = 158, /* not official! This type is for TSIG, not DNSSEC */
        LDNS_SIGN_HMACSHA256 = 159  /* ditto */
@@ -307,6 +328,9 @@ void ldns_key_set_dsa_key(ldns_key *k, DSA *d);
  * \return the gost id for EVP_CTX creation.
  */
 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 */
 
 /**
@@ -576,4 +600,15 @@ char *ldns_key_get_file_base_name(ldns_key *key);
  */
 int ldns_key_algo_supported(int algo);
 
+/**
+ * Get signing algorithm by name.  Comparison is case insensitive.
+ * \param[in] name string with the name.
+ * \returns 0 on parse failure or the algorithm number.
+ */
+ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_KEYS_H */
diff --git a/contrib/ldns/ldns/ldns.h b/contrib/ldns/ldns/ldns.h
deleted file mode 100644 (file)
index b403392..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * dns.h -- defines for the Domain Name System
- *
- * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
- *
- * See LICENSE for the license.
- *
- * This library was created by:
- * Jelte Jansen, Erik Rozendaal and Miek Gieben
- *
- * A bunch of defines that are used in the DNS.
- */
-
-
-/**
-\mainpage LDNS Documentation
-
-\section introduction Introduction
-
-The goal of ldns is to simplify DNS programming, it supports recent RFCs
-like the DNSSEC documents, and allow developers to easily create software
-conforming to current RFCs, and experimental software for current Internet
-drafts. A secondary benefit of using ldns is speed, because ldns is written
-in C, and although it is not optimized for performance, it should be a lot
-faster than Perl.
-
-The first main tool to use ldns is Drill, from which part of the library was
-derived. From version 1.0.0 on, drill is included in the ldns release
-and will not be distributed seperately anymore. The library also includes some
-other examples and tools to show how it can be used. These can be found in the
-examples/ directory in the tarball.
-
-ldns depends on OpenSSL for it's cryptographic functions.
-Feature list
-
-  - Transparent IPv4 and IPv6 support (overridable if necessary),
-  - TSIG support,
-  - DNSSEC support; signing and verification,
-  - small size,
-  - online documentation as well as manual pages. 
-
-If you want to send us patches please use the code from subversion (trunk). 
-
-\section using_ldns Using ldns
-
-Almost all interaction between an application and ldns goes through the ldns
-data structures (\ref ldns_rr, \ref ldns_pkt, etc.). These are input or
-output to the functions of ldns. For example, \ref ldns_zone_new_frm_fp
-reads a zone from a \c FILE pointer, and returns an \ref ldns_zone
-structure.
-
-
-Let's use Drill as an example. Drill is a tool much like dig, whose most
-basic function is to send 1 query to a nameserver and print the response.
-
-To be able to do this, drill uses the resolver module of ldns, which acts as
-a stub resolver. The resolver module uses the net module to actually send
-the query that drill requested. It then uses the wire2host module to
-translate the response and place it in ldns' internal structures. These are
-passed back to drill, which then uses the host2str module to print the
-response in presentation format.
-
-\section gettingstarted Getting Started
-
-See the \ref design page for a very high level description of the design
-choices made for ldns. 
-
-For an overview of the functions and types ldns provides, you can check out
-the \ref ldns ldns header file descriptions.
-
-If you want to see some libdns action, you can read our tutorials:
-  - \ref tutorial1_mx
-  - \ref tutorial2_zone
-  - \ref tutorial3_signzone
-
-Or you can just use the menu above to browse through the API docs.
-
-<div style="visibility:hidden;">
-\image html LogoInGradientBar2-y100.png
-</div>
-*/
-
-/**
- * \file ldns.h
- *
- * Including this file will include all ldns files, and define some lookup tables.
- */
-
-#ifndef LDNS_DNS_H
-#define LDNS_DNS_H
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <ldns/util.h>
-#include <ldns/buffer.h>
-#include <ldns/common.h>
-#include <ldns/dname.h>
-#include <ldns/dnssec.h>
-#include <ldns/dnssec_verify.h>
-#include <ldns/dnssec_sign.h>
-#include <ldns/error.h>
-#include <ldns/higher.h>
-#include <ldns/host2str.h>
-#include <ldns/host2wire.h>
-#include <ldns/net.h>
-#include <ldns/packet.h>
-#include <ldns/rdata.h>
-#include <ldns/resolver.h>
-#include <ldns/rr.h>
-#include <ldns/str2host.h>
-#include <ldns/tsig.h>
-#include <ldns/update.h>
-#include <ldns/wire2host.h>
-#include <ldns/rr_functions.h>
-#include <ldns/keys.h>
-#include <ldns/parse.h>
-#include <ldns/zone.h>
-#include <ldns/dnssec_zone.h>
-#include <ldns/rbtree.h>
-#include <ldns/sha1.h>
-#include <ldns/sha2.h>
-
-#define LDNS_IP4ADDRLEN      (32/8)
-#define LDNS_IP6ADDRLEN      (128/8)
-#define LDNS_PORT      53
-#define LDNS_ROOT_LABEL_STR     "."
-#define LDNS_DEFAULT_TTL       3600
-
-/* lookup tables for standard DNS stuff  */
-
-/** Taken from RFC 2538, section 2.1.  */
-extern ldns_lookup_table ldns_certificate_types[];
-/** Taken from RFC 2535, section 7.  */
-extern ldns_lookup_table ldns_algorithms[];
-/** Taken from RFC 2538.  */
-extern ldns_lookup_table ldns_cert_algorithms[];
-/** rr types  */
-extern ldns_lookup_table ldns_rr_classes[];
-/** Response codes */
-extern ldns_lookup_table ldns_rcodes[];
-/** Operation codes */
-extern ldns_lookup_table ldns_opcodes[];
-/** EDNS flags */
-extern ldns_lookup_table ldns_edns_flags[];
-
-#endif /* LDNS_DNS_H */
diff --git a/contrib/ldns/ldns/net.h.in b/contrib/ldns/ldns/net.h.in
deleted file mode 100644 (file)
index d4beb7d..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * net.h
- *
- * DNS Resolver definitions
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- *
- * See the file LICENSE for the license
- */
-
-#ifndef LDNS_NET_H
-#define LDNS_NET_H
-
-#include <ldns/ldns.h>
-@include_sys_socket_h@
-
-#define LDNS_DEFAULT_TIMEOUT_SEC 2
-#define LDNS_DEFAULT_TIMEOUT_USEC 0
-
-/**
- * \file
- *
- * Contains functions to send and receive packets over a network.
- */
-
-/**
- * Sends a buffer to an ip using udp and return the respons as a ldns_pkt
- * \param[in] qbin the ldns_buffer to be send
- * \param[in] to the ip addr to send to
- * \param[in] tolen length of the ip addr
- * \param[in] timeout the timeout value for the network
- * \param[out] answersize size of the packet
- * \param[out] result packet with the answer
- * \return status
- */
-ldns_status ldns_udp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout, size_t *answersize);
-
-/**
- * Send an udp query and don't wait for an answer but return
- * the socket
- * \param[in] qbin the ldns_buffer to be send
- * \param[in] to the ip addr to send to
- * \param[in] tolen length of the ip addr
- * \param[in] timeout *unused*, was the timeout value for the network
- * \return the socket used
- */
-
-int ldns_udp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout);
-
-/**
- * Send an tcp query and don't wait for an answer but return
- * the socket
- * \param[in] qbin the ldns_buffer to be send
- * \param[in] to the ip addr to send to
- * \param[in] tolen length of the ip addr
- * \param[in] timeout the timeout value for the connect attempt
- * \return the socket used
- */
-int ldns_tcp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout);
-
-/**
- * Sends a buffer to an ip using tcp and return the respons as a ldns_pkt
- * \param[in] qbin the ldns_buffer to be send
- * \param[in] qbin the ldns_buffer to be send
- * \param[in] to the ip addr to send to
- * \param[in] tolen length of the ip addr
- * \param[in] timeout the timeout value for the network
- * \param[out] answersize size of the packet
- * \param[out] result packet with the answer
- * \return status
- */
-ldns_status ldns_tcp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout, size_t *answersize);
-
-/**
- * Sends ptk to the nameserver at the resolver object. Returns the data
- * as a ldns_pkt
- * 
- * \param[out] pkt packet received from the nameserver
- * \param[in] r the resolver to use 
- * \param[in] query_pkt the query to send
- * \return status
- */
-ldns_status ldns_send(ldns_pkt **pkt, ldns_resolver *r, const ldns_pkt *query_pkt);
-
-/**
- * Sends and ldns_buffer (presumably containing a packet to the nameserver at the resolver object. Returns the data
- * as a ldns_pkt
- * 
- * \param[out] pkt packet received from the nameserver
- * \param[in] r the resolver to use 
- * \param[in] qb the buffer to send
- * \param[in] tsig_mac the tsig MAC to authenticate the response with (NULL to do no TSIG authentication)
- * \return status
- */
-ldns_status ldns_send_buffer(ldns_pkt **pkt, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac);
-
-/**
- * Create a tcp socket to the specified address
- * \param[in] to ip and family
- * \param[in] tolen length of to
- * \param[in] timeout timeout for the connect attempt
- * \return a socket descriptor
- */
-int ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout);
-
-/**
- * Create a udp socket to the specified address
- * \param[in] to ip and family
- * \param[in] timeout *unused*, was timeout for the socket
- * \return a socket descriptor
- */
-int ldns_udp_connect(const struct sockaddr_storage *to, struct timeval timeout);
-
-/**
- * send a query via tcp to a server. Don't want for the answer
- *
- * \param[in] qbin the buffer to send
- * \param[in] sockfd the socket to use
- * \param[in] to which ip to send it
- * \param[in] tolen socketlen
- * \return number of bytes sent
- */
-ssize_t ldns_tcp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, socklen_t tolen);
-
-/**
- * send a query via udp to a server. Don;t want for the answer
- *
- * \param[in] qbin the buffer to send
- * \param[in] sockfd the socket to use
- * \param[in] to which ip to send it
- * \param[in] tolen socketlen
- * \return number of bytes sent
- */
-ssize_t ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, socklen_t tolen);
-
-/**
- * Gives back a raw packet from the wire and reads the header data from the given
- * socket. Allocates the data (of size size) itself, so don't forget to free
- *
- * \param[in] sockfd the socket to read from
- * \param[out] size the number of bytes that are read
- * \param[in] timeout the time allowed between packets.
- * \return the data read
- */
-uint8_t *ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout);
-
-/**
- * This routine may block. Use ldns_tcp_read_wire_timeout, it checks timeouts.
- * Gives back a raw packet from the wire and reads the header data from the given
- * socket. Allocates the data (of size size) itself, so don't forget to free
- *
- * \param[in] sockfd the socket to read from
- * \param[out] size the number of bytes that are read
- * \return the data read
- */
-uint8_t *ldns_tcp_read_wire(int sockfd, size_t *size);
-
-/**
- * Gives back a raw packet from the wire and reads the header data from the given
- * socket. Allocates the data (of size size) itself, so don't forget to free
- *
- * \param[in] sockfd the socket to read from
- * \param[in] fr the address of the client (if applicable)
- * \param[in] *frlen the lenght of the client's addr (if applicable)
- * \param[out] size the number of bytes that are read
- * \return the data read
- */
-uint8_t *ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *fr, socklen_t *frlen);
-
-/**
- * returns the native sockaddr representation from the rdf.
- * \param[in] rd the ldns_rdf to operate on
- * \param[in] port what port to use. 0 means; use default (53)
- * \param[out] size what is the size of the sockaddr_storage
- * \return struct sockaddr* the address in the format so other
- * functions can use it (sendto)
- */
-struct sockaddr_storage * ldns_rdf2native_sockaddr_storage(const ldns_rdf *rd, uint16_t port, size_t *size);
-
-/**
- * returns an rdf with the sockaddr info. works for ip4 and ip6
- * \param[in] sock the struct sockaddr_storage to convert
- * \param[in] port what port was used. When NULL this is not set
- * \return ldns_rdf* wth the address
- */
-ldns_rdf * ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port);
-
-/**
- * Prepares the resolver for an axfr query
- * The query is sent and the answers can be read with ldns_axfr_next
- * \param[in] resolver the resolver to use
- * \param[in] domain the domain to exfr
- * \param[in] c the class to use
- * \return ldns_status the status of the transfer
- */
-ldns_status ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class c);
-
-#endif  /* LDNS_NET_H */
index 45f80b8..1a927d2 100644 (file)
 #include <ldns/rr.h>
 #include <sys/time.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* opcodes for pkt's */
 enum ldns_enum_pkt_opcode {
        LDNS_PACKET_QUERY = 0,
@@ -840,8 +844,12 @@ bool ldns_pkt_safe_push_rr_list(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr_lis
 /**
  * check if a packet is empty
  * \param[in] p packet
- * \return true: empty, false: empty
+ * \return true: empty, false: not empty
  */
 bool ldns_pkt_empty(ldns_pkt *p);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif  /* LDNS_PACKET_H */
index 5d3dfd4..0e9034c 100644 (file)
 #include <ldns/common.h>
 #include <ldns/buffer.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define LDNS_PARSE_SKIP_SPACE          "\f\n\r\v"
 #define LDNS_PARSE_NORMAL              " \f\n\r\t\v"
 #define LDNS_PARSE_NO_NL               " \t"
@@ -156,4 +160,8 @@ void ldns_fskipcs(FILE *fp, const char *s);
  */
 void ldns_fskipcs_l(FILE *fp, const char *s, int *line_nr);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_PARSE_H */
index ac20dde..98bd880 100644 (file)
@@ -2,24 +2,24 @@
  * rbtree.h -- generic red-black tree
  *
  * Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
- * 
+ *
  * This software is open source.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
- * 
+ *
  * Redistributions of source code must retain the above copyright notice,
  * this list of conditions and the following disclaimer.
- * 
+ *
  * Redistributions in binary form must reproduce the above copyright notice,
  * this list of conditions and the following disclaimer in the documentation
  * and/or other materials provided with the distribution.
- * 
+ *
  * Neither the name of the NLNET LABS nor the names of its contributors may
  * be used to endorse or promote products derived from this software without
  * specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 #ifndef LDNS_RBTREE_H_
 #define        LDNS_RBTREE_H_
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * This structure must be the first member of the data structure in
  * the rbtree.  This allows easy casting between an rbnode_t and the
  * user data (poor man's inheritance).
+ * Or you can use the data pointer member to get to your data item.
  */
 typedef struct ldns_rbnode_t ldns_rbnode_t;
 /**
@@ -82,15 +87,15 @@ struct ldns_rbtree_t {
        /** The number of the nodes in the tree */
        size_t       count;
 
-       /** 
-        * Key compare function. <0,0,>0 like strcmp. 
-        * Return 0 on two NULL ptrs. 
+       /**
+        * Key compare function. <0,0,>0 like strcmp.
+        * Return 0 on two NULL ptrs.
         */
        int (*cmp) (const void *, const void *);
 };
 
-/** 
- * Create new tree (malloced) with given key compare function. 
+/**
+ * Create new tree (malloced) with given key compare function.
  * @param cmpf: compare function (like strcmp) takes pointers to two keys.
  * @return: new tree, empty.
  */
@@ -102,18 +107,18 @@ ldns_rbtree_t *ldns_rbtree_create(int (*cmpf)(const void *, const void *));
  */
 void ldns_rbtree_free(ldns_rbtree_t *rbtree);
 
-/** 
- * Init a new tree (malloced by caller) with given key compare function. 
+/**
+ * Init a new tree (malloced by caller) with given key compare function.
  * @param rbtree: uninitialised memory for new tree, returned empty.
  * @param cmpf: compare function (like strcmp) takes pointers to two keys.
  */
 void ldns_rbtree_init(ldns_rbtree_t *rbtree, int (*cmpf)(const void *, const void *));
 
-/** 
- * Insert data into the tree. 
+/**
+ * Insert data into the tree.
  * @param rbtree: tree to insert to.
- * @param data: element to insert. 
- * @return: data ptr or NULL if key already present. 
+ * @param data: element to insert.
+ * @return: data ptr or NULL if key already present.
  */
 ldns_rbnode_t *ldns_rbtree_insert(ldns_rbtree_t *rbtree, ldns_rbnode_t *data);
 
@@ -129,8 +134,8 @@ void ldns_rbtree_insert_vref(ldns_rbnode_t *data, void *rbtree);
  * Delete element from tree.
  * @param rbtree: tree to delete from.
  * @param key: key of item to delete.
- * @return: node that is now unlinked from the tree. User to delete it. 
- * returns 0 if node not present 
+ * @return: node that is now unlinked from the tree. User to delete it.
+ * returns 0 if node not present
  */
 ldns_rbnode_t *ldns_rbtree_delete(ldns_rbtree_t *rbtree, const void *key);
 
@@ -149,9 +154,9 @@ ldns_rbnode_t *ldns_rbtree_search(ldns_rbtree_t *rbtree, const void *key);
  * @param result: set to the exact node if present, otherwise to element that
  *   precedes the position of key in the tree. NULL if no smaller element.
  * @return: true if exact match in result. Else result points to <= element,
- * or NULL if key is smaller than the smallest key. 
+ * or NULL if key is smaller than the smallest key.
  */
-int ldns_rbtree_find_less_equal(ldns_rbtree_t *rbtree, const void *key, 
+int ldns_rbtree_find_less_equal(ldns_rbtree_t *rbtree, const void *key,
        ldns_rbnode_t **result);
 
 /**
@@ -197,7 +202,7 @@ void ldns_rbtree_join(ldns_rbtree_t *tree1, ldns_rbtree_t *tree2);
 
 /**
  * Call with node=variable of struct* with rbnode_t as first element.
- * with type is the type of a pointer to that struct. 
+ * with type is the type of a pointer to that struct.
  */
 #define LDNS_RBTREE_FOR(node, type, rbtree) \
        for(node=(type)ldns_rbtree_first(rbtree); \
@@ -215,7 +220,11 @@ void ldns_rbtree_join(ldns_rbtree_t *tree1, ldns_rbtree_t *tree2);
  *     The function must not alter the rbtree.
  * @param arg: user argument.
  */
-void ldns_traverse_postorder(ldns_rbtree_t* tree, 
+void ldns_traverse_postorder(ldns_rbtree_t* tree,
        void (*func)(ldns_rbnode_t*, void*), void* arg);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* UTIL_RBTREE_H_ */
index dc90270..2d5af88 100644 (file)
 #include <ldns/common.h>
 #include <ldns/error.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define LDNS_MAX_RDFLEN        8192
 
 #define LDNS_RDF_SIZE_BYTE              1
@@ -369,4 +373,8 @@ ldns_rdf *ldns_rdf_clone(const ldns_rdf *rd);
  */
 int ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_RDATA_H */
index 80b853e..f887aaf 100644 (file)
@@ -14,7 +14,7 @@
  * \file
  *
  * Defines the  ldns_resolver structure, a stub resolver that can send queries and parse answers.
- * 
+ *
  */
 
 #ifndef LDNS_RESOLVER_H
 #include <ldns/packet.h>
 #include <sys/time.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /** Default location of the resolv.conf file */
 #define LDNS_RESOLV_CONF       "/etc/resolv.conf"
 /** Default location of the hosts file */
 #define LDNS_RESOLV_HOSTS      "/etc/hosts"
 
-#define LDNS_RESOLV_KEYWORD     -1     
+#define LDNS_RESOLV_KEYWORD     -1
 #define LDNS_RESOLV_DEFDOMAIN  0
 #define LDNS_RESOLV_NAMESERVER 1
 #define LDNS_RESOLV_SEARCH     2
@@ -58,7 +62,7 @@ struct ldns_struct_resolver
        uint16_t _port;
 
        /** Array of nameservers to query (IP addresses or dnames) */
-       ldns_rdf **_nameservers; 
+       ldns_rdf **_nameservers;
        /** Number of nameservers in \c _nameservers */
        size_t _nameserver_count; /* how many do we have */
 
@@ -70,9 +74,9 @@ struct ldns_struct_resolver
 
        /**  Print debug information */
        bool _debug;
-       
+
        /**  Default domain to add to non fully qualified domain names */
-       ldns_rdf *_domain; 
+       ldns_rdf *_domain;
 
        /**  Searchlist array, add the names in this array if a query cannot be found */
        ldns_rdf **_searchlist;
@@ -124,7 +128,7 @@ struct ldns_struct_resolver
        uint16_t _axfr_i;
        /* EDNS0 available buffer size */
        uint16_t _edns_udp_size;
-       
+
        /* Optional tsig key for signing queries,
        outgoing messages are signed if and only if both are set
        */
@@ -143,7 +147,7 @@ typedef struct ldns_struct_resolver ldns_resolver;
 /**
  * Get the port the resolver should use
  * \param[in] r the resolver
- * \return the port number 
+ * \return the port number
  */
 uint16_t ldns_resolver_port(const ldns_resolver *r);
 
@@ -208,13 +212,25 @@ bool ldns_resolver_usevc(const ldns_resolver *r);
  */
 bool ldns_resolver_fail(const ldns_resolver *r);
 /**
+ * Does the resolver apply default domain name
+ * \param[in] r the resolver
+ * \return true: yes, false: no
+ */
+bool ldns_resolver_defnames(const ldns_resolver *r);
+/**
+ * Does the resolver apply search list
+ * \param[in] r the resolver
+ * \return true: yes, false: no
+ */
+bool ldns_resolver_dnsrch(const ldns_resolver *r);
+/**
  * Does the resolver do DNSSEC
  * \param[in] r the resolver
  * \return true: yes, false: no
  */
 bool ldns_resolver_dnssec(const ldns_resolver *r);
 /**
- * Does the resolver set the CD bit 
+ * Does the resolver set the CD bit
  * \param[in] r the resolver
  * \return true: yes, false: no
  */
@@ -362,7 +378,7 @@ void ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c);
 void ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **rd);
 
 /**
- * Set the resolver's default domain. This gets appended when no 
+ * Set the resolver's default domain. This gets appended when no
  * absolute name is given
  * \param[in] r the resolver
  * \param[in] rd the name to append
@@ -528,7 +544,7 @@ void ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value
 void ldns_resolver_set_random(ldns_resolver *r, bool b);
 
 /**
- * push a new nameserver to the resolver. It must be an IP
+ * Push a new nameserver to the resolver. It must be an IP
  * address v4 or v6.
  * \param[in] r the resolver
  * \param[in] n the ip address
@@ -537,16 +553,16 @@ void ldns_resolver_set_random(ldns_resolver *r, bool b);
 ldns_status ldns_resolver_push_nameserver(ldns_resolver *r, ldns_rdf *n);
 
 /**
- * push a new nameserver to the resolver. It must be an 
+ * Push a new nameserver to the resolver. It must be an
  * A or AAAA RR record type
  * \param[in] r the resolver
- * \param[in] rr the resource record 
+ * \param[in] rr the resource record
  * \return ldns_status a status
  */
 ldns_status ldns_resolver_push_nameserver_rr(ldns_resolver *r, ldns_rr *rr);
 
 /**
- * push a new nameserver rr_list to the resolver.
+ * Push a new nameserver rr_list to the resolver.
  * \param[in] r the resolver
  * \param[in] rrlist the rr_list to push
  * \return ldns_status a status
@@ -579,7 +595,7 @@ ldns_pkt* ldns_resolver_search(const ldns_resolver *r, const ldns_rdf *rdf, ldns
 ldns_status ldns_resolver_prepare_query_pkt(ldns_pkt **q, ldns_resolver *r, const  ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t f);
 
 /**
- * Send the query for name as-is 
+ * Send the query for name as-is
  * \param[out] **answer a pointer to a ldns_pkt pointer (initialized by this function)
  * \param[in] *r operate using this resolver
  * \param[in] *name query for this name
@@ -611,8 +627,8 @@ ldns_status ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r, ldns_pkt
 ldns_pkt* ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
 
 
-/** 
- * Create a new resolver structure 
+/**
+ * Create a new resolver structure
  * \return ldns_resolver* pointer to new strcture
  */
 ldns_resolver* ldns_resolver_new(void);
@@ -637,44 +653,46 @@ ldns_status ldns_resolver_new_frm_fp(ldns_resolver **r, FILE *fp);
 ldns_status ldns_resolver_new_frm_fp_l(ldns_resolver **r, FILE *fp, int *line_nr);
 
 /**
- * configure a resolver by means of a resolv.conf file 
+ * Configure a resolver by means of a resolv.conf file
  * The file may be NULL in which case there will  be
  * looked the RESOLV_CONF (defaults to /etc/resolv.conf
  * \param[out] r the new resolver
  * \param[in] filename the filename to use
  * \return LDNS_STATUS_OK or the error
- */                             
+ */
 ldns_status ldns_resolver_new_frm_file(ldns_resolver **r, const char *filename);
 
-/**                             
+/**
  * Frees the allocated space for this resolver. Only frees the resolver pionter! You should probably be using _deep_free.
- * \param res resolver to free  
- */     
+ * \param res resolver to free
+ */
 void ldns_resolver_free(ldns_resolver *res);
 
-/**                             
+/**
  * Frees the allocated space for this resolver and all it's data
- * \param res resolver to free  
- */     
+ * \param res resolver to free
+ */
 void ldns_resolver_deep_free(ldns_resolver *res);
 
 /**
- *  get the next stream of RRs in a AXFR 
+ * Get the next stream of RRs in a AXFR
  * \param[in] resolver the resolver to use. First ldns_axfr_start() must be
  * called
  * \return ldns_rr the next RR from the AXFR stream
+ * After you get this returned RR (not NULL: on error), then check if 
+ * ldns_axfr_complete() is true to see if the zone transfer has completed.
  */
 ldns_rr* ldns_axfr_next(ldns_resolver *resolver);
 
 /**
- * returns true if the axfr transfer has completed (i.e. 2 SOA RRs and no errors were encountered 
+ * Returns true if the axfr transfer has completed (i.e. 2 SOA RRs and no errors were encountered
  * \param[in] resolver the resolver that is used
  * \return bool true if axfr transfer was completed without error
  */
 bool ldns_axfr_complete(const ldns_resolver *resolver);
 
 /**
- * returns a pointer to the last ldns_pkt that was sent by the server in the AXFR transfer
+ * Returns a pointer to the last ldns_pkt that was sent by the server in the AXFR transfer
  * uasable for instance to get the error code on failure
  * \param[in] res the resolver that was used in the axfr transfer
  * \return ldns_pkt the last packet sent
@@ -682,12 +700,12 @@ bool ldns_axfr_complete(const ldns_resolver *resolver);
 ldns_pkt *ldns_axfr_last_pkt(const ldns_resolver *res);
 
 /**
- * randomize the nameserver list in the resolver
+ * Randomize the nameserver list in the resolver
  * \param[in] r the resolver
  */
 void ldns_resolver_nameservers_randomize(ldns_resolver *r);
 
-/** 
+/**
  * Returns true if at least one of the provided keys is a trust anchor
  * \param[in] r the current resolver
  * \param[in] keys the keyset to check
@@ -696,4 +714,8 @@ void ldns_resolver_nameservers_randomize(ldns_resolver *r);
  */
 bool ldns_resolver_trusted_key(const ldns_resolver *r, ldns_rr_list * keys, ldns_rr_list * trusted_keys);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif  /* LDNS_RESOLVER_H */
index f9ae0c1..86e31de 100644 (file)
 #include <ldns/buffer.h>
 #include <ldns/error.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /** Maximum length of a dname label */
 #define LDNS_MAX_LABELLEN     63
 /** Maximum length of a complete dname */
@@ -33,7 +37,7 @@
 #define LDNS_RR_OVERHEAD       10
 
 /* The first fields are 'common' and can be referenced instantly */
-#define LDNS_RDATA_FIELD_DESCRIPTORS_COMMON 51
+#define LDNS_RDATA_FIELD_DESCRIPTORS_COMMON 52
 
 
 
@@ -174,6 +178,9 @@ enum ldns_enum_rr_type
        LDNS_RR_TYPE_NSEC3 = 50,
        LDNS_RR_TYPE_NSEC3PARAMS = 51,
 
+        /** draft-ietf-dnsop-trust-history */
+        LDNS_RR_TYPE_TALINK = 58,
+
        LDNS_RR_TYPE_SPF = 99,
 
        LDNS_RR_TYPE_UINFO = 100,
@@ -871,4 +878,8 @@ ldns_rr_list_type(const ldns_rr_list *rr_list);
 ldns_rdf *
 ldns_rr_list_owner(const ldns_rr_list *rr_list);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_RR_H */
index 617e942..635a125 100644 (file)
 #ifndef LDNS_RR_FUNCTIONS_H
 #define LDNS_RR_FUNCTIONS_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * \file
  *
@@ -248,4 +252,8 @@ size_t ldns_rr_dnskey_key_size_raw(const unsigned char *keydata,
  */
 size_t ldns_rr_dnskey_key_size(const ldns_rr *key);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_RR_FUNCTIONS_H */
index 7ff62d2..d5b1082 100644 (file)
@@ -1,5 +1,9 @@
 #ifndef LDNS_SHA1_H
 #define LDNS_SHA1_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
  
 #define LDNS_SHA1_BLOCK_LENGTH               64
 #define LDNS_SHA1_DIGEST_LENGTH              20
@@ -26,4 +30,9 @@ void ldns_sha1_final(unsigned char digest[LDNS_SHA1_DIGEST_LENGTH], ldns_sha1_ct
  * \return the SHA1 digest of the given data
  */
 unsigned char *ldns_sha1(unsigned char *data, unsigned int data_len, unsigned char *digest);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_SHA1_H */
index cccad01..09416cd 100644 (file)
 #include <ldns/buffer.h>
 #include <ctype.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * \file
  *
@@ -240,4 +244,8 @@ ldns_status ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str);
  */
 ldns_status ldns_str2rdf_dname(ldns_rdf **rd, const char *str);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_2HOST_H */
index c3a10a6..4ce666a 100644 (file)
@@ -9,6 +9,10 @@
 #ifndef LDNS_TSIG_H
 #define LDNS_TSIG_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * \file
  *
@@ -36,11 +40,21 @@ char *ldns_tsig_keydata_clone(ldns_tsig_credentials *);
 /**
  * verifies the tsig rr for the given packet and key.
  * The wire must be given too because tsig does not sign normalized packets.
- *
+ * \param[in] pkt the packet to verify
+ * \param[in] wire needed to verify the mac
+ * \param[in] wire_size size of wire
+ * \param[in] key_name the name of the shared key
+ * \param[in] key_data the key in base 64 format
+ * \param[in] mac original mac
+ * \param[in] tsig_timers_only must be zero for the first packet and positive for subsequent packets. If zero, all digest
+   components are used to verify the _mac. If non-zero, only the TSIG timers are used to verify the mac.
  * \return true if tsig is correct, false if not, or if tsig is not set
  */
 bool ldns_pkt_tsig_verify(ldns_pkt *pkt, uint8_t *wire, size_t wire_size, const char *key_name, const char *key_data, ldns_rdf *mac);
 
+bool ldns_pkt_tsig_verify_next(ldns_pkt *pkt, uint8_t *wire, size_t wire_size, const char *key_name, const char *key_data, ldns_rdf *mac,
+    int tsig_timers_only);
+
 /**
  * creates a tsig rr for the given packet and key.
  * \param[in] pkt the packet to sign
@@ -49,8 +63,18 @@ bool ldns_pkt_tsig_verify(ldns_pkt *pkt, uint8_t *wire, size_t wire_size, const
  * \param[in] fudge seconds of error permitted in time signed
  * \param[in] algorithm_name the name of the algorithm used
  * \param[in] query_mac is added to the digest if not NULL (so NULL is for signing queries, not NULL is for signing answers)
+ * \param[in] tsig_timers_only must be zero for the first packet and positive for subsequent packets. If zero, all digest
+   components are used to create the query_mac. If non-zero, only the TSIG timers are used to create the query_mac.
  * \return status (OK if success)
  */
-ldns_status ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge, const char *algorithm_name, ldns_rdf *query_mac);
+ldns_status ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge,
+    const char *algorithm_name, ldns_rdf *query_mac);
+
+ldns_status ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge,
+    const char *algorithm_name, ldns_rdf *query_mac, int tsig_timers_only);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* LDNS_TSIG_H */
index 1d0d8f8..d3459d3 100644 (file)
 
 #include <ldns/resolver.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * create an update packet from zone name, class and the rr lists
  * \param[in] zone_rdf name of the zone
@@ -104,4 +108,8 @@ ldns_status ldns_update_soa_mname(ldns_rdf *zone, ldns_resolver *r, ldns_rr_clas
  */
 ldns_status ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r, ldns_rr_class c, ldns_rdf **zone_rdf, ldns_rdf **mname_rdf);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif  /* LDNS_UPDATE_H */
diff --git a/contrib/ldns/ldns/util.h.in b/contrib/ldns/ldns/util.h.in
deleted file mode 100644 (file)
index d63d617..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * util.h
- *  
- * helper function header file
- * 
- * a Net::DNS like library for C
- * 
- * (c) NLnet Labs, 2004
- * 
- * See the file LICENSE for the license
- */
-
-#ifndef _UTIL_H
-#define _UTIL_H
-
-@include_inttypes_h@
-#include <ldns/common.h>
-#include <time.h>
-#include <stdio.h>
-
-#define dprintf(X,Y) fprintf(stderr, (X), (Y))
-/* #define     dprintf(X, Y)  */
-
-#define LDNS_VERSION "@PACKAGE_VERSION@"
-#define LDNS_REVISION @PACKAGE_REVISION@
-
-/**
- * splint static inline workaround
- */
-#ifdef S_SPLINT_S
-#  define INLINE 
-#else
-#  ifdef SWIG
-#    define INLINE static
-#  else
-#    define INLINE static inline
-#  endif
-#endif
-
-/**
- * Memory management macros
- */
-#define LDNS_MALLOC(type)              LDNS_XMALLOC(type, 1)
-
-#define LDNS_XMALLOC(type, count)      ((type *) malloc((count) * sizeof(type)))
-
-#define LDNS_REALLOC(ptr, type)                LDNS_XREALLOC((ptr), type, 1)
-
-#define LDNS_XREALLOC(ptr, type, count)                                \
-       ((type *) realloc((ptr), (count) * sizeof(type)))
-
-#define LDNS_FREE(ptr) \
-       do { free((ptr)); (ptr) = NULL; } while (0)
-
-#define LDNS_DEP     printf("DEPRECATED FUNCTION!\n");
-
-/*
- * Copy data allowing for unaligned accesses in network byte order
- * (big endian).
- */
-INLINE uint16_t
-ldns_read_uint16(const void *src)
-{
-#ifdef ALLOW_UNALIGNED_ACCESSES
-       return ntohs(*(uint16_t *) src);
-#else
-       uint8_t *p = (uint8_t *) src;
-       return ((uint16_t) p[0] << 8) | (uint16_t) p[1];
-#endif
-}
-
-INLINE uint32_t
-ldns_read_uint32(const void *src)
-{
-#ifdef ALLOW_UNALIGNED_ACCESSES
-       return ntohl(*(uint32_t *) src);
-#else
-       uint8_t *p = (uint8_t *) src;
-       return (  ((uint32_t) p[0] << 24)
-               | ((uint32_t) p[1] << 16)
-               | ((uint32_t) p[2] << 8)
-               |  (uint32_t) p[3]);
-#endif
-}
-
-/*
- * Copy data allowing for unaligned accesses in network byte order
- * (big endian).
- */
-INLINE void
-ldns_write_uint16(void *dst, uint16_t data)
-{
-#ifdef ALLOW_UNALIGNED_ACCESSES
-       * (uint16_t *) dst = htons(data);
-#else
-       uint8_t *p = (uint8_t *) dst;
-       p[0] = (uint8_t) ((data >> 8) & 0xff);
-       p[1] = (uint8_t) (data & 0xff);
-#endif
-}
-
-INLINE void
-ldns_write_uint32(void *dst, uint32_t data)
-{
-#ifdef ALLOW_UNALIGNED_ACCESSES
-       * (uint32_t *) dst = htonl(data);
-#else
-       uint8_t *p = (uint8_t *) dst;
-       p[0] = (uint8_t) ((data >> 24) & 0xff);
-       p[1] = (uint8_t) ((data >> 16) & 0xff);
-       p[2] = (uint8_t) ((data >> 8) & 0xff);
-       p[3] = (uint8_t) (data & 0xff);
-#endif
-}
-
-/* warning. */
-INLINE void
-ldns_write_uint64_as_uint48(void *dst, uint64_t data)
-{
-       uint8_t *p = (uint8_t *) dst;
-       p[0] = (uint8_t) ((data >> 40) & 0xff);
-       p[1] = (uint8_t) ((data >> 32) & 0xff);
-       p[2] = (uint8_t) ((data >> 24) & 0xff);
-       p[3] = (uint8_t) ((data >> 16) & 0xff);
-       p[4] = (uint8_t) ((data >> 8) & 0xff);
-       p[5] = (uint8_t) (data & 0xff);
-}
-
-
-/**
- * Structure to do a Schwartzian-like transformation, for instance when
- * sorting. If you need a transformation on the objects that are sorted,
- * you can sue this to store the transformed values, so you do not
- * need to do the transformation again for each comparison
- */
-struct ldns_schwartzian_compare_struct {
-       void *original_object;
-       void *transformed_object;
-};
-
-/** A general purpose lookup table
- *  
- *  Lookup tables are arrays of (id, name) pairs,
- *  So you can for instance lookup the RCODE 3, which is "NXDOMAIN",
- *  and vice versa. The lookup tables themselves are defined wherever needed,
- *  for instance in \ref host2str.c
- */
-struct ldns_struct_lookup_table {
-        int id;
-        const char *name;
-};
-typedef struct ldns_struct_lookup_table ldns_lookup_table;
-  
-/**
- * Looks up the table entry by name, returns NULL if not found.
- * \param[in] table the lookup table to search in
- * \param[in] name what to search for
- * \return the item found
- */
-ldns_lookup_table *ldns_lookup_by_name(ldns_lookup_table table[],
-                                       const char *name);
-
-/**
- * Looks up the table entry by id, returns NULL if not found.
- * \param[in] table the lookup table to search in
- * \param[in] id what to search for
- * \return the item found
- */
-ldns_lookup_table *ldns_lookup_by_id(ldns_lookup_table table[], int id);
-
-/**
- * Returns the value of the specified bit
- * The bits are counted from left to right, so bit #0 is the
- * left most bit.
- * \param[in] bits array holding the bits
- * \param[in] index to the wanted bit
- * \return 
- */
-int ldns_get_bit(uint8_t bits[], size_t index);
-
-
-/**
- * Returns the value of the specified bit
- * The bits are counted from right to left, so bit #0 is the
- * right most bit.
- * \param[in] bits array holding the bits
- * \param[in] index to the wanted bit
- * \return 1 or 0 depending no the bit state
- */
-int ldns_get_bit_r(uint8_t bits[], size_t index);
-
-/**
- * sets the specified bit in the specified byte to
- * 1 if value is true, 0 if false
- * The bits are counted from right to left, so bit #0 is the
- * right most bit.
- * \param[in] byte the bit to set the bit in
- * \param[in] bit_nr the bit to set (0 <= n <= 7)
- * \param[in] value whether to set the bit to 1 or 0
- * \return 1 or 0 depending no the bit state
- */
-void ldns_set_bit(uint8_t *byte, int bit_nr, bool value);
-
-/**
- * Returns the value of a to the power of b
- * (or 1 of b < 1)
- */
-/*@unused@*/
-INLINE long
-ldns_power(long a, long b) {
-       long result = 1;
-       while (b > 0) {
-               if (b & 1) {
-                       result *= a;
-                       if (b == 1) {
-                               return result;
-                       }
-               }
-               a *= a;
-               b /= 2;
-       }
-       return result;
-}
-
-/**
- * Returns the int value of the given (hex) digit
- * \param[in] ch the hex char to convert
- * \return the converted decimal value
- */
-int ldns_hexdigit_to_int(char ch);
-
-/**
- * Returns the char (hex) representation of the given int
- * \param[in] ch the int to convert
- * \return the converted hex char
- */
-char ldns_int_to_hexdigit(int ch);
-
-/**
- * Converts a hex string to binary data
- *
- * \param[out] data The binary result is placed here.
- * At least strlen(str)/2 bytes should be allocated
- * \param[in] str The hex string to convert.
- * This string should not contain spaces
- * \return The number of bytes of converted data, or -1 if one of the arguments * is NULL, or -2 if the string length is not an even number
- */
-int
-ldns_hexstring_to_data(uint8_t *data, const char *str);
-
-/**
- * Show the internal library version
- * \return a string with the version in it
- */
-const char * ldns_version(void);
-
-/**
- * Convert TM to seconds since epoch (midnight, January 1st, 1970).
- * Like timegm(3), which is not always available.
- * \param[in] tm a struct tm* with the date
- * \return the seconds since epoch
- */
-time_t mktime_from_utc(const struct tm *tm);
-
-/**
- * Seed the random function.
- * If the file descriptor is specified, the random generator is seeded with
- * data from that file. If not, /dev/urandom is used.
- *
- * applications should call this if they need entropy data within ldns
- * If openSSL is available, it is automatically seeded from /dev/urandom
- * or /dev/random.
- *
- * If you need more entropy, or have no openssl available, this function
- * MUST be called at the start of the program
- *
- * If openssl *is* available, this function just adds more entropy
- *
- * \param[in] fd a file providing entropy data for the seed
- * \param[in] size the number of bytes to use as entropy data. If this is 0,
- *            only the minimal amount is taken (usually 4 bytes)
- * \return 0 if seeding succeeds, 1 if it fails
- */
-int ldns_init_random(FILE *fd, unsigned int size);
-
-
-/**
- * Encode data as BubbleBabble
- *
- * \param[in] data a pointer to data to be encoded
- * \param[in] len size the number of bytes of data
- * \return a string of BubbleBabble
- */
-char *ldns_bubblebabble(uint8_t *data, size_t len);
-
-#ifndef B32_NTOP
-int ldns_b32_ntop(uint8_t const *src, size_t srclength,
-            char *target, size_t targsize);
-int b32_ntop(uint8_t const *src, size_t srclength,
-            char *target, size_t targsize);
-int ldns_b32_ntop_extended_hex(uint8_t const *src, size_t srclength,
-            char *target, size_t targsize);
-int b32_ntop_extended_hex(uint8_t const *src, size_t srclength,
-            char *target, size_t targsize);
-/**
- * calculates the size needed to store the result of b32_ntop
- */
-/*@unused@*/
-INLINE size_t ldns_b32_ntop_calculate_size(size_t srcsize)
-{
-       size_t result = ((((srcsize / 5) * 8) - 2) + 2);
-       return result;
-}
-#endif /* !B32_NTOP */
-#ifndef B32_PTON
-int ldns_b32_pton(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize);
-int b32_pton(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize);
-int ldns_b32_pton_extended_hex(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize);
-int b32_pton_extended_hex(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize);
-/**
- * calculates the size needed to store the result of b32_pton
- */
-/*@unused@*/
-INLINE size_t ldns_b32_pton_calculate_size(size_t srcsize)
-{
-       size_t result = ((((srcsize) / 8) * 5));
-       return result;
-}
-#endif /* !B32_PTON */
-
-#endif /* !_UTIL_H */
index 5c4941c..53155b3 100644 (file)
 #include <ldns/rr.h>
 #include <ldns/packet.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* The length of the header */
 #define        LDNS_HEADER_SIZE        12
 
@@ -186,4 +190,8 @@ ldns_status ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *
  */
 ldns_status ldns_wire2rr(ldns_rr **rr, const uint8_t *wire, size_t max, size_t *pos, ldns_pkt_section section);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_WIRE2HOST_H */
index e8c29c8..a683ea8 100644 (file)
 #include <ldns/rr.h>
 #include <ldns/error.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /** 
  * DNS Zone
  *
@@ -164,4 +168,8 @@ void ldns_zone_deep_free(ldns_zone *zone);
  */
 void ldns_zone_sort(ldns_zone *zone);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LDNS_ZONE_H */
index cdc69c5..1b06754 100644 (file)
@@ -44,7 +44,6 @@ ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt)
                tsig_mac = ldns_rr_rdf(ldns_pkt_tsig(query_pkt), 3);
        }
 
-
        if (!query_pkt ||
            ldns_pkt2buffer_wire(qb, query_pkt) != LDNS_STATUS_OK) {
                result = LDNS_STATUS_ERR;
@@ -53,7 +52,7 @@ ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt)
        }
 
        ldns_buffer_free(qb);
-       
+
        return result;
 }
 
@@ -97,7 +96,6 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
                        /* not reachable nameserver! */
                        continue;
                }
-               all_servers_rtt_inf = false;
 
                /* maybe verbosity setting?
                printf("Sending to ");
@@ -106,17 +104,21 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
                */
                ns = ldns_rdf2native_sockaddr_storage(ns_array[i],
                                ldns_resolver_port(r), &ns_len);
-               
-               if ((ns->ss_family == AF_INET) && 
+
+               if ((ns->ss_family == AF_INET) &&
                                (ldns_resolver_ip6(r) == LDNS_RESOLV_INET6)) {
+                       /* not reachable */
                        continue;
                }
 
                if ((ns->ss_family == AF_INET6) &&
                                 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET)) {
+                       /* not reachable */
                        continue;
                }
 
+               all_servers_rtt_inf = false;
+
                gettimeofday(&tv_s, NULL);
 
                send_status = LDNS_STATUS_ERR;
@@ -210,7 +212,7 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
 #else
        (void)tsig_mac;
 #endif /* HAVE_SSL */
-       
+
        LDNS_FREE(reply_bytes);
        if (result) {
                *result = reply;
@@ -281,7 +283,7 @@ ldns_sock_wait(int sockfd, struct timeval timeout, int write)
 }
 
 ldns_status
-ldns_udp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, 
+ldns_udp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to,
                socklen_t tolen, struct timeval timeout, size_t *answer_size)
 {
        int sockfd;
@@ -295,12 +297,20 @@ ldns_udp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage
 
        /* wait for an response*/
        if(!ldns_sock_wait(sockfd, timeout, 0)) {
+#ifndef USE_WINSOCK
                close(sockfd);
+#else
+                closesocket(sockfd);
+#endif
                return LDNS_STATUS_NETWORK_ERR;
        }
-       
+
        answer = ldns_udp_read_wire(sockfd, answer_size, NULL, NULL);
+#ifndef USE_WINSOCK
        close(sockfd);
+#else
+        closesocket(sockfd);
+#endif
 
        if (*answer_size == 0) {
                /* oops */
@@ -333,7 +343,7 @@ int
 ldns_udp_connect(const struct sockaddr_storage *to, struct timeval ATTR_UNUSED(timeout))
 {
        int sockfd;
-       
+
        if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_DGRAM, 
                                        IPPROTO_UDP)) 
                        == -1) {
@@ -347,7 +357,7 @@ ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen,
                struct timeval timeout)
 {
        int sockfd;
-       
+
        if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_STREAM, 
                                        IPPROTO_TCP)) == -1) {
                return 0;
@@ -381,7 +391,11 @@ ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen,
                socklen_t len = (socklen_t)sizeof(error);
 
                if(!ldns_sock_wait(sockfd, timeout, 1)) {
+#ifndef USE_WINSOCK
                        close(sockfd);
+#else
+                       closesocket(sockfd);
+#endif
                        return 0;
                }
 
@@ -435,6 +449,7 @@ ldns_tcp_send_query(ldns_buffer *qbin, int sockfd,
 
        /* add length of packet */
        sendbuf = LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
+       if(!sendbuf) return 0;
        ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
        memcpy(sendbuf + 2, ldns_buffer_export(qbin), ldns_buffer_position(qbin));
 
@@ -472,7 +487,7 @@ uint8_t *
 ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from,
                socklen_t *fromlen)
 {
-       uint8_t *wire;
+       uint8_t *wire, *wireout;
        ssize_t wire_size;
 
        wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
@@ -492,9 +507,10 @@ ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from,
        }
 
        *size = (size_t)wire_size;
-       wire = LDNS_XREALLOC(wire, uint8_t, (size_t)wire_size);
+       wireout = LDNS_XREALLOC(wire, uint8_t, (size_t)wire_size);
+       if(!wireout) LDNS_FREE(wire);
 
-       return wire;
+       return wireout;
 }
 
 uint8_t *
@@ -502,7 +518,7 @@ ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
 {
        uint8_t *wire;
        uint16_t wire_size;
-       ssize_t bytes = 0;
+       ssize_t bytes = 0, rc = 0;
 
        wire = LDNS_XMALLOC(uint8_t, 2);
        if (!wire) {
@@ -516,12 +532,14 @@ ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
                        LDNS_FREE(wire);
                        return NULL;
                }
-               bytes = recv(sockfd, (void*)wire, 2, 0);
-               if (bytes == -1 || bytes == 0) {
+               rc = recv(sockfd, (void*) (wire + bytes), 
+                               (size_t) (2 - bytes), 0);
+               if (rc == -1 || rc == 0) {
                        *size = 0;
                        LDNS_FREE(wire);
                        return NULL;
                }
+                bytes += rc;
        }
 
        wire_size = ldns_read_uint16(wire);
@@ -536,13 +554,14 @@ ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
                        LDNS_FREE(wire);
                        return NULL;
                }
-               bytes += recv(sockfd, (void*) (wire + bytes), 
+               rc = recv(sockfd, (void*) (wire + bytes), 
                                (size_t) (wire_size - bytes), 0);
-               if (bytes == -1 || bytes == 0) {
+               if (rc == -1 || rc == 0) {
                        LDNS_FREE(wire);
                        *size = 0;
                        return NULL;
                }
+                bytes += rc;
        }
        
        *size = (size_t) bytes;
@@ -554,7 +573,7 @@ ldns_tcp_read_wire(int sockfd, size_t *size)
 {
        uint8_t *wire;
        uint16_t wire_size;
-       ssize_t bytes = 0;
+       ssize_t bytes = 0, rc = 0;
 
        wire = LDNS_XMALLOC(uint8_t, 2);
        if (!wire) {
@@ -563,12 +582,14 @@ ldns_tcp_read_wire(int sockfd, size_t *size)
        }
        
        while (bytes < 2) {
-               bytes = recv(sockfd, (void*)wire, 2, 0);
-               if (bytes == -1 || bytes == 0) {
+               rc = recv(sockfd, (void*) (wire + bytes), 
+                               (size_t) (2 - bytes), 0);
+               if (rc == -1 || rc == 0) {
                        *size = 0;
                        LDNS_FREE(wire);
                        return NULL;
                }
+                bytes += rc;
        }
 
        wire_size = ldns_read_uint16(wire);
@@ -578,13 +599,14 @@ ldns_tcp_read_wire(int sockfd, size_t *size)
        bytes = 0;
 
        while (bytes < (ssize_t) wire_size) {
-               bytes += recv(sockfd, (void*) (wire + bytes), 
+               rc = recv(sockfd, (void*) (wire + bytes), 
                                (size_t) (wire_size - bytes), 0);
-               if (bytes == -1 || bytes == 0) {
+               if (rc == -1 || rc == 0) {
                        LDNS_FREE(wire);
                        *size = 0;
                        return NULL;
                }
+                bytes += rc;
        }
        
        *size = (size_t) bytes;
@@ -608,7 +630,11 @@ ldns_tcp_send(uint8_t **result,  ldns_buffer *qbin, const struct sockaddr_storag
        }
 
        answer = ldns_tcp_read_wire_timeout(sockfd, answer_size, timeout);
+#ifndef USE_WINSOCK
        close(sockfd);
+#else
+       closesocket(sockfd);
+#endif
 
        if (*answer_size == 0) {
                /* oops */
@@ -734,7 +760,7 @@ ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class)
                 return LDNS_STATUS_ADDRESS_ERR;
         }
         /* For AXFR, we have to make the connection ourselves */
-        /* try all nameservers (which usually would mean v4 fallback if 
+        /* try all nameservers (which usually would mean v4 fallback if
          * @hostname is used */
         for (ns_i = 0;
              ns_i < ldns_resolver_nameserver_count(resolver) &&
@@ -743,8 +769,8 @@ ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class)
                ns = ldns_rdf2native_sockaddr_storage(
                        resolver->_nameservers[ns_i],
                        ldns_resolver_port(resolver), &ns_len);
-       
-               resolver->_socket = ldns_tcp_connect(ns, (socklen_t)ns_len, 
+
+               resolver->_socket = ldns_tcp_connect(ns, (socklen_t)ns_len,
                                ldns_resolver_timeout(resolver));
        }
 
@@ -761,26 +787,58 @@ ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class)
                                            ldns_resolver_tsig_keydata(resolver),
                                            300, ldns_resolver_tsig_algorithm(resolver), NULL);
                if (status != LDNS_STATUS_OK) {
+                       /* RoRi: to prevent problems on subsequent calls to ldns_axfr_start
+                          we have to close the socket here! */
+#ifndef USE_WINSOCK
+                       close(resolver->_socket);
+#else
+                       closesocket(resolver->_socket);
+#endif
+                       resolver->_socket = 0;
+
                        return LDNS_STATUS_CRYPTO_TSIG_ERR;
                }
        }
 #endif /* HAVE_SSL */
 
-        /* Convert the query to a buffer          * Is this necessary?
+        /* Convert the query to a buffer
+         * Is this necessary?
          */
         query_wire = ldns_buffer_new(LDNS_MAX_PACKETLEN);
         status = ldns_pkt2buffer_wire(query_wire, query);
         if (status != LDNS_STATUS_OK) {
                 ldns_pkt_free(query);
+               ldns_buffer_free(query_wire);
                 LDNS_FREE(ns);
+
+               /* RoRi: to prevent problems on subsequent calls to ldns_axfr_start
+                   we have to close the socket here! */
+#ifndef USE_WINSOCK
+               close(resolver->_socket);
+#else
+               closesocket(resolver->_socket);
+#endif
+               resolver->_socket = 0;
+
                 return status;
         }
         /* Send the query */
-        if (ldns_tcp_send_query(query_wire, resolver->_socket, ns, 
+        if (ldns_tcp_send_query(query_wire, resolver->_socket, ns,
                                (socklen_t)ns_len) == 0) {
                 ldns_pkt_free(query);
                 ldns_buffer_free(query_wire);
                 LDNS_FREE(ns);
+
+               /* RoRi: to prevent problems on subsequent calls to ldns_axfr_start
+                        we have to close the socket here! */
+
+#ifndef USE_WINSOCK
+               close(resolver->_socket);
+#else
+               closesocket(resolver->_socket);
+#endif
+               resolver->_socket = 0;
+
                 return LDNS_STATUS_NETWORK_ERR;
         }
 
index 32d5a2a..0ac5ca8 100644 (file)
@@ -412,9 +412,10 @@ ldns_pkt_empty(ldns_pkt *p)
                return true; /* NULL is empty? */
        }
        if (ldns_pkt_section_count(p, LDNS_SECTION_ANY) > 0) {
-               return true;
-       } else
                return false;
+       } else {
+               return true;
+    }
 }
 
 
@@ -454,14 +455,7 @@ ldns_pkt_set_id(ldns_pkt *packet, uint16_t id)
 void
 ldns_pkt_set_random_id(ldns_pkt *packet)
 {
-       uint16_t rid = 0;
-#ifdef HAVE_SSL
-       if (RAND_bytes((unsigned char*)&rid, 2) != 1) {
-               rid = (uint16_t) random();
-       }
-#else
-       rid = (uint16_t) random();
-#endif
+       uint16_t rid = ldns_get_random();
        ldns_pkt_set_id(packet, rid);
 }
 
@@ -989,7 +983,7 @@ ldns_pkt_clone(ldns_pkt *pkt)
        ldns_pkt_set_answerfrom(new_pkt, ldns_pkt_answerfrom(pkt));
        ldns_pkt_set_querytime(new_pkt, ldns_pkt_querytime(pkt));
        ldns_pkt_set_size(new_pkt, ldns_pkt_size(pkt));
-       ldns_pkt_set_tsig(new_pkt, ldns_pkt_tsig(pkt));
+       ldns_pkt_set_tsig(new_pkt, ldns_rr_clone(ldns_pkt_tsig(pkt)));
        
        ldns_pkt_set_edns_udp_size(new_pkt, ldns_pkt_edns_udp_size(pkt));
        ldns_pkt_set_edns_extended_rcode(new_pkt, 
index 03b31b0..9e11975 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * a generic (simple) parser. Use to parse rr's, private key 
+ * a generic (simple) parser. Use to parse rr's, private key
  * information and /etc/resolv.conf files
  *
  * a Net::DNS like library for C
 #include <strings.h>
 
 ldns_lookup_table ldns_directive_types[] = {
-        { LDNS_DIR_TTL, "$TTL" },  
-        { LDNS_DIR_ORIGIN, "$ORIGIN" }, 
-        { LDNS_DIR_INCLUDE, "$INCLUDE" },  
+        { LDNS_DIR_TTL, "$TTL" },
+        { LDNS_DIR_ORIGIN, "$ORIGIN" },
+        { LDNS_DIR_INCLUDE, "$INCLUDE" },
         { 0, NULL }
 };
 
 /* add max_limit here? */
 ssize_t
 ldns_fget_token(FILE *f, char *token, const char *delim, size_t limit)
-{      
+{
        return ldns_fget_token_l(f, token, delim, limit, NULL);
 }
 
 ssize_t
 ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr)
-{      
+{
        int c, prev_c;
        int p; /* 0 -> no parenthese seen, >0 nr of ( seen */
        int com, quoted;
@@ -111,12 +111,13 @@ ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *li
                        continue;
                }
 
-               
+
                if (c == '\n' && p != 0 && t > token) {
                        /* in parentheses */
                        if (line_nr) {
                                *line_nr = *line_nr + 1;
                        }
+                       *t++ = ' ';
                        prev_c = c;
                        continue;
                }
@@ -170,7 +171,7 @@ ssize_t
 ldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data,
                const char *d_del, size_t data_limit)
 {
-       return ldns_fget_keyword_data_l(f, keyword, k_del, data, d_del, 
+       return ldns_fget_keyword_data_l(f, keyword, k_del, data, d_del,
                       data_limit, NULL);
 }
 
@@ -183,9 +184,14 @@ ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *
        ssize_t i;
 
        fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
-       i = 0;
+       if(!fkeyword)
+               return -1;
 
        i = ldns_fget_token(f, fkeyword, k_del, LDNS_MAX_KEYWORDLEN);
+       if(i==0 || i==-1) {
+               LDNS_FREE(fkeyword);
+               return -1;
+       }
 
        /* case??? i instead of strlen? */
        if (strncmp(fkeyword, keyword, LDNS_MAX_KEYWORDLEN - 1) == 0) {
@@ -204,7 +210,7 @@ ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *
 
 ssize_t
 ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
-{      
+{
        int c, lc;
        int p; /* 0 -> no parenthese seen, >0 nr of ( seen */
        int com, quoted;
@@ -227,7 +233,7 @@ ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
        quoted = 0;
        t = token;
        lc = 0;
-       if (delim[0] == '"') {
+       if (del[0] == '"') {
                quoted = 1;
        }
 
@@ -253,7 +259,6 @@ ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
                if (p < 0) {
                        /* more ) then ( */
                        *t = '\0';
-                       lc = c;
                        return 0;
                }
 
@@ -283,6 +288,7 @@ ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
 
                if (c == '\n' && p != 0) {
                        /* in parentheses */
+                       *t++ = ' ';
                        lc = c;
                        continue;
                }
@@ -293,10 +299,10 @@ ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
                                goto tokenread;
                         }
                }
-               
+
                *t++ = c;
                i++;
-               if (limit > 0 && i >= limit - 1) {
+               if (limit > 0 && i >= limit) {
                        *t = '\0';
                        return -1;
                }
@@ -320,9 +326,9 @@ ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
 tokenread:
        ldns_bskipcs(b, delim);
        *t = '\0';
-       
+
        if (p != 0) {
-               return -1; 
+               return -1;
        }
        return (ssize_t)i;
 }
@@ -331,7 +337,7 @@ void
 ldns_bskipc(ldns_buffer *buffer, char c)
 {
         while (c == (char) ldns_buffer_read_u8_at(buffer, ldns_buffer_position(buffer))) {
-                if (ldns_buffer_available_at(buffer, 
+                if (ldns_buffer_available_at(buffer,
                                        buffer->_position + sizeof(char), sizeof(char))) {
                         buffer->_position += sizeof(char);
                 } else {
@@ -411,17 +417,24 @@ ldns_bget_keyword_data(ldns_buffer *b, const char *keyword, const char *k_del, c
        ssize_t i;
 
        fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
-       i = 0;
+       if(!fkeyword)
+               return -1; /* out of memory */
 
        i = ldns_bget_token(b, fkeyword, k_del, data_limit);
+       if(i==0 || i==-1) {
+               LDNS_FREE(fkeyword);
+               return -1; /* nothing read */
+       }
 
        /* case??? */
        if (strncmp(fkeyword, keyword, strlen(keyword)) == 0) {
+               LDNS_FREE(fkeyword);
                /* whee, the match! */
                /* retrieve it's data */
                i = ldns_bget_token(b, data, d_del, 0);
                return i;
        } else {
+               LDNS_FREE(fkeyword);
                return -1;
        }
 }
index 465bdc5..9177775 100644 (file)
@@ -546,18 +546,22 @@ ldns_rbtree_find_less_equal(ldns_rbtree_t *rbtree, const void *key, ldns_rbnode_
 ldns_rbnode_t *
 ldns_rbtree_first (ldns_rbtree_t *rbtree)
 {
-       ldns_rbnode_t *node;
+       ldns_rbnode_t *node = rbtree->root;
 
-       for (node = rbtree->root; node->left != LDNS_RBTREE_NULL; node = node->left);
+       if (rbtree->root != LDNS_RBTREE_NULL) {
+               for (node = rbtree->root; node->left != LDNS_RBTREE_NULL; node = node->left);
+       }
        return node;
 }
 
 ldns_rbnode_t *
 ldns_rbtree_last (ldns_rbtree_t *rbtree)
 {
-       ldns_rbnode_t *node;
+       ldns_rbnode_t *node = rbtree->root;
 
-       for (node = rbtree->root; node->right != LDNS_RBTREE_NULL; node = node->right);
+       if (rbtree->root != LDNS_RBTREE_NULL) {
+               for (node = rbtree->root; node->right != LDNS_RBTREE_NULL; node = node->right);
+       }
        return node;
 }
 
index 05f9122..37e36e6 100644 (file)
@@ -132,34 +132,46 @@ ldns_rdf *
 ldns_native2rdf_int16(ldns_rdf_type type, uint16_t value)
 {
        uint16_t *rdf_data = LDNS_XMALLOC(uint16_t, 1);
+        ldns_rdf* rdf;
        if (!rdf_data) {
                return NULL;
        }
        ldns_write_uint16(rdf_data, value);
-       return ldns_rdf_new(type, LDNS_RDF_SIZE_WORD, rdf_data);
+       rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_WORD, rdf_data);
+        if(!rdf)
+                LDNS_FREE(rdf_data);
+        return rdf;
 }
 
 ldns_rdf *
 ldns_native2rdf_int32(ldns_rdf_type type, uint32_t value)
 {
        uint32_t *rdf_data = LDNS_XMALLOC(uint32_t, 1);
+        ldns_rdf* rdf;
        if (!rdf_data) {
                return NULL;
        }
        ldns_write_uint32(rdf_data, value);
-       return ldns_rdf_new(type, LDNS_RDF_SIZE_DOUBLEWORD, rdf_data);
+       rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_DOUBLEWORD, rdf_data);
+        if(!rdf)
+                LDNS_FREE(rdf_data);
+        return rdf;
 }
 
 ldns_rdf *
 ldns_native2rdf_int16_data(size_t size, uint8_t *data)
 {
        uint8_t *rdf_data = LDNS_XMALLOC(uint8_t, size + 2);
+        ldns_rdf* rdf;
        if (!rdf_data) {
                return NULL;
        }
        ldns_write_uint16(rdf_data, size);
        memcpy(rdf_data + 2, data, size);
-       return ldns_rdf_new(LDNS_RDF_TYPE_INT16_DATA, size + 2, rdf_data);
+       rdf = ldns_rdf_new(LDNS_RDF_TYPE_INT16_DATA, size + 2, rdf_data);
+        if(!rdf)
+                LDNS_FREE(rdf_data);
+        return rdf;
 }
 
 /* note: data must be allocated memory */
@@ -359,7 +371,7 @@ ldns_rdf_new_frm_fp_l(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp, int *line_nr
        }
 
        /* read an entire line in from the file */
-       if ((t = ldns_fget_token_l(fp, line, LDNS_PARSE_SKIP_SPACE, 0, line_nr)) == -1) {
+       if ((t = ldns_fget_token_l(fp, line, LDNS_PARSE_SKIP_SPACE, 0, line_nr)) == -1 || t == 0) {
                LDNS_FREE(line);
                return LDNS_STATUS_SYNTAX_RDATA_ERR;
        }
index 2b01b42..db238c3 100644 (file)
@@ -542,19 +542,22 @@ ldns_resolver_push_searchlist(ldns_resolver *r, ldns_rdf *d)
 void
 ldns_resolver_set_tsig_keyname(ldns_resolver *r, char *tsig_keyname)
 {
-       r->_tsig_keyname = tsig_keyname;
+       LDNS_FREE(r->_tsig_keyname);
+       r->_tsig_keyname = strdup(tsig_keyname);
 }
 
 void
 ldns_resolver_set_tsig_algorithm(ldns_resolver *r, char *tsig_algorithm)
 {
-       r->_tsig_algorithm = tsig_algorithm;
+       LDNS_FREE(r->_tsig_algorithm);
+       r->_tsig_algorithm = strdup(tsig_algorithm);
 }
 
 void
 ldns_resolver_set_tsig_keydata(ldns_resolver *r, char *tsig_keydata)
 {
-       r->_tsig_keydata = tsig_keydata;
+       LDNS_FREE(r->_tsig_keydata);
+       r->_tsig_keydata = strdup(tsig_keydata);
 }
 
 void
@@ -594,6 +597,9 @@ ldns_resolver_new(void)
        ldns_resolver_set_dnssec_cd(r, false);
        ldns_resolver_set_dnssec_anchors(r, NULL);
        ldns_resolver_set_ip6(r, LDNS_RESOLV_INETANY);
+       ldns_resolver_set_igntc(r, false);
+       ldns_resolver_set_recursive(r, false);
+       ldns_resolver_set_dnsrch(r, true);
 
        /* randomize the nameserver to be queried
         * when there are multiple
@@ -605,6 +611,8 @@ ldns_resolver_new(void)
        r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC;
        r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC;
 
+       /* TODO: fd=0 is actually a valid socket (stdin),
+           replace with -1 */
        r->_socket = 0;
        r->_axfr_soa_count = 0;
        r->_axfr_i = 0;
@@ -634,8 +642,10 @@ ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
 #ifdef HAVE_SSL
        ldns_rr *tmp_rr;
 #endif
-       ssize_t gtr;
+       ssize_t gtr, bgtr;
        ldns_buffer *b;
+        int lnr = 0, oldline;
+        if(!line_nr) line_nr = &lnr;
 
        /* do this better
         * expect =
@@ -661,25 +671,36 @@ ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
 
        gtr = 1;
        word[0] = 0;
+        oldline = *line_nr;
+        expect = LDNS_RESOLV_KEYWORD;
        while (gtr > 0) {
                /* check comments */
                if (word[0] == '#') {
-                       /* read the rest of the line, should be 1 word */
-                       gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
-                       /* prepare the next string for further parsing */
-                       gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
+                        word[0]='x';
+                        if(oldline == *line_nr) {
+                                /* skip until end of line */
+                                int c;
+                                do {
+                                        c = fgetc(fp);
+                                } while(c != EOF && c != '\n');
+                                if(c=='\n' && line_nr) (*line_nr)++;
+                        }
+                       /* and read next to prepare for further parsing */
+                        oldline = *line_nr;
                        continue;
                }
+                oldline = *line_nr;
                switch(expect) {
                        case LDNS_RESOLV_KEYWORD:
                                /* keyword */
                                gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
                                if (gtr != 0) {
+                                        if(word[0] == '#') continue;
                                        for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) {
                                                if (strcasecmp(keyword[i], word) == 0) {
                                                        /* chosen the keyword and
                                                         * expect values carefully
-                                                        */
+                                                        */
                                                        expect = i;
                                                        break;
                                                }
@@ -700,6 +721,10 @@ ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
                                if (gtr == 0) {
                                        return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
                                }
+                                if(word[0] == '#') {
+                                        expect = LDNS_RESOLV_KEYWORD;
+                                        continue;
+                                }
                                tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
                                if (!tmp) {
                                        ldns_resolver_deep_free(r);
@@ -716,6 +741,15 @@ ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
                                if (gtr == 0) {
                                        return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
                                }
+                                if(word[0] == '#') {
+                                        expect = LDNS_RESOLV_KEYWORD;
+                                        continue;
+                                }
+                                if(strchr(word, '%')) {
+                                        /* snip off interface labels,
+                                         * fe80::222:19ff:fe31:4222%eth0 */
+                                        strchr(word, '%')[0]=0;
+                                }
                                tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word);
                                if (!tmp) {
                                        /* try ip4 */
@@ -734,20 +768,37 @@ ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
                                /* search list domain dname */
                                gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
                                b = LDNS_MALLOC(ldns_buffer);
-                               ldns_buffer_new_frm_data(b, word, (size_t) gtr);
+                               if(!b) {
+                                       ldns_resolver_deep_free(r);
+                                       return LDNS_STATUS_MEM_ERR;
+                               }
 
-                               gtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr);
-                               while (gtr > 0) {
+                               ldns_buffer_new_frm_data(b, word, (size_t) gtr);
+                               if(ldns_buffer_status(b) != LDNS_STATUS_OK) {
+                                       LDNS_FREE(b);
+                                       ldns_resolver_deep_free(r);
+                                       return LDNS_STATUS_MEM_ERR;
+                               }
+                               bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1);
+                               while (bgtr > 0) {
+                                       gtr -= bgtr;
+                                        if(word[0] == '#') {
+                                                expect = LDNS_RESOLV_KEYWORD;
+                                               ldns_buffer_free(b);
+                                                continue;
+                                        }
                                        tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
                                        if (!tmp) {
                                                ldns_resolver_deep_free(r);
+                                               ldns_buffer_free(b);
                                                return LDNS_STATUS_SYNTAX_DNAME_ERR;
                                        }
 
                                        ldns_resolver_push_searchlist(r, tmp);
 
                                        ldns_rdf_deep_free(tmp);
-                                       gtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr);
+                                       bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL,
+                                           (size_t) gtr + 1);
                                }
                                ldns_buffer_free(b);
                                gtr = 1;
@@ -767,8 +818,13 @@ ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
                                /* a file containing a DNSSEC trust anchor */
                                gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
                                if (gtr == 0) {
+                                       ldns_resolver_deep_free(r);
                                        return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
                                }
+                                if(word[0] == '#') {
+                                        expect = LDNS_RESOLV_KEYWORD;
+                                        continue;
+                                }
 
 #ifdef HAVE_SSL
                                tmp_rr = ldns_read_anchor_file(word);
@@ -784,6 +840,7 @@ ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
                *res = r;
                return LDNS_STATUS_OK;
        } else {
+               ldns_resolver_deep_free(r);
                return LDNS_STATUS_NULL;
        }
 }
@@ -845,9 +902,15 @@ ldns_resolver_deep_free(ldns_resolver *res)
                if (ldns_resolver_domain(res)) {
                        ldns_rdf_deep_free(ldns_resolver_domain(res));
                }
-               if (ldns_resolver_tsig_keyname(res)) {
+               if (res->_tsig_keyname) {
                        LDNS_FREE(res->_tsig_keyname);
                }
+               if (res->_tsig_keydata) {
+                       LDNS_FREE(res->_tsig_keydata);
+               }
+               if (res->_tsig_algorithm) {
+                       LDNS_FREE(res->_tsig_algorithm);
+               }
 
                if (res->_cur_axfr_pkt) {
                        ldns_pkt_free(res->_cur_axfr_pkt);
@@ -864,7 +927,7 @@ ldns_resolver_deep_free(ldns_resolver *res)
 }
 
 ldns_pkt *
-ldns_resolver_search(const ldns_resolver *r,const  ldns_rdf *name, 
+ldns_resolver_search(const ldns_resolver *r,const  ldns_rdf *name,
        ldns_rr_type t, ldns_rr_class c, uint16_t flags)
 {
 
@@ -879,7 +942,7 @@ ldns_resolver_search(const ldns_resolver *r,const  ldns_rdf *name,
        if (ldns_dname_str_absolute(str_dname)) {
                /* query as-is */
                return ldns_resolver_query(r, name, t, c, flags);
-       } else {
+       } else if (ldns_resolver_dnsrch(r)) {
                search_list = ldns_resolver_searchlist(r);
                for (i = 0; i < ldns_resolver_searchlist_count(r); i++) {
                        new_name = ldns_dname_cat_clone(name, search_list[i]);
@@ -887,7 +950,12 @@ ldns_resolver_search(const ldns_resolver *r,const  ldns_rdf *name,
                        p = ldns_resolver_query(r, new_name, t, c, flags);
                        ldns_rdf_free(new_name);
                        if (p) {
-                               return p;
+                               if (ldns_pkt_get_rcode(p) == LDNS_RCODE_NOERROR) {
+                                       return p;
+                               } else {
+                                       ldns_pkt_free(p);
+                                       p = NULL;
+                               }
                        }
                }
        }
@@ -895,7 +963,7 @@ ldns_resolver_search(const ldns_resolver *r,const  ldns_rdf *name,
 }
 
 ldns_pkt *
-ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, 
+ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name,
        ldns_rr_type t, ldns_rr_class c, uint16_t flags)
 {
        ldns_rdf *newname;
@@ -905,7 +973,7 @@ ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name,
        pkt = NULL;
 
        if (!ldns_resolver_defnames(r)) {
-               status = ldns_resolver_send(&pkt, (ldns_resolver *)r, name, 
+               status = ldns_resolver_send(&pkt, (ldns_resolver *)r, name,
                                t, c, flags);
                if (status == LDNS_STATUS_OK) {
                        return pkt;
@@ -913,7 +981,6 @@ ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name,
                        if (pkt) {
                                ldns_pkt_free(pkt);
                        }
-                       fprintf(stderr, "error: %s\n", ldns_get_errorstr_by_id(status));
                        return NULL;
                }
        }
@@ -939,7 +1006,8 @@ ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name,
                }
                return NULL;
        }
-       status = ldns_resolver_send(&pkt, (ldns_resolver *)r, newname, t, c,
+
+       (void)ldns_resolver_send(&pkt, (ldns_resolver *)r, newname, t, c,
                        flags);
 
        ldns_rdf_free(newname);
@@ -961,7 +1029,6 @@ ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r,
                        answer_pkt = NULL;
                }
        } else {
-
                /* if tc=1 fall back to EDNS and/or TCP */
                /* check for tcp first (otherwise we don't care about tc=1) */
                if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) {
@@ -984,7 +1051,6 @@ ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r,
                }
        }
 
-
        if (answer) {
                *answer = answer_pkt;
        }
@@ -1087,6 +1153,7 @@ ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name,
 #else
        return LDNS_STATUS_CRYPTO_TSIG_ERR;
 #endif /* HAVE_SSL */
+
        status = ldns_resolver_send_pkt(&answer_pkt, r, query_pkt);
        ldns_pkt_free(query_pkt);
 
@@ -1124,7 +1191,11 @@ ldns_axfr_next(ldns_resolver *resolver)
                if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) {
                        resolver->_axfr_soa_count++;
                        if (resolver->_axfr_soa_count >= 2) {
+#ifndef USE_WINSOCK
                                close(resolver->_socket);
+#else
+                               closesocket(resolver->_socket);
+#endif
                                resolver->_socket = 0;
                                ldns_pkt_free(resolver->_cur_axfr_pkt);
                                resolver->_cur_axfr_pkt = NULL;
@@ -1144,10 +1215,32 @@ ldns_axfr_next(ldns_resolver *resolver)
                if (status != LDNS_STATUS_OK) {
                        /* TODO: make status return type of this function (...api change) */
                        fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status));
+
+                       /* RoRi: we must now also close the socket, otherwise subsequent uses of the
+                          same resolver structure will fail because the link is still open or
+                          in an undefined state */
+#ifndef USE_WINSOCK
+                       close(resolver->_socket);
+#else
+                       closesocket(resolver->_socket);
+#endif
+                       resolver->_socket = 0;
+
                        return NULL;
                } else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) {
                        rcode = ldns_lookup_by_id(ldns_rcodes, (int) ldns_pkt_get_rcode(resolver->_cur_axfr_pkt));
                        fprintf(stderr, "Error in AXFR: %s\n", rcode->name);
+
+                       /* RoRi: we must now also close the socket, otherwise subsequent uses of the
+                          same resolver structure will fail because the link is still open or
+                          in an undefined state */
+#ifndef USE_WINSOCK
+                       close(resolver->_socket);
+#else
+                       closesocket(resolver->_socket);
+#endif
+                       resolver->_socket = 0;
+
                        return NULL;
                } else {
                        return ldns_axfr_next(resolver);
@@ -1174,16 +1267,15 @@ ldns_axfr_last_pkt(const ldns_resolver *res)
 void
 ldns_resolver_nameservers_randomize(ldns_resolver *r)
 {
-       uint8_t i, j;
+       uint16_t i, j;
        ldns_rdf **ns, *tmp;
 
        /* should I check for ldns_resolver_random?? */
        assert(r != NULL);
 
        ns = ldns_resolver_nameservers(r);
-
        for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
-               j = random() % ldns_resolver_nameserver_count(r);
+               j = ldns_get_random() % ldns_resolver_nameserver_count(r);
                tmp = ns[i];
                ns[i] = ns[j];
                ns[j] = tmp;
index a8aad56..60ce498 100644 (file)
@@ -120,7 +120,8 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
        const char *delimiters;
        ssize_t c;
        ldns_rdf *owner_dname;
-    const char* endptr;
+        const char* endptr;
+        int was_unknown_rr_format = 0;
 
        /* used for types with unknown number of rdatas */
        bool done;
@@ -130,12 +131,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
        uint16_t r_cnt;
        uint16_t r_min;
        uint16_t r_max;
-
-       uint16_t hex_data_size;
-       char *hex_data_str;
-       uint16_t cur_hex_data_size;
-       uint8_t *hex_data;
-       size_t hex_pos;
+        size_t pre_data_pos;
 
        new = ldns_rr_new();
 
@@ -150,9 +146,6 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
        if (!new || !owner || !ttl || !clas || !rdata || !rr_buf || !rd_buf || !rd || !b64 ) {
                return LDNS_STATUS_MEM_ERR;
        }
-       r_cnt = 0;
-       ttl_val = 0;
-       clas_val = 0;
 
        ldns_buffer_new_frm_data(rr_buf, (char*)str, strlen(str));
 
@@ -213,6 +206,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                        LDNS_FREE(rdata);
                        LDNS_FREE(rd);
                        LDNS_FREE(rd_buf);
+                       LDNS_FREE(b64);
                        ldns_buffer_free(rr_buf);
                        ldns_rr_free(new);
                        return LDNS_STATUS_SYNTAX_CLASS_ERR;
@@ -238,6 +232,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                        LDNS_FREE(rdata);
                        LDNS_FREE(rd);
                        LDNS_FREE(rd_buf);
+                       LDNS_FREE(b64);
                        ldns_buffer_free(rr_buf);
                        ldns_rr_free(new);
                        return LDNS_STATUS_SYNTAX_TYPE_ERR;
@@ -298,6 +293,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                                        LDNS_FREE(rdata);
                                        LDNS_FREE(rd);
                                        LDNS_FREE(rd_buf);
+                                       LDNS_FREE(b64);
                                        ldns_buffer_free(rr_buf);
                                        ldns_rr_free(new);
                                        return LDNS_STATUS_SYNTAX_ERR;
@@ -314,6 +310,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                                        LDNS_FREE(rdata);
                                        LDNS_FREE(rd);
                                        LDNS_FREE(rd_buf);
+                                       LDNS_FREE(b64);
                                        ldns_buffer_free(rr_buf);
                                        ldns_rr_free(new);
                                        return LDNS_STATUS_SYNTAX_ERR;
@@ -399,6 +396,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                                        ldns_buffer_skip(rd_buf, 1);
                                }
 
+                               pre_data_pos = ldns_buffer_position(rd_buf);
                                if ((c = ldns_bget_token(rd_buf, rd, delimiters,
                                                        LDNS_MAX_RDFLEN)) != -1) {
                                        /* hmmz, rfc3597 specifies that any type can be represented with
@@ -408,7 +406,17 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                                        rd_strlen = strlen(rd);
 
                                        /* unknown RR data */
-                                       if (rd_strlen == 2 && strncmp(rd, "\\#", 2) == 0 && !quoted) {
+                                       if (strncmp(rd, "\\#", 2) == 0 && !quoted && (rd_strlen == 2 || rd[2]==' ')) {
+                                               uint16_t hex_data_size;
+                                                char *hex_data_str;
+                                                uint16_t cur_hex_data_size;
+
+                                                was_unknown_rr_format = 1;
+                                                /* go back to before \# and skip it while setting delimiters better */
+                                                ldns_buffer_set_position(rd_buf, pre_data_pos);
+                                               delimiters = "\n\t ";
+                                                (void)ldns_bget_token(rd_buf, rd, delimiters, LDNS_MAX_RDFLEN);
+                                                /* read rdata octet length */
                                                c = ldns_bget_token(rd_buf, rd, delimiters, LDNS_MAX_RDFLEN);
                                                if (c == -1) {
                                                        /* something goes very wrong here */
@@ -437,10 +445,10 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                                                /* correct the rdf type */
                                                /* if *we* know the type, interpret it as wireformat */
                                                if (desc) {
-                                                       hex_data = LDNS_XMALLOC(uint8_t, hex_data_size + 2);
+                                                       size_t hex_pos = 0;
+                                                       uint8_t *hex_data = LDNS_XMALLOC(uint8_t, hex_data_size + 2);
                                                        ldns_write_uint16(hex_data, hex_data_size);
                                                        ldns_hexstring_to_data(hex_data + 2, hex_data_str);
-                                                       hex_pos = 0;
                                                        (void) ldns_wire2rdf(new, hex_data,
                                                                         hex_data_size+2, &hex_pos);
                                                        LDNS_FREE(hex_data);
@@ -532,7 +540,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
        ldns_buffer_free(rr_buf);
        LDNS_FREE(rdata);
 
-       if (!question && desc && ldns_rr_rd_count(new) < r_min) {
+       if (!question && desc && !was_unknown_rr_format && ldns_rr_rd_count(new) < r_min) {
                ldns_rr_free(new);
                return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
        }
@@ -580,13 +588,12 @@ ldns_rr_new_frm_fp_l(ldns_rr **newrr, FILE *fp, uint32_t *default_ttl, ldns_rdf
        char *line;
        const char *endptr;  /* unused */
        ldns_rr *rr;
-       char *keyword;
        uint32_t ttl;
        ldns_rdf *tmp;
        ldns_status s;
        ssize_t size;
+       int offset = 0;
 
-       s = LDNS_STATUS_ERR;
        if (default_ttl) {
                ttl = *default_ttl;
        } else {
@@ -616,12 +623,16 @@ ldns_rr_new_frm_fp_l(ldns_rr **newrr, FILE *fp, uint32_t *default_ttl, ldns_rdf
                return LDNS_STATUS_SYNTAX_EMPTY;
        }
 
-       if ((keyword = strstr(line, "$ORIGIN "))) {
+       if (strncmp(line, "$ORIGIN", 7) == 0 && isspace(line[7])) {
                if (*origin) {
                        ldns_rdf_deep_free(*origin);
                        *origin = NULL;
                }
-               tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, keyword + 8);
+               offset = 8;
+               while (isspace(line[offset])) {
+                       offset++;
+               }
+               tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, line + offset);
                if (!tmp) {
                        /* could not parse what next to $ORIGIN */
                        LDNS_FREE(line);
@@ -629,11 +640,17 @@ ldns_rr_new_frm_fp_l(ldns_rr **newrr, FILE *fp, uint32_t *default_ttl, ldns_rdf
                }
                *origin = tmp;
                s = LDNS_STATUS_SYNTAX_ORIGIN;
-       } else if ((keyword = strstr(line, "$TTL "))) {
+       } else if (strncmp(line, "$TTL", 4) == 0 && isspace(line[4])) {
+               offset = 5;
+               while (isspace(line[offset])) {
+                       offset++;
+               }
                if (default_ttl) {
-                       *default_ttl = ldns_str2period(keyword + 5, &endptr);
+                       *default_ttl = ldns_str2period(line + offset, &endptr);
                }
                s = LDNS_STATUS_SYNTAX_TTL;
+       } else if (strncmp(line, "$INCLUDE", 8) == 0) {
+               s = LDNS_STATUS_SYNTAX_INCLUDE;
        } else {
                if (origin && *origin) {
                        s = ldns_rr_new_frm_str(&rr, (const char*) line, ttl, *origin, prev);
@@ -689,11 +706,9 @@ ldns_rr_set_rdf(ldns_rr *rr, const ldns_rdf *f, size_t position)
 {
        size_t rd_count;
        ldns_rdf *pop;
-       ldns_rdf **rdata_fields;
 
        rd_count = ldns_rr_rd_count(rr);
        if (position < rd_count) {
-               rdata_fields = rr->_rdata_fields;
                /* dicard the old one */
                pop = rr->_rdata_fields[position];
                rr->_rdata_fields[position] = (ldns_rdf*)f;
@@ -731,6 +746,7 @@ ldns_rr_pop_rdf(ldns_rr *rr)
 {
        size_t rd_count;
        ldns_rdf *pop;
+       ldns_rdf** newrd;
 
        rd_count = ldns_rr_rd_count(rr);
 
@@ -740,9 +756,15 @@ ldns_rr_pop_rdf(ldns_rr *rr)
 
        pop = rr->_rdata_fields[rd_count - 1];
 
-       /* shrink the array */
-       rr->_rdata_fields = LDNS_XREALLOC(
-               rr->_rdata_fields, ldns_rdf *, rd_count - 1);
+       /* try to shrink the array */
+       if(rd_count > 1) {
+               newrd = LDNS_XREALLOC(
+                       rr->_rdata_fields, ldns_rdf *, rd_count - 1);
+               if(newrd)
+                       rr->_rdata_fields = newrd;
+       } else {
+               LDNS_FREE(rr->_rdata_fields);
+       }
 
        ldns_rr_set_rd_count(rr, rd_count - 1);
        return pop;
@@ -878,12 +900,9 @@ bool
 ldns_rr_list_cat(ldns_rr_list *left, ldns_rr_list *right)
 {
        size_t r_rr_count;
-       size_t l_rr_count;
        size_t i;
 
-       if (left) {
-               l_rr_count = ldns_rr_list_rr_count(left);
-       } else {
+       if (!left) {
                return false;
        }
 
@@ -908,8 +927,6 @@ ldns_rr_list_cat_clone(ldns_rr_list *left, ldns_rr_list *right)
        size_t i;
        ldns_rr_list *cat;
 
-       l_rr_count = 0;
-
        if (left) {
                l_rr_count = ldns_rr_list_rr_count(left);
        } else {
@@ -1257,6 +1274,7 @@ ldns_rr_clone(const ldns_rr *rr)
        ldns_rr_set_ttl(new_rr, ldns_rr_ttl(rr));
        ldns_rr_set_type(new_rr, ldns_rr_get_type(rr));
        ldns_rr_set_class(new_rr, ldns_rr_get_class(rr));
+       ldns_rr_set_question(new_rr, ldns_rr_is_question(rr));
 
        for (i = 0; i < ldns_rr_rd_count(rr); i++) {
                if (ldns_rr_rdf(rr,i)) {
@@ -1340,7 +1358,6 @@ qsort_schwartz_rr_compare(const void *a, const void *b)
                        ldns_rr2canonical(canonical_a);
                        sa->transformed_object = ldns_buffer_new(ldns_rr_uncompressed_size(canonical_a));
                        if (ldns_rr2buffer_wire(sa->transformed_object, canonical_a, LDNS_SECTION_ANY) != LDNS_STATUS_OK) {
-                               fprintf(stderr, "ERR!\n");
                                ldns_rr_free(canonical_a);
                                return 0;
                        }
@@ -1351,7 +1368,6 @@ qsort_schwartz_rr_compare(const void *a, const void *b)
                        ldns_rr2canonical(canonical_b);
                        sb->transformed_object = ldns_buffer_new(ldns_rr_uncompressed_size(canonical_b));
                        if (ldns_rr2buffer_wire(sb->transformed_object, canonical_b, LDNS_SECTION_ANY) != LDNS_STATUS_OK) {
-                               fprintf(stderr, "ERR!\n");
                                ldns_rr_free(canonical_b);
                                return 0;
                        }
@@ -1801,6 +1817,9 @@ static const ldns_rdf_type type_nsec_wireformat[] = {
 static const ldns_rdf_type type_dhcid_wireformat[] = {
        LDNS_RDF_TYPE_B64
 };
+static const ldns_rdf_type type_talink_wireformat[] = {
+       LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
+};
 /* nsec3 is some vars, followed by same type of data of nsec */
 static const ldns_rdf_type type_nsec3_wireformat[] = {
 /*     LDNS_RDF_TYPE_NSEC3_VARS, LDNS_RDF_TYPE_NSEC3_NEXT_OWNER, LDNS_RDF_TYPE_NSEC*/
@@ -1949,7 +1968,7 @@ static ldns_rr_descriptor rdata_field_descriptors[] = {
 {LDNS_RR_TYPE_NULL, "TYPE55", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 {LDNS_RR_TYPE_NULL, "TYPE56", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 {LDNS_RR_TYPE_NULL, "TYPE57", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE58", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_TALINK, "TALINK", 2, 2, type_talink_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
 {LDNS_RR_TYPE_NULL, "TYPE59", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 {LDNS_RR_TYPE_NULL, "TYPE60", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 {LDNS_RR_TYPE_NULL, "TYPE61", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
index 3297f7a..f4c5e4f 100644 (file)
@@ -312,13 +312,17 @@ ldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
                }
                break;
 #ifdef USE_GOST
-       case LDNS_SIGN_GOST:
+       case LDNS_SIGN_ECC_GOST:
                return 512;
-               break;
+#endif
+#ifdef USE_ECDSA
+        case LDNS_SIGN_ECDSAP256SHA256:
+                return 256;
+        case LDNS_SIGN_ECDSAP384SHA384:
+                return 384;
 #endif
        case LDNS_SIGN_HMACMD5:
                return len;
-               break;
        default:
                return 0;
        }
index 4ee3e78..f73b23d 100644 (file)
@@ -258,9 +258,9 @@ parse_escape(uint8_t *s, uint8_t *q) {
                return 3;
        } else {
                s++;
-               if (*s == '\0') {
+               if (*s == '\0' || isdigit((int) *s)) {
                        /* apparently the string terminator
-                        * has been escaped...
+                        * or a digit has been escaped...
                         */
                        return 0;
                }
@@ -280,7 +280,7 @@ ldns_str2rdf_dname(ldns_rdf **d, const char *str)
        size_t len;
 
        int esc;
-       uint8_t *s,*p,*q, *pq, label_len;
+       uint8_t *s, *q, *pq, label_len;
        uint8_t buf[LDNS_MAX_DOMAINLEN + 1];
        *d = NULL;
 
@@ -301,15 +301,16 @@ ldns_str2rdf_dname(ldns_rdf **d, const char *str)
 
        /* get on with the rest */
 
-       /* s is on the current dot
-        * p on the previous one
-        * q builds the dname
+       /* s is on the current character in the string
+         * pq points to where the labellength is going to go
+         * label_len keeps track of the current label's length
+        * q builds the dname inside the buf array
         */
        len = 0;
        q = buf+1;
        pq = buf;
        label_len = 0;
-       for (s = p = (uint8_t *) str; *s; s++, q++) {
+       for (s = (uint8_t *)str; *s; s++, q++) {
                if (q > buf + LDNS_MAX_DOMAINLEN) {
                        return LDNS_STATUS_DOMAINNAME_OVERFLOW;
                }
@@ -326,7 +327,6 @@ ldns_str2rdf_dname(ldns_rdf **d, const char *str)
                        *pq = label_len;
                        label_len = 0;
                        pq = q;
-                       p = s+1;
                        break;
                case '\\':
                        /* octet value or literal char */
@@ -349,6 +349,12 @@ ldns_str2rdf_dname(ldns_rdf **d, const char *str)
                if (q > buf + LDNS_MAX_DOMAINLEN) {
                        return LDNS_STATUS_DOMAINNAME_OVERFLOW;
                }
+                if (label_len > LDNS_MAX_LABELLEN) {
+                        return LDNS_STATUS_LABEL_OVERFLOW;
+                }
+                if (label_len == 0) { /* label_len 0 but not . at end? */
+                        return LDNS_STATUS_EMPTY_LABEL;
+                }
                len += label_len + 1;
                *pq = label_len;
                *q = 0;
@@ -390,7 +396,7 @@ ldns_status
 ldns_str2rdf_str(ldns_rdf **rd, const char *str)
 {
        uint8_t *data;
-       size_t i, str_i;
+       size_t i, str_i, esc_i;
 
        if (strlen(str) > 255) {
                return LDNS_STATUS_INVALID_STR;
@@ -401,7 +407,12 @@ ldns_str2rdf_str(ldns_rdf **rd, const char *str)
        for (str_i = 0; str_i < strlen(str); str_i++) {
                if (str[str_i] == '\\') {
                        /* octet value or literal char */
-                       str_i += (size_t) parse_escape((uint8_t*) &str[str_i], (uint8_t*) &data[i]);
+                       esc_i = (size_t) parse_escape((uint8_t*) &str[str_i], (uint8_t*) &data[i]);
+                       if (esc_i == 0) {
+                               LDNS_FREE(data);
+                               return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
+                       }
+                       str_i += esc_i;
                } else {
                        data[i] = (uint8_t) str[str_i];
                }
@@ -600,11 +611,25 @@ ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
        uint16_t cur_type;
        size_t type_count = 0;
        ldns_rr_type type_list[1024];
+       if(!token) return LDNS_STATUS_MEM_ERR;
+       if(rd == NULL) {
+               LDNS_FREE(token);
+               return LDNS_STATUS_NULL;
+       }
 
        str_buf = LDNS_MALLOC(ldns_buffer);
+       if(!str_buf) {
+               LDNS_FREE(token);
+               return LDNS_STATUS_MEM_ERR;
+       }
        ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
+       if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
+               LDNS_FREE(str_buf);
+               LDNS_FREE(token);
+               return LDNS_STATUS_MEM_ERR;
+       }
 
-       while ((c = ldns_bget_token(str_buf, token, delimiters, LDNS_MAX_RDFLEN)) != -1) {
+       while ((c = ldns_bget_token(str_buf, token, delimiters, LDNS_MAX_RDFLEN)) != -1 && c != 0) {
                cur_type = ldns_get_rr_type_by_name(token);
                type_list[type_count] = cur_type;
                type_count++;
@@ -614,8 +639,7 @@ ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
                                             type_count,
                                             LDNS_RR_TYPE_NSEC);
 
-       if (token)
-               LDNS_FREE(token);
+       LDNS_FREE(token);
        ldns_buffer_free(str_buf);
        return LDNS_STATUS_OK;
 }
@@ -948,17 +972,28 @@ ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
        ldns_buffer *str_buf;
 
        char *proto_str = NULL;
-       char *token = LDNS_XMALLOC(char, 50);
+       char *token;
+       if(strlen(str) == 0)
+               token = LDNS_XMALLOC(char, 50);
+       else    token = LDNS_XMALLOC(char, strlen(str)+2);
+       if(!token) return LDNS_STATUS_MEM_ERR;
 
        str_buf = LDNS_MALLOC(ldns_buffer);
+       if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
        ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
+       if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
+               LDNS_FREE(str_buf);
+               LDNS_FREE(token);
+               return LDNS_STATUS_MEM_ERR;
+       }
 
        while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
                if (!proto_str) {
                        proto_str = strdup(token);
                        if (!proto_str) {
+                               LDNS_FREE(bitmap);
                                LDNS_FREE(token);
-                               LDNS_FREE(str_buf);
+                               ldns_buffer_free(str_buf);
                                return LDNS_STATUS_INVALID_STR;
                        }
                } else {
@@ -969,7 +1004,15 @@ ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
                                serv_port = atoi(token);
                        }
                        if (serv_port / 8 >= bm_len) {
-                               bitmap = LDNS_XREALLOC(bitmap, uint8_t, (serv_port / 8) + 1);
+                               uint8_t *b2 = LDNS_XREALLOC(bitmap, uint8_t, (serv_port / 8) + 1);
+                                if(!b2) {
+                                       LDNS_FREE(bitmap);
+                                       LDNS_FREE(token);
+                                       ldns_buffer_free(str_buf);
+                                       free(proto_str);
+                                       return LDNS_STATUS_INVALID_STR;
+                                }
+                               bitmap = b2;
                                /* set to zero to be sure */
                                for (; bm_len <= serv_port / 8; bm_len++) {
                                        bitmap[bm_len] = 0;
@@ -979,13 +1022,22 @@ ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
                }
        }
 
-       if (!proto_str) {
+       if (!proto_str || !bitmap) {
+               LDNS_FREE(bitmap);
                LDNS_FREE(token);
-               LDNS_FREE(str_buf);
+               ldns_buffer_free(str_buf);
+               free(proto_str);
                return LDNS_STATUS_INVALID_STR;
        }
 
        data = LDNS_XMALLOC(uint8_t, bm_len + 1);
+        if(!data) {
+               LDNS_FREE(token);
+               ldns_buffer_free(str_buf);
+               LDNS_FREE(bitmap);
+               free(proto_str);
+               return LDNS_STATUS_INVALID_STR;
+        }
     if (proto_str)
                proto = getprotobyname(proto_str);
        if (proto) {
@@ -1011,6 +1063,8 @@ ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
        endprotoent();
 #endif
 
+       if(!*rd) return LDNS_STATUS_MEM_ERR;
+
        return LDNS_STATUS_OK;
 }
 
@@ -1063,15 +1117,26 @@ ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
        char* publickey = NULL;
        uint8_t *data;
        ldns_buffer *str_buf;
-       char *token = LDNS_XMALLOC(char, 256);
+       char *token;
        int token_count = 0;
        int ipseckey_len = 0;
        ldns_rdf* gateway_rdf = NULL;
        ldns_rdf* publickey_rdf = NULL;
        ldns_status status = LDNS_STATUS_OK;
+       
+       if(strlen(str) == 0)
+               token = LDNS_XMALLOC(char, 256);
+       else    token = LDNS_XMALLOC(char, strlen(str)+2);
+       if(!token) return LDNS_STATUS_MEM_ERR;
 
        str_buf = LDNS_MALLOC(ldns_buffer);
+       if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
        ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
+       if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
+               LDNS_FREE(str_buf);
+               LDNS_FREE(token);
+               return LDNS_STATUS_MEM_ERR;
+       }
        while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
                switch (token_count) {
                                case 0:
@@ -1089,7 +1154,7 @@ ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
                                                        (token[0] != '.' || token[1] != '\0'))) {
                                                LDNS_FREE(gateway);
                                                LDNS_FREE(token);
-                                               LDNS_FREE(str_buf);
+                                               ldns_buffer_free(str_buf);
                                                return LDNS_STATUS_INVALID_STR;
                                        }
                                        break;
@@ -1098,7 +1163,7 @@ ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
                                        break;
                                default:
                                        LDNS_FREE(token);
-                                       LDNS_FREE(str_buf);
+                                       ldns_buffer_free(str_buf);
                                        return LDNS_STATUS_INVALID_STR;
                                        break;
                }
@@ -1111,7 +1176,7 @@ ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
                if (publickey)
                        LDNS_FREE(publickey);
                LDNS_FREE(token);
-               LDNS_FREE(str_buf);
+               ldns_buffer_free(str_buf);
                return LDNS_STATUS_INVALID_STR;
        }
 
@@ -1129,7 +1194,7 @@ ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
                if (publickey)
                        LDNS_FREE(publickey);
                LDNS_FREE(token);
-               LDNS_FREE(str_buf);
+               ldns_buffer_free(str_buf);
                return LDNS_STATUS_INVALID_STR;
        }
 
@@ -1141,7 +1206,8 @@ ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
                if (publickey)
                        LDNS_FREE(publickey);
                LDNS_FREE(token);
-               LDNS_FREE(str_buf);
+               ldns_buffer_free(str_buf);
+               if (gateway_rdf) ldns_rdf_free(gateway_rdf);
                return LDNS_STATUS_INVALID_STR;
        }
 
@@ -1152,6 +1218,17 @@ ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
                ipseckey_len = 3 + ldns_rdf_size(publickey_rdf);
 
        data = LDNS_XMALLOC(uint8_t, ipseckey_len);
+       if(!data) {
+               if (gateway)
+                       LDNS_FREE(gateway);
+               if (publickey)
+                       LDNS_FREE(publickey);
+               LDNS_FREE(token);
+               ldns_buffer_free(str_buf);
+               if (gateway_rdf) ldns_rdf_free(gateway_rdf);
+               if (publickey_rdf) ldns_rdf_free(publickey_rdf);
+               return LDNS_STATUS_MEM_ERR;
+       }
 
        data[0] = precedence;
        data[1] = gateway_type;
@@ -1178,5 +1255,6 @@ ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
        ldns_rdf_free(gateway_rdf);
        ldns_rdf_free(publickey_rdf);
        LDNS_FREE(data);
+       if(!*rd) return LDNS_STATUS_MEM_ERR;
        return LDNS_STATUS_OK;
 }
index 38a9a0e..4083960 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * tsig.c
  *
  * contains the functions needed for TSIG [RFC2845]
@@ -149,7 +149,7 @@ static ldns_status
 ldns_tsig_mac_new(ldns_rdf **tsig_mac, uint8_t *pkt_wire, size_t pkt_wire_size,
                const char *key_data, ldns_rdf *key_name_rdf, ldns_rdf *fudge_rdf,
                ldns_rdf *algorithm_rdf, ldns_rdf *time_signed_rdf, ldns_rdf *error_rdf,
-               ldns_rdf *other_data_rdf, ldns_rdf *orig_mac_rdf)
+               ldns_rdf *other_data_rdf, ldns_rdf *orig_mac_rdf, int tsig_timers_only)
 {
        char *wireformat;
        int wiresize;
@@ -166,37 +166,63 @@ ldns_tsig_mac_new(ldns_rdf **tsig_mac, uint8_t *pkt_wire, size_t pkt_wire_size,
         * prepare the digestable information
         */
        data_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+       if(!data_buffer) {
+               return LDNS_STATUS_MEM_ERR;
+       }
        /* if orig_mac is not NULL, add it too */
        if (orig_mac_rdf) {
                (void) ldns_rdf2buffer_wire(data_buffer, orig_mac_rdf);
        }
        ldns_buffer_write(data_buffer, pkt_wire, pkt_wire_size);
-       (void)ldns_rdf2buffer_wire(data_buffer, 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);
+       if (!tsig_timers_only) {
+               (void)ldns_rdf2buffer_wire(data_buffer, 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);
+       }
        (void)ldns_rdf2buffer_wire(data_buffer, time_signed_rdf);
        (void)ldns_rdf2buffer_wire(data_buffer, fudge_rdf);
-       (void)ldns_rdf2buffer_wire(data_buffer, error_rdf);
-       (void)ldns_rdf2buffer_wire(data_buffer, other_data_rdf);
+       if (!tsig_timers_only) {
+               (void)ldns_rdf2buffer_wire(data_buffer, error_rdf);
+               (void)ldns_rdf2buffer_wire(data_buffer, other_data_rdf);
+       }
 
        wireformat = (char *) data_buffer->_data;
        wiresize = (int) ldns_buffer_position(data_buffer);
 
        algorithm_name = ldns_rdf2str(algorithm_rdf);
+       if(!algorithm_name) {
+               ldns_buffer_free(data_buffer);
+               return LDNS_STATUS_MEM_ERR;
+       }
 
        /* prepare the key */
        key_bytes = LDNS_XMALLOC(unsigned char,
                        ldns_b64_pton_calculate_size(strlen(key_data)));
-       key_size = ldns_b64_pton(key_data, key_bytes, strlen(key_data) * 2);
+       if(!key_bytes) {
+               LDNS_FREE(algorithm_name);
+               ldns_buffer_free(data_buffer);
+               return LDNS_STATUS_MEM_ERR;
+       }
+       key_size = ldns_b64_pton(key_data, key_bytes,
+                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;
        }
        /* hmac it */
        /* 2 spare bytes for the length */
-       mac_bytes = LDNS_XMALLOC(unsigned char, md_len);
-       memset(mac_bytes, 0, md_len);
+       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;
+       }
+       memset(mac_bytes, 0, md_len+2);
 
        digester = ldns_digest_function(algorithm_name);
 
@@ -208,6 +234,10 @@ 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;
        }
 
@@ -225,8 +255,15 @@ ldns_tsig_mac_new(ldns_rdf **tsig_mac, uint8_t *pkt_wire, size_t pkt_wire_size,
 
 #ifdef HAVE_SSL
 bool
-ldns_pkt_tsig_verify(ldns_pkt *pkt, uint8_t *wire, size_t wirelen,
-               const char *key_name, const char *key_data, ldns_rdf *orig_mac_rdf)
+ldns_pkt_tsig_verify(ldns_pkt *pkt, uint8_t *wire, size_t wirelen, const char *key_name,
+       const char *key_data, ldns_rdf *orig_mac_rdf)
+{
+       return ldns_pkt_tsig_verify_next(pkt, wire, wirelen, key_name, key_data, orig_mac_rdf, 0);
+}
+
+bool
+ldns_pkt_tsig_verify_next(ldns_pkt *pkt, uint8_t *wire, size_t wirelen, const char* key_name,
+       const char *key_data, ldns_rdf *orig_mac_rdf, int tsig_timers_only)
 {
        ldns_rdf *fudge_rdf;
        ldns_rdf *algorithm_rdf;
@@ -268,7 +305,7 @@ ldns_pkt_tsig_verify(ldns_pkt *pkt, uint8_t *wire, size_t wirelen,
 
        status = ldns_tsig_mac_new(&my_mac_rdf, prepared_wire, prepared_wire_size,
                        key_data, key_name_rdf, fudge_rdf, algorithm_rdf,
-                       time_signed_rdf, error_rdf, other_data_rdf, orig_mac_rdf);
+                       time_signed_rdf, error_rdf, other_data_rdf, orig_mac_rdf, tsig_timers_only);
 
        LDNS_FREE(prepared_wire);
 
@@ -296,7 +333,14 @@ ldns_pkt_tsig_verify(ldns_pkt *pkt, uint8_t *wire, size_t wirelen,
 /* TODO: memory :p */
 ldns_status
 ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data,
-               uint16_t fudge, const char *algorithm_name, ldns_rdf *query_mac)
+       uint16_t fudge, const char *algorithm_name, ldns_rdf *query_mac)
+{
+       return ldns_pkt_tsig_sign_next(pkt, key_name, key_data, fudge, algorithm_name, query_mac, 0);
+}
+
+ldns_status
+ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_data,
+       uint16_t fudge, const char *algorithm_name, ldns_rdf *query_mac, int tsig_timers_only)
 {
        ldns_rr *tsig_rr;
        ldns_rdf *key_name_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, key_name);
@@ -346,7 +390,7 @@ ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data,
 
        status = ldns_tsig_mac_new(&mac_rdf, pkt_wire, pkt_wire_len,
                        key_data, key_name_rdf, fudge_rdf, algorithm_rdf,
-                       time_signed_rdf, error_rdf, other_data_rdf, query_mac);
+                       time_signed_rdf, error_rdf, other_data_rdf, query_mac, tsig_timers_only);
 
        if (!mac_rdf) {
                goto clean;
index 82fa264..3b446ba 100644 (file)
@@ -262,7 +262,6 @@ ldns_init_random(FILE *fd, unsigned int size)
        size_t read = 0;
        unsigned int seed_i;
        struct timeval tv;
-       struct timezone tz;
 
        /* we'll need at least sizeof(unsigned int) bytes for the
           standard prng seed */
@@ -279,7 +278,7 @@ ldns_init_random(FILE *fd, unsigned int size)
                                /* no readable /dev/random either, and no entropy
                                   source given. we'll have to improvise */
                                for (read = 0; read < size; read++) {
-                                       gettimeofday(&tv, &tz);
+                                       gettimeofday(&tv, NULL);
                                        seed[read] = (uint8_t) (tv.tv_usec % 256);
                                }
                        } else {
@@ -312,12 +311,30 @@ ldns_init_random(FILE *fd, unsigned int size)
        }
 
        if (!fd) {
-               fclose(rand_f);
+                if (rand_f) fclose(rand_f);
        }
 
        return 0;
 }
 
+/**
+ * Get random number.
+ *
+ */
+uint16_t
+ldns_get_random(void)
+{
+        uint16_t rid = 0;
+#ifdef HAVE_SSL
+        if (RAND_bytes((unsigned char*)&rid, 2) != 1) {
+                rid = (uint16_t) random();
+        }
+#else
+        rid = (uint16_t) random();
+#endif
+       return rid;
+}
+
 /*
  * BubbleBabble code taken from OpenSSH
  * Copyright (c) 2001 Carsten Raskgaard.  All rights reserved.
@@ -333,6 +350,7 @@ ldns_bubblebabble(uint8_t *data, size_t len)
 
        rounds = (len / 2) + 1;
        retval = LDNS_XMALLOC(char, rounds * 6);
+       if(!retval) return NULL;
        retval[j++] = 'x';
        for (i = 0; i < rounds; i++) {
                size_t idx0, idx1, idx2, idx3, idx4;