Merge remote-tracking branch 'origin/vendor/LDNS'
authorzrj <zrj@dragonflybsd.org>
Wed, 24 Apr 2019 17:14:10 +0000 (20:14 +0300)
committerzrj <zrj@dragonflybsd.org>
Wed, 24 Apr 2019 17:14:10 +0000 (20:14 +0300)
88 files changed:
contrib/ldns/README [deleted file]
contrib/ldns/buffer.c
contrib/ldns/compat/b32_ntop.c [deleted file]
contrib/ldns/compat/b32_pton.c [deleted file]
contrib/ldns/compat/b64_ntop.c
contrib/ldns/compat/b64_pton.c
contrib/ldns/compat/calloc.c [deleted file]
contrib/ldns/compat/ctime_r.c [deleted file]
contrib/ldns/compat/fake-rfc2553.c [deleted file]
contrib/ldns/compat/fake-rfc2553.h [deleted file]
contrib/ldns/compat/gmtime_r.c [deleted file]
contrib/ldns/compat/inet_aton.c [deleted file]
contrib/ldns/compat/inet_ntop.c [deleted file]
contrib/ldns/compat/inet_pton.c [deleted file]
contrib/ldns/compat/isascii.c [deleted file]
contrib/ldns/compat/isblank.c [deleted file]
contrib/ldns/compat/localtime_r.c [deleted file]
contrib/ldns/compat/malloc.c [deleted file]
contrib/ldns/compat/memmove.c [deleted file]
contrib/ldns/compat/realloc.c [deleted file]
contrib/ldns/compat/snprintf.c [deleted file]
contrib/ldns/compat/strlcpy.c [deleted file]
contrib/ldns/compat/timegm.c [deleted file]
contrib/ldns/dane.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/ChangeLog.22-nov-2005 [deleted file]
contrib/ldns/drill/README [deleted file]
contrib/ldns/drill/REGRESSIONS [deleted file]
contrib/ldns/drill/chasetrace.c
contrib/ldns/drill/drill.c
contrib/ldns/drill/drill.h
contrib/ldns/drill/drill_util.c
contrib/ldns/drill/error.c
contrib/ldns/drill/securetrace.c
contrib/ldns/drill/work.c
contrib/ldns/duration.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/dane.h
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/duration.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 [new file with mode: 0644]
contrib/ldns/ldns/packet.h
contrib/ldns/ldns/radix.h [new file with mode: 0644]
contrib/ldns/ldns/rbtree.h
contrib/ldns/ldns/rdata.h
contrib/ldns/ldns/resolver.h
contrib/ldns/ldns/rr.h
contrib/ldns/ldns/str2host.h
contrib/ldns/ldns/tsig.h
contrib/ldns/ldns/update.h
contrib/ldns/ldns/wire2host.h
contrib/ldns/ldns/zone.h
contrib/ldns/linktest.c [deleted file]
contrib/ldns/net.c
contrib/ldns/packet.c
contrib/ldns/parse.c
contrib/ldns/radix.c [new file with mode: 0644]
contrib/ldns/rbtree.c
contrib/ldns/rdata.c
contrib/ldns/resolver.c
contrib/ldns/rr.c
contrib/ldns/rr_functions.c
contrib/ldns/sha1.c
contrib/ldns/sha2.c
contrib/ldns/str2host.c
contrib/ldns/tsig.c
contrib/ldns/update.c
contrib/ldns/util.c
contrib/ldns/wire2host.c
contrib/ldns/zone.c

diff --git a/contrib/ldns/README b/contrib/ldns/README
deleted file mode 100644 (file)
index 70eb3dc..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-
-Contents: 
-       REQUIREMENTS
-       INSTALLATION
-               libdns
-               examples
-               drill
-       INFORMATION FOR SPECIFIC OPERATING SYSTEMS
-               Mac OS X
-               Solaris
-       KNOWN ISSUES
-               pyldns
-        Your Support
-
-Project page:
-http://www.nlnetlabs.nl/ldns/
-On that page you can also subscribe to the ldns mailing list.
-
-* Development 
-ldns is mainly developed on Linux and FreeBSD. It is regularly tested to
-compile on other systems like Solaris and Mac OS X.
-
-REQUIREMENTS
-- OpenSSL (Optional, but needed for features like DNSSEC)
-- libpcap (Optional, but needed for examples/ldns-dpa)
-- (GNU) libtool (in OSX, that's glibtool, not libtool)
-- GNU make
-
-INSTALLATION
-1. Unpack the tarball
-2. cd ldns-<VERSION>
-3. ./configure
-4. gmake (it needs gnu make to compile, on systems where GNU make is the
-   default you can just use 'make')
-5. sudo gmake install
-6. Optional. (cd examples; ./configure; gmake), make example programs included.
-7. Optional. (cd drill; ./configure; gmake; gmake install), to build drill.
-
-You can configure and compile it in a separate build directory.
-
-* Examples
-There are some examples and dns related tools in the examples/ directory.
-These can be built with:
-1. cd examples/
-2. ./configure [--with-ldns=<path to ldns installation or build>]
-3. gmake
-
-* Drill
-Drill can be built with:
-1. cd drill/
-2. ./configure [--with-ldns=<path to ldns installation or build>]
-3. gmake
-
-Note that you need to set LD_LIBRARY_PATH if you want to run the binaries
-and you have not installed the library to a system directory. You can use
-the make target all-static for the examples to run them if you don't want to
-install the library.
-
-
-* Building from subversion repository
-
-If you are building from the repository you will need to have (gnu)
-autotools like libtool and autoreconf installed. A list of all the commands
-needed to build everything can be found in README.svn. Note that the actual
-commands may be a little bit different on your machine. Most notable, you'll need to run libtoolize (or glibtoolize), if you skip this step, you'll get an error about missing config.sub.
-
-* Developers
-ldns is developed by the ldns team at NLnet Labs. This team currently
-consists of:
-  o Willem Toorop
-  o Wouter Wijngaards
-  o Matthijs Mekking
-
-Former main developers:
-  o Jelte Jansen
-  o Miek Gieben
-
-* Credits
-We have received patches from the following people, thanks!
-  o Bedrich Kosata
-  o Erik Rozendaal
-  o Håkan Olsson
-  o Jakob Schlyter
-  o Paul Wouters
-  o Simon Vallet
-  o Ondřej Surý
-
-
-INFORMATION FOR SPECIFIC OPERATING SYSTEMS
-
-MAC OS X
-
-For MACOSX 10.4 and later, it seems that you have to set the
-MACOSX_DEPLOYMENT_TARGET environment variable to 10.4 before running
-make. Apparently it defaults to 10.1.
-
-This appears to be a known problem in 10.2 to 10.4, see:
-http://developer.apple.com/qa/qa2001/qa1233.html
-for more information.
-
-
-SOLARIS
-
-In Solaris multi-architecture systems (that have both 32-bit and
-64-bit support), it can be a bit taxing to convince the system to
-compile in 64-bit mode. Jakob Schlyter has kindly contributed a build
-script that sets the right build and link options. You can find it in
-contrib/build-solaris.sh
-
-KNOWN ISSUES
-
-A complete list of currently known open issues can be found here:
-http://www.nlnetlabs.nl/projects/ldns/bugs
-
-* pyldns
-Compiling pyldns produces many ``unused parameter'' warnings.  Those are
-harmless and may safely be ignored.
-Also when building with Swig which version is before 2.0.4, compiling
-pyldns produces many ``missing initializer'' warnings. Those are harmless
-too.
-
-Your Support
-NLnet Labs offers all of its software products as open source, most are
-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/.
-
index fc6c17e..e008831 100644 (file)
@@ -38,7 +38,7 @@ ldns_buffer_new(size_t capacity)
 }
 
 void
-ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size)
+ldns_buffer_new_frm_data(ldns_buffer *buffer, const void *data, size_t size)
 {
        assert(data != NULL);
 
@@ -165,7 +165,7 @@ ldns_bgetc(ldns_buffer *buffer)
 }
 
 void 
-ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from)
+ldns_buffer_copy(ldns_buffer* result, const ldns_buffer* from)
 {
        size_t tocopy = ldns_buffer_limit(from);
 
diff --git a/contrib/ldns/compat/b32_ntop.c b/contrib/ldns/compat/b32_ntop.c
deleted file mode 100644 (file)
index 038ebdc..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (c) 1996, 1998 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-/*
- * Portions Copyright (c) 1995 by International Business Machines, Inc.
- *
- * International Business Machines, Inc. (hereinafter called IBM) grants
- * permission under its copyrights to use, copy, modify, and distribute this
- * Software with or without fee, provided that the above copyright notice and
- * all paragraphs of this notice appear in all copies, and that the name of IBM
- * not be used in connection with the marketing of any product incorporating
- * the Software or modifications thereof, without specific, written prior
- * permission.
- *
- * To the extent it has a right to do so, IBM grants an immunity from suit
- * under its patents, if any, for the use, sale or manufacture of products to
- * the extent that such products are used for performing Domain Name System
- * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
- * granted for any product per se or for any other function of any product.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
- * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
- * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
- */
-#include <ldns/config.h>
-
-#include <sys/types.h>
-#include <sys/param.h>
-#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
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <assert.h>
-
-static const char Base32[] =
-       "abcdefghijklmnopqrstuvwxyz234567";
-/*     "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";*/
-/*       00000000001111111111222222222233
-         01234567890123456789012345678901*/
-static const char Base32_extended_hex[] =
-/*     "0123456789ABCDEFGHIJKLMNOPQRSTUV";*/
-       "0123456789abcdefghijklmnopqrstuv";
-static const char Pad32 = '=';
-
-/* (From RFC3548 and draft-josefsson-rfc3548bis-00.txt)
-5.  Base 32 Encoding
-
-   The Base 32 encoding is designed to represent arbitrary sequences of
-   octets in a form that needs to be case insensitive but need not be
-   humanly readable.
-
-   A 33-character subset of US-ASCII is used, enabling 5 bits to be
-   represented per printable character.  (The extra 33rd character, "=",
-   is used to signify a special processing function.)
-
-   The encoding process represents 40-bit groups of input bits as output
-   strings of 8 encoded characters.  Proceeding from left to right, a
-   40-bit input group is formed by concatenating 5 8bit input groups.
-   These 40 bits are then treated as 8 concatenated 5-bit groups, each
-   of which is translated into a single digit in the base 32 alphabet.
-   When encoding a bit stream via the base 32 encoding, the bit stream
-   must be presumed to be ordered with the most-significant-bit first.
-   That is, the first bit in the stream will be the high-order bit in
-   the first 8bit byte, and the eighth bit will be the low-order bit in
-   the first 8bit byte, and so on.
-
-   Each 5-bit group is used as an index into an array of 32 printable
-   characters.  The character referenced by the index is placed in the
-   output string.  These characters, identified in Table 3, below, are
-   selected from US-ASCII digits and uppercase letters.
-
-                      Table 3: The Base 32 Alphabet
-
-         Value Encoding  Value Encoding  Value Encoding  Value Encoding
-             0 A             9 J            18 S            27 3
-             1 B            10 K            19 T            28 4
-             2 C            11 L            20 U            29 5
-             3 D            12 M            21 V            30 6
-             4 E            13 N            22 W            31 7
-             5 F            14 O            23 X
-             6 G            15 P            24 Y         (pad) =
-             7 H            16 Q            25 Z
-             8 I            17 R            26 2
-
-
-   Special processing is performed if fewer than 40 bits are available
-   at the end of the data being encoded.  A full encoding quantum is
-   always completed at the end of a body.  When fewer than 40 input bits
-   are available in an input group, zero bits are added (on the right)
-   to form an integral number of 5-bit groups.  Padding at the end of
-   the data is performed using the "=" character.  Since all base 32
-   input is an integral number of octets, only the following cases can
-   arise:
-
-   (1) the final quantum of encoding input is an integral multiple of 40
-   bits; here, the final unit of encoded output will be an integral
-   multiple of 8 characters with no "=" padding,
-
-   (2) the final quantum of encoding input is exactly 8 bits; here, the
-   final unit of encoded output will be two characters followed by six
-   "=" padding characters,
-
-   (3) the final quantum of encoding input is exactly 16 bits; here, the
-   final unit of encoded output will be four characters followed by four
-   "=" padding characters,
-
-   (4) the final quantum of encoding input is exactly 24 bits; here, the
-   final unit of encoded output will be five characters followed by
-   three "=" padding characters, or
-
-   (5) the final quantum of encoding input is exactly 32 bits; here, the
-   final unit of encoded output will be seven characters followed by one
-   "=" padding character.
-
-
-6.  Base 32 Encoding with Extended Hex Alphabet
-
-   The following description of base 32 is due to [7].  This encoding
-   should not be regarded as the same as the "base32" encoding, and
-   should not be referred to as only "base32".
-
-   One property with this alphabet, that the base64 and base32 alphabet
-   lack, is that encoded data maintain its sort order when the encoded
-   data is compared bit-wise.
-
-   This encoding is identical to the previous one, except for the
-   alphabet.  The new alphabet is found in table 4.
-
-                     Table 4: The "Extended Hex" Base 32 Alphabet
-
-         Value Encoding  Value Encoding  Value Encoding  Value Encoding
-             0 0             9 9            18 I            27 R
-             1 1            10 A            19 J            28 S
-             2 2            11 B            20 K            29 T
-             3 3            12 C            21 L            30 U
-             4 4            13 D            22 M            31 V
-             5 5            14 E            23 N
-             6 6            15 F            24 O         (pad) =
-             7 7            16 G            25 P
-             8 8            17 H            26 Q
-
-*/
-
-
-int
-ldns_b32_ntop_ar(uint8_t const *src, size_t srclength, char *target, size_t targsize, const char B32_ar[]) {
-       size_t datalength = 0;
-       uint8_t input[5];
-       uint8_t output[8];
-       size_t i;
-        memset(output, 0, 8);
-
-       while (4 < srclength) {
-               input[0] = *src++;
-               input[1] = *src++;
-               input[2] = *src++;
-               input[3] = *src++;
-               input[4] = *src++;
-               srclength -= 5;
-
-               output[0] = (input[0] & 0xf8) >> 3;
-               output[1] = ((input[0] & 0x07) << 2) + ((input[1] & 0xc0) >> 6);
-               output[2] = (input[1] & 0x3e) >> 1;
-               output[3] = ((input[1] & 0x01) << 4) + ((input[2] & 0xf0) >> 4);
-               output[4] = ((input[2] & 0x0f) << 1) + ((input[3] & 0x80) >> 7);
-               output[5] = (input[3] & 0x7c) >> 2;
-               output[6] = ((input[3] & 0x03) << 3) + ((input[4] & 0xe0) >> 5);
-               output[7] = (input[4] & 0x1f);
-
-               assert(output[0] < 32);
-               assert(output[1] < 32);
-               assert(output[2] < 32);
-               assert(output[3] < 32);
-               assert(output[4] < 32);
-               assert(output[5] < 32);
-               assert(output[6] < 32);
-               assert(output[7] < 32);
-
-               if (datalength + 8 > targsize) {
-                       return (-1);
-               }
-               target[datalength++] = B32_ar[output[0]];
-               target[datalength++] = B32_ar[output[1]];
-               target[datalength++] = B32_ar[output[2]];
-               target[datalength++] = B32_ar[output[3]];
-               target[datalength++] = B32_ar[output[4]];
-               target[datalength++] = B32_ar[output[5]];
-               target[datalength++] = B32_ar[output[6]];
-               target[datalength++] = B32_ar[output[7]];
-       }
-    
-       /* Now we worry about padding. */
-       if (0 != srclength) {
-               /* Get what's left. */
-               input[0] = input[1] = input[2] = input[3] = input[4] = (uint8_t) '\0';
-               for (i = 0; i < srclength; i++)
-                       input[i] = *src++;
-       
-               output[0] = (input[0] & 0xf8) >> 3;
-               assert(output[0] < 32);
-               if (srclength >= 1) {
-                       output[1] = ((input[0] & 0x07) << 2) + ((input[1] & 0xc0) >> 6);
-                       assert(output[1] < 32);
-                       output[2] = (input[1] & 0x3e) >> 1;
-                       assert(output[2] < 32);
-               }
-               if (srclength >= 2) {
-                       output[3] = ((input[1] & 0x01) << 4) + ((input[2] & 0xf0) >> 4);
-                       assert(output[3] < 32);
-               }
-               if (srclength >= 3) {
-                       output[4] = ((input[2] & 0x0f) << 1) + ((input[3] & 0x80) >> 7);
-                       assert(output[4] < 32);
-                       output[5] = (input[3] & 0x7c) >> 2;
-                       assert(output[5] < 32);
-               }
-               if (srclength >= 4) {
-                       output[6] = ((input[3] & 0x03) << 3) + ((input[4] & 0xe0) >> 5);
-                       assert(output[6] < 32);
-               }
-
-
-               if (datalength + 1 > targsize) {
-                       return (-2);
-               }
-               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+1 > targsize) {
-               return (int) (datalength);
-       }
-       target[datalength] = '\0';      /* Returned value doesn't count \0. */
-       return (int) (datalength);
-}
-
-int
-ldns_b32_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
-       return ldns_b32_ntop_ar(src, srclength, target, targsize, Base32);
-}
-
-/* deprecated, here for backwards compatibility */
-int
-b32_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
-       return ldns_b32_ntop_ar(src, srclength, target, targsize, Base32);
-}
-
-int
-ldns_b32_ntop_extended_hex(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
-       return ldns_b32_ntop_ar(src, srclength, target, targsize, Base32_extended_hex);
-}
-
-/* deprecated, here for backwards compatibility */
-int
-b32_ntop_extended_hex(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
-       return ldns_b32_ntop_ar(src, srclength, target, targsize, Base32_extended_hex);
-}
-
diff --git a/contrib/ldns/compat/b32_pton.c b/contrib/ldns/compat/b32_pton.c
deleted file mode 100644 (file)
index 9c261e6..0000000
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright (c) 1996, 1998 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-/*
- * Portions Copyright (c) 1995 by International Business Machines, Inc.
- *
- * International Business Machines, Inc. (hereinafter called IBM) grants
- * permission under its copyrights to use, copy, modify, and distribute this
- * Software with or without fee, provided that the above copyright notice and
- * all paragraphs of this notice appear in all copies, and that the name of IBM
- * not be used in connection with the marketing of any product incorporating
- * the Software or modifications thereof, without specific, written prior
- * permission.
- *
- * To the extent it has a right to do so, IBM grants an immunity from suit
- * under its patents, if any, for the use, sale or manufacture of products to
- * the extent that such products are used for performing Domain Name System
- * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
- * granted for any product per se or for any other function of any product.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
- * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
- * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
- */
-#include <ldns/config.h>
-
-#include <sys/types.h>
-#include <sys/param.h>
-#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
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*     "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";*/
-static const char Base32[] =
-       "abcdefghijklmnopqrstuvwxyz234567";
-/*     "0123456789ABCDEFGHIJKLMNOPQRSTUV";*/
-static const char Base32_extended_hex[] =
-       "0123456789abcdefghijklmnopqrstuv";
-static const char Pad32 = '=';
-
-/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
-5.  Base 32 Encoding
-
-   The Base 32 encoding is designed to represent arbitrary sequences of
-   octets in a form that needs to be case insensitive but need not be
-   humanly readable.
-
-   A 33-character subset of US-ASCII is used, enabling 5 bits to be
-   represented per printable character.  (The extra 33rd character, "=",
-   is used to signify a special processing function.)
-
-   The encoding process represents 40-bit groups of input bits as output
-   strings of 8 encoded characters.  Proceeding from left to right, a
-   40-bit input group is formed by concatenating 5 8bit input groups.
-   These 40 bits are then treated as 8 concatenated 5-bit groups, each
-   of which is translated into a single digit in the base 32 alphabet.
-   When encoding a bit stream via the base 32 encoding, the bit stream
-   must be presumed to be ordered with the most-significant-bit first.
-   That is, the first bit in the stream will be the high-order bit in
-   the first 8bit byte, and the eighth bit will be the low-order bit in
-   the first 8bit byte, and so on.
-
-   Each 5-bit group is used as an index into an array of 32 printable
-   characters.  The character referenced by the index is placed in the
-   output string.  These characters, identified in Table 3, below, are
-   selected from US-ASCII digits and uppercase letters.
-
-                      Table 3: The Base 32 Alphabet
-
-         Value Encoding  Value Encoding  Value Encoding  Value Encoding
-             0 A             9 J            18 S            27 3
-             1 B            10 K            19 T            28 4
-             2 C            11 L            20 U            29 5
-             3 D            12 M            21 V            30 6
-             4 E            13 N            22 W            31 7
-             5 F            14 O            23 X
-             6 G            15 P            24 Y         (pad) =
-             7 H            16 Q            25 Z
-             8 I            17 R            26 2
-
-
-   Special processing is performed if fewer than 40 bits are available
-   at the end of the data being encoded.  A full encoding quantum is
-   always completed at the end of a body.  When fewer than 40 input bits
-   are available in an input group, zero bits are added (on the right)
-   to form an integral number of 5-bit groups.  Padding at the end of
-   the data is performed using the "=" character.  Since all base 32
-   input is an integral number of octets, only the following cases can
-   arise:
-
-   (1) the final quantum of encoding input is an integral multiple of 40
-   bits; here, the final unit of encoded output will be an integral
-   multiple of 8 characters with no "=" padding,
-
-   (2) the final quantum of encoding input is exactly 8 bits; here, the
-   final unit of encoded output will be two characters followed by six
-   "=" padding characters,
-
-   (3) the final quantum of encoding input is exactly 16 bits; here, the
-   final unit of encoded output will be four characters followed by four
-   "=" padding characters,
-
-   (4) the final quantum of encoding input is exactly 24 bits; here, the
-   final unit of encoded output will be five characters followed by
-   three "=" padding characters, or
-
-   (5) the final quantum of encoding input is exactly 32 bits; here, the
-   final unit of encoded output will be seven characters followed by one
-   "=" padding character.
-
-
-6.  Base 32 Encoding with Extended Hex Alphabet
-
-   The following description of base 32 is due to [7].  This encoding
-   should not be regarded as the same as the "base32" encoding, and
-   should not be referred to as only "base32".
-
-   One property with this alphabet, that the base32 and base32 alphabet
-   lack, is that encoded data maintain its sort order when the encoded
-   data is compared bit-wise.
-
-   This encoding is identical to the previous one, except for the
-   alphabet.  The new alphabet is found in table 4.
-
-                     Table 4: The "Extended Hex" Base 32 Alphabet
-
-         Value Encoding  Value Encoding  Value Encoding  Value Encoding
-             0 0             9 9            18 I            27 R
-             1 1            10 A            19 J            28 S
-             2 2            11 B            20 K            29 T
-             3 3            12 C            21 L            30 U
-             4 4            13 D            22 M            31 V
-             5 5            14 E            23 N
-             6 6            15 F            24 O         (pad) =
-             7 7            16 G            25 P
-             8 8            17 H            26 Q
-
-
-
-
-*/
-/* skips all whitespace anywhere.
-   converts characters, four at a time, starting at (or after)
-   src from base - 32 numbers into three 8 bit bytes in the target area.
-   it returns the number of data bytes stored at the target, or -1 on error.
- */
-
-int
-ldns_b32_pton_ar(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize, const char B32_ar[])
-{
-       int tarindex, state, ch;
-       char *pos;
-       int i = 0;
-
-       state = 0;
-       tarindex = 0;
-       
-       while ((ch = *src++) != '\0' && (i == 0 || i < (int) hashed_owner_str_len)) {
-               i++;
-               ch = tolower(ch);
-               if (isspace((unsigned char)ch))        /* Skip whitespace anywhere. */
-                       continue;
-
-               if (ch == Pad32)
-                       break;
-
-               pos = strchr(B32_ar, ch);
-               if (pos == 0) {
-                       /* A non-base32 character. */
-                       return (-ch);
-               }
-
-               switch (state) {
-               case 0:
-                       if (target) {
-                               if ((size_t)tarindex >= targsize) {
-                                       return (-2);
-                               }
-                               target[tarindex] = (pos - B32_ar) << 3;
-                       }
-                       state = 1;
-                       break;
-               case 1:
-                       if (target) {
-                               if ((size_t)tarindex + 1 >= targsize) {
-                                       return (-3);
-                               }
-                               target[tarindex]   |=  (pos - B32_ar) >> 2;
-                               target[tarindex+1]  = ((pos - B32_ar) & 0x03)
-                                                       << 6 ;
-                       }
-                       tarindex++;
-                       state = 2;
-                       break;
-               case 2:
-                       if (target) {
-                               if ((size_t)tarindex + 1 >= targsize) {
-                                       return (-4);
-                               }
-                               target[tarindex]   |=  (pos - B32_ar) << 1;
-                       }
-                       /*tarindex++;*/
-                       state = 3;
-                       break;
-               case 3:
-                       if (target) {
-                               if ((size_t)tarindex + 1 >= targsize) {
-                                       return (-5);
-                               }
-                               target[tarindex]   |=  (pos - B32_ar) >> 4;
-                               target[tarindex+1]  = ((pos - B32_ar) & 0x0f) << 4 ;
-                       }
-                       tarindex++;
-                       state = 4;
-                       break;
-               case 4:
-                       if (target) {
-                               if ((size_t)tarindex + 1 >= targsize) {
-                                       return (-6);
-                               }
-                               target[tarindex]   |=  (pos - B32_ar) >> 1;
-                               target[tarindex+1]  = ((pos - B32_ar) & 0x01)
-                                                       << 7 ;
-                       }
-                       tarindex++;
-                       state = 5;
-                       break;
-               case 5:
-                       if (target) {
-                               if ((size_t)tarindex + 1 >= targsize) {
-                                       return (-7);
-                               }
-                               target[tarindex]   |=  (pos - B32_ar) << 2;
-                       }
-                       state = 6;
-                       break;
-               case 6:
-                       if (target) {
-                               if ((size_t)tarindex + 1 >= targsize) {
-                                       return (-8);
-                               }
-                               target[tarindex]   |=  (pos - B32_ar) >> 3;
-                               target[tarindex+1]  = ((pos - B32_ar) & 0x07)
-                                                       << 5 ;
-                       }
-                       tarindex++;
-                       state = 7;
-                       break;
-               case 7:
-                       if (target) {
-                               if ((size_t)tarindex + 1 >= targsize) {
-                                       return (-9);
-                               }
-                               target[tarindex]   |=  (pos - B32_ar);
-                       }
-                       tarindex++;
-                       state = 0;
-                       break;
-               default:
-                       abort();
-               }
-       }
-
-       /*
-        * We are done decoding Base-32 chars.  Let's see if we ended
-        * on a byte boundary, and/or with erroneous trailing characters.
-        */
-
-       if (ch == Pad32) {              /* We got a pad char. */
-               ch = *src++;            /* Skip it, get next. */
-               switch (state) {
-               case 0:         /* Invalid = in first position */
-               case 1:         /* Invalid = in second position */
-                       return (-10);
-
-               case 2:         /* Valid, means one byte of info */
-               case 3:
-                       /* Skip any number of spaces. */
-                       for ((void)NULL; ch != '\0'; ch = *src++)
-                               if (!isspace((unsigned char)ch))
-                                       break;
-                       /* Make sure there is another trailing = sign. */
-                       if (ch != Pad32) {
-                               return (-11);
-                       }
-                       ch = *src++;            /* Skip the = */
-                       /* Fall through to "single trailing =" case. */
-                       /* FALLTHROUGH */
-
-               case 4:         /* Valid, means two bytes of info */
-               case 5:
-               case 6:
-                       /*
-                        * We know this char is an =.  Is there anything but
-                        * whitespace after it?
-                        */
-                       for ((void)NULL; ch != '\0'; ch = *src++)
-                               if (!(isspace((unsigned char)ch) || ch == '=')) {
-                                       return (-12);
-                               }
-
-               case 7:         /* Valid, means three bytes of info */
-                       /*
-                        * We know this char is an =.  Is there anything but
-                        * whitespace after it?
-                        */
-                       for ((void)NULL; ch != '\0'; ch = *src++)
-                               if (!isspace((unsigned char)ch)) {
-                                       return (-13);
-                               }
-
-                       /*
-                        * Now make sure for cases 2 and 3 that the "extra"
-                        * bits that slopped past the last full byte were
-                        * zeros.  If we don't check them, they become a
-                        * subliminal channel.
-                        */
-                       if (target && target[tarindex] != 0) {
-                               return (-14);
-                       }
-               }
-       } else {
-               /*
-                * We ended by seeing the end of the string.  Make sure we
-                * have no partial bytes lying around.
-                */
-               if (state != 0)
-                       return (-15);
-       }
-
-       return (tarindex);
-}
-
-int
-ldns_b32_pton(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize)
-{
-       return ldns_b32_pton_ar(src, hashed_owner_str_len, target, targsize, Base32);
-}
-
-/* deprecated, here for backwards compatibility */
-int
-b32_pton(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize)
-{
-       return ldns_b32_pton_ar(src, hashed_owner_str_len, target, targsize, Base32);
-}
-
-int
-ldns_b32_pton_extended_hex(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize)
-{
-       return ldns_b32_pton_ar(src, hashed_owner_str_len, target, targsize, Base32_extended_hex);
-}
-
-/* deprecated, here for backwards compatibility */
-int
-b32_pton_extended_hex(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize)
-{
-       return ldns_b32_pton_ar(src, hashed_owner_str_len, target, targsize, Base32_extended_hex);
-}
index d0b52b5..6895aca 100644 (file)
  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
  */
 #include <ldns/config.h>
-
-#include <sys/types.h>
-#include <sys/param.h>
-#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
-
 #include <ctype.h>
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#define Assert(Cond) if (!(Cond)) abort()
-
 static const char Base64[] =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 static const char Pad64 = '=';
@@ -154,10 +137,10 @@ ldns_b64_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsiz
                output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
                output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
                output[3] = input[2] & 0x3f;
-               Assert(output[0] < 64);
-               Assert(output[1] < 64);
-               Assert(output[2] < 64);
-               Assert(output[3] < 64);
+               assert(output[0] < 64);
+               assert(output[1] < 64);
+               assert(output[2] < 64);
+               assert(output[3] < 64);
 
                if (datalength + 4 > targsize) {
                        return (-1);
@@ -178,9 +161,9 @@ ldns_b64_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsiz
                output[0] = input[0] >> 2;
                output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
                output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
-               Assert(output[0] < 64);
-               Assert(output[1] < 64);
-               Assert(output[2] < 64);
+               assert(output[0] < 64);
+               assert(output[1] < 64);
+               assert(output[2] < 64);
 
                if (datalength + 4 > targsize) {
                        return (-2);
index aa637d2..18d8c8e 100644 (file)
  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
  */
 #include <ldns/config.h>
-
-#include <sys/types.h>
-#include <sys/param.h>
-#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
-
 #include <ctype.h>
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#define Assert(Cond) if (!(Cond)) abort()
-
 static const char Base64[] =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 static const char Pad64 = '=';
@@ -135,15 +118,16 @@ static const char Pad64 = '=';
  */
 
 int
-ldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
+ldns_b64_pton(char const *origsrc, uint8_t *target, size_t targsize)
 {
+       unsigned char const* src = (unsigned char*)origsrc;
        int tarindex, state, ch;
        char *pos;
 
        state = 0;
        tarindex = 0;
 
-       if (strlen(src) == 0) {
+       if (strlen(origsrc) == 0) {
                return 0;
        }
 
diff --git a/contrib/ldns/compat/calloc.c b/contrib/ldns/compat/calloc.c
deleted file mode 100644 (file)
index c86b956..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Just a replacement, if the original malloc is not
-   GNU-compliant. See autoconf documentation. */
-
-#if HAVE_CONFIG_H
-#include <ldns/config.h>
-#endif
-
-void *calloc();
-
-#if !HAVE_BZERO && HAVE_MEMSET
-# define bzero(buf, bytes)     ((void) memset (buf, 0, bytes))
-#endif
-
-void *
-calloc(size_t num, size_t size)
-{
-       void *new = malloc(num * size);
-       if (!new) {
-               return NULL;
-       }
-       bzero(new, num * size);
-       return new;
-}
-
diff --git a/contrib/ldns/compat/ctime_r.c b/contrib/ldns/compat/ctime_r.c
deleted file mode 100644 (file)
index 4ffd8b7..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include <ldns/config.h>
-#endif
-
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-
-char *ctime_r(const time_t *timep, char *buf)
-{
-       /* no thread safety. */
-       char* result = ctime(timep);
-       if(buf && result)
-               strcpy(buf, result);
-       return result;
-}
diff --git a/contrib/ldns/compat/fake-rfc2553.c b/contrib/ldns/compat/fake-rfc2553.c
deleted file mode 100644 (file)
index 431e04a..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-/* From openssh 4.3p2 filename openbsd-compat/fake-rfc2553.h */
-/*
- * Copyright (C) 2000-2003 Damien Miller.  All rights reserved.
- * Copyright (C) 1999 WIDE Project.  All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the project 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 PROJECT 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 PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Pseudo-implementation of RFC2553 name / address resolution functions
- *
- * But these functions are not implemented correctly. The minimum subset
- * is implemented for ssh use only. For example, this routine assumes
- * that ai_family is AF_INET. Don't use it for another purpose.
- */
-
-#include <ldns/config.h>
-#include <ldns/common.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "compat/fake-rfc2553.h"
-
-#ifndef HAVE_GETNAMEINFO
-int getnameinfo(const struct sockaddr *sa, size_t ATTR_UNUSED(salen), char *host, 
-                size_t hostlen, char *serv, size_t servlen, int flags)
-{
-       struct sockaddr_in *sin = (struct sockaddr_in *)sa;
-       struct hostent *hp;
-       char tmpserv[16];
-
-       if (serv != NULL) {
-               snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port));
-               if (strlcpy(serv, tmpserv, servlen) >= servlen)
-                       return (EAI_MEMORY);
-       }
-
-       if (host != NULL) {
-               if (flags & NI_NUMERICHOST) {
-                       if (strlcpy(host, inet_ntoa(sin->sin_addr),
-                           hostlen) >= hostlen)
-                               return (EAI_MEMORY);
-                       else
-                               return (0);
-               } else {
-                       hp = gethostbyaddr((char *)&sin->sin_addr, 
-                           sizeof(struct in_addr), AF_INET);
-                       if (hp == NULL)
-                               return (EAI_NODATA);
-                       
-                       if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
-                               return (EAI_MEMORY);
-                       else
-                               return (0);
-               }
-       }
-       return (0);
-}
-#endif /* !HAVE_GETNAMEINFO */
-
-#ifndef HAVE_GAI_STRERROR
-#ifdef HAVE_CONST_GAI_STRERROR_PROTO
-const char *
-#else
-char *
-#endif
-gai_strerror(int err)
-{
-       switch (err) {
-       case EAI_NODATA:
-               return ("no address associated with name");
-       case EAI_MEMORY:
-               return ("memory allocation failure.");
-       case EAI_NONAME:
-               return ("nodename nor servname provided, or not known");
-       default:
-               return ("unknown/invalid error.");
-       }
-}    
-#endif /* !HAVE_GAI_STRERROR */
-
-#ifndef HAVE_FREEADDRINFO
-void
-freeaddrinfo(struct addrinfo *ai)
-{
-       struct addrinfo *next;
-
-       for(; ai != NULL;) {
-               next = ai->ai_next;
-               free(ai);
-               ai = next;
-       }
-}
-#endif /* !HAVE_FREEADDRINFO */
-
-#ifndef HAVE_GETADDRINFO
-static struct
-addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints)
-{
-       struct addrinfo *ai;
-
-       ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in));
-       if (ai == NULL)
-               return (NULL);
-       
-       memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in));
-       
-       ai->ai_addr = (struct sockaddr *)(ai + 1);
-       /* XXX -- ssh doesn't use sa_len */
-       ai->ai_addrlen = sizeof(struct sockaddr_in);
-       ai->ai_addr->sa_family = ai->ai_family = AF_INET;
-
-       ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
-       ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
-       
-       /* XXX: the following is not generally correct, but does what we want */
-       if (hints->ai_socktype)
-               ai->ai_socktype = hints->ai_socktype;
-       else
-               ai->ai_socktype = SOCK_STREAM;
-
-       if (hints->ai_protocol)
-               ai->ai_protocol = hints->ai_protocol;
-
-       return (ai);
-}
-
-int
-getaddrinfo(const char *hostname, const char *servname, 
-    const struct addrinfo *hints, struct addrinfo **res)
-{
-       struct hostent *hp;
-       struct servent *sp;
-       struct in_addr in;
-       int i;
-       long int port;
-       u_long addr;
-
-       port = 0;
-       if (servname != NULL) {
-               char *cp;
-
-               port = strtol(servname, &cp, 10);
-               if (port > 0 && port <= 65535 && *cp == '\0')
-                       port = htons(port);
-               else if ((sp = getservbyname(servname, NULL)) != NULL)
-                       port = sp->s_port;
-               else
-                       port = 0;
-       }
-
-       if (hints && hints->ai_flags & AI_PASSIVE) {
-               addr = htonl(0x00000000);
-               if (hostname && inet_aton(hostname, &in) != 0)
-                       addr = in.s_addr;
-               *res = malloc_ai(port, addr, hints);
-               if (*res == NULL) 
-                       return (EAI_MEMORY);
-               return (0);
-       }
-               
-       if (!hostname) {
-               *res = malloc_ai(port, htonl(0x7f000001), hints);
-               if (*res == NULL) 
-                       return (EAI_MEMORY);
-               return (0);
-       }
-       
-       if (inet_aton(hostname, &in)) {
-               *res = malloc_ai(port, in.s_addr, hints);
-               if (*res == NULL) 
-                       return (EAI_MEMORY);
-               return (0);
-       }
-       
-       /* Don't try DNS if AI_NUMERICHOST is set */
-       if (hints && hints->ai_flags & AI_NUMERICHOST)
-               return (EAI_NONAME);
-       
-       hp = gethostbyname(hostname);
-       if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
-               struct addrinfo *cur, *prev;
-
-               cur = prev = *res = NULL;
-               for (i = 0; hp->h_addr_list[i]; i++) {
-                       struct in_addr *in = (struct in_addr *)hp->h_addr_list[i];
-
-                       cur = malloc_ai(port, in->s_addr, hints);
-                       if (cur == NULL) {
-                               if (*res != NULL)
-                                       freeaddrinfo(*res);
-                               return (EAI_MEMORY);
-                       }
-                       if (prev)
-                               prev->ai_next = cur;
-                       else
-                               *res = cur;
-
-                       prev = cur;
-               }
-               return (0);
-       }
-       
-       return (EAI_NODATA);
-}
-#endif /* !HAVE_GETADDRINFO */
diff --git a/contrib/ldns/compat/fake-rfc2553.h b/contrib/ldns/compat/fake-rfc2553.h
deleted file mode 100644 (file)
index 4c277ee..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/* From openssh 4.3p2 filename openbsd-compat/fake-rfc2553.h */
-/*
- * Copyright (C) 2000-2003 Damien Miller.  All rights reserved.
- * Copyright (C) 1999 WIDE Project.  All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the project 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 PROJECT 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 PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Pseudo-implementation of RFC2553 name / address resolution functions
- *
- * But these functions are not implemented correctly. The minimum subset
- * is implemented for ssh use only. For example, this routine assumes
- * that ai_family is AF_INET. Don't use it for another purpose.
- */
-
-#ifndef _FAKE_RFC2553_H
-#define _FAKE_RFC2553_H
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <limits.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * First, socket and INET6 related definitions 
- */
-#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
-#ifndef _SS_MAXSIZE
-# define       _SS_MAXSIZE     128     /* Implementation specific max size */
-# define       _SS_PADSIZE     (_SS_MAXSIZE - sizeof (struct sockaddr))
-struct sockaddr_storage {
-       struct sockaddr ss_sa;
-       char            __ss_pad2[_SS_PADSIZE];
-};
-# define ss_family ss_sa.sa_family
-#endif /* _SS_MAXSIZE */
-#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */
-
-#ifndef IN6_IS_ADDR_LOOPBACK
-# define IN6_IS_ADDR_LOOPBACK(a) \
-       (((uint32_t *)(a))[0] == 0 && ((uint32_t *)(a))[1] == 0 && \
-        ((uint32_t *)(a))[2] == 0 && ((uint32_t *)(a))[3] == htonl(1))
-#endif /* !IN6_IS_ADDR_LOOPBACK */
-
-#ifndef HAVE_STRUCT_IN6_ADDR
-struct in6_addr {
-       uint8_t s6_addr[16];
-};
-#endif /* !HAVE_STRUCT_IN6_ADDR */
-
-#ifndef HAVE_STRUCT_SOCKADDR_IN6
-struct sockaddr_in6 {
-       unsigned short  sin6_family;
-       uint16_t        sin6_port;
-       uint32_t        sin6_flowinfo;
-       struct in6_addr sin6_addr;
-};
-#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */
-
-#ifndef AF_INET6
-/* Define it to something that should never appear */
-#define AF_INET6 AF_MAX
-#endif
-
-/*
- * Next, RFC2553 name / address resolution API
- */
-
-#ifndef NI_NUMERICHOST
-# define NI_NUMERICHOST    (1)
-#endif
-#ifndef NI_NAMEREQD
-# define NI_NAMEREQD       (1<<1)
-#endif
-#ifndef NI_NUMERICSERV
-# define NI_NUMERICSERV    (1<<2)
-#endif
-
-#ifndef AI_PASSIVE
-# define AI_PASSIVE            (1)
-#endif
-#ifndef AI_CANONNAME
-# define AI_CANONNAME          (1<<1)
-#endif
-#ifndef AI_NUMERICHOST
-# define AI_NUMERICHOST                (1<<2)
-#endif
-
-#ifndef NI_MAXSERV
-# define NI_MAXSERV 32
-#endif /* !NI_MAXSERV */
-#ifndef NI_MAXHOST
-# define NI_MAXHOST 1025
-#endif /* !NI_MAXHOST */
-
-#ifndef INT_MAX
-#define INT_MAX                0xffffffff
-#endif
-
-#ifndef EAI_NODATA
-# define EAI_NODATA    (INT_MAX - 1)
-#endif
-#ifndef EAI_MEMORY
-# define EAI_MEMORY    (INT_MAX - 2)
-#endif
-#ifndef EAI_NONAME
-# define EAI_NONAME    (INT_MAX - 3)
-#endif
-#ifndef EAI_SYSTEM
-# define EAI_SYSTEM    (INT_MAX - 4)
-#endif
-
-#ifndef HAVE_STRUCT_ADDRINFO
-struct addrinfo {
-       int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME */
-       int     ai_family;      /* PF_xxx */
-       int     ai_socktype;    /* SOCK_xxx */
-       int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
-       size_t  ai_addrlen;     /* length of ai_addr */
-       char    *ai_canonname;  /* canonical name for hostname */
-       struct sockaddr *ai_addr;       /* binary address */
-       struct addrinfo *ai_next;       /* next structure in linked list */
-};
-#endif /* !HAVE_STRUCT_ADDRINFO */
-
-#ifndef HAVE_GETADDRINFO
-#ifdef getaddrinfo
-# undef getaddrinfo
-#endif
-#define getaddrinfo(a,b,c,d)   (ssh_getaddrinfo(a,b,c,d))
-int getaddrinfo(const char *, const char *, 
-    const struct addrinfo *, struct addrinfo **);
-#endif /* !HAVE_GETADDRINFO */
-
-#if !defined(HAVE_GAI_STRERROR) && !defined(HAVE_CONST_GAI_STRERROR_PROTO)
-#define gai_strerror(a)                (ssh_gai_strerror(a))
-char *gai_strerror(int);
-#endif /* !HAVE_GAI_STRERROR */
-
-#ifndef HAVE_FREEADDRINFO
-#define freeaddrinfo(a)                (ssh_freeaddrinfo(a))
-void freeaddrinfo(struct addrinfo *);
-#endif /* !HAVE_FREEADDRINFO */
-
-#ifndef HAVE_GETNAMEINFO
-#define getnameinfo(a,b,c,d,e,f,g) (ssh_getnameinfo(a,b,c,d,e,f,g))
-int getnameinfo(const struct sockaddr *, size_t, char *, size_t, 
-    char *, size_t, int);
-#endif /* !HAVE_GETNAMEINFO */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !_FAKE_RFC2553_H */
-
diff --git a/contrib/ldns/compat/gmtime_r.c b/contrib/ldns/compat/gmtime_r.c
deleted file mode 100644 (file)
index 7062e7d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include <ldns/config.h>
-#endif
-
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-
-struct tm *gmtime_r(const time_t *timep, struct tm *result)
-{
-       /* no thread safety. */
-       *result = *gmtime(timep);
-       return result;
-}
diff --git a/contrib/ldns/compat/inet_aton.c b/contrib/ldns/compat/inet_aton.c
deleted file mode 100644 (file)
index e8c3a57..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/* From openssh4.3p2 compat/inet_aton.c */
-/*
- * Copyright (c) 1983, 1990, 1993
- *    The Regents of the University of California.  All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University 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 REGENTS 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 PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- * 
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-/* OPENBSD ORIGINAL: lib/libc/net/inet_addr.c */
-
-#include <ldns/config.h>
-
-#if !defined(HAVE_INET_ATON)
-
-#include <sys/types.h>
-#include <sys/param.h>
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#include <ctype.h>
-
-#if 0
-/*
- * Ascii internet address interpretation routine.
- * The value returned is in network order.
- */
-in_addr_t
-inet_addr(const char *cp)
-{
-       struct in_addr val;
-
-       if (inet_aton(cp, &val))
-               return (val.s_addr);
-       return (INADDR_NONE);
-}
-#endif
-
-/* 
- * Check whether "cp" is a valid ascii representation
- * of an Internet address and convert to a binary address.
- * Returns 1 if the address is valid, 0 if not.
- * This replaces inet_addr, the return value from which
- * cannot distinguish between failure and a local broadcast address.
- */
-int
-inet_aton(const char *cp, struct in_addr *addr)
-{
-       uint32_t val;
-       int base, n;
-       char c;
-       unsigned int parts[4];
-       unsigned int *pp = parts;
-
-       c = *cp;
-       for (;;) {
-               /*
-                * Collect number up to ``.''.
-                * Values are specified as for C:
-                * 0x=hex, 0=octal, isdigit=decimal.
-                */
-               if (!isdigit((int) c))
-                       return (0);
-               val = 0; base = 10;
-               if (c == '0') {
-                       c = *++cp;
-                       if (c == 'x' || c == 'X')
-                               base = 16, c = *++cp;
-                       else
-                               base = 8;
-               }
-               for (;;) {
-                       if (isascii((int) c) && isdigit((int) c)) {
-                               val = (val * base) + (c - '0');
-                               c = *++cp;
-                       } else if (base == 16 && isascii((int) c) && isxdigit((int) c)) {
-                               val = (val << 4) |
-                                       (c + 10 - (islower((int) c) ? 'a' : 'A'));
-                               c = *++cp;
-                       } else
-                               break;
-               }
-               if (c == '.') {
-                       /*
-                        * Internet format:
-                        *      a.b.c.d
-                        *      a.b.c   (with c treated as 16 bits)
-                        *      a.b     (with b treated as 24 bits)
-                        */
-                       if (pp >= parts + 3)
-                               return (0);
-                       *pp++ = val;
-                       c = *++cp;
-               } else
-                       break;
-       }
-       /*
-        * Check for trailing characters.
-        */
-       if (c != '\0' && (!isascii((int) c) || !isspace((int) c)))
-               return (0);
-       /*
-        * Concoct the address according to
-        * the number of parts specified.
-        */
-       n = pp - parts + 1;
-       switch (n) {
-
-       case 0:
-               return (0);             /* initial nondigit */
-
-       case 1:                         /* a -- 32 bits */
-               break;
-
-       case 2:                         /* a.b -- 8.24 bits */
-               if ((val > 0xffffff) || (parts[0] > 0xff))
-                       return (0);
-               val |= parts[0] << 24;
-               break;
-
-       case 3:                         /* a.b.c -- 8.8.16 bits */
-               if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
-                       return (0);
-               val |= (parts[0] << 24) | (parts[1] << 16);
-               break;
-
-       case 4:                         /* a.b.c.d -- 8.8.8.8 bits */
-               if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
-                       return (0);
-               val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
-               break;
-       }
-       if (addr)
-               addr->s_addr = htonl(val);
-       return (1);
-}
-
-#endif /* !defined(HAVE_INET_ATON) */
diff --git a/contrib/ldns/compat/inet_ntop.c b/contrib/ldns/compat/inet_ntop.c
deleted file mode 100644 (file)
index 52197d0..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-/* From openssh 4.3p2 compat/inet_ntop.c */
-/* Copyright (c) 1996 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-/* OPENBSD ORIGINAL: lib/libc/net/inet_ntop.c */
-
-#include <ldns/config.h>
-
-#ifndef HAVE_INET_NTOP
-
-#include <sys/param.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-
-#ifndef IN6ADDRSZ
-#define IN6ADDRSZ   16   /* IPv6 T_AAAA */                 
-#endif
-
-#ifndef INT16SZ
-#define INT16SZ     2    /* for systems without 16-bit ints */
-#endif
-
-/*
- * WARNING: Don't even consider trying to compile this on a system where
- * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
- */
-
-static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
-static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
-
-/* char *
- * inet_ntop(af, src, dst, size)
- *     convert a network format address to presentation format.
- * return:
- *     pointer to presentation format address (`dst'), or NULL (see errno).
- * author:
- *     Paul Vixie, 1996.
- */
-const char *
-inet_ntop(int af, const void *src, char *dst, size_t size)
-{
-       switch (af) {
-       case AF_INET:
-               return (inet_ntop4(src, dst, size));
-       case AF_INET6:
-               return (inet_ntop6(src, dst, size));
-       default:
-#ifdef EAFNOSUPPORT
-               errno = EAFNOSUPPORT;
-#else
-               errno = ENOSYS;
-#endif
-               return (NULL);
-       }
-       /* NOTREACHED */
-}
-
-/* const char *
- * inet_ntop4(src, dst, size)
- *     format an IPv4 address, more or less like inet_ntoa()
- * return:
- *     `dst' (as a const)
- * notes:
- *     (1) uses no statics
- *     (2) takes a u_char* not an in_addr as input
- * author:
- *     Paul Vixie, 1996.
- */
-static const char *
-inet_ntop4(const u_char *src, char *dst, size_t size)
-{
-       static const char fmt[] = "%u.%u.%u.%u";
-       char tmp[sizeof "255.255.255.255"];
-       int l;
-
-       l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]);
-       if (l <= 0 || l >= (int)size) {
-               errno = ENOSPC;
-               return (NULL);
-       }
-       strlcpy(dst, tmp, size);
-       return (dst);
-}
-
-/* const char *
- * inet_ntop6(src, dst, size)
- *     convert IPv6 binary address into presentation (printable) format
- * author:
- *     Paul Vixie, 1996.
- */
-static const char *
-inet_ntop6(const u_char *src, char *dst, size_t size)
-{
-       /*
-        * Note that int32_t and int16_t need only be "at least" large enough
-        * to contain a value of the specified size.  On some systems, like
-        * Crays, there is no such thing as an integer variable with 16 bits.
-        * Keep this in mind if you think this function should have been coded
-        * to use pointer overlays.  All the world's not a VAX.
-        */
-       char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
-       char *tp, *ep;
-       struct { int base, len; } best, cur;
-       u_int words[IN6ADDRSZ / INT16SZ];
-       int i;
-       int advance;
-
-       /*
-        * Preprocess:
-        *      Copy the input (bytewise) array into a wordwise array.
-        *      Find the longest run of 0x00's in src[] for :: shorthanding.
-        */
-       memset(words, '\0', sizeof words);
-       for (i = 0; i < IN6ADDRSZ; i++)
-               words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
-       best.base = -1;
-       best.len = 0;
-       cur.base = -1;
-       cur.len = 0;
-       for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
-               if (words[i] == 0) {
-                       if (cur.base == -1)
-                               cur.base = i, cur.len = 1;
-                       else
-                               cur.len++;
-               } else {
-                       if (cur.base != -1) {
-                               if (best.base == -1 || cur.len > best.len)
-                                       best = cur;
-                               cur.base = -1;
-                       }
-               }
-       }
-       if (cur.base != -1) {
-               if (best.base == -1 || cur.len > best.len)
-                       best = cur;
-       }
-       if (best.base != -1 && best.len < 2)
-               best.base = -1;
-
-       /*
-        * Format the result.
-        */
-       tp = tmp;
-       ep = tmp + sizeof(tmp);
-       for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) {
-               /* Are we inside the best run of 0x00's? */
-               if (best.base != -1 && i >= best.base &&
-                   i < (best.base + best.len)) {
-                       if (i == best.base) {
-                               if (tp + 1 >= ep)
-                                       return (NULL);
-                               *tp++ = ':';
-                       }
-                       continue;
-               }
-               /* Are we following an initial run of 0x00s or any real hex? */
-               if (i != 0) {
-                       if (tp + 1 >= ep)
-                               return (NULL);
-                       *tp++ = ':';
-               }
-               /* Is this address an encapsulated IPv4? */
-               if (i == 6 && best.base == 0 &&
-                   (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
-                       if (!inet_ntop4(src+12, tp, (size_t)(ep - tp)))
-                               return (NULL);
-                       tp += strlen(tp);
-                       break;
-               }
-               advance = snprintf(tp, ep - tp, "%x", words[i]);
-               if (advance <= 0 || advance >= ep - tp)
-                       return (NULL);
-               tp += advance;
-       }
-       /* Was it a trailing run of 0x00's? */
-       if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) {
-               if (tp + 1 >= ep)
-                       return (NULL);
-               *tp++ = ':';
-       }
-       if (tp + 1 >= ep)
-               return (NULL);
-       *tp++ = '\0';
-
-       /*
-        * Check for overflow, copy, and we're done.
-        */
-       if ((size_t)(tp - tmp) > size) {
-               errno = ENOSPC;
-               return (NULL);
-       }
-       strlcpy(dst, tmp, size);
-       return (dst);
-}
-
-#endif /* !HAVE_INET_NTOP */
diff --git a/contrib/ldns/compat/inet_pton.c b/contrib/ldns/compat/inet_pton.c
deleted file mode 100644 (file)
index 7a4f576..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/*     $KAME: inet_pton.c,v 1.5 2001/08/20 02:32:40 itojun Exp $       */
-
-/* Copyright (c) 1996 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#include <ldns/config.h>
-
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-
-/*
- * WARNING: Don't even consider trying to compile this on a system where
- * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
- */
-
-static int     inet_pton4 (const char *src, uint8_t *dst);
-static int     inet_pton6 (const char *src, uint8_t *dst);
-
-/*
- *
- * The definitions we might miss.
- *
- */
-#ifndef NS_INT16SZ
-#define        NS_INT16SZ      2
-#endif
-
-#ifndef NS_IN6ADDRSZ
-#define NS_IN6ADDRSZ 16
-#endif
-
-#ifndef NS_INADDRSZ
-#define NS_INADDRSZ 4
-#endif
-
-/* int
- * inet_pton(af, src, dst)
- *     convert from presentation format (which usually means ASCII printable)
- *     to network format (which is usually some kind of binary format).
- * return:
- *     1 if the address was valid for the specified address family
- *     0 if the address wasn't valid (`dst' is untouched in this case)
- *     -1 if some other error occurred (`dst' is untouched in this case, too)
- * author:
- *     Paul Vixie, 1996.
- */
-int
-inet_pton(af, src, dst)
-       int af;
-       const char *src;
-       void *dst;
-{
-       switch (af) {
-       case AF_INET:
-               return (inet_pton4(src, dst));
-       case AF_INET6:
-               return (inet_pton6(src, dst));
-       default:
-#ifdef EAFNOSUPPORT
-               errno = EAFNOSUPPORT;
-#else
-               errno = ENOSYS;
-#endif
-               return (-1);
-       }
-       /* NOTREACHED */
-}
-
-/* int
- * inet_pton4(src, dst)
- *     like inet_aton() but without all the hexadecimal and shorthand.
- * return:
- *     1 if `src' is a valid dotted quad, else 0.
- * notice:
- *     does not touch `dst' unless it's returning 1.
- * author:
- *     Paul Vixie, 1996.
- */
-static int
-inet_pton4(src, dst)
-       const char *src;
-       uint8_t *dst;
-{
-       static const char digits[] = "0123456789";
-       int saw_digit, octets, ch;
-       uint8_t tmp[NS_INADDRSZ], *tp;
-
-       saw_digit = 0;
-       octets = 0;
-       *(tp = tmp) = 0;
-       while ((ch = *src++) != '\0') {
-               const char *pch;
-
-               if ((pch = strchr(digits, ch)) != NULL) {
-                       uint32_t new = *tp * 10 + (pch - digits);
-
-                       if (new > 255)
-                               return (0);
-                       *tp = new;
-                       if (! saw_digit) {
-                               if (++octets > 4)
-                                       return (0);
-                               saw_digit = 1;
-                       }
-               } else if (ch == '.' && saw_digit) {
-                       if (octets == 4)
-                               return (0);
-                       *++tp = 0;
-                       saw_digit = 0;
-               } else
-                       return (0);
-       }
-       if (octets < 4)
-               return (0);
-
-       memcpy(dst, tmp, NS_INADDRSZ);
-       return (1);
-}
-
-/* int
- * inet_pton6(src, dst)
- *     convert presentation level address to network order binary form.
- * return:
- *     1 if `src' is a valid [RFC1884 2.2] address, else 0.
- * notice:
- *     (1) does not touch `dst' unless it's returning 1.
- *     (2) :: in a full address is silently ignored.
- * credit:
- *     inspired by Mark Andrews.
- * author:
- *     Paul Vixie, 1996.
- */
-static int
-inet_pton6(src, dst)
-       const char *src;
-       uint8_t *dst;
-{
-       static const char xdigits_l[] = "0123456789abcdef",
-                         xdigits_u[] = "0123456789ABCDEF";
-       uint8_t tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
-       const char *xdigits, *curtok;
-       int ch, saw_xdigit;
-       uint32_t val;
-
-       memset((tp = tmp), '\0', NS_IN6ADDRSZ);
-       endp = tp + NS_IN6ADDRSZ;
-       colonp = NULL;
-       /* Leading :: requires some special handling. */
-       if (*src == ':')
-               if (*++src != ':')
-                       return (0);
-       curtok = src;
-       saw_xdigit = 0;
-       val = 0;
-       while ((ch = *src++) != '\0') {
-               const char *pch;
-
-               if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
-                       pch = strchr((xdigits = xdigits_u), ch);
-               if (pch != NULL) {
-                       val <<= 4;
-                       val |= (pch - xdigits);
-                       if (val > 0xffff)
-                               return (0);
-                       saw_xdigit = 1;
-                       continue;
-               }
-               if (ch == ':') {
-                       curtok = src;
-                       if (!saw_xdigit) {
-                               if (colonp)
-                                       return (0);
-                               colonp = tp;
-                               continue;
-                       }
-                       if (tp + NS_INT16SZ > endp)
-                               return (0);
-                       *tp++ = (uint8_t) (val >> 8) & 0xff;
-                       *tp++ = (uint8_t) val & 0xff;
-                       saw_xdigit = 0;
-                       val = 0;
-                       continue;
-               }
-               if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
-                   inet_pton4(curtok, tp) > 0) {
-                       tp += NS_INADDRSZ;
-                       saw_xdigit = 0;
-                       break;  /* '\0' was seen by inet_pton4(). */
-               }
-               return (0);
-       }
-       if (saw_xdigit) {
-               if (tp + NS_INT16SZ > endp)
-                       return (0);
-               *tp++ = (uint8_t) (val >> 8) & 0xff;
-               *tp++ = (uint8_t) val & 0xff;
-       }
-       if (colonp != NULL) {
-               /*
-                * Since some memmove()'s erroneously fail to handle
-                * overlapping regions, we'll do the shift by hand.
-                */
-               const int n = tp - colonp;
-               int i;
-
-               for (i = 1; i <= n; i++) {
-                       endp[- i] = colonp[n - i];
-                       colonp[n - i] = 0;
-               }
-               tp = endp;
-       }
-       if (tp != endp)
-               return (0);
-       memcpy(dst, tmp, NS_IN6ADDRSZ);
-       return (1);
-}
diff --git a/contrib/ldns/compat/isascii.c b/contrib/ldns/compat/isascii.c
deleted file mode 100644 (file)
index 8a4ab37..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* Just a replacement, if the original isascii is not
-   present */
-
-#if HAVE_CONFIG_H
-#include <ldns/config.h>
-#endif
-
-int isascii(int c);
-
-/* true if character is ascii. */
-int
-isascii(int c)
-{
-       return c >= 0 && c < 128;
-}
diff --git a/contrib/ldns/compat/isblank.c b/contrib/ldns/compat/isblank.c
deleted file mode 100644 (file)
index 3b38154..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* Just a replacement, if the original isblank is not
-   present */
-
-#if HAVE_CONFIG_H
-#include <ldns/config.h>
-#endif
-
-int isblank(int c);
-
-/* true if character is a blank (space or tab). C99. */
-int
-isblank(int c)
-{
-       return (c == ' ') || (c == '\t');
-}
diff --git a/contrib/ldns/compat/localtime_r.c b/contrib/ldns/compat/localtime_r.c
deleted file mode 100644 (file)
index 017c6e4..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include <ldns/config.h>
-#endif
-
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-
-struct tm *localtime_r(const time_t *timep, struct tm *result)
-{
-       /* no thread safety. */
-       *result = *localtime(timep);
-       return result;
-}
diff --git a/contrib/ldns/compat/malloc.c b/contrib/ldns/compat/malloc.c
deleted file mode 100644 (file)
index bbc632e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Just a replacement, if the original malloc is not
-   GNU-compliant. See autoconf documentation. */
-
-#if HAVE_CONFIG_H
-#include <ldns/config.h>
-#endif
-#undef malloc
-
-#include <sys/types.h>
-
-void *malloc ();
-
-/* Allocate an N-byte block of memory from the heap.
-   If N is zero, allocate a 1-byte block.  */
-
-void *
-rpl_malloc (size_t n)
-{
-  if (n == 0)
-    n = 1;
-  return malloc (n);
-}
diff --git a/contrib/ldns/compat/memmove.c b/contrib/ldns/compat/memmove.c
deleted file mode 100644 (file)
index e458092..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *     memmove.c: memmove compat implementation.
- *
- *     Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
- *
- * See LICENSE for the license.
-*/
-
-#include <ldns/config.h>
-#include <stdlib.h>
-
-void *memmove(void *dest, const void *src, size_t n);
-
-void *memmove(void *dest, const void *src, size_t n)
-{
-       uint8_t* from = (uint8_t*) src;
-       uint8_t* to = (uint8_t*) dest;
-
-       if (from == to || n == 0)
-               return dest;
-       if (to > from && to-from < (int)n) {
-               /* to overlaps with from */
-               /*  <from......>         */
-               /*         <to........>  */
-               /* copy in reverse, to avoid overwriting from */
-               int i;
-               for(i=n-1; i>=0; i--)
-                       to[i] = from[i];
-               return dest;
-       }
-       if (from > to  && from-to < (int)n) {
-               /* to overlaps with from */
-               /*        <from......>   */
-               /*  <to........>         */
-               /* copy forwards, to avoid overwriting from */
-               size_t i;
-               for(i=0; i<n; i++)
-                       to[i] = from[i];
-               return dest;
-       }
-       memcpy(dest, src, n);
-       return dest;
-}
diff --git a/contrib/ldns/compat/realloc.c b/contrib/ldns/compat/realloc.c
deleted file mode 100644 (file)
index bdaf76d..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Just a replacement, if the original malloc is not
-   GNU-compliant. Based on malloc.c */
-
-#if HAVE_CONFIG_H
-#include <ldns/config.h>
-#endif
-#undef realloc
-
-#include <sys/types.h>
-
-void *realloc (void*, size_t);
-void *malloc (size_t);
-
-/* Changes allocation to new sizes, copies over old data.
- * if oldptr is NULL, does a malloc.
- * if size is zero, allocate 1-byte block....
- *   (does not return NULL and free block)
- */
-
-void *
-rpl_realloc (void* ptr, size_t n)
-{
-  if (n == 0)
-    n = 1;
-  if(ptr == 0) {
-    return malloc(n);
-  }
-  return realloc(ptr, n);
-}
-
diff --git a/contrib/ldns/compat/snprintf.c b/contrib/ldns/compat/snprintf.c
deleted file mode 100644 (file)
index b744511..0000000
+++ /dev/null
@@ -1,770 +0,0 @@
-#include <ldns/config.h>
-
-#ifndef HAVE_SNPRINTF
-
-#include <ctype.h>
-#include <sys/types.h>
-
-/* Define this as a fall through, HAVE_STDARG_H is probably already set */
-
-#define HAVE_VARARGS_H
-
-/**************************************************************
- * Original:
- * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
- * A bombproof version of doprnt (dopr) included.
- * Sigh.  This sort of thing is always nasty do deal with.  Note that
- * the version here does not include floating point...
- *
- * snprintf() is used instead of sprintf() as it does limit checks
- * for string length.  This covers a nasty loophole.
- *
- * The other functions are there to prevent NULL pointers from
- * causing nast effects.
- *
- * More Recently:
- *  Brandon Long (blong@fiction.net) 9/15/96 for mutt 0.43
- *  This was ugly.  It is still ugly.  I opted out of floating point
- *  numbers, but the formatter understands just about everything
- *  from the normal C string format, at least as far as I can tell from
- *  the Solaris 2.5 printf(3S) man page.
- *
- *  Brandon Long (blong@fiction.net) 10/22/97 for mutt 0.87.1
- *    Ok, added some minimal floating point support, which means this
- *    probably requires libm on most operating systems.  Don't yet
- *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
- *    was pretty badly broken, it just wasn't being exercised in ways
- *    which showed it, so that's been fixed.  Also, formated the code
- *    to mutt conventions, and removed dead code left over from the
- *    original.  Also, there is now a builtin-test, just compile with:
- *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
- *    and run snprintf for results.
- *
- **************************************************************/
-
-
-/* varargs declarations: */
-
-#if defined(HAVE_STDARG_H)
-# include <stdarg.h>
-# define HAVE_STDARGS    /* let's hope that works everywhere (mj) */
-# define VA_LOCAL_DECL   va_list ap
-# define VA_START(f)     va_start(ap, f)
-# define VA_SHIFT(v,t)  ;   /* no-op for ANSI */
-# define VA_END          va_end(ap)
-#else
-# if defined(HAVE_VARARGS_H)
-#  include <varargs.h>
-#  undef HAVE_STDARGS
-#  define VA_LOCAL_DECL   va_list ap
-#  define VA_START(f)     va_start(ap)      /* f is ignored! */
-#  define VA_SHIFT(v,t) v = va_arg(ap,t)
-#  define VA_END        va_end(ap)
-# else
-/*XX ** NO VARARGS ** XX*/
-# endif
-#endif
-
-int snprintf (char *str, size_t count, const char *fmt, ...);
-int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
-
-static void dopr (char *buffer, size_t maxlen, const char *format, 
-                  va_list args);
-static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
-                   char *value, int flags, int min, int max);
-static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
-                   long value, int base, int min, int max, int flags);
-static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
-                  long double fvalue, int min, int max, int flags);
-static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
-
-int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
-{
-  str[0] = 0;
-  dopr(str, count, fmt, args);
-  return(strlen(str));
-}
-
-/* VARARGS3 */
-#ifdef HAVE_STDARGS
-int snprintf (char *str,size_t count,const char *fmt,...)
-#else
-int snprintf (va_alist) va_dcl
-#endif
-{
-#ifndef HAVE_STDARGS
-  char *str;
-  size_t count;
-  char *fmt;
-#endif
-  VA_LOCAL_DECL;
-    
-  VA_START (fmt);
-  VA_SHIFT (str, char *);
-  VA_SHIFT (count, size_t );
-  VA_SHIFT (fmt, char *);
-  (void) vsnprintf(str, count, fmt, ap);
-  VA_END;
-  return(strlen(str));
-}
-
-/*
- * dopr(): poor man's version of doprintf
- */
-
-/* format read states */
-#define DP_S_DEFAULT 0
-#define DP_S_FLAGS   1
-#define DP_S_MIN     2
-#define DP_S_DOT     3
-#define DP_S_MAX     4
-#define DP_S_MOD     5
-#define DP_S_CONV    6
-#define DP_S_DONE    7
-
-/* format flags - Bits */
-#define DP_F_MINUS 1
-#define DP_F_PLUS  2
-#define DP_F_SPACE 4
-#define DP_F_NUM   8
-#define DP_F_ZERO  16
-#define DP_F_UP    32
-
-/* Conversion Flags */
-#define DP_C_SHORT   1
-#define DP_C_LONG    2
-#define DP_C_LDOUBLE 3
-
-#define char_to_int(p) (p - '0')
-#define MAX(p,q) ((p >= q) ? p : q)
-
-static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
-{
-  char ch;
-  long value;
-  long double fvalue;
-  char *strvalue;
-  int min;
-  int max;
-  int state;
-  int flags;
-  int cflags;
-  size_t currlen;
-  
-  state = DP_S_DEFAULT;
-  currlen = flags = cflags = min = 0;
-  max = -1;
-  ch = *format++;
-
-  while (state != DP_S_DONE)
-  {
-    if ((ch == '\0') || (currlen >= maxlen)) 
-      state = DP_S_DONE;
-
-    switch(state) 
-    {
-    case DP_S_DEFAULT:
-      if (ch == '%') 
-       state = DP_S_FLAGS;
-      else 
-       dopr_outch (buffer, &currlen, maxlen, ch);
-      ch = *format++;
-      break;
-    case DP_S_FLAGS:
-      switch (ch) 
-      {
-      case '-':
-       flags |= DP_F_MINUS;
-        ch = *format++;
-       break;
-      case '+':
-       flags |= DP_F_PLUS;
-        ch = *format++;
-       break;
-      case ' ':
-       flags |= DP_F_SPACE;
-        ch = *format++;
-       break;
-      case '#':
-       flags |= DP_F_NUM;
-        ch = *format++;
-       break;
-      case '0':
-       flags |= DP_F_ZERO;
-        ch = *format++;
-       break;
-      default:
-       state = DP_S_MIN;
-       break;
-      }
-      break;
-    case DP_S_MIN:
-      if (isdigit((int) ch)) 
-      {
-       min = 10*min + char_to_int (ch);
-       ch = *format++;
-      } 
-      else if (ch == '*') 
-      {
-       min = va_arg (args, int);
-       ch = *format++;
-       state = DP_S_DOT;
-      } 
-      else 
-       state = DP_S_DOT;
-      break;
-    case DP_S_DOT:
-      if (ch == '.') 
-      {
-       state = DP_S_MAX;
-       ch = *format++;
-      } 
-      else 
-       state = DP_S_MOD;
-      break;
-    case DP_S_MAX:
-      if (isdigit((int) ch)) 
-      {
-       if (max < 0)
-         max = 0;
-       max = 10*max + char_to_int (ch);
-       ch = *format++;
-      } 
-      else if (ch == '*') 
-      {
-       max = va_arg (args, int);
-       ch = *format++;
-       state = DP_S_MOD;
-      } 
-      else 
-       state = DP_S_MOD;
-      break;
-    case DP_S_MOD:
-      /* Currently, we don't support Long Long, bummer */
-      switch (ch) 
-      {
-      case 'h':
-       cflags = DP_C_SHORT;
-       ch = *format++;
-       break;
-      case 'l':
-       cflags = DP_C_LONG;
-       ch = *format++;
-       break;
-      case 'L':
-       cflags = DP_C_LDOUBLE;
-       ch = *format++;
-       break;
-      default:
-       break;
-      }
-      state = DP_S_CONV;
-      break;
-    case DP_S_CONV:
-      switch (ch) 
-      {
-      case 'd':
-      case 'i':
-       if (cflags == DP_C_SHORT) 
-         value = va_arg (args, int);
-       else if (cflags == DP_C_LONG)
-         value = va_arg (args, long int);
-       else
-         value = va_arg (args, int);
-       fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
-       break;
-      case 'o':
-       flags &= ~DP_F_PLUS;
-       if (cflags == DP_C_SHORT)
-         value = va_arg (args, unsigned int);
-       else if (cflags == DP_C_LONG)
-         value = va_arg (args, unsigned long int);
-       else
-         value = va_arg (args, unsigned int);
-       fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
-       break;
-      case 'u':
-       flags &= ~DP_F_PLUS;
-       if (cflags == DP_C_SHORT)
-         value = va_arg (args, unsigned int);
-       else if (cflags == DP_C_LONG)
-         value = va_arg (args, unsigned long int);
-       else
-         value = va_arg (args, unsigned int);
-       fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
-       break;
-      case 'X':
-       flags |= DP_F_UP;
-      case 'x':
-       flags &= ~DP_F_PLUS;
-       if (cflags == DP_C_SHORT)
-         value = va_arg (args, unsigned int);
-       else if (cflags == DP_C_LONG)
-         value = va_arg (args, unsigned long int);
-       else
-         value = va_arg (args, unsigned int);
-       fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
-       break;
-      case 'f':
-       if (cflags == DP_C_LDOUBLE)
-         fvalue = va_arg (args, long double);
-       else
-         fvalue = va_arg (args, double);
-       /* um, floating point? */
-       fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
-       break;
-      case 'E':
-       flags |= DP_F_UP;
-      case 'e':
-       if (cflags == DP_C_LDOUBLE)
-         fvalue = va_arg (args, long double);
-       else
-         fvalue = va_arg (args, double);
-       break;
-      case 'G':
-       flags |= DP_F_UP;
-      case 'g':
-       if (cflags == DP_C_LDOUBLE)
-         fvalue = va_arg (args, long double);
-       else
-         fvalue = va_arg (args, double);
-       break;
-      case 'c':
-       dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
-       break;
-      case 's':
-       strvalue = va_arg (args, char *);
-       if (max < 0) 
-         max = maxlen; /* ie, no max */
-       fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
-       break;
-      case 'p':
-       strvalue = va_arg (args, void *);
-       fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
-       break;
-      case 'n':
-       if (cflags == DP_C_SHORT) 
-       {
-         short int *num;
-         num = va_arg (args, short int *);
-         *num = currlen;
-        } 
-       else if (cflags == DP_C_LONG) 
-       {
-         long int *num;
-         num = va_arg (args, long int *);
-         *num = currlen;
-        } 
-       else 
-       {
-         int *num;
-         num = va_arg (args, int *);
-         *num = currlen;
-        }
-       break;
-      case '%':
-       dopr_outch (buffer, &currlen, maxlen, ch);
-       break;
-      case 'w':
-       /* not supported yet, treat as next char */
-       ch = *format++;
-       break;
-      default:
-       /* Unknown, skip */
-       break;
-      }
-      ch = *format++;
-      state = DP_S_DEFAULT;
-      flags = cflags = min = 0;
-      max = -1;
-      break;
-    case DP_S_DONE:
-      break;
-    default:
-      /* hmm? */
-      break; /* some picky compilers need this */
-    }
-  }
-  if (currlen < maxlen - 1) 
-    buffer[currlen] = '\0';
-  else 
-    buffer[maxlen - 1] = '\0';
-}
-
-static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
-                   char *value, int flags, int min, int max)
-{
-  int padlen, strln;     /* amount to pad */
-  int cnt = 0;
-  
-  if (value == 0)
-  {
-    value = (char *) "<NULL>";
-  }
-
-  for (strln = 0; value[strln]; ++strln); /* strlen */
-  padlen = min - strln;
-  if (padlen < 0) 
-    padlen = 0;
-  if (flags & DP_F_MINUS) 
-    padlen = -padlen; /* Left Justify */
-
-  while ((padlen > 0) && (cnt < max)) 
-  {
-    dopr_outch (buffer, currlen, maxlen, ' ');
-    --padlen;
-    ++cnt;
-  }
-  while (*value && (cnt < max)) 
-  {
-    dopr_outch (buffer, currlen, maxlen, *value++);
-    ++cnt;
-  }
-  while ((padlen < 0) && (cnt < max)) 
-  {
-    dopr_outch (buffer, currlen, maxlen, ' ');
-    ++padlen;
-    ++cnt;
-  }
-}
-
-/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
-
-static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
-                   long value, int base, int min, int max, int flags)
-{
-  int signvalue = 0;
-  unsigned long uvalue;
-  char convert[20];
-  int place = 0;
-  int spadlen = 0; /* amount to space pad */
-  int zpadlen = 0; /* amount to zero pad */
-  int caps = 0;
-  
-  if (max < 0)
-    max = 0;
-
-  uvalue = value;
-  if( value < 0 ) {
-    signvalue = '-';
-    uvalue = -value;
-  }
-  else
-    if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
-      signvalue = '+';
-    else
-      if (flags & DP_F_SPACE)
-       signvalue = ' ';
-
-  if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
-
-  do {
-    convert[place++] =
-      (caps? "0123456789ABCDEF":"0123456789abcdef")
-      [uvalue % (unsigned)base  ];
-    uvalue = (uvalue / (unsigned)base );
-  } while(uvalue && (place < 20));
-  if (place == 20) place--;
-  convert[place] = 0;
-
-  zpadlen = max - place;
-  spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); 
-  if (zpadlen < 0) zpadlen = 0;
-  if (spadlen < 0) spadlen = 0;
-  if (flags & DP_F_ZERO)
-  {
-    zpadlen = MAX(zpadlen, spadlen);
-    spadlen = 0;
-  }
-  if (flags & DP_F_MINUS) 
-    spadlen = -spadlen; /* Left Justifty */
-
-#ifdef DEBUG_SNPRINTF
-  dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
-      zpadlen, spadlen, min, max, place));
-#endif
-
-  /* Spaces */
-  while (spadlen > 0) 
-  {
-    dopr_outch (buffer, currlen, maxlen, ' ');
-    --spadlen;
-  }
-
-  /* Sign */
-  if (signvalue) 
-    dopr_outch (buffer, currlen, maxlen, signvalue);
-
-  /* Zeros */
-  if (zpadlen > 0) 
-  {
-    while (zpadlen > 0)
-    {
-      dopr_outch (buffer, currlen, maxlen, '0');
-      --zpadlen;
-    }
-  }
-
-  /* Digits */
-  while (place > 0) 
-    dopr_outch (buffer, currlen, maxlen, convert[--place]);
-  
-  /* Left Justified spaces */
-  while (spadlen < 0) {
-    dopr_outch (buffer, currlen, maxlen, ' ');
-    ++spadlen;
-  }
-}
-
-static long double abs_val (long double value)
-{
-  long double result = value;
-
-  if (value < 0)
-    result = -value;
-
-  return result;
-}
-
-static double pow10 (double exp)
-{
-  long double result = 1;
-
-  while (exp)
-  {
-    result *= 10;
-    exp--;
-  }
-  
-  return result;
-}
-
-static double round (double value)
-{
-  long intpart;
-
-  intpart = value;
-  value = value - intpart;
-  if (value >= 0.5)
-    intpart++;
-
-  return intpart;
-}
-
-static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
-                  long double fvalue, int min, int max, int flags)
-{
-  int signvalue = 0;
-  long double ufvalue;
-  char iconvert[20];
-  char fconvert[20];
-  int iplace = 0;
-  int fplace = 0;
-  int padlen = 0; /* amount to pad */
-  int zpadlen = 0; 
-  int caps = 0;
-  long intpart;
-  long fracpart;
-  
-  /* 
-   * AIX manpage says the default is 0, but Solaris says the default
-   * is 6, and sprintf on AIX defaults to 6
-   */
-  if (max < 0)
-    max = 6;
-
-  ufvalue = abs_val (fvalue);
-
-  if (fvalue < 0)
-    signvalue = '-';
-  else
-    if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
-      signvalue = '+';
-    else
-      if (flags & DP_F_SPACE)
-       signvalue = ' ';
-
-#if 0
-  if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
-#endif
-
-  intpart = ufvalue;
-
-  /* 
-   * Sorry, we only support 9 digits past the decimal because of our 
-   * conversion method
-   */
-  if (max > 9)
-    max = 9;
-
-  /* We "cheat" by converting the fractional part to integer by
-   * multiplying by a factor of 10
-   */
-  fracpart = round ((pow10 (max)) * (ufvalue - intpart));
-
-  if (fracpart >= pow10 (max))
-  {
-    intpart++;
-    fracpart -= pow10 (max);
-  }
-
-#ifdef DEBUG_SNPRINTF
-  dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart));
-#endif
-
-  /* Convert integer part */
-  do {
-    iconvert[iplace++] =
-      (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
-    intpart = (intpart / 10);
-  } while(intpart && (iplace < 20));
-  if (iplace == 20) iplace--;
-  iconvert[iplace] = 0;
-
-  /* Convert fractional part */
-  do {
-    fconvert[fplace++] =
-      (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
-    fracpart = (fracpart / 10);
-  } while(fracpart && (fplace < 20));
-  if (fplace == 20) fplace--;
-  fconvert[fplace] = 0;
-
-  /* -1 for decimal point, another -1 if we are printing a sign */
-  padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 
-  zpadlen = max - fplace;
-  if (zpadlen < 0)
-    zpadlen = 0;
-  if (padlen < 0) 
-    padlen = 0;
-  if (flags & DP_F_MINUS) 
-    padlen = -padlen; /* Left Justifty */
-
-  if ((flags & DP_F_ZERO) && (padlen > 0)) 
-  {
-    if (signvalue) 
-    {
-      dopr_outch (buffer, currlen, maxlen, signvalue);
-      --padlen;
-      signvalue = 0;
-    }
-    while (padlen > 0)
-    {
-      dopr_outch (buffer, currlen, maxlen, '0');
-      --padlen;
-    }
-  }
-  while (padlen > 0)
-  {
-    dopr_outch (buffer, currlen, maxlen, ' ');
-    --padlen;
-  }
-  if (signvalue) 
-    dopr_outch (buffer, currlen, maxlen, signvalue);
-
-  while (iplace > 0) 
-    dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
-
-  /*
-   * Decimal point.  This should probably use locale to find the correct
-   * char to print out.
-   */
-  dopr_outch (buffer, currlen, maxlen, '.');
-
-  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, ' ');
-    ++padlen;
-  }
-}
-
-static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
-{
-  if (*currlen < maxlen)
-    buffer[(*currlen)++] = c;
-}
-
-#ifdef TEST_SNPRINTF
-#ifndef LONG_STRING
-#define LONG_STRING 1024
-#endif
-int main (void)
-{
-  char buf1[LONG_STRING];
-  char buf2[LONG_STRING];
-  char *fp_fmt[] = {
-    "%-1.5f",
-    "%1.5f",
-    "%123.9f",
-    "%10.5f",
-    "% 10.5f",
-    "%+22.9f",
-    "%+4.9f",
-    "%01.3f",
-    "%4f",
-    "%3.1f",
-    "%3.2f",
-    NULL
-  };
-  double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 
-    0.9996, 1.996, 4.136, 0};
-  char *int_fmt[] = {
-    "%-1.5d",
-    "%1.5d",
-    "%123.9d",
-    "%5.5d",
-    "%10.5d",
-    "% 10.5d",
-    "%+22.33d",
-    "%01.3d",
-    "%4d",
-    NULL
-  };
-  long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
-  int x, y;
-  int fail = 0;
-  int num = 0;
-
-  printf ("Testing snprintf format codes against system sprintf...\n");
-
-  for (x = 0; fp_fmt[x] != NULL ; x++)
-    for (y = 0; fp_nums[y] != 0 ; y++)
-    {
-      snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]);
-      sprintf (buf2, fp_fmt[x], fp_nums[y]);
-      if (strcmp (buf1, buf2))
-      {
-       printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf  = %s\n", 
-           fp_fmt[x], buf1, buf2);
-       fail++;
-      }
-      num++;
-    }
-
-  for (x = 0; int_fmt[x] != NULL ; x++)
-    for (y = 0; int_nums[y] != 0 ; y++)
-    {
-      snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]);
-      sprintf (buf2, int_fmt[x], int_nums[y]);
-      if (strcmp (buf1, buf2))
-      {
-       printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf  = %s\n", 
-           int_fmt[x], buf1, buf2);
-       fail++;
-      }
-      num++;
-    }
-  printf ("%d tests failed out of %d.\n", fail, num);
-}
-#endif /* SNPRINTF_TEST */
-
-#endif /* !HAVE_SNPRINTF */
diff --git a/contrib/ldns/compat/strlcpy.c b/contrib/ldns/compat/strlcpy.c
deleted file mode 100644 (file)
index d6c34c1..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* from openssh 4.3p2 compat/strlcpy.c */
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */
-
-#include <ldns/config.h>
-#ifndef HAVE_STRLCPY
-
-#include <sys/types.h>
-#include <string.h>
-
-/*
- * Copy src to string dst of size siz.  At most siz-1 characters
- * will be copied.  Always NUL terminates (unless siz == 0).
- * Returns strlen(src); if retval >= siz, truncation occurred.
- */
-size_t
-strlcpy(char *dst, const char *src, size_t siz)
-{
-       char *d = dst;
-       const char *s = src;
-       size_t n = siz;
-
-       /* Copy as many bytes as will fit */
-       if (n != 0 && --n != 0) {
-               do {
-                       if ((*d++ = *s++) == 0)
-                               break;
-               } while (--n != 0);
-       }
-
-       /* Not enough room in dst, add NUL and traverse rest of src */
-       if (n == 0) {
-               if (siz != 0)
-                       *d = '\0';              /* NUL-terminate dst */
-               while (*s++)
-                       ;
-       }
-
-       return(s - src - 1);    /* count does not include NUL */
-}
-
-#endif /* !HAVE_STRLCPY */
diff --git a/contrib/ldns/compat/timegm.c b/contrib/ldns/compat/timegm.c
deleted file mode 100644 (file)
index 97e1e54..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include <ldns/config.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include <time.h>
-
-time_t
-timegm (struct tm *tm) {
-       time_t ret;
-       char *tz;
-       
-       tz = getenv("TZ");
-       putenv((char*)"TZ=");
-       tzset();
-       ret = mktime(tm);
-       if (tz) {
-               char buf[256];
-               snprintf(buf, sizeof(buf), "TZ=%s", tz);
-               putenv(tz);
-       }
-       else
-               putenv((char*)"TZ");
-       tzset();
-       return ret;
-}
index 793005d..30dc1f7 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <ldns/config.h>
+#ifdef USE_DANE
 
 #include <ldns/ldns.h>
 #include <ldns/dane.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
+#ifdef HAVE_NETDB_H
 #include <netdb.h>
+#endif
 
 #ifdef HAVE_SSL
 #include <openssl/ssl.h>
@@ -119,13 +124,13 @@ ldns_dane_cert2rdf(ldns_rdf** rdf, X509* cert,
        
        case LDNS_TLSA_MATCHING_TYPE_SHA256:
 
-               digest = LDNS_XMALLOC(unsigned char, SHA256_DIGEST_LENGTH);
+               digest = LDNS_XMALLOC(unsigned char, LDNS_SHA256_DIGEST_LENGTH);
                if (digest == NULL) {
                        LDNS_FREE(buf);
                        return LDNS_STATUS_MEM_ERR;
                }
                (void) ldns_sha256(buf, (unsigned int)len, digest);
-               *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, SHA256_DIGEST_LENGTH,
+               *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, LDNS_SHA256_DIGEST_LENGTH,
                                digest);
                LDNS_FREE(buf);
 
@@ -134,13 +139,13 @@ ldns_dane_cert2rdf(ldns_rdf** rdf, X509* cert,
 
        case LDNS_TLSA_MATCHING_TYPE_SHA512:
 
-               digest = LDNS_XMALLOC(unsigned char, SHA512_DIGEST_LENGTH);
+               digest = LDNS_XMALLOC(unsigned char, LDNS_SHA512_DIGEST_LENGTH);
                if (digest == NULL) {
                        LDNS_FREE(buf);
                        return LDNS_STATUS_MEM_ERR;
                }
                (void) ldns_sha512(buf, (unsigned int)len, digest);
-               *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, SHA512_DIGEST_LENGTH,
+               *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, LDNS_SHA512_DIGEST_LENGTH,
                                digest);
                LDNS_FREE(buf);
 
@@ -322,8 +327,8 @@ ldns_dane_pkix_get_last_self_signed(X509** out_cert,
 
        }
        (void) X509_verify_cert(vrfy_ctx);
-       if (vrfy_ctx->error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ||
-           vrfy_ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT){
+       if (X509_STORE_CTX_get_error(vrfy_ctx) == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ||
+           X509_STORE_CTX_get_error(vrfy_ctx) == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT){
 
                *out_cert = X509_STORE_CTX_get_current_cert( vrfy_ctx);
                s = LDNS_STATUS_OK;
@@ -351,7 +356,7 @@ ldns_dane_select_certificate(X509** selected_cert,
        assert(selected_cert != NULL);
        assert(cert != NULL);
 
-       /* With PKIX validation explicitely turned off (pkix_validation_store
+       /* With PKIX validation explicitly turned off (pkix_validation_store
         *  == NULL), treat the "CA constraint" and "Service certificate
         * constraint" the same as "Trust anchor assertion" and "Domain issued
         * certificate" respectively.
@@ -499,6 +504,7 @@ memerror:
 }
 
 
+#ifdef USE_DANE_VERIFY
 /* Return tlsas that actually are TLSA resource records with known values
  * for the Certificate usage, Selector and Matching type rdata fields.
  */
@@ -530,6 +536,7 @@ ldns_dane_filter_unusable_records(const ldns_rr_list* tlsas)
 }
 
 
+#if !defined(USE_DANE_TA_USAGE)
 /* Return whether cert/selector/matching_type matches data.
  */
 static ldns_status
@@ -586,34 +593,108 @@ ldns_dane_match_any_cert_with_data(STACK_OF(X509)* chain,
        }
        return s;
 }
+#endif /* !defined(USE_DANE_TA_USAGE) */
+#endif /* USE_DANE_VERIFY */
 
-
+#ifdef USE_DANE_VERIFY
 ldns_status
 ldns_dane_verify_rr(const ldns_rr* tlsa_rr,
                X509* cert, STACK_OF(X509)* extra_certs,
                X509_STORE* pkix_validation_store)
 {
-       ldns_status s;
-
+#if defined(USE_DANE_TA_USAGE)
+       SSL_CTX *ssl_ctx = NULL;
+       SSL *ssl = NULL;
+       X509_STORE_CTX *store_ctx = NULL;
+#else
        STACK_OF(X509)* pkix_validation_chain = NULL;
+#endif
+       ldns_status s = LDNS_STATUS_OK;
 
-       ldns_tlsa_certificate_usage cert_usage;
+       ldns_tlsa_certificate_usage usage;
        ldns_tlsa_selector          selector;
-       ldns_tlsa_matching_type     matching_type;
+       ldns_tlsa_matching_type     mtype;
        ldns_rdf*                   data;
 
-       if (! tlsa_rr) {
-               /* No TLSA, so regular PKIX validation
+       if (! tlsa_rr || ldns_rr_get_type(tlsa_rr) != LDNS_RR_TYPE_TLSA ||
+                       ldns_rr_rd_count(tlsa_rr) != 4 ||
+                       ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0)) > 3 ||
+                       ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1)) > 1 ||
+                       ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2)) > 2 ) {
+               /* No (usable) TLSA, so regular PKIX validation
                 */
                return ldns_dane_pkix_validate(cert, extra_certs,
                                pkix_validation_store);
        }
-       cert_usage    = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0));
-       selector      = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1));
-       matching_type = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2));
-       data          =                      ldns_rr_rdf(tlsa_rr, 3) ;
+       usage    = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0));
+       selector = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1));
+       mtype    = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2));
+       data     =                      ldns_rr_rdf(tlsa_rr, 3) ;
+
+#if defined(USE_DANE_TA_USAGE)
+       /* Rely on OpenSSL dane functions.
+        *
+        * OpenSSL does not provide offline dane verification.  The dane unit
+        * tests within openssl use the undocumented SSL_get0_dane() and 
+        * X509_STORE_CTX_set0_dane() to convey dane parameters set on SSL and
+        * SSL_CTX to a X509_STORE_CTX that can be used to do offline
+        * verification.  We use these undocumented means with the ldns
+        * dane function prototypes which did only offline dane verification.
+        */
+       if (!(ssl_ctx = SSL_CTX_new(TLS_client_method())))
+               s = LDNS_STATUS_MEM_ERR;
 
-       switch (cert_usage) {
+       else if (SSL_CTX_dane_enable(ssl_ctx) <= 0)
+               s = LDNS_STATUS_SSL_ERR;
+
+       else if (SSL_CTX_dane_set_flags(
+                               ssl_ctx, DANE_FLAG_NO_DANE_EE_NAMECHECKS),
+                       !(ssl = SSL_new(ssl_ctx)))
+               s = LDNS_STATUS_MEM_ERR;
+
+       else if (SSL_set_connect_state(ssl),
+                       (SSL_dane_enable(ssl, NULL) <= 0))
+               s = LDNS_STATUS_SSL_ERR;
+
+       else if (SSL_dane_tlsa_add(ssl, usage, selector, mtype,
+                               ldns_rdf_data(data), ldns_rdf_size(data)) <= 0)
+               s = LDNS_STATUS_SSL_ERR;
+
+       else if (!(store_ctx =  X509_STORE_CTX_new()))
+               s = LDNS_STATUS_MEM_ERR;
+
+       else if (!X509_STORE_CTX_init(store_ctx, pkix_validation_store, cert, extra_certs))
+               s = LDNS_STATUS_SSL_ERR;
+
+       else {
+               int ret;
+
+               X509_STORE_CTX_set_default(store_ctx,
+                               SSL_is_server(ssl) ? "ssl_client" : "ssl_server");
+               X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(store_ctx),
+                               SSL_get0_param(ssl));
+               X509_STORE_CTX_set0_dane(store_ctx, SSL_get0_dane(ssl));
+               if (SSL_get_verify_callback(ssl))
+                       X509_STORE_CTX_set_verify_cb(store_ctx, SSL_get_verify_callback(ssl));
+
+               ret = X509_verify_cert(store_ctx);
+               if (!ret) {
+                       if (X509_STORE_CTX_get_error(store_ctx) == X509_V_ERR_DANE_NO_MATCH)
+                               s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH;
+                       else
+                               s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
+               }
+               X509_STORE_CTX_cleanup(store_ctx);
+       }
+       if (store_ctx)
+               X509_STORE_CTX_free(store_ctx);
+       if (ssl)
+               SSL_free(ssl);
+       if (ssl_ctx)
+               SSL_CTX_free(ssl_ctx);
+       return s;
+#else
+       switch (usage) {
        case LDNS_TLSA_USAGE_CA_CONSTRAINT:
                s = ldns_dane_pkix_validate_and_get_chain(
                                &pkix_validation_chain, 
@@ -633,7 +714,7 @@ ldns_dane_verify_rr(const ldns_rr* tlsa_rr,
                         */
                        s = ldns_dane_match_any_cert_with_data(
                                        pkix_validation_chain,
-                                       selector, matching_type, data, true);
+                                       selector, mtype, data, true);
 
                        if (s == LDNS_STATUS_OK) {
                                /* A TLSA record did match a cert from the
@@ -648,15 +729,16 @@ ldns_dane_verify_rr(const ldns_rr* tlsa_rr,
 
                        s = ldns_dane_match_any_cert_with_data(
                                        pkix_validation_chain,
-                                       selector, matching_type, data, true);
+                                       selector, mtype, data, true);
                }
                sk_X509_pop_free(pkix_validation_chain, X509_free);
                return s;
                break;
 
        case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
+
                s = ldns_dane_match_cert_with_data(cert,
-                               selector, matching_type, data);
+                               selector, mtype, data);
 
                if (s == LDNS_STATUS_OK) {
                        return ldns_dane_pkix_validate(cert, extra_certs,
@@ -666,77 +748,194 @@ ldns_dane_verify_rr(const ldns_rr* tlsa_rr,
                break;
 
        case LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION:
+#if 0
                s = ldns_dane_pkix_get_chain(&pkix_validation_chain,
                                cert, extra_certs);
 
                if (s == LDNS_STATUS_OK) {
                        s = ldns_dane_match_any_cert_with_data(
                                        pkix_validation_chain,
-                                       selector, matching_type, data, false);
+                                       selector, mtype, data, false);
 
                } else if (! pkix_validation_chain) {
                        return s;
                }
                sk_X509_pop_free(pkix_validation_chain, X509_free);
                return s;
+#else
+               return LDNS_STATUS_DANE_NEED_OPENSSL_GE_1_1_FOR_DANE_TA;
+#endif
                break;
 
        case LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE:
                return ldns_dane_match_cert_with_data(cert,
-                               selector, matching_type, data);
+                               selector, mtype, data);
                break;
 
        default:
                break;
        }
+#endif
        return LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE;
 }
 
 
 ldns_status
-ldns_dane_verify(ldns_rr_list* tlsas,
+ldns_dane_verify(const ldns_rr_list* tlsas,
                X509* cert, STACK_OF(X509)* extra_certs,
                X509_STORE* pkix_validation_store)
 {
+#if defined(USE_DANE_TA_USAGE)
+       SSL_CTX *ssl_ctx = NULL;
+       ldns_rdf *basename_rdf = NULL;
+       char *basename = NULL;
+       SSL *ssl = NULL;
+       X509_STORE_CTX *store_ctx = NULL;
+#else
+       ldns_status ps;
+#endif
        size_t i;
        ldns_rr* tlsa_rr;
-       ldns_status s = LDNS_STATUS_OK, ps;
+       ldns_rr_list *usable_tlsas;
+       ldns_status s = LDNS_STATUS_OK;
 
        assert(cert != NULL);
 
-       if (tlsas && ldns_rr_list_rr_count(tlsas) > 0) {
-               tlsas = ldns_dane_filter_unusable_records(tlsas);
-               if (! tlsas) {
-                       return LDNS_STATUS_MEM_ERR;
-               }
-       }
-       if (! tlsas || ldns_rr_list_rr_count(tlsas) == 0) {
+       if (! tlsas || ldns_rr_list_rr_count(tlsas) == 0)
                /* No TLSA's, so regular PKIX validation
                 */
                return ldns_dane_pkix_validate(cert, extra_certs,
                                pkix_validation_store);
-       } else {
-               for (i = 0; i < ldns_rr_list_rr_count(tlsas); i++) {
-                       tlsa_rr = ldns_rr_list_rr(tlsas, i);
-                       ps = s;
-                       s = ldns_dane_verify_rr(tlsa_rr, cert, extra_certs,
-                                       pkix_validation_store);
 
-                       if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH &&
-                           s != LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE) {
+/* To enable name checks (which we don't) */
+#if defined(USE_DANE_TA_USAGE) && 0
+       else if (!(basename_rdf = ldns_dname_clone_from(
+                                       ldns_rr_list_owner(tlsas), 2)))
+               /* Could nog get DANE base name */
+               s = LDNS_STATUS_ERR;
 
-                               /* which would be LDNS_STATUS_OK (match)
-                                * or some fatal error preventing use from
-                                * trying the next TLSA record.
-                                */
-                               break;
-                       }
-                       s = (s > ps ? s : ps); /* prefer PKIX_DID_NOT_VALIDATE
-                                               * over   TLSA_DID_NOT_MATCH
-                                               */
+       else if (!(basename = ldns_rdf2str(basename_rdf)))
+               s = LDNS_STATUS_MEM_ERR;
+
+       else if (strlen(basename) && (basename[strlen(basename)-1]  = 0))
+               s = LDNS_STATUS_ERR; /* Intended to be unreachable */
+#endif
+
+       else if (!(usable_tlsas = ldns_dane_filter_unusable_records(tlsas)))
+               return LDNS_STATUS_MEM_ERR;
+
+       else if (ldns_rr_list_rr_count(usable_tlsas) == 0) {
+               /* No TLSA's, so regular PKIX validation
+                */
+               ldns_rr_list_free(usable_tlsas);
+               return ldns_dane_pkix_validate(cert, extra_certs,
+                               pkix_validation_store);
+       }
+#if defined(USE_DANE_TA_USAGE)
+       /* Rely on OpenSSL dane functions.
+        *
+        * OpenSSL does not provide offline dane verification.  The dane unit
+        * tests within openssl use the undocumented SSL_get0_dane() and 
+        * X509_STORE_CTX_set0_dane() to convey dane parameters set on SSL and
+        * SSL_CTX to a X509_STORE_CTX that can be used to do offline
+        * verification.  We use these undocumented means with the ldns
+        * dane function prototypes which did only offline dane verification.
+        */
+       if (!(ssl_ctx = SSL_CTX_new(TLS_client_method())))
+               s = LDNS_STATUS_MEM_ERR;
+
+       else if (SSL_CTX_dane_enable(ssl_ctx) <= 0)
+               s = LDNS_STATUS_SSL_ERR;
+
+       else if (SSL_CTX_dane_set_flags(
+                               ssl_ctx, DANE_FLAG_NO_DANE_EE_NAMECHECKS),
+                       !(ssl = SSL_new(ssl_ctx)))
+               s = LDNS_STATUS_MEM_ERR;
+
+       else if (SSL_set_connect_state(ssl),
+                       (SSL_dane_enable(ssl, basename) <= 0))
+               s = LDNS_STATUS_SSL_ERR;
+
+       else for (i = 0; i < ldns_rr_list_rr_count(usable_tlsas); i++) {
+               ldns_tlsa_certificate_usage usage;
+               ldns_tlsa_selector          selector;
+               ldns_tlsa_matching_type     mtype;
+               ldns_rdf*                   data;
+
+               tlsa_rr = ldns_rr_list_rr(usable_tlsas, i);
+               usage   = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr,0));
+               selector= ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr,1));
+               mtype   = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr,2));
+               data    =                      ldns_rr_rdf(tlsa_rr,3) ;
+
+               if (SSL_dane_tlsa_add(ssl, usage, selector, mtype,
+                                       ldns_rdf_data(data),
+                                       ldns_rdf_size(data)) <= 0) {
+                       s = LDNS_STATUS_SSL_ERR;
+                       break;
+               }
+       }
+       if (!s && !(store_ctx =  X509_STORE_CTX_new()))
+               s = LDNS_STATUS_MEM_ERR;
+
+       else if (!X509_STORE_CTX_init(store_ctx, pkix_validation_store, cert, extra_certs))
+               s = LDNS_STATUS_SSL_ERR;
+
+       else {
+               int ret;
+
+               X509_STORE_CTX_set_default(store_ctx,
+                               SSL_is_server(ssl) ? "ssl_client" : "ssl_server");
+               X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(store_ctx),
+                               SSL_get0_param(ssl));
+               X509_STORE_CTX_set0_dane(store_ctx, SSL_get0_dane(ssl));
+               if (SSL_get_verify_callback(ssl))
+                       X509_STORE_CTX_set_verify_cb(store_ctx, SSL_get_verify_callback(ssl));
+
+               ret = X509_verify_cert(store_ctx);
+               if (!ret) {
+                       if (X509_STORE_CTX_get_error(store_ctx) == X509_V_ERR_DANE_NO_MATCH)
+                               s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH;
+                       else
+                               s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
+               }
+               X509_STORE_CTX_cleanup(store_ctx);
+       }
+       if (store_ctx)
+               X509_STORE_CTX_free(store_ctx);
+       if (ssl)
+               SSL_free(ssl);
+       if (ssl_ctx)
+               SSL_CTX_free(ssl_ctx);
+       if (basename)
+               free(basename);
+       ldns_rdf_deep_free(basename_rdf);
+#else
+       for (i = 0; i < ldns_rr_list_rr_count(usable_tlsas); i++) {
+               tlsa_rr = ldns_rr_list_rr(usable_tlsas, i);
+               ps = s;
+               s = ldns_dane_verify_rr(tlsa_rr, cert, extra_certs,
+                               pkix_validation_store);
+
+               if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH &&
+                   s != LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE &&
+                   s != LDNS_STATUS_DANE_NEED_OPENSSL_GE_1_1_FOR_DANE_TA) {
+
+                       /* which would be LDNS_STATUS_OK (match)
+                        * or some fatal error preventing use from
+                        * trying the next TLSA record.
+                        */
+                       break;
                }
-               ldns_rr_list_free(tlsas);
+               s = (s > ps ? s : ps); /* pref NEED_OPENSSL_GE_1_1_FOR_DANE_TA
+                                       * over PKIX_DID_NOT_VALIDATE
+                                       * over TLSA_DID_NOT_MATCH
+                                       */
        }
+#endif
+       ldns_rr_list_free(usable_tlsas);
        return s;
 }
+#endif /* USE_DANE_VERIFY */
 #endif /* HAVE_SSL */
+#endif /* USE_DANE */
index 55aba5d..17afe1d 100644 (file)
@@ -87,7 +87,7 @@ ldns_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2)
 }
 
 ldns_status
-ldns_dname_cat(ldns_rdf *rd1, ldns_rdf *rd2)
+ldns_dname_cat(ldns_rdf *rd1, const ldns_rdf *rd2)
 {
        uint16_t left_size;
        uint16_t size;
@@ -251,6 +251,9 @@ ldns_dname_new(uint16_t s, void *d)
 {
         ldns_rdf *rd;
 
+        if (!s || !d) {
+                return NULL;
+        }
         rd = LDNS_MALLOC(ldns_rdf);
         if (!rd) {
                 return NULL;
@@ -527,10 +530,11 @@ ldns_dname_str_absolute(const char *dname_str)
         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]))
+                                && isdigit((unsigned char)s[1])
+                               && isdigit((unsigned char)s[2])
+                               && isdigit((unsigned char)s[3]))
                                 s += 3;
-                        else if(!s[1] || isdigit(s[1])) /* escape of nul,0-9 */
+                        else if(!s[1] || isdigit((unsigned char)s[1])) /* escape of nul,0-9 */
                                 return 0; /* parse error */
                         else s++; /* another character escaped */
                 }
index 684d171..e3c99de 100644 (file)
@@ -81,7 +81,7 @@ ldns_dnssec_get_dnskey_for_rrsig(const ldns_rr *rrsig,
 }
 
 ldns_rdf *
-ldns_nsec_get_bitmap(ldns_rr *nsec) {
+ldns_nsec_get_bitmap(const ldns_rr *nsec) {
        if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC) {
                return ldns_rr_rdf(nsec, 1);
        } else if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC3) {
@@ -94,9 +94,9 @@ ldns_nsec_get_bitmap(ldns_rr *nsec) {
 /*return the owner name of the closest encloser for name from the list of rrs */
 /* this is NOT the hash, but the original name! */
 ldns_rdf *
-ldns_dnssec_nsec3_closest_encloser(ldns_rdf *qname,
+ldns_dnssec_nsec3_closest_encloser(const ldns_rdf *qname,
                                    ATTR_UNUSED(ldns_rr_type qtype),
-                                   ldns_rr_list *nsec3s)
+                                   const ldns_rr_list *nsec3s)
 {
        /* remember parameters, they must match */
        uint8_t algorithm;
@@ -215,7 +215,7 @@ ldns_dnssec_pkt_has_rrsigs(const ldns_pkt *pkt)
 
 ldns_rr_list *
 ldns_dnssec_pkt_get_rrsigs_for_name_and_type(const ldns_pkt *pkt,
-                                                                       ldns_rdf *name,
+                                                                       const ldns_rdf *name,
                                                                        ldns_rr_type type)
 {
        uint16_t t_netorder;
@@ -298,7 +298,7 @@ ldns_calc_keytag(const ldns_rr *key)
        return ac16;
 }
 
-uint16_t ldns_calc_keytag_raw(uint8_t* key, size_t keysize)
+uint16_t ldns_calc_keytag_raw(const uint8_t* key, size_t keysize)
 {
        unsigned int i;
        uint32_t ac32;
@@ -327,14 +327,14 @@ uint16_t ldns_calc_keytag_raw(uint8_t* key, size_t keysize)
 
 #ifdef HAVE_SSL
 DSA *
-ldns_key_buf2dsa(ldns_buffer *key)
+ldns_key_buf2dsa(const ldns_buffer *key)
 {
-       return ldns_key_buf2dsa_raw((unsigned char*)ldns_buffer_begin(key),
+       return ldns_key_buf2dsa_raw((const unsigned char*)ldns_buffer_begin(key),
                                                   ldns_buffer_position(key));
 }
 
 DSA *
-ldns_key_buf2dsa_raw(unsigned char* key, size_t len)
+ldns_key_buf2dsa_raw(const unsigned char* key, size_t len)
 {
        uint8_t T;
        uint16_t length;
@@ -375,25 +375,43 @@ ldns_key_buf2dsa_raw(unsigned char* key, size_t len)
                BN_free(Y);
                return NULL;
        }
+#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
 #ifndef S_SPLINT_S
        dsa->p = P;
        dsa->q = Q;
        dsa->g = G;
        dsa->pub_key = Y;
 #endif /* splint */
+#else /* OPENSSL_VERSION_NUMBER */
+       if (!DSA_set0_pqg(dsa, P, Q, G)) {
+               /* QPG not yet attached, need to free */
+               BN_free(Q);
+               BN_free(P);
+               BN_free(G);
 
+               DSA_free(dsa);
+               BN_free(Y);
+               return NULL;
+       }
+       if (!DSA_set0_key(dsa, Y, NULL)) {
+               /* QPG attached, cleaned up by DSA_fre() */
+               DSA_free(dsa);
+               BN_free(Y);
+               return NULL;
+       }
+#endif /* OPENSSL_VERSION_NUMBER */
        return dsa;
 }
 
 RSA *
-ldns_key_buf2rsa(ldns_buffer *key)
+ldns_key_buf2rsa(const ldns_buffer *key)
 {
-       return ldns_key_buf2rsa_raw((unsigned char*)ldns_buffer_begin(key),
+       return ldns_key_buf2rsa_raw((const unsigned char*)ldns_buffer_begin(key),
                                                   ldns_buffer_position(key));
 }
 
 RSA *
-ldns_key_buf2rsa_raw(unsigned char* key, size_t len)
+ldns_key_buf2rsa_raw(const unsigned char* key, size_t len)
 {
        uint16_t offset;
        uint16_t exp;
@@ -443,16 +461,25 @@ ldns_key_buf2rsa_raw(unsigned char* key, size_t len)
                BN_free(modulus);
                return NULL;
        }
+#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
 #ifndef S_SPLINT_S
        rsa->n = modulus;
        rsa->e = exponent;
 #endif /* splint */
+#else /* OPENSSL_VERSION_NUMBER */
+       if (!RSA_set0_key(rsa, modulus, exponent, NULL)) {
+               BN_free(exponent);
+               BN_free(modulus);
+               RSA_free(rsa);
+               return NULL;
+       }
+#endif /* OPENSSL_VERSION_NUMBER */
 
        return rsa;
 }
 
 int
-ldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
+ldns_digest_evp(const unsigned char* data, unsigned int len, unsigned char* dest,
        const EVP_MD* md)
 {
        EVP_MD_CTX* ctx;
@@ -654,110 +681,120 @@ ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
        return ds;
 }
 
+/* From RFC3845:
+ *
+ * 2.1.2.  The List of Type Bit Map(s) Field
+ * 
+ *    The RR type space is split into 256 window blocks, each representing
+ *    the low-order 8 bits of the 16-bit RR type space.  Each block that
+ *    has at least one active RR type is encoded using a single octet
+ *    window number (from 0 to 255), a single octet bitmap length (from 1
+ *    to 32) indicating the number of octets used for the window block's
+ *    bitmap, and up to 32 octets (256 bits) of bitmap.
+ * 
+ *    Window blocks are present in the NSEC RR RDATA in increasing
+ *    numerical order.
+ * 
+ *    "|" denotes concatenation
+ * 
+ *    Type Bit Map(s) Field = ( Window Block # | Bitmap Length | Bitmap ) +
+ * 
+ *    <cut>
+ * 
+ *    Blocks with no types present MUST NOT be included.  Trailing zero
+ *    octets in the bitmap MUST be omitted.  The length of each block's
+ *    bitmap is determined by the type code with the largest numerical
+ *    value within that block, among the set of RR types present at the
+ *    NSEC RR's owner name.  Trailing zero octets not specified MUST be
+ *    interpreted as zero octets.
+ */
 ldns_rdf *
 ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[],
                                size_t size,
                                ldns_rr_type nsec_type)
 {
-       size_t i;
-       uint8_t *bitmap;
-       uint16_t bm_len = 0;
-       uint16_t i_type;
-       ldns_rdf *bitmap_rdf;
-
-       uint8_t *data = NULL;
-       uint8_t cur_data[32];
-       uint8_t cur_window = 0;
-       uint8_t cur_window_max = 0;
-       uint16_t cur_data_size = 0;
+       uint8_t  window;                /*  most significant octet of type */
+       uint8_t  subtype;               /* least significant octet of type */
+       int      windows[256];          /* Max subtype per window */
+       uint8_t  windowpresent[256];    /* bool if window appears in bitmap */
+       ldns_rr_type* d;        /* used to traverse rr_type_list*/
+       size_t i;               /* used to traverse windows array */
+
+       size_t sz;                      /* size needed for type bitmap rdf */
+       uint8_t* data = NULL;           /* rdf data */
+       uint8_t* dptr;                  /* used to itraverse rdf data */
+       ldns_rdf* rdf;                  /* bitmap rdf to return */
 
        if (nsec_type != LDNS_RR_TYPE_NSEC &&
            nsec_type != LDNS_RR_TYPE_NSEC3) {
                return NULL;
        }
+       memset(windows, 0, sizeof(int)*256);
+       memset(windowpresent, 0, 256);
 
-       i_type = 0;
-       for (i = 0; i < size; i++) {
-               if (i_type < rr_type_list[i])
-                       i_type = rr_type_list[i];
-       }
-       if (i_type < nsec_type) {
-               i_type = nsec_type;
-       }
-
-       bm_len = i_type / 8 + 2;
-       bitmap = LDNS_XMALLOC(uint8_t, bm_len);
-        if(!bitmap) return NULL;
-       for (i = 0; i < bm_len; i++) {
-               bitmap[i] = 0;
-       }
-
-       for (i = 0; i < size; i++) {
-               i_type = rr_type_list[i];
-               ldns_set_bit(bitmap + (int) i_type / 8,
-                                  (int) (7 - (i_type % 8)),
-                                  true);
-       }
-
-       /* fold it into windows TODO: can this be done directly? */
-       memset(cur_data, 0, 32);
-       for (i = 0; i < bm_len; i++) {
-               if (i / 32 > cur_window) {
-                       /* check, copy, new */
-                       if (cur_window_max > 0) {
-                               /* this window has stuff, add it */
-                               data = LDNS_XREALLOC(data,
-                                                                uint8_t,
-                                                                cur_data_size + cur_window_max + 3);
-                                if(!data) {
-                                        LDNS_FREE(bitmap);
-                                        return NULL;
-                                }
-                               data[cur_data_size] = cur_window;
-                               data[cur_data_size + 1] = cur_window_max + 1;
-                               memcpy(data + cur_data_size + 2,
-                                         cur_data,
-                                         cur_window_max+1);
-                               cur_data_size += cur_window_max + 3;
-                       }
-                       cur_window++;
-                       cur_window_max = 0;
-                       memset(cur_data, 0, 32);
+       /* Which other windows need to be in the bitmap rdf?
+        */
+       for (d = rr_type_list; d < rr_type_list + size; d++) {
+               window  = *d >> 8;
+               subtype = *d & 0xff;
+               windowpresent[window] = 1;
+               if (windows[window] < (int)subtype) {
+                       windows[window] = (int)subtype;
                }
-               cur_data[i%32] = bitmap[i];
-               if (bitmap[i] > 0) {
-                       cur_window_max = i%32;
+       }
+
+       /* How much space do we need in the rdf for those windows?
+        */
+       sz = 0;
+       for (i = 0; i < 256; i++) {
+               if (windowpresent[i]) {
+                       sz += windows[i] / 8 + 3;
                }
        }
-       if (cur_window_max > 0 || cur_data[0] != 0) {
-               /* this window has stuff, add it */
-               data = LDNS_XREALLOC(data,
-                                                uint8_t,
-                                                cur_data_size + cur_window_max + 3);
-                if(!data) {
-                        LDNS_FREE(bitmap);
-                        return NULL;
-                }
-               data[cur_data_size] = cur_window;
-               data[cur_data_size + 1] = cur_window_max + 1;
-               memcpy(data + cur_data_size + 2, cur_data, cur_window_max+1);
-               cur_data_size += cur_window_max + 3;
+       if (sz > 0) {
+               /* Format rdf data according RFC3845 Section 2.1.2 (see above)
+                */
+               dptr = data = LDNS_CALLOC(uint8_t, sz);
+               if (!data) {
+                       return NULL;
+               }
+               for (i = 0; i < 256; i++) {
+                       if (windowpresent[i]) {
+                               *dptr++ = (uint8_t)i;
+                               *dptr++ = (uint8_t)(windows[i] / 8 + 1);
+
+                               /* Now let windows[i] index the bitmap
+                                * within data
+                                */
+                               windows[i] = (int)(dptr - data);
+
+                               dptr += dptr[-1];
+                       }
+               }
        }
-       bitmap_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC,
-                                                               cur_data_size,
-                                                               data);
 
-       LDNS_FREE(bitmap);
-       LDNS_FREE(data);
+       /* Set the bits?
+        */
+       for (d = rr_type_list; d < rr_type_list + size; d++) {
+               subtype = *d & 0xff;
+               data[windows[*d >> 8] + subtype/8] |= (0x80 >> (subtype % 8));
+       }
 
-       return bitmap_rdf;
+       /* Allocate and return rdf structure for the data
+        */
+       rdf = ldns_rdf_new(LDNS_RDF_TYPE_BITMAP, sz, data);
+       if (!rdf) {
+               LDNS_FREE(data);
+               return NULL;
+       }
+       return rdf;
 }
 
 int
-ldns_dnssec_rrsets_contains_type(ldns_dnssec_rrsets *rrsets,
+ldns_dnssec_rrsets_contains_type(const ldns_dnssec_rrsets *rrsets,
                                  ldns_rr_type type)
 {
-       ldns_dnssec_rrsets *cur_rrset = rrsets;
+       const ldns_dnssec_rrsets *cur_rrset = rrsets;
        while (cur_rrset) {
                if (cur_rrset->type == type) {
                        return 1;
@@ -768,8 +805,8 @@ ldns_dnssec_rrsets_contains_type(ldns_dnssec_rrsets *rrsets,
 }
 
 ldns_rr *
-ldns_dnssec_create_nsec(ldns_dnssec_name *from,
-                        ldns_dnssec_name *to,
+ldns_dnssec_create_nsec(const ldns_dnssec_name *from,
+                        const ldns_dnssec_name *to,
                         ldns_rr_type nsec_type)
 {
        ldns_rr *nsec_rr;
@@ -822,14 +859,14 @@ ldns_dnssec_create_nsec(ldns_dnssec_name *from,
 }
 
 ldns_rr *
-ldns_dnssec_create_nsec3(ldns_dnssec_name *from,
-                                       ldns_dnssec_name *to,
-                                       ldns_rdf *zone_name,
+ldns_dnssec_create_nsec3(const ldns_dnssec_name *from,
+                                       const ldns_dnssec_name *to,
+                                       const ldns_rdf *zone_name,
                                        uint8_t algorithm,
                                        uint8_t flags,
                                        uint16_t iterations,
                                        uint8_t salt_length,
-                                       uint8_t *salt)
+                                       const uint8_t *salt)
 {
        ldns_rr *nsec_rr;
        ldns_rr_type types[65536];
@@ -961,11 +998,11 @@ ldns_create_nsec(ldns_rdf *cur_owner, ldns_rdf *next_owner, ldns_rr_list *rrs)
 }
 
 ldns_rdf *
-ldns_nsec3_hash_name(ldns_rdf *name,
+ldns_nsec3_hash_name(const ldns_rdf *name,
                                 uint8_t algorithm,
                                 uint16_t iterations,
                                 uint8_t salt_length,
-                                uint8_t *salt)
+                                const uint8_t *salt)
 {
        size_t hashed_owner_str_len;
        ldns_rdf *cann;
@@ -987,7 +1024,9 @@ ldns_nsec3_hash_name(ldns_rdf *name,
        /* prepare the owner name according to the draft section bla */
        cann = ldns_rdf_clone(name);
        if(!cann) {
+#ifdef STDERR_MSGS
                fprintf(stderr, "Memory error\n");
+#endif
                return NULL;
        }
        ldns_dname2canonical(cann);
@@ -1032,11 +1071,13 @@ ldns_nsec3_hash_name(ldns_rdf *name,
                 hashed_owner_b32,
                 ldns_b32_ntop_calculate_size(hashed_owner_str_len)+1);
        if (hashed_owner_b32_len < 1) {
+#ifdef STDERR_MSGS
                fprintf(stderr, "Error in base32 extended hex encoding ");
                fprintf(stderr, "of hashed owner name (name: ");
                ldns_rdf_print(stderr, name);
                fprintf(stderr, ", return code: %u)\n",
                        (unsigned int) hashed_owner_b32_len);
+#endif
                LDNS_FREE(hashed_owner_b32);
                return NULL;
        }
@@ -1044,7 +1085,9 @@ ldns_nsec3_hash_name(ldns_rdf *name,
 
        status = ldns_str2rdf_dname(&hashed_owner, hashed_owner_b32);
        if (status != LDNS_STATUS_OK) {
+#ifdef STDERR_MSGS
                fprintf(stderr, "Error creating rdf from %s\n", hashed_owner_b32);
+#endif
                LDNS_FREE(hashed_owner_b32);
                return NULL;
        }
@@ -1059,7 +1102,7 @@ ldns_nsec3_add_param_rdfs(ldns_rr *rr,
                                         uint8_t flags,
                                         uint16_t iterations,
                                         uint8_t salt_length,
-                                        uint8_t *salt)
+                                        const uint8_t *salt)
 {
        ldns_rdf *salt_rdf = NULL;
        uint8_t *salt_data = NULL;
@@ -1105,7 +1148,7 @@ ldns_nsec3_add_param_rdfs(ldns_rr *rr,
 }
 
 static int
-rr_list_delegation_only(ldns_rdf *origin, ldns_rr_list *rr_list)
+rr_list_delegation_only(const ldns_rdf *origin, const ldns_rr_list *rr_list)
 {
        size_t i;
        ldns_rr *cur_rr;
@@ -1125,14 +1168,14 @@ rr_list_delegation_only(ldns_rdf *origin, ldns_rr_list *rr_list)
 /* this will NOT return the NSEC3  completed, you will have to run the
    finalize function on the rrlist later! */
 ldns_rr *
-ldns_create_nsec3(ldns_rdf *cur_owner,
-                  ldns_rdf *cur_zone,
-                  ldns_rr_list *rrs,
+ldns_create_nsec3(const ldns_rdf *cur_owner,
+                  const ldns_rdf *cur_zone,
+                  const ldns_rr_list *rrs,
                   uint8_t algorithm,
                   uint8_t flags,
                   uint16_t iterations,
                   uint8_t salt_length,
-                  uint8_t *salt,
+                  const uint8_t *salt,
                   bool emptynonterminal)
 {
        size_t i;
@@ -1313,7 +1356,7 @@ ldns_nsec3_bitmap(const ldns_rr *nsec3_rr)
 }
 
 ldns_rdf *
-ldns_nsec3_hash_name_frm_nsec3(const ldns_rr *nsec, ldns_rdf *name)
+ldns_nsec3_hash_name_frm_nsec3(const ldns_rr *nsec, const ldns_rdf *name)
 {
        uint8_t algorithm;
        uint16_t iterations;
@@ -1338,38 +1381,120 @@ ldns_nsec3_hash_name_frm_nsec3(const ldns_rr *nsec, ldns_rdf *name)
 }
 
 bool
-ldns_nsec_bitmap_covers_type(const ldns_rdf *nsec_bitmap, ldns_rr_type type)
+ldns_nsec_bitmap_covers_type(const ldns_rdfbitmap, ldns_rr_type type)
 {
-       uint8_t window_block_nr;
-       uint8_t bitmap_length;
-       uint16_t cur_type;
-       uint16_t pos = 0;
-       uint16_t bit_pos;
-       uint8_t *data;
-
-       if (nsec_bitmap == NULL) {
+       uint8_t* dptr;
+       uint8_t* dend;
+
+       /* From RFC3845 Section 2.1.2:
+        *
+        *      "The RR type space is split into 256 window blocks, each re-
+        *       presenting the low-order 8 bits of the 16-bit RR type space."
+        */
+       uint8_t  window = type >> 8;
+       uint8_t subtype = type & 0xff;
+
+       if (! bitmap) {
                return false;
        }
-       data = ldns_rdf_data(nsec_bitmap);
-       while(pos < ldns_rdf_size(nsec_bitmap)) {
-               window_block_nr = data[pos];
-               bitmap_length = data[pos + 1];
-               pos += 2;
-
-               for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
-                       if (ldns_get_bit(&data[pos], bit_pos)) {
-                               cur_type = 256 * (uint16_t) window_block_nr + bit_pos;
-                               if (cur_type == type) {
-                                       return true;
-                               }
-                       }
-               }
+       assert(ldns_rdf_get_type(bitmap) == LDNS_RDF_TYPE_BITMAP);
+
+       dptr = ldns_rdf_data(bitmap);
+       dend = ldns_rdf_data(bitmap) + ldns_rdf_size(bitmap);
 
-               pos += (uint16_t) bitmap_length;
+       /* Type Bitmap = ( Window Block # | Bitmap Length | Bitmap ) +
+        *                 dptr[0]          dptr[1]         dptr[2:]
+        */
+       while (dptr < dend && dptr[0] <= window) {
+
+               if (dptr[0] == window && subtype / 8 < dptr[1] &&
+                               dptr + dptr[1] + 2 <= dend) {
+
+                       return dptr[2 + subtype / 8] & (0x80 >> (subtype % 8));
+               }
+               dptr += dptr[1] + 2; /* next window */
        }
        return false;
 }
 
+ldns_status
+ldns_nsec_bitmap_set_type(ldns_rdf* bitmap, ldns_rr_type type)
+{
+       uint8_t* dptr;
+       uint8_t* dend;
+
+       /* From RFC3845 Section 2.1.2:
+        *
+        *      "The RR type space is split into 256 window blocks, each re-
+        *       presenting the low-order 8 bits of the 16-bit RR type space."
+        */
+       uint8_t  window = type >> 8;
+       uint8_t subtype = type & 0xff;
+
+       if (! bitmap) {
+               return false;
+       }
+       assert(ldns_rdf_get_type(bitmap) == LDNS_RDF_TYPE_BITMAP);
+
+       dptr = ldns_rdf_data(bitmap);
+       dend = ldns_rdf_data(bitmap) + ldns_rdf_size(bitmap);
+
+       /* Type Bitmap = ( Window Block # | Bitmap Length | Bitmap ) +
+        *                 dptr[0]          dptr[1]         dptr[2:]
+        */
+       while (dptr < dend && dptr[0] <= window) {
+
+               if (dptr[0] == window && subtype / 8 < dptr[1] &&
+                               dptr + dptr[1] + 2 <= dend) {
+
+                       dptr[2 + subtype / 8] |= (0x80 >> (subtype % 8));
+                       return LDNS_STATUS_OK;
+               }
+               dptr += dptr[1] + 2; /* next window */
+       }
+       return LDNS_STATUS_TYPE_NOT_IN_BITMAP;
+}
+
+ldns_status
+ldns_nsec_bitmap_clear_type(ldns_rdf* bitmap, ldns_rr_type type)
+{
+       uint8_t* dptr;
+       uint8_t* dend;
+
+       /* From RFC3845 Section 2.1.2:
+        *
+        *      "The RR type space is split into 256 window blocks, each re-
+        *       presenting the low-order 8 bits of the 16-bit RR type space."
+        */
+       uint8_t  window = type >> 8;
+       uint8_t subtype = type & 0xff;
+
+       if (! bitmap) {
+               return false;
+       }
+
+       assert(ldns_rdf_get_type(bitmap) == LDNS_RDF_TYPE_BITMAP);
+
+       dptr = ldns_rdf_data(bitmap);
+       dend = ldns_rdf_data(bitmap) + ldns_rdf_size(bitmap);
+
+       /* Type Bitmap = ( Window Block # | Bitmap Length | Bitmap ) +
+        *                 dptr[0]          dptr[1]         dptr[2:]
+        */
+       while (dptr < dend && dptr[0] <= window) {
+
+               if (dptr[0] == window && subtype / 8 < dptr[1] &&
+                               dptr + dptr[1] + 2 <= dend) {
+
+                       dptr[2 + subtype / 8] &= ~(0x80 >> (subtype % 8));
+                       return LDNS_STATUS_OK;
+               }
+               dptr += dptr[1] + 2; /* next window */
+       }
+       return LDNS_STATUS_TYPE_NOT_IN_BITMAP;
+}
+
+
 bool
 ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name)
 {
@@ -1407,9 +1532,11 @@ ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name)
        if(ldns_dname_compare(nsec_owner, nsec_next) > 0) {
                result = (ldns_dname_compare(nsec_owner, name) <= 0 ||
                                ldns_dname_compare(name, nsec_next) < 0);
-       } else {
+       } else if(ldns_dname_compare(nsec_owner, nsec_next) < 0) {
                result = (ldns_dname_compare(nsec_owner, name) <= 0 &&
                          ldns_dname_compare(name, nsec_next) < 0);
+       } else {
+               result = true;
        }
 
        ldns_rdf_deep_free(nsec_next);
@@ -1420,8 +1547,8 @@ ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name)
 /* sig may be null - if so look in the packet */
 
 ldns_status
-ldns_pkt_verify_time(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, 
-               ldns_rr_list *k, ldns_rr_list *s, 
+ldns_pkt_verify_time(const ldns_pkt *p, ldns_rr_type t, const ldns_rdf *o, 
+               const ldns_rr_list *k, const ldns_rr_list *s, 
                time_t check_time, ldns_rr_list *good_keys)
 {
        ldns_rr_list *rrset;
@@ -1442,7 +1569,7 @@ ldns_pkt_verify_time(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o,
 
        if (s) {
                /* if s is not NULL, the sigs are given to use */
-               sigs = s;
+               sigs = (ldns_rr_list *)s;
        } else {
                /* otherwise get them from the packet */
                sigs = ldns_pkt_rr_list_by_name_and_type(p, o,
@@ -1484,8 +1611,8 @@ ldns_pkt_verify_time(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o,
 }
 
 ldns_status
-ldns_pkt_verify(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, 
-               ldns_rr_list *k, ldns_rr_list *s, ldns_rr_list *good_keys)
+ldns_pkt_verify(const ldns_pkt *p, ldns_rr_type t, const ldns_rdf *o, 
+               const ldns_rr_list *k, const ldns_rr_list *s, ldns_rr_list *good_keys)
 {
        return ldns_pkt_verify_time(p, t, o, k, s, ldns_time(NULL), good_keys);
 }
@@ -1607,8 +1734,10 @@ ldns_rdf *
 ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig,
                                                  const long sig_len)
 {
+#ifdef USE_DSA
        ldns_rdf *sigdata_rdf;
        DSA_SIG *dsasig;
+       const BIGNUM *R, *S;
        unsigned char *dsasig_data = (unsigned char*)ldns_buffer_begin(sig);
        size_t byte_offset;
 
@@ -1626,22 +1755,28 @@ ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig,
                 return NULL;
         }
        dsasig_data[0] = 0;
-       byte_offset = (size_t) (20 - BN_num_bytes(dsasig->r));
+# ifdef HAVE_DSA_SIG_GET0
+       DSA_SIG_get0(dsasig, &R, &S);
+# else
+       R = dsasig->r;
+       S = dsasig->s;
+# endif
+       byte_offset = (size_t) (20 - BN_num_bytes(R));
        if (byte_offset > 20) {
                 DSA_SIG_free(dsasig);
                 LDNS_FREE(dsasig_data);
                return NULL;
        }
        memset(&dsasig_data[1], 0, byte_offset);
-       BN_bn2bin(dsasig->r, &dsasig_data[1 + byte_offset]);
-       byte_offset = (size_t) (20 - BN_num_bytes(dsasig->s));
+       BN_bn2bin(R, &dsasig_data[1 + byte_offset]);
+       byte_offset = (size_t) (20 - BN_num_bytes(S));
        if (byte_offset > 20) {
                 DSA_SIG_free(dsasig);
                 LDNS_FREE(dsasig_data);
                return NULL;
        }
        memset(&dsasig_data[21], 0, byte_offset);
-       BN_bn2bin(dsasig->s, &dsasig_data[21 + byte_offset]);
+       BN_bn2bin(S, &dsasig_data[21 + byte_offset]);
 
        sigdata_rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, 41, dsasig_data);
         if(!sigdata_rdf) {
@@ -1650,12 +1785,17 @@ ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig,
        DSA_SIG_free(dsasig);
 
        return sigdata_rdf;
+#else
+       (void)sig; (void)sig_len;
+       return NULL;
+#endif
 }
 
 ldns_status
 ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
                                                  const ldns_rdf *sig_rdf)
 {
+#ifdef USE_DSA
        /* the EVP api wants the DER encoding of the signature... */
        BIGNUM *R, *S;
        DSA_SIG *dsasig;
@@ -1683,9 +1823,13 @@ ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
                BN_free(S);
                return LDNS_STATUS_MEM_ERR;
        }
-
+# ifdef HAVE_DSA_SIG_SET0
+       if (! DSA_SIG_set0(dsasig, R, S))
+              return LDNS_STATUS_SSL_ERR;
+# else
        dsasig->r = R;
        dsasig->s = S;
+# endif
 
        raw_sig_len = i2d_DSA_SIG(dsasig, &raw_sig);
        if (raw_sig_len < 0) {
@@ -1701,30 +1845,48 @@ ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
        free(raw_sig);
 
        return ldns_buffer_status(target_buffer);
+#else
+       (void)target_buffer; (void)sig_rdf;
+       return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
+#endif
 }
 
 #ifdef USE_ECDSA
 #ifndef S_SPLINT_S
 ldns_rdf *
-ldns_convert_ecdsa_rrsig_asn12rdf(const ldns_buffer *sig, const long sig_len)
+ldns_convert_ecdsa_rrsig_asn1len2rdf(const ldns_buffer *sig,
+       const long sig_len, int num_bytes)
 {
         ECDSA_SIG* ecdsa_sig;
+       const BIGNUM *r, *s;
        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;
 
+#ifdef HAVE_ECDSA_SIG_GET0
+       ECDSA_SIG_get0(ecdsa_sig, &r, &s);
+#else
+       r = ecdsa_sig->r;
+       s = ecdsa_sig->s;
+#endif
         /* "r | s". */
-        data = LDNS_XMALLOC(unsigned char,
-                BN_num_bytes(ecdsa_sig->r) + BN_num_bytes(ecdsa_sig->s));
+        if(BN_num_bytes(r) > num_bytes ||
+               BN_num_bytes(s) > num_bytes) {
+                ECDSA_SIG_free(ecdsa_sig);
+               return NULL; /* numbers too big for passed curve size */
+       }
+        data = LDNS_XMALLOC(unsigned char, num_bytes*2);
         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, (size_t)(
-               BN_num_bytes(ecdsa_sig->r) + BN_num_bytes(ecdsa_sig->s)), data);
+       /* write the bignums (in big-endian) a little offset if the BN code
+        * wants to write a shorter number of bytes, with zeroes prefixed */
+       memset(data, 0, num_bytes*2);
+        BN_bn2bin(r, data+num_bytes-BN_num_bytes(r));
+        BN_bn2bin(s, data+num_bytes*2-BN_num_bytes(s));
+       rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, (size_t)(num_bytes*2), data);
         ECDSA_SIG_free(ecdsa_sig);
         return rdf;
 }
@@ -1733,37 +1895,116 @@ ldns_status
 ldns_convert_ecdsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
         const ldns_rdf *sig_rdf)
 {
-        ECDSA_SIG* sig;
-       int raw_sig_len;
+        /* convert from two BIGNUMs in the rdata buffer, to ASN notation.
+        * ASN preable:  30440220 <R 32bytefor256> 0220 <S 32bytefor256>
+        * the '20' is the length of that field (=bnsize).
+        * the '44' is the total remaining length.
+        * if negative, start with leading zero.
+        * if starts with 00s, remove them from the number.
+        */
+        uint8_t pre[] = {0x30, 0x44, 0x02, 0x20};
+        int pre_len = 4;
+        uint8_t mid[] = {0x02, 0x20};
+        int mid_len = 2;
+        int raw_sig_len, r_high, s_high, r_rem=0, s_rem=0;
         long bnsize = (long)ldns_rdf_size(sig_rdf) / 2;
+        uint8_t* d = ldns_rdf_data(sig_rdf);
         /* 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;
+        /* strip leading zeroes from r (but not last one) */
+        while(r_rem < bnsize-1 && d[r_rem] == 0)
+                r_rem++;
+        /* strip leading zeroes from s (but not last one) */
+        while(s_rem < bnsize-1 && d[bnsize+s_rem] == 0)
+                s_rem++;
+
+        r_high = ((d[0+r_rem]&0x80)?1:0);
+        s_high = ((d[bnsize+s_rem]&0x80)?1:0);
+        raw_sig_len = pre_len + r_high + bnsize - r_rem + mid_len +
+               s_high + bnsize - s_rem;
+        if(ldns_buffer_reserve(target_buffer, (size_t) raw_sig_len)) {
+                ldns_buffer_write_u8(target_buffer, pre[0]);
+                ldns_buffer_write_u8(target_buffer, raw_sig_len-2);
+                ldns_buffer_write_u8(target_buffer, pre[2]);
+                ldns_buffer_write_u8(target_buffer, bnsize + r_high - r_rem);
+                if(r_high)
+                        ldns_buffer_write_u8(target_buffer, 0);
+                ldns_buffer_write(target_buffer, d+r_rem, bnsize-r_rem);
+                ldns_buffer_write(target_buffer, mid, mid_len-1);
+                ldns_buffer_write_u8(target_buffer, bnsize + s_high - s_rem);
+                if(s_high)
+                        ldns_buffer_write_u8(target_buffer, 0);
+                ldns_buffer_write(target_buffer, d+bnsize+s_rem, bnsize-s_rem);
         }
-
-       raw_sig_len = i2d_ECDSA_SIG(sig, NULL);
-       if (ldns_buffer_reserve(target_buffer, (size_t) raw_sig_len)) {
-                unsigned char* pp = (unsigned char*)
-                       ldns_buffer_current(target_buffer);
-               raw_sig_len = i2d_ECDSA_SIG(sig, &pp);
-                ldns_buffer_skip(target_buffer, (ssize_t) raw_sig_len);
-       }
-        ECDSA_SIG_free(sig);
-
-       return ldns_buffer_status(target_buffer);
+        return ldns_buffer_status(target_buffer);
 }
 
 #endif /* S_SPLINT_S */
 #endif /* USE_ECDSA */
+
+#if defined(USE_ED25519) || defined(USE_ED448)
+/* debug printout routine */
+static void print_hex(const char* str, uint8_t* d, int len)
+{
+       const char hex[] = "0123456789abcdef";
+       int i;
+       printf("%s [len=%d]: ", str, len);
+       for(i=0; i<len; i++) {
+               int x = (d[i]&0xf0)>>4;
+               int y = (d[i]&0x0f);
+               printf("%c%c", hex[x], hex[y]);
+       }
+       printf("\n");
+}
+#endif
+
+#ifdef USE_ED25519
+ldns_rdf *
+ldns_convert_ed25519_rrsig_asn12rdf(const ldns_buffer *sig, long sig_len)
+{
+       unsigned char *data = (unsigned char*)ldns_buffer_begin(sig);
+        ldns_rdf* rdf = NULL;
+
+       /* TODO when Openssl supports signing and you can test this */
+       print_hex("sig in ASN", data, sig_len);
+
+        return rdf;
+}
+
+ldns_status
+ldns_convert_ed25519_rrsig_rdf2asn1(ldns_buffer *target_buffer,
+        const ldns_rdf *sig_rdf)
+{
+       /* TODO when Openssl supports signing and you can test this. */
+       /* convert sig_buf into ASN1 into the target_buffer */
+       print_hex("sig raw", ldns_rdf_data(sig_rdf), ldns_rdf_size(sig_rdf));
+        return ldns_buffer_status(target_buffer);
+}
+#endif /* USE_ED25519 */
+
+#ifdef USE_ED448
+ldns_rdf *
+ldns_convert_ed448_rrsig_asn12rdf(const ldns_buffer *sig, long sig_len)
+{
+       unsigned char *data = (unsigned char*)ldns_buffer_begin(sig);
+        ldns_rdf* rdf = NULL;
+
+       /* TODO when Openssl supports signing and you can test this */
+       print_hex("sig in ASN", data, sig_len);
+
+       return rdf;
+}
+
+ldns_status
+ldns_convert_ed448_rrsig_rdf2asn1(ldns_buffer *target_buffer,
+        const ldns_rdf *sig_rdf)
+{
+       /* TODO when Openssl supports signing and you can test this. */
+       /* convert sig_buf into ASN1 into the target_buffer */
+       print_hex("sig raw", ldns_rdf_data(sig_rdf), ldns_rdf_size(sig_rdf));
+        return ldns_buffer_status(target_buffer);
+}
+#endif /* USE_ED448 */
+
 #endif /* HAVE_SSL */
index f2f9d9d..22f0981 100644 (file)
@@ -20,8 +20,8 @@
 #endif /* HAVE_SSL */
 
 ldns_rr *
-ldns_create_empty_rrsig(ldns_rr_list *rrset,
-                        ldns_key *current_key)
+ldns_create_empty_rrsig(const ldns_rr_list *rrset,
+                        const ldns_key *current_key)
 {
        uint32_t orig_ttl;
        ldns_rr_class orig_class;
@@ -122,13 +122,20 @@ ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
        ldns_rdf *b64rdf = NULL;
 
        switch(ldns_key_algorithm(current_key)) {
+#ifdef USE_DSA
        case LDNS_SIGN_DSA:
        case LDNS_SIGN_DSA_NSEC3:
                b64rdf = ldns_sign_public_evp(
                                   sign_buf,
                                   ldns_key_evp_key(current_key),
-                                  EVP_dss1());
+# ifdef HAVE_EVP_DSS1
+                                  EVP_dss1()
+# else
+                                  EVP_sha1()
+# endif
+                                  );
                break;
+#endif /* USE_DSA */
        case LDNS_SIGN_RSASHA1:
        case LDNS_SIGN_RSASHA1_NSEC3:
                b64rdf = ldns_sign_public_evp(
@@ -171,6 +178,22 @@ ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
                                   ldns_key_evp_key(current_key),
                                   EVP_sha384());
                 break;
+#endif
+#ifdef USE_ED25519
+        case LDNS_SIGN_ED25519:
+               b64rdf = ldns_sign_public_evp(
+                                  sign_buf,
+                                  ldns_key_evp_key(current_key),
+                                  EVP_sha512());
+                break;
+#endif
+#ifdef USE_ED448
+        case LDNS_SIGN_ED448:
+               b64rdf = ldns_sign_public_evp(
+                                  sign_buf,
+                                  ldns_key_evp_key(current_key),
+                                  EVP_sha512());
+                break;
 #endif
        case LDNS_SIGN_RSAMD5:
                b64rdf = ldns_sign_public_evp(
@@ -308,11 +331,13 @@ ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
 ldns_rdf *
 ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
 {
+#ifdef USE_DSA
        unsigned char *sha1_hash;
        ldns_rdf *sigdata_rdf;
        ldns_buffer *b64sig;
 
        DSA_SIG *sig;
+       const BIGNUM *R, *S;
        uint8_t *data;
        size_t pad;
 
@@ -342,17 +367,23 @@ ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
         }
 
        data[0] = 1;
-       pad = 20 - (size_t) BN_num_bytes(sig->r);
+# ifdef HAVE_DSA_SIG_GET0
+       DSA_SIG_get0(sig, &R, &S);
+# else
+       R = sig->r;
+       S = sig->s;
+# endif
+       pad = 20 - (size_t) BN_num_bytes(R);
        if (pad > 0) {
                memset(data + 1, 0, pad);
        }
-       BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad);
+       BN_bn2bin(R, (unsigned char *) (data + 1) + pad);
 
-       pad = 20 - (size_t) BN_num_bytes(sig->s);
+       pad = 20 - (size_t) BN_num_bytes(S);
        if (pad > 0) {
                memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
        }
-       BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
+       BN_bn2bin(S, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
 
        sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
                                                                 1 + 2 * SHA_DIGEST_LENGTH,
@@ -363,28 +394,40 @@ ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
         DSA_SIG_free(sig);
 
        return sigdata_rdf;
+#else
+       (void)to_sign; (void)key;
+       return NULL;
+#endif
 }
 
 #ifdef USE_ECDSA
 #ifndef S_SPLINT_S
+/** returns the number of bytes per signature-component (i.e. bits/8), or 0. */
 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)
+#ifdef HAVE_EVP_PKEY_BASE_ID
+        if(EVP_PKEY_base_id(pkey) != EVP_PKEY_EC)
                 return 0;
+#else
+        if(EVP_PKEY_type(key->type) != EVP_PKEY_EC)
+                return 0;
+#endif
         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) {
+        if(EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1) {
                 EC_KEY_free(ec);
-                return 1;
+                return 32; /* 256/8 */
+       }
+        if(EC_GROUP_get_curve_name(g) == NID_secp384r1) {
+                EC_KEY_free(ec);
+                return 48; /* 384/8 */
         }
         /* downref the eckey, the original is still inside the pkey */
         EC_KEY_free(ec);
@@ -399,9 +442,9 @@ ldns_sign_public_evp(ldns_buffer *to_sign,
                                 const EVP_MD *digest_type)
 {
        unsigned int siglen;
-       ldns_rdf *sigdata_rdf;
+       ldns_rdf *sigdata_rdf = NULL;
        ldns_buffer *b64sig;
-       EVP_MD_CTX ctx;
+       EVP_MD_CTX *ctx;
        const EVP_MD *md_type;
        int r;
 
@@ -419,45 +462,94 @@ ldns_sign_public_evp(ldns_buffer *to_sign,
                return NULL;
        }
 
-       EVP_MD_CTX_init(&ctx);
-       r = EVP_SignInit(&ctx, md_type);
+#ifdef HAVE_EVP_MD_CTX_NEW
+       ctx = EVP_MD_CTX_new();
+#else
+       ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
+       if(ctx) EVP_MD_CTX_init(ctx);
+#endif
+       if(!ctx) {
+               ldns_buffer_free(b64sig);
+               return NULL;
+       }
+
+       r = EVP_SignInit(ctx, md_type);
        if(r == 1) {
-               r = EVP_SignUpdate(&ctx, (unsigned char*)
+               r = EVP_SignUpdate(ctx, (unsigned char*)
                                            ldns_buffer_begin(to_sign),
                                            ldns_buffer_position(to_sign));
        } else {
                ldns_buffer_free(b64sig);
+               EVP_MD_CTX_destroy(ctx);
                return NULL;
        }
        if(r == 1) {
-               r = EVP_SignFinal(&ctx, (unsigned char*)
+               r = EVP_SignFinal(ctx, (unsigned char*)
                                           ldns_buffer_begin(b64sig), &siglen, key);
        } else {
                ldns_buffer_free(b64sig);
+               EVP_MD_CTX_destroy(ctx);
                return NULL;
        }
        if(r != 1) {
                ldns_buffer_free(b64sig);
+               EVP_MD_CTX_destroy(ctx);
                return NULL;
        }
 
-       /* unfortunately, OpenSSL output is differenct from DNS DSA format */
+       /* OpenSSL output is different, convert it */
+       r = 0;
+#ifdef USE_DSA
 #ifndef S_SPLINT_S
+       /* unfortunately, OpenSSL output is different from DNS DSA format */
+# ifdef HAVE_EVP_PKEY_BASE_ID
+       if (EVP_PKEY_base_id(key) == EVP_PKEY_DSA) {
+# else
        if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
+# endif
+               r = 1;
                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 {
+#endif
+#if defined(USE_ECDSA) || defined(USE_ED25519) || defined(USE_ED448)
+       if(
+#  ifdef HAVE_EVP_PKEY_BASE_ID
+               EVP_PKEY_base_id(key)
+#  else
+               EVP_PKEY_type(key->type)
+#  endif
+               == EVP_PKEY_EC) {
+#  ifdef USE_ECDSA
+                if(ldns_pkey_is_ecdsa(key)) {
+                       r = 1;
+                       sigdata_rdf = ldns_convert_ecdsa_rrsig_asn1len2rdf(
+                               b64sig, (long)siglen, ldns_pkey_is_ecdsa(key));
+               }
+#  endif /* USE_ECDSA */
+#  ifdef USE_ED25519
+               if(EVP_PKEY_id(key) == NID_X25519) {
+                       r = 1;
+                       sigdata_rdf = ldns_convert_ed25519_rrsig_asn12rdf(
+                               b64sig, siglen);
+               }
+#  endif /* USE_ED25519 */
+#  ifdef USE_ED448
+               if(EVP_PKEY_id(key) == NID_X448) {
+                       r = 1;
+                       sigdata_rdf = ldns_convert_ed448_rrsig_asn12rdf(
+                               b64sig, siglen);
+               }
+#  endif /* USE_ED448 */
+       }
+#endif /* PKEY_EC */
+       if(r == 0) {
                /* ok output for other types is the same */
                sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
                                                                         ldns_buffer_begin(b64sig));
        }
-#endif /* splint */
        ldns_buffer_free(b64sig);
-       EVP_MD_CTX_cleanup(&ctx);
+       EVP_MD_CTX_destroy(ctx);
        return sigdata_rdf;
 }
 
@@ -566,7 +658,7 @@ ldns_dnssec_addresses_on_glue_list(
  * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
  * function. But watch out! Names that are partially occluded (like glue with
  * the same name as the delegation) will not be marked and should specifically 
- * be taken into account seperately.
+ * be taken into account separately.
  *
  * When glue_list is given (not NULL), in the process of marking the names, all
  * glue resource records will be pushed to that list, even glue at delegation names.
@@ -659,7 +751,7 @@ ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone,
  * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
  * function. But watch out! Names that are partially occluded (like glue with
  * the same name as the delegation) will not be marked and should specifically 
- * be taken into account seperately.
+ * be taken into account separately.
  *
  * \param[in] zone the zone in which to mark the names
  * \return LDNS_STATUS_OK on success, an error code otherwise
@@ -771,10 +863,13 @@ ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
 }
 
 #ifdef HAVE_SSL
-/* in dnssec_zone.c */
-extern int ldns_dname_compare_v(const void *a, const void *b);
+static void
+ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
+       (void) arg;
+       LDNS_FREE(node);
+}
 
-ldns_status
+static ldns_status
 ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
                ldns_rr_list *new_rrs,
                uint8_t algorithm,
@@ -813,21 +908,28 @@ ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
                nsec_ttl = LDNS_DEFAULT_TTL;
        }
 
-       if (map) {
-               if ((*map = ldns_rbtree_create(ldns_dname_compare_v)) 
-                               == NULL) {
-                       map = NULL;
-               };
+       if (ldns_rdf_size(zone->soa->name) > 222) {
+               return LDNS_STATUS_NSEC3_DOMAINNAME_OVERFLOW;
+       }
+
+       if (zone->hashed_names) {
+               ldns_traverse_postorder(zone->hashed_names,
+                               ldns_hashed_names_node_free, NULL);
+               LDNS_FREE(zone->hashed_names);
+       }
+       zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
+       if (zone->hashed_names && map) {
+               *map = zone->hashed_names;
        }
-       nsec3_list = ldns_rr_list_new();
 
        first_name_node = ldns_dnssec_name_node_next_nonglue(
                                          ldns_rbtree_first(zone->names));
 
        current_name_node = first_name_node;
 
-       while (current_name_node &&
-              current_name_node != LDNS_RBTREE_NULL) {
+       while (current_name_node && current_name_node != LDNS_RBTREE_NULL &&
+                       result == LDNS_STATUS_OK) {
+
                current_name = (ldns_dnssec_name *) current_name_node->data;
                nsec_rr = ldns_dnssec_create_nsec3(current_name,
                                                   NULL,
@@ -845,28 +947,49 @@ ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
                ldns_rr_set_ttl(nsec_rr, nsec_ttl);
                result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
                ldns_rr_list_push_rr(new_rrs, nsec_rr);
-               ldns_rr_list_push_rr(nsec3_list, nsec_rr);
-               if (map) {
+               if (ldns_rr_owner(nsec_rr)) {
                        hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
-                       if (hashmap_node && ldns_rr_owner(nsec_rr)) {
-                               hashmap_node->key = ldns_dname_label(
-                                       ldns_rr_owner(nsec_rr), 0);
-                               if (hashmap_node->key) {
-                                       hashmap_node->data = current_name->name;
-                                       (void) ldns_rbtree_insert(
-                                                       *map, hashmap_node);
-                               }
+                       if (hashmap_node == NULL) {
+                               return LDNS_STATUS_MEM_ERR;
+                       }
+                       current_name->hashed_name = 
+                               ldns_dname_label(ldns_rr_owner(nsec_rr), 0);
+
+                       if (current_name->hashed_name == NULL) {
+                               LDNS_FREE(hashmap_node);
+                               return LDNS_STATUS_MEM_ERR;
+                       }
+                       hashmap_node->key  = current_name->hashed_name;
+                       hashmap_node->data = current_name;
+
+                       if (! ldns_rbtree_insert(zone->hashed_names
+                                               , hashmap_node)) {
+                               LDNS_FREE(hashmap_node);
                        }
                }
                current_name_node = ldns_dnssec_name_node_next_nonglue(
                                   ldns_rbtree_next(current_name_node));
        }
        if (result != LDNS_STATUS_OK) {
-               ldns_rr_list_free(nsec3_list);
                return result;
        }
 
-       ldns_rr_list_sort_nsec3(nsec3_list);
+       /* Make sorted list of nsec3s (via zone->hashed_names)
+        */
+       nsec3_list = ldns_rr_list_new();
+       if (nsec3_list == NULL) {
+               return LDNS_STATUS_MEM_ERR;
+       }
+       for ( hashmap_node  = ldns_rbtree_first(zone->hashed_names)
+           ; hashmap_node != LDNS_RBTREE_NULL
+           ; hashmap_node  = ldns_rbtree_next(hashmap_node)
+           ) {
+               current_name = (ldns_dnssec_name *) hashmap_node->data;
+               nsec_rr = ((ldns_dnssec_name *) hashmap_node->data)->nsec;
+               if (nsec_rr) {
+                       ldns_rr_list_push_rr(nsec3_list, nsec_rr);
+               }
+       }
        result = ldns_dnssec_chain_nsec3_list(nsec3_list);
        ldns_rr_list_free(nsec3_list);
 
@@ -913,7 +1036,9 @@ ldns_dnssec_remove_signatures( ldns_dnssec_rrs *signatures
                ldns_key_list_set_use(key_list, false);
                break;
                default:
+#ifdef STDERR_MSGS
                        fprintf(stderr, "[XX] unknown return value from callback\n");
+#endif
                        break;
                }
                return NULL;
@@ -965,7 +1090,9 @@ ldns_dnssec_remove_signatures( ldns_dnssec_rrs *signatures
                        LDNS_FREE(cur_rr);
                        break;
                default:
+#ifdef STDERR_MSGS
                        fprintf(stderr, "[XX] unknown return value from callback\n");
+#endif
                        break;
                }
                cur_rr = next_rr;
@@ -988,39 +1115,86 @@ ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
 
 /** If there are KSKs use only them and mark ZSKs unused */
 static void
-ldns_key_list_filter_for_dnskey(ldns_key_list *key_list)
+ldns_key_list_filter_for_dnskey(ldns_key_list *key_list, int flags)
 {
-       int saw_ksk = 0;
+       bool algos[256]
+#ifndef S_SPLINT_S
+                       = { false }
+#endif
+                                  ;
+       ldns_signing_algorithm saw_ksk = 0;
+       ldns_key *key;
        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_ksk = 1;
-                       break;
-               }
-       if(!saw_ksk)
+
+       if (!ldns_key_list_key_count(key_list))
+               return;
+
+       for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
+               key = ldns_key_list_key(key_list, i);
+               if ((ldns_key_flags(key) & LDNS_KEY_SEP_KEY) && !saw_ksk)
+                       saw_ksk = ldns_key_algorithm(key);
+               algos[ldns_key_algorithm(key)] = true;
+       }
+       if (!saw_ksk)
                return;
-       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);
+       else
+               algos[saw_ksk] = 0;
+
+       for (i =0; i < ldns_key_list_key_count(key_list); i++) {
+               key = ldns_key_list_key(key_list, i);
+               if (!(ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
+                       /* We have a ZSK.
+                        * Still use it if it has a unique algorithm though!
+                        */
+                       if ((flags & LDNS_SIGN_WITH_ALL_ALGORITHMS) &&
+                           algos[ldns_key_algorithm(key)])
+                               algos[ldns_key_algorithm(key)] = false;
+                       else
+                               ldns_key_set_use(key, 0);
+               }
+       }
 }
 
 /** If there are no ZSKs use KSK as ZSK */
 static void
-ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list)
+ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list, int flags)
 {
-       int saw_zsk = 0;
+       bool algos[256]
+#ifndef S_SPLINT_S
+                       = { false }
+#endif
+                                  ;
+       ldns_signing_algorithm saw_zsk = 0;
+       ldns_key *key;
        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)
+       
+       if (!ldns_key_list_key_count(key_list))
                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);
+
+       for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
+               key = ldns_key_list_key(key_list, i);
+               if (!(ldns_key_flags(key) & LDNS_KEY_SEP_KEY) && !saw_zsk)
+                       saw_zsk = ldns_key_algorithm(key);
+               algos[ldns_key_algorithm(key)] = true;
+       }
+       if (!saw_zsk)
+               return;
+       else
+               algos[saw_zsk] = 0;
+
+       for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
+               key = ldns_key_list_key(key_list, i);
+               if((ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
+                       /* We have a KSK.
+                        * Still use it if it has a unique algorithm though!
+                        */
+                       if ((flags & LDNS_SIGN_WITH_ALL_ALGORITHMS) &&
+                           algos[ldns_key_algorithm(key)])
+                               algos[ldns_key_algorithm(key)] = false;
+                       else
+                               ldns_key_set_use(key, 0);
+               }
+       }
 }
 
 ldns_status
@@ -1079,10 +1253,10 @@ ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone
                                                                                        arg);
                                if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) &&
                                        cur_rrset->type == LDNS_RR_TYPE_DNSKEY)
-                                       ldns_key_list_filter_for_dnskey(key_list);
+                                       ldns_key_list_filter_for_dnskey(key_list, flags);
 
                                if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY)
-                                       ldns_key_list_filter_for_non_dnskey(key_list);
+                                       ldns_key_list_filter_for_non_dnskey(key_list, flags);
 
                                /* TODO: just set count to zero? */
                                rr_list = ldns_rr_list_new();
@@ -1135,7 +1309,7 @@ ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone
                                                                                key_list,
                                                                                func,
                                                                                arg);
-                       ldns_key_list_filter_for_non_dnskey(key_list);
+                       ldns_key_list_filter_for_non_dnskey(key_list, flags);
 
                        rr_list = ldns_rr_list_new();
                        ldns_rr_list_push_rr(rr_list, cur_name->nsec);
index d8d4664..8ba4c81 100644 (file)
@@ -16,7 +16,7 @@
 #include <openssl/md5.h>
 
 ldns_dnssec_data_chain *
-ldns_dnssec_data_chain_new()
+ldns_dnssec_data_chain_new(void)
 {
        ldns_dnssec_data_chain *nc = LDNS_CALLOC(ldns_dnssec_data_chain, 1);
         if(!nc) return NULL;
@@ -216,7 +216,7 @@ ldns_dnssec_build_data_chain_other(ldns_resolver *res,
        }
 }
 
-ldns_dnssec_data_chain *
+static ldns_dnssec_data_chain *
 ldns_dnssec_build_data_chain_nokeyname(ldns_resolver *res,
                                        uint16_t qflags,
                                        ldns_rr *orig_rr,
@@ -439,7 +439,7 @@ ldns_dnssec_build_data_chain(ldns_resolver *res,
 }
 
 ldns_dnssec_trust_tree *
-ldns_dnssec_trust_tree_new()
+ldns_dnssec_trust_tree_new(void)
 {
        ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree,
                                                                                   1);
@@ -495,7 +495,7 @@ print_tabs(FILE *out, size_t nr, uint8_t *map, size_t treedepth)
        }
 }
 
-void
+static void
 ldns_dnssec_trust_tree_print_sm_fmt(FILE *out, 
                const ldns_output_format *fmt,
                ldns_dnssec_trust_tree *tree,
@@ -628,18 +628,6 @@ ldns_dnssec_trust_tree_print_sm_fmt(FILE *out,
        }
 }
 
-void
-ldns_dnssec_trust_tree_print_sm(FILE *out, 
-               ldns_dnssec_trust_tree *tree,
-               size_t tabs,
-               bool extended,
-               uint8_t *sibmap,
-               size_t treedepth)
-{
-       ldns_dnssec_trust_tree_print_sm_fmt(out, ldns_output_format_default, 
-                       tree, tabs, extended, sibmap, treedepth);
-}
-
 void
 ldns_dnssec_trust_tree_print_fmt(FILE *out, const ldns_output_format *fmt,
                ldns_dnssec_trust_tree *tree,
@@ -1100,8 +1088,8 @@ ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree,
 
 ldns_status
 ldns_verify_time(
-               ldns_rr_list *rrset,
-               ldns_rr_list *rrsig, 
+               const ldns_rr_list *rrset,
+               const ldns_rr_list *rrsig, 
                const ldns_rr_list *keys, 
                time_t check_time,
                ldns_rr_list *good_keys
@@ -1821,7 +1809,7 @@ ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
 
 #ifdef USE_GOST
 EVP_PKEY*
-ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
+ldns_gost2pkey_raw(const unsigned char* key, size_t keylen)
 {
        /* prefix header for X509 encoding */
        uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 
@@ -1844,8 +1832,8 @@ ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
 }
 
 static ldns_status
-ldns_verify_rrsig_gost_raw(unsigned char* sig, size_t siglen, 
-       ldns_buffer* rrset, unsigned char* key, size_t keylen)
+ldns_verify_rrsig_gost_raw(const unsigned char* sig, size_t siglen, 
+       const ldns_buffer* rrset, const unsigned char* key, size_t keylen)
 {
        EVP_PKEY *evp_key;
        ldns_status result;
@@ -1866,9 +1854,103 @@ ldns_verify_rrsig_gost_raw(unsigned char* sig, size_t siglen,
 }
 #endif
 
+#ifdef USE_ED25519
+EVP_PKEY*
+ldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
+{
+        const unsigned char* pp = key; /* pp gets modified by o2i() */
+        EVP_PKEY *evp_key;
+        EC_KEY *ec;
+       if(keylen != 32)
+               return NULL; /* wrong length */
+        ec = EC_KEY_new_by_curve_name(NID_X25519);
+       if(!ec) return NULL;
+        if(!o2i_ECPublicKey(&ec, &pp, (int)keylen)) {
+                EC_KEY_free(ec);
+                return NULL;
+       }
+        evp_key = EVP_PKEY_new();
+        if(!evp_key) {
+                EC_KEY_free(ec);
+                return NULL;
+        }
+        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
+               EVP_PKEY_free(evp_key);
+               EC_KEY_free(ec);
+               return NULL;
+       }
+        return evp_key;
+}
+
+static ldns_status
+ldns_verify_rrsig_ed25519_raw(unsigned char* sig, size_t siglen,
+       ldns_buffer* rrset, unsigned char* key, size_t keylen)
+{
+        EVP_PKEY *evp_key;
+        ldns_status result;
+
+        evp_key = ldns_ed255192pkey_raw(key, keylen);
+        if(!evp_key) {
+               /* could not convert key */
+               return LDNS_STATUS_CRYPTO_BOGUS;
+        }
+       result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key,
+               EVP_sha512());
+       EVP_PKEY_free(evp_key);
+       return result;
+}
+#endif /* USE_ED25519 */
+
+#ifdef USE_ED448
+EVP_PKEY*
+ldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
+{
+        const unsigned char* pp = key; /* pp gets modified by o2i() */
+        EVP_PKEY *evp_key;
+        EC_KEY *ec;
+       if(keylen != 57)
+               return NULL; /* wrong length */
+        ec = EC_KEY_new_by_curve_name(NID_X448);
+       if(!ec) return NULL;
+        if(!o2i_ECPublicKey(&ec, &pp, (int)keylen)) {
+                EC_KEY_free(ec);
+                return NULL;
+       }
+        evp_key = EVP_PKEY_new();
+        if(!evp_key) {
+                EC_KEY_free(ec);
+                return NULL;
+        }
+        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
+               EVP_PKEY_free(evp_key);
+               EC_KEY_free(ec);
+               return NULL;
+       }
+        return evp_key;
+}
+
+static ldns_status
+ldns_verify_rrsig_ed448_raw(unsigned char* sig, size_t siglen,
+       ldns_buffer* rrset, unsigned char* key, size_t keylen)
+{
+        EVP_PKEY *evp_key;
+        ldns_status result;
+
+        evp_key = ldns_ed4482pkey_raw(key, keylen);
+        if(!evp_key) {
+               /* could not convert key */
+               return LDNS_STATUS_CRYPTO_BOGUS;
+        }
+       result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key,
+               EVP_sha512());
+       EVP_PKEY_free(evp_key);
+       return result;
+}
+#endif /* USE_ED448 */
+
 #ifdef USE_ECDSA
 EVP_PKEY*
-ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
+ldns_ecdsa2pkey_raw(const 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;
@@ -1947,6 +2029,7 @@ ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
 {
        /* check for right key */
        switch(algo) {
+#ifdef USE_DSA
        case LDNS_DSA:
        case LDNS_DSA_NSEC3:
                return ldns_verify_rrsig_dsa_raw(sig,
@@ -1955,6 +2038,7 @@ ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
                                                                   key,
                                                                   keylen);
                break;
+#endif
        case LDNS_RSASHA1:
        case LDNS_RSASHA1_NSEC3:
                return ldns_verify_rrsig_rsasha1_raw(sig,
@@ -1991,6 +2075,18 @@ ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
                return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf,
                        key, keylen, algo);
                break;
+#endif
+#ifdef USE_ED25519
+       case LDNS_ED25519:
+               return ldns_verify_rrsig_ed25519_raw(sig, siglen, verify_buf,
+                       key, keylen);
+               break;
+#endif
+#ifdef USE_ED448
+       case LDNS_ED448:
+               return ldns_verify_rrsig_ed448_raw(sig, siglen, verify_buf,
+                       key, keylen);
+               break;
 #endif
        case LDNS_RSAMD5:
                return ldns_verify_rrsig_rsamd5_raw(sig,
@@ -2014,7 +2110,7 @@ ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
  * @param sig: signature to take TTL and wildcard values from
  */
 static void
-ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
+ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, const ldns_rr* rrsig)
 {
        uint32_t orig_ttl;
        uint16_t i;
@@ -2063,7 +2159,7 @@ ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
  * @return OK or more specific error.
  */
 static ldns_status
-ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
+ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, const ldns_rr* rrsig)
 {
        uint8_t sig_algo;
        
@@ -2100,6 +2196,7 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
                        return LDNS_STATUS_MEM_ERR;
                }
                break;
+#ifdef USE_DSA
        case LDNS_DSA:
        case LDNS_DSA_NSEC3:
                /* EVP takes rfc2459 format, which is a tad longer than dns format */
@@ -2116,6 +2213,7 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
                        return LDNS_STATUS_MEM_ERR;
                }
                break;
+#endif
 #ifdef USE_ECDSA
         case LDNS_ECDSAP256SHA256:
         case LDNS_ECDSAP384SHA384:
@@ -2130,6 +2228,32 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
                        return LDNS_STATUS_MEM_ERR;
                 }
                 break;
+#endif
+#ifdef USE_ED25519
+       case LDNS_ED25519:
+                /* EVP produces an ASN prefix on the signature, which is
+                 * not used in the DNS */
+               if (ldns_rr_rdf(rrsig, 8) == NULL) {
+                       return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
+               }
+               if (ldns_convert_ed25519_rrsig_rdf2asn1(
+                       rawsig_buf, ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
+                       return LDNS_STATUS_MEM_ERR;
+                }
+               break;
+#endif
+#ifdef USE_ED448
+       case LDNS_ED448:
+                /* EVP produces an ASN prefix on the signature, which is
+                 * not used in the DNS */
+               if (ldns_rr_rdf(rrsig, 8) == NULL) {
+                       return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
+               }
+               if (ldns_convert_ed448_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:
@@ -2148,7 +2272,7 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
  * @return status code LDNS_STATUS_OK if all is fine.
  */
 static ldns_status
-ldns_rrsig_check_timestamps(ldns_rr* rrsig, time_t now)
+ldns_rrsig_check_timestamps(const ldns_rr* rrsig, time_t now)
 {
        int32_t inception, expiration;
        
@@ -2183,7 +2307,7 @@ ldns_rrsig_check_timestamps(ldns_rr* rrsig, time_t now)
  */
 static ldns_status
 ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 
-       ldns_rr_list* rrset_clone, ldns_rr* rrsig)
+       ldns_rr_list* rrset_clone, const ldns_rr* rrsig)
 {
        ldns_status result;
 
@@ -2230,7 +2354,7 @@ ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
  */
 static ldns_status
 ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 
-       ldns_rr* rrsig, ldns_rr* key)
+       const ldns_rr* rrsig, ldns_rr* key)
 {
        uint8_t sig_algo;
        
@@ -2297,8 +2421,8 @@ ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf,
  */
 ldns_status
 ldns_verify_rrsig_keylist_time(
-               ldns_rr_list *rrset,
-               ldns_rr *rrsig,
+               const ldns_rr_list *rrset,
+               const ldns_rr *rrsig,
                const ldns_rr_list *keys, 
                time_t check_time,
                ldns_rr_list *good_keys)
@@ -2346,8 +2470,8 @@ ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
 }
 
 ldns_status
-ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
-                                        ldns_rr *rrsig,
+ldns_verify_rrsig_keylist_notime(const ldns_rr_list *rrset,
+                                        const ldns_rr *rrsig,
                                         const ldns_rr_list *keys, 
                                         ldns_rr_list *good_keys)
 {
@@ -2494,21 +2618,28 @@ ldns_verify_rrsig_evp(ldns_buffer *sig,
 }
 
 ldns_status
-ldns_verify_rrsig_evp_raw(unsigned char *sig, size_t siglen, 
-                                        ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
+ldns_verify_rrsig_evp_raw(const unsigned char *sig, size_t siglen, 
+                                        const ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
 {
-       EVP_MD_CTX ctx;
+       EVP_MD_CTX *ctx;
        int res;
 
-       EVP_MD_CTX_init(&ctx);
+#ifdef HAVE_EVP_MD_CTX_NEW
+       ctx = EVP_MD_CTX_new();
+#else
+       ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
+       if(ctx) EVP_MD_CTX_init(ctx);
+#endif
+       if(!ctx)
+               return LDNS_STATUS_MEM_ERR;
        
-       EVP_VerifyInit(&ctx, digest_type);
-       EVP_VerifyUpdate(&ctx,
+       EVP_VerifyInit(ctx, digest_type);
+       EVP_VerifyUpdate(ctx,
                                  ldns_buffer_begin(rrset),
                                  ldns_buffer_position(rrset));
-       res = EVP_VerifyFinal(&ctx, sig, (unsigned int) siglen, key);
+       res = EVP_VerifyFinal(ctx, sig, (unsigned int) siglen, key);
        
-       EVP_MD_CTX_cleanup(&ctx);
+       EVP_MD_CTX_destroy(ctx);
        
        if (res == 1) {
                return LDNS_STATUS_OK;
@@ -2557,6 +2688,7 @@ ldns_status
 ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
                                         ldns_buffer* rrset, unsigned char* key, size_t keylen)
 {
+#ifdef USE_DSA
        EVP_PKEY *evp_key;
        ldns_status result;
 
@@ -2566,13 +2698,21 @@ ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
                                                                siglen,
                                                                rrset,
                                                                evp_key,
-                                                               EVP_dss1());
+# ifdef HAVE_EVP_DSS1
+                                                               EVP_dss1()
+# else
+                                                               EVP_sha1()
+# endif
+                                                               );
        } else {
                result = LDNS_STATUS_SSL_ERR;
        }
        EVP_PKEY_free(evp_key);
        return result;
-
+#else
+       (void)sig; (void)siglen; (void)rrset; (void)key; (void)keylen;
+       return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
+#endif
 }
 
 ldns_status
index df71a23..f610a3c 100644 (file)
@@ -7,7 +7,7 @@
 #include <ldns/ldns.h>
 
 ldns_dnssec_rrs *
-ldns_dnssec_rrs_new()
+ldns_dnssec_rrs_new(void)
 {
        ldns_dnssec_rrs *new_rrs;
        new_rrs = LDNS_MALLOC(ldns_dnssec_rrs);
@@ -54,10 +54,8 @@ ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr)
 
        /* this could be done more efficiently; name and type should already
           be equal */
-       cmp = ldns_rr_compare(rrs->rr,
-                                         rr);
-       /* should we error on equal? */
-       if (cmp <= 0) {
+       cmp = ldns_rr_compare(rrs->rr, rr);
+       if (cmp < 0) {
                if (rrs->next) {
                        return ldns_dnssec_rrs_add_rr(rrs->next, rr);
                } else {
@@ -74,12 +72,13 @@ ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr)
                rrs->rr = rr;
                rrs->next = new_rrs;
        }
+       /* Silently ignore equal rr's */
        return LDNS_STATUS_OK;
 }
 
 void
 ldns_dnssec_rrs_print_fmt(FILE *out, const ldns_output_format *fmt,
-              ldns_dnssec_rrs *rrs)
+              const ldns_dnssec_rrs *rrs)
 {
        if (!rrs) {
                if ((fmt->flags & LDNS_COMMENT_LAYOUT))
@@ -95,14 +94,14 @@ ldns_dnssec_rrs_print_fmt(FILE *out, const ldns_output_format *fmt,
 }
 
 void
-ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs)
+ldns_dnssec_rrs_print(FILE *out, const ldns_dnssec_rrs *rrs)
 {
        ldns_dnssec_rrs_print_fmt(out, ldns_output_format_default, rrs);
 }
 
 
 ldns_dnssec_rrsets *
-ldns_dnssec_rrsets_new()
+ldns_dnssec_rrsets_new(void)
 {
        ldns_dnssec_rrsets *new_rrsets;
        new_rrsets = LDNS_MALLOC(ldns_dnssec_rrsets);
@@ -144,7 +143,7 @@ ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets)
 }
 
 ldns_rr_type
-ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets)
+ldns_dnssec_rrsets_type(const ldns_dnssec_rrsets *rrsets)
 {
        if (rrsets) {
                return rrsets->type;
@@ -164,7 +163,7 @@ ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
        return LDNS_STATUS_ERR;
 }
 
-ldns_dnssec_rrsets *
+static ldns_dnssec_rrsets *
 ldns_dnssec_rrsets_new_frm_rr(ldns_rr *rr)
 {
        ldns_dnssec_rrsets *new_rrsets;
@@ -270,9 +269,9 @@ ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr)
        return result;
 }
 
-void
+static void
 ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
-               ldns_dnssec_rrsets *rrsets,
+               const ldns_dnssec_rrsets *rrsets,
                bool follow,
                bool show_soa)
 {
@@ -298,34 +297,24 @@ ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
        }
 }
 
-void
-ldns_dnssec_rrsets_print_soa(FILE *out,
-               ldns_dnssec_rrsets *rrsets,
-               bool follow,
-               bool show_soa)
-{
-       ldns_dnssec_rrsets_print_soa_fmt(out, ldns_output_format_default,
-                       rrsets, follow, show_soa);
-}
-
 
 void
 ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt,
-               ldns_dnssec_rrsets *rrsets, 
+               const ldns_dnssec_rrsets *rrsets, 
                bool follow)
 {
        ldns_dnssec_rrsets_print_soa_fmt(out, fmt, rrsets, follow, true);
 }
 
 void
-ldns_dnssec_rrsets_print(FILE *out, ldns_dnssec_rrsets *rrsets, bool follow)
+ldns_dnssec_rrsets_print(FILE *out, const ldns_dnssec_rrsets *rrsets, bool follow)
 {
        ldns_dnssec_rrsets_print_fmt(out, ldns_output_format_default, 
                        rrsets, follow);
 }
 
 ldns_dnssec_name *
-ldns_dnssec_name_new()
+ldns_dnssec_name_new(void)
 {
        ldns_dnssec_name *new_name;
 
@@ -402,7 +391,7 @@ ldns_dnssec_name_deep_free(ldns_dnssec_name *name)
 }
 
 ldns_rdf *
-ldns_dnssec_name_name(ldns_dnssec_name *name)
+ldns_dnssec_name_name(const ldns_dnssec_name *name)
 {
        if (name) {
                return name->name;
@@ -411,7 +400,7 @@ ldns_dnssec_name_name(ldns_dnssec_name *name)
 }
 
 bool
-ldns_dnssec_name_is_glue(ldns_dnssec_name *name)
+ldns_dnssec_name_is_glue(const ldns_dnssec_name *name)
 {
        if (name) {
                return name->is_glue;
@@ -428,14 +417,6 @@ ldns_dnssec_name_set_name(ldns_dnssec_name *rrset,
        }
 }
 
-ldns_rr *
-ldns_dnssec_name_nsec(ldns_dnssec_name *rrset)
-{
-       if (rrset) {
-               return rrset->nsec;
-       }
-       return NULL;
-}
 
 void
 ldns_dnssec_name_set_nsec(ldns_dnssec_name *rrset, ldns_rr *nsec)
@@ -468,8 +449,6 @@ ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
                                    ldns_rr *rr)
 {
        ldns_status result = LDNS_STATUS_OK;
-       ldns_rdf *name_name;
-       bool hashed_name = false;
        ldns_rr_type rr_type;
        ldns_rr_type typecovered = 0;
 
@@ -485,19 +464,6 @@ ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
                typecovered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
        }
 
-#ifdef HAVE_SSL
-       if (rr_type == LDNS_RR_TYPE_NSEC3 ||
-           typecovered == LDNS_RR_TYPE_NSEC3) {
-               name_name = ldns_nsec3_hash_name_frm_nsec3(rr,
-                                                                                  ldns_dnssec_name_name(name));
-               hashed_name = true;
-       } else {
-               name_name = ldns_dnssec_name_name(name);
-       }
-#else
-       name_name = ldns_dnssec_name_name(name);
-#endif /* HAVE_SSL */
-
        if (rr_type == LDNS_RR_TYPE_NSEC ||
            rr_type == LDNS_RR_TYPE_NSEC3) {
                /* XX check if is already set (and error?) */
@@ -519,16 +485,11 @@ ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
                        result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
                }
        }
-
-       if (hashed_name) {
-               ldns_rdf_deep_free(name_name);
-       }
-
        return result;
 }
 
 ldns_dnssec_rrsets *
-ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
+ldns_dnssec_name_find_rrset(const ldns_dnssec_name *name,
                                           ldns_rr_type type) {
        ldns_dnssec_rrsets *result;
 
@@ -544,13 +505,13 @@ ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
 }
 
 ldns_dnssec_rrsets *
-ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
-                                          ldns_rdf *dname,
+ldns_dnssec_zone_find_rrset(const ldns_dnssec_zone *zone,
+                                          const ldns_rdf *dname,
                                           ldns_rr_type type)
 {
        ldns_rbnode_t *node;
 
-       if (!zone || !dname) {
+       if (!zone || !dname || !zone->names) {
                return NULL;
        }
 
@@ -563,9 +524,9 @@ ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
        }
 }
 
-void
+static void
 ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
-               ldns_dnssec_name *name, 
+               const ldns_dnssec_name *name, 
                bool show_soa)
 {
        if (name) {
@@ -589,34 +550,30 @@ ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
        }
 }
 
-void
-ldns_dnssec_name_print_soa(FILE *out, ldns_dnssec_name *name, bool show_soa)
-{
-       ldns_dnssec_name_print_soa_fmt(out, ldns_output_format_default,
-                      name, show_soa);
-}
 
 void
 ldns_dnssec_name_print_fmt(FILE *out, const ldns_output_format *fmt,
-               ldns_dnssec_name *name)
+               const ldns_dnssec_name *name)
 {
        ldns_dnssec_name_print_soa_fmt(out, fmt, name, true);
 }
 
 void
-ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name)
+ldns_dnssec_name_print(FILE *out, const ldns_dnssec_name *name)
 {
        ldns_dnssec_name_print_fmt(out, ldns_output_format_default, name);
 }
 
 
 ldns_dnssec_zone *
-ldns_dnssec_zone_new()
+ldns_dnssec_zone_new(void)
 {
        ldns_dnssec_zone *zone = LDNS_MALLOC(ldns_dnssec_zone);
         if(!zone) return NULL;
        zone->soa = NULL;
        zone->names = NULL;
+       zone->hashed_names = NULL;
+       zone->_nsec3params = NULL;
 
        return zone;
 }
@@ -636,8 +593,19 @@ rr_is_rrsig_covering(ldns_rr* rr, ldns_rr_type t)
  */
 #define FASTER_DNSSEC_ZONE_NEW_FRM_FP 1 /* Because of L2 cache efficiency */
 
+static ldns_status
+ldns_dnssec_zone_add_empty_nonterminals_nsec3(
+               ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s);
+
+static void
+ldns_todo_nsec3_ents_node_free(ldns_rbnode_t *node, void *arg) {
+       (void) arg;
+       ldns_rdf_deep_free((ldns_rdf *)node->key);
+       LDNS_FREE(node);
+}
+
 ldns_status
-ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
+ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, const ldns_rdf* origin,
                uint32_t ttl, ldns_rr_class ATTR_UNUSED(c), int* line_nr)
 {
        ldns_rr* cur_rr;
@@ -647,34 +615,58 @@ ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
        ldns_rdf *my_prev = NULL;
 
        ldns_dnssec_zone *newzone = ldns_dnssec_zone_new();
+       /* NSEC3s may occur before the names they refer to. We must remember
+          them and add them to the name later on, after the name is read.
+          We track not yet  matching NSEC3s*n the todo_nsec3s list */
+       ldns_rr_list* todo_nsec3s = ldns_rr_list_new();
        /* when reading NSEC3s, there is a chance that we encounter nsecs
           for empty nonterminals, whose nonterminals we cannot derive yet
-          because the needed information is to be read later. in that case
-          we keep a list of those nsec3's and retry to add them later */
-       ldns_rr_list* todo_nsec3s = ldns_rr_list_new();
+          because the needed information is to be read later.
+
+          nsec3_ents (where ent is e.n.t.; i.e. empty non terminal) will
+          hold the NSEC3s that still didn't have a matching name in the
+          zone tree, even after all names were read.  They can only match
+          after the zone is equiped with all the empty non terminals. */
+       ldns_rbtree_t todo_nsec3_ents;
+       ldns_rbnode_t *new_node;
        ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new();
 
-       ldns_status status = LDNS_STATUS_MEM_ERR;
+       ldns_status status;
 
 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
        ldns_zone* zone = NULL;
-       if (ldns_zone_new_frm_fp_l(&zone, fp, origin,ttl, c, line_nr)
-                       != LDNS_STATUS_OK) goto error;
 #else
        uint32_t  my_ttl = ttl;
 #endif
 
-       if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) goto error;
+       ldns_rbtree_init(&todo_nsec3_ents, ldns_dname_compare_v);
 
+#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
+       status = ldns_zone_new_frm_fp_l(&zone, fp, origin,ttl, c, line_nr);
+       if (status != LDNS_STATUS_OK)
+               goto error;
+#endif
+       if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) {
+               status = LDNS_STATUS_MEM_ERR;
+               goto error;
+       }
        if (origin) {
-               if (!(my_origin = ldns_rdf_clone(origin))) goto error;
-               if (!(my_prev   = ldns_rdf_clone(origin))) goto error;
+               if (!(my_origin = ldns_rdf_clone(origin))) {
+                       status = LDNS_STATUS_MEM_ERR;
+                       goto error;
+               }
+               if (!(my_prev   = ldns_rdf_clone(origin))) {
+                       status = LDNS_STATUS_MEM_ERR;
+                       goto error;
+               }
        }
 
 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
-       if (ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone))
-                       != LDNS_STATUS_OK) goto error;
-
+       if (ldns_zone_soa(zone)) {
+               status = ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone));
+               if (status != LDNS_STATUS_OK)
+                       goto error;
+       }
        for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
                cur_rr = ldns_rr_list_rr(ldns_zone_rrs(zone), i);
                status = LDNS_STATUS_OK;
@@ -699,6 +691,8 @@ ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
                                        ldns_rr_list_push_rr(todo_nsec3s,
                                                        cur_rr);
                                }
+                               status = LDNS_STATUS_OK;
+
                        } else if (status != LDNS_STATUS_OK)
                                goto error;
 
@@ -720,28 +714,33 @@ ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
                }
        }
 
-       if (ldns_rr_list_rr_count(todo_nsec3s) > 0) {
-               (void) ldns_dnssec_zone_add_empty_nonterminals(newzone);
-               for (i = 0; status == LDNS_STATUS_OK && 
-                               i < ldns_rr_list_rr_count(todo_nsec3s); i++) {
-                       cur_rr = ldns_rr_list_rr(todo_nsec3s, i);
-                       status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
-               }
-               for (i = 0; status == LDNS_STATUS_OK &&
-                               i < ldns_rr_list_rr_count(todo_nsec3_rrsigs);
-                               i++){
-                       cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
-                       status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
-               }
-       } else if (ldns_rr_list_rr_count(todo_nsec3_rrsigs) > 0) {
-               for (i = 0; status == LDNS_STATUS_OK &&
-                               i < ldns_rr_list_rr_count(todo_nsec3_rrsigs);
-                               i++){
-                       cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
-                       status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
+       for (i = 0; status == LDNS_STATUS_OK &&
+                       i < ldns_rr_list_rr_count(todo_nsec3s); i++) {
+               cur_rr = ldns_rr_list_rr(todo_nsec3s, i);
+               status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
+               if (status == LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) {
+                       if (!(new_node = LDNS_MALLOC(ldns_rbnode_t))) {
+                               status = LDNS_STATUS_MEM_ERR;
+                               break;
+                       }
+                       new_node->key  = ldns_dname_label(ldns_rr_owner(cur_rr), 0);
+                       new_node->data = cur_rr;
+                       if (!ldns_rbtree_insert(&todo_nsec3_ents, new_node)) {
+                               LDNS_FREE(new_node);
+                               status = LDNS_STATUS_MEM_ERR;
+                               break;
+                       }
+                       status = LDNS_STATUS_OK;
                }
        }
-
+       if (todo_nsec3_ents.count > 0)
+               (void) ldns_dnssec_zone_add_empty_nonterminals_nsec3(
+                               newzone, &todo_nsec3_ents);
+       for (i = 0; status == LDNS_STATUS_OK &&
+                       i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++) {
+               cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
+               status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
+       }
        if (z) {
                *z = newzone;
                newzone = NULL;
@@ -756,6 +755,8 @@ error:
        }
 #endif
        ldns_rr_list_free(todo_nsec3_rrsigs);
+       ldns_traverse_postorder(&todo_nsec3_ents,
+                       ldns_todo_nsec3_ents_node_free, NULL);
        ldns_rr_list_free(todo_nsec3s);
 
        if (my_origin) {
@@ -771,20 +772,20 @@ error:
 }
 
 ldns_status
-ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
+ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp, const ldns_rdf* origin,
                uint32_t ttl, ldns_rr_class ATTR_UNUSED(c))
 {
        return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
 }
 
-void
+static void
 ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) {
        (void) arg;
        ldns_dnssec_name_free((ldns_dnssec_name *)node->data);
        LDNS_FREE(node);
 }
 
-void
+static void
 ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) {
        (void) arg;
        ldns_dnssec_name_deep_free((ldns_dnssec_name *)node->data);
@@ -827,31 +828,99 @@ ldns_dname_compare_v(const void *a, const void *b) {
        return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b);
 }
 
-ldns_rbnode_t *
-ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone,
-                                     ldns_rr *rr) {
-       ldns_rbnode_t *current_node = ldns_rbtree_first(zone->names);
-       ldns_dnssec_name *current_name;
-       ldns_rdf *hashed_name;
+static void
+ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
+               ldns_dnssec_name* name, ldns_rr* nsec3rr);
 
-       hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
+static void
+ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
+       (void) arg;
+       LDNS_FREE(node);
+}
 
-       while (current_node != LDNS_RBTREE_NULL) {
+static void
+ldns_dnssec_zone_hashed_names_from_nsec3(
+               ldns_dnssec_zone* zone, ldns_rr* nsec3rr)
+{
+       ldns_rbnode_t* current_node;
+       ldns_dnssec_name* current_name;
+
+       assert(zone != NULL);
+       assert(nsec3rr != NULL);
+
+       if (zone->hashed_names) {
+               ldns_traverse_postorder(zone->hashed_names,
+                               ldns_hashed_names_node_free, NULL);
+               LDNS_FREE(zone->hashed_names);
+       }
+       zone->_nsec3params = nsec3rr;
+
+       /* So this is a NSEC3 zone.
+       * Calculate hashes for all names already in the zone
+       */
+       zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
+       if (zone->hashed_names == NULL) {
+               return;
+       }
+       for ( current_node  = ldns_rbtree_first(zone->names)
+           ; current_node != LDNS_RBTREE_NULL
+           ; current_node  = ldns_rbtree_next(current_node)
+           ) {
                current_name = (ldns_dnssec_name *) current_node->data;
-               if (!current_name->hashed_name) {
-                       current_name->hashed_name =
-                               ldns_nsec3_hash_name_frm_nsec3(rr, current_name->name);
+               ldns_dnssec_name_make_hashed_name(zone, current_name, nsec3rr);
+
+       }
+}
+
+static void
+ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
+               ldns_dnssec_name* name, ldns_rr* nsec3rr)
+{
+       ldns_rbnode_t* new_node;
+
+       assert(name != NULL);
+       if (! zone->_nsec3params) {
+               if (! nsec3rr) {
+                       return;
                }
-               if (ldns_dname_compare(hashed_name,
-                                                  current_name->hashed_name)
-                   == 0) {
-                       ldns_rdf_deep_free(hashed_name);
-                       return current_node;
+               ldns_dnssec_zone_hashed_names_from_nsec3(zone, nsec3rr);
+
+       } else if (! nsec3rr) {
+               nsec3rr = zone->_nsec3params;
+       }
+       name->hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsec3rr, name->name);
+
+       /* Also store in zone->hashed_names */
+       if ((new_node = LDNS_MALLOC(ldns_rbnode_t))) {
+
+               new_node->key  = name->hashed_name;
+               new_node->data = name;
+
+               if (ldns_rbtree_insert(zone->hashed_names, new_node) == NULL) {
+
+                               LDNS_FREE(new_node);
                }
-               current_node = ldns_rbtree_next(current_node);
        }
-       ldns_rdf_deep_free(hashed_name);
-       return NULL;
+}
+
+
+static ldns_rbnode_t *
+ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) {
+       ldns_rdf *hashed_name;
+
+       hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
+       if (hashed_name == NULL) {
+               return NULL;
+       }
+       if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){
+
+               ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr);
+       }
+       if (zone->hashed_names == NULL) {
+               ldns_rdf_deep_free(hashed_name);
+               return NULL;
+       }
+       return  ldns_rbtree_search(zone->hashed_names, hashed_name);
 }
 
 ldns_status
@@ -878,15 +947,13 @@ ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
        }
        if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 ||
            type_covered == LDNS_RR_TYPE_NSEC3) {
-               cur_node = ldns_dnssec_zone_find_nsec3_original(zone,
-                                                                                          rr);
+               cur_node = ldns_dnssec_zone_find_nsec3_original(zone, rr);
                if (!cur_node) {
                        return LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND;
                }
        } else {
                cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr));
        }
-
        if (!cur_node) {
                /* add */
                cur_name = ldns_dnssec_name_new_frm_rr(rr);
@@ -899,27 +966,20 @@ ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
                cur_node->key = ldns_rr_owner(rr);
                cur_node->data = cur_name;
                (void)ldns_rbtree_insert(zone->names, cur_node);
+               ldns_dnssec_name_make_hashed_name(zone, cur_name, NULL);
        } else {
                cur_name = (ldns_dnssec_name *) cur_node->data;
                result = ldns_dnssec_name_add_rr(cur_name, rr);
        }
-
-       if (result != LDNS_STATUS_OK) {
-               fprintf(stderr, "error adding rr: ");
-               ldns_rr_print(stderr, rr);
-       }
-
-       /*TODO ldns_dnssec_name_print_names(stdout, zone->names, 0);*/
        if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
                zone->soa = cur_name;
        }
-
        return result;
 }
 
 void
 ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
-               ldns_rbtree_t *tree, 
+               const ldns_rbtree_t *tree, 
                bool print_soa)
 {
        ldns_rbnode_t *node;
@@ -936,7 +996,7 @@ ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
 }
 
 void
-ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa)
+ldns_dnssec_zone_names_print(FILE *out, const ldns_rbtree_t *tree, bool print_soa)
 {
        ldns_dnssec_zone_names_print_fmt(out, ldns_output_format_default,
                       tree, print_soa);
@@ -944,7 +1004,7 @@ ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa)
 
 void
 ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt,
-              ldns_dnssec_zone *zone)
+              const ldns_dnssec_zone *zone)
 {
        if (zone) {
                if (zone->soa) {
@@ -971,13 +1031,14 @@ ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt,
 }
 
 void
-ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone)
+ldns_dnssec_zone_print(FILE *out, const ldns_dnssec_zone *zone)
 {
        ldns_dnssec_zone_print_fmt(out, ldns_output_format_default, zone);
 }
 
-ldns_status
-ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
+static ldns_status
+ldns_dnssec_zone_add_empty_nonterminals_nsec3(
+               ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s)
 {
        ldns_dnssec_name *new_name;
        ldns_rdf *cur_name;
@@ -1040,12 +1101,34 @@ ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
                                /* We have an empty nonterminal, add it to the
                                 * tree
                                 */
+                               ldns_rbnode_t *node = NULL;
+                               ldns_rdf *ent_name;
+
+                               if (!(ent_name = ldns_dname_clone_from(
+                                               next_name, i)))
+                                       return LDNS_STATUS_MEM_ERR;
+
+                               if (nsec3s && zone->_nsec3params) {
+                                       ldns_rdf *ent_hashed_name;
+
+                                       if (!(ent_hashed_name =
+                                           ldns_nsec3_hash_name_frm_nsec3(
+                                                       zone->_nsec3params,
+                                                       ent_name)))
+                                               return LDNS_STATUS_MEM_ERR;
+                                       node = ldns_rbtree_search(nsec3s, 
+                                                       ent_hashed_name);
+                                       if (!node) {
+                                               ldns_rdf_deep_free(l1);
+                                               ldns_rdf_deep_free(l2);
+                                               continue;
+                                       }
+                               }
                                new_name = ldns_dnssec_name_new();
                                if (!new_name) {
                                        return LDNS_STATUS_MEM_ERR;
                                }
-                               new_name->name = ldns_dname_clone_from(next_name,
-                                                                      i);
+                               new_name->name = ent_name;
                                if (!new_name->name) {
                                        ldns_dnssec_name_free(new_name);
                                        return LDNS_STATUS_MEM_ERR;
@@ -1059,6 +1142,11 @@ ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
                                new_node->key = new_name->name;
                                new_node->data = new_name;
                                (void)ldns_rbtree_insert(zone->names, new_node);
+                               ldns_dnssec_name_make_hashed_name(
+                                               zone, new_name, NULL);
+                               if (node)
+                                       (void) ldns_dnssec_zone_add_rr(zone,
+                                                       (ldns_rr *)node->data);
                        }
                        ldns_rdf_deep_free(l1);
                        ldns_rdf_deep_free(l2);
@@ -1076,8 +1164,14 @@ ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
        return LDNS_STATUS_OK;
 }
 
+ldns_status
+ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
+{
+       return ldns_dnssec_zone_add_empty_nonterminals_nsec3(zone, NULL);
+}
+
 bool
-ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone* zone)
+ldns_dnssec_zone_is_nsec3_optout(const ldns_dnssec_zone* zone)
 {
        ldns_rr* nsec3;
        ldns_rbnode_t* node;
diff --git a/contrib/ldns/drill/ChangeLog.22-nov-2005 b/contrib/ldns/drill/ChangeLog.22-nov-2005
deleted file mode 100644 (file)
index 1ce8b0b..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
---------- Drill now is a subdirectory in ldns. To make life easier 
---------- we are using ldns' version numbering for drill from now on. 
---------- Sadly this means we GO BACKWARDS in the versions
---------- This ChangeLog will not be updated anymore - all changes are
---------- documented in ldns' ChangeLog
-
-1.0-pre3: to be released: drill-team
-       * Secure tracing works
-       * Added section about DNSSEC in the manual page
-       * Allow the class information to be given to do_chase()
-       * Lint fixes for the code
-       * Bugzilla was setup for drill
-       * Bug #97 (drill); -S crash was fixed
-       * Add -Q (quiet) flag was added. This supresses output from drill.
-
-1.0-pre2: 20 Jun 2005: drill-team
-       * Second prerelease
-       * Bugs where fix in the chasing functionality
-
-1.0-pre1: 1 Jun 2005: drill-team
-       * First drill release based on ldns
-       * drill's core code is not much more simple, as
-         all the difficult stuff is moved to ldns.
-       * Much saner argument parsing
-
----------- Above Newer drill based on ldns              --------------
----------- Below Older drill with it's own DNS handling --------------
-
-0.9.2: Feb 3 2005: drill-team
-       * Added two more options (borrowed from dig)
-         --rd, don't set the RD bit in queries
-         --fail, don't query the next nameserver on SERVFAIL
-       * Fixed handling of obscure data types
-       * Handle classes other the 'IN' when making a query
-
-       * For people using FreeBSD: drill is now in the ports
-         (Thanks to Jaap Akkerhuis)
-
-0.9.1: Jan 5 2005: drill-team
-       * Makefile tweaks
-       * drill ns . works
-       * re-check the root in when tracing
-       * added handling for some lesser known types (including WKS)
-
-0.9: Dec 6 2004: drill-team
-       * big configure.ac and Makefile.in updates (made more general)
-       * escapes in names argument and txt and dname data
-       * gcc 2(.95) support
-       * packet wire data is now checked for dangerous elements (like
-         looping compression etc)
-       * (Multiple) Octal char representation
-       * Responses can be saved to file
-       * 'Answers' can be read from file instead of server
-       * Lots and lots of bugfixes and improvements
-
-0.8.1: Oct 27 2004: Miek
-       * configure.ac updates
-       * secure resolving updates (still doesn't work)
-       * printing additions
-         - CERT RR supported
-         - LOC RR support
-       * All non supported RRs are handled as unknown
-       * If no namservers found in /etc/resolv.conf 
-         default to 127.0.0.1
-       * Various bugs fixed
-         - Close sockets after using them
-         - Some memory leaks were plugged
-
-0.8: Oct 26 2004: Miek
-       * Lots of features added. Drill is almost feature complete
-       * Unknown RR's are supported
-       * Numerous smaller updates in documentation
-       * Numerous code cleanups
-       * Dig is no longer needed to build drill
-
-0.7: Oct 21 2004: Miek
-       * reworked interal code
-       * DNSSEC is working, except the secure resolving
-       * build updates
-       * more sane options parsing
-       * more sane argument handling
-
-0.6-alpha: Oct 2004: Jelte
-       * No log
-
-0.5-alpha: Sept 22 2004: Miek
-       * most of the DNS stuff is working
-       * moved to configure
-       * tested on Linux/FreeBSD
-       * fully IPV6 capable
-       * new DNSSEC types supported
-       * DNSSEC somewhat working
-       * gcc => 3 is needed for building
-
-0.4-alpha: Sept 9 2004: Miek 
-       * moved to autoconf for building
-       * lots of various updates
-       * really a workable program now
-
-0.3-alpha: Sept 6 2004: Miek 
-       * IPv6 support
-       * automatic secure resolving
-       * --trace updates
-       * --chase updates
-       * more checks
diff --git a/contrib/ldns/drill/README b/contrib/ldns/drill/README
deleted file mode 100644 (file)
index bbbb816..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-QUICK INSTALL GUIDE
-
-drill is a subdirectory in ldns.
-
-To compile drill you need:
-autoreconf && ./configure && make
-
-If ldns is installed in a different location, use --with-ldns=directory
-See also ./configure --help
-
-In the first case you must run drill as:
-LD_LIBRARY_PATH=../.libs ./drill <options>
diff --git a/contrib/ldns/drill/REGRESSIONS b/contrib/ldns/drill/REGRESSIONS
deleted file mode 100644 (file)
index b8f6be9..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-REGRESSIONS
-
-This version of drill is based on ldns and as such some things
-are slightly changed. This file documents the changes.
-
-o When tracing (-T option) we use the local resolver (as specified
-  in /etc/resolv.conf) to lookup names. This increases the speed
-  dramatically, but you obviously need to be able to reach a recursive
-  server/cache.
-  Previously drill would try to resolve the names by itself.
-
-o Printing of DSs after DNSKEY records. Because we don't parse our
-  own packets anymore, we cannot print the DS directly after the DNSKEY 
-  record. The DSs are now printed AFTER the packet.
-
-o The long options are removed.
-
-o The chase function has a different output, and will be subject to change
-  in the near future.
-o The useless (for jokes only) -I option was dropped.
-
-FIXED:
-o the argument parsing is much smarter, the order doesn't matter (much)
-  anymore
index 0a37ff3..1f8a290 100644 (file)
 #include "drill.h"
 #include <ldns/ldns.h>
 
+/* Cache all RRs from rr_list "rr_list" to "referrals" database for lookup
+ * later on.  Print the NS RRs that were not already present.
+ */
+static void add_rr_list_to_referrals(
+    ldns_dnssec_zone *referrals, ldns_rr_list *rr_list)
+{
+       size_t i;
+       ldns_rr *rr;
+       ldns_dnssec_rrsets *rrset;
+       ldns_dnssec_rrs *rrs;
+
+       for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
+               rr = ldns_rr_list_rr(rr_list, i);
+               /* Check if a RR equal to "rr" is present in "referrals" */
+               rrset = ldns_dnssec_zone_find_rrset(
+                   referrals, ldns_rr_owner(rr), ldns_rr_get_type(rr));
+               if (rrset) {
+                       for (rrs = rrset->rrs; rrs; rrs = rrs->next)
+                               if (ldns_rr_compare(rr, rrs->rr) == 0)
+                                       break;
+                       if (rrs) continue; /* "rr" is present, next! */
+               }
+               if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NS && verbosity != -1)
+                       ldns_rr_print(stdout, rr);
+               (void) ldns_dnssec_zone_add_rr(referrals, rr);
+       }
+}
+
+/* Cache all RRs from packet "p" to "referrals" database for lookup later on.
+ * Print the NS RRs that were not already present.
+ */
+static void add_referrals(ldns_dnssec_zone *referrals, ldns_pkt *p)
+{
+       ldns_rr_list *l = ldns_pkt_all_noquestion(p);
+       if (l) {
+               add_rr_list_to_referrals(referrals, l);
+               ldns_rr_list_free(l);
+       }
+}
+
+/* Equip name-server "res" with the name-servers authoritative for as much
+ * of "name" as possible.  Lookup addresses if needed.
+ */
+static bool set_nss_for_name(
+    ldns_resolver *res, ldns_dnssec_zone *referrals, ldns_rdf *name,
+    ldns_resolver *local_res, ldns_rr_class c)
+{
+       ldns_dnssec_rrsets *nss = NULL;
+       ldns_dnssec_rrs *nss_rrs;
+       ldns_dnssec_rrsets *as = NULL;
+       ldns_dnssec_rrs *as_rrs;
+       ldns_rdf *lookup = ldns_rdf_clone(name);
+       ldns_rdf *new_lookup;
+       ldns_rdf *addr;
+       ldns_rr_list *addrs;
+
+       /* nss will become the rrset of as much of "name" as possible */
+       for (;;) {
+               nss = ldns_dnssec_zone_find_rrset(
+                   referrals, lookup, LDNS_RR_TYPE_NS);
+               if (nss != NULL) {
+                       ldns_rdf_deep_free(lookup);
+                       break;
+               }
+               new_lookup = ldns_dname_left_chop(lookup);
+               ldns_rdf_deep_free(lookup);
+               lookup = new_lookup;
+               if (!lookup) {
+                       error("No referrals for name found");
+                       return false;
+               }
+       }
+
+       /* remove the old nameserver from the resolver */
+       while ((addr = ldns_resolver_pop_nameserver(res)))
+               ldns_rdf_deep_free(addr);
+
+       /* Find and add the address records for the rrset as name-servers */
+       for (nss_rrs = nss->rrs; nss_rrs; nss_rrs = nss_rrs->next) {
+
+               if ((as = ldns_dnssec_zone_find_rrset(
+                   referrals, ldns_rr_rdf(nss_rrs->rr, 0), LDNS_RR_TYPE_A)))
+                       for (as_rrs = as->rrs; as_rrs; as_rrs = as_rrs->next)
+                               (void) ldns_resolver_push_nameserver(
+                                   res, ldns_rr_rdf(as_rrs->rr, 0));
+
+               if ((as = ldns_dnssec_zone_find_rrset(
+                   referrals, ldns_rr_rdf(nss_rrs->rr, 0), LDNS_RR_TYPE_AAAA)))
+                       for (as_rrs = as->rrs; as_rrs; as_rrs = as_rrs->next)
+                               (void) ldns_resolver_push_nameserver(
+                                   res, ldns_rr_rdf(as_rrs->rr, 0));
+       }
+       /* Is our resolver equipped with name-servers? Good! We're done */
+       if (ldns_resolver_nameserver_count(res) > 0)
+               return true;
+
+       /* Lookup addresses with local resolver add add to "referrals" database */
+       addrs = ldns_rr_list_new();
+       for (nss_rrs = nss->rrs; nss_rrs; nss_rrs = nss_rrs->next) {
+               ldns_rr_list *addrs_by_name =
+                   ldns_get_rr_list_addr_by_name(
+                       local_res, ldns_rr_rdf(nss_rrs->rr, 0), c, 0);
+               ldns_rr_list_cat(addrs, addrs_by_name);
+               ldns_rr_list_free(addrs_by_name);
+       }
+
+       if (ldns_rr_list_rr_count(addrs) == 0)
+               error("Could not find the nameserver ip addr; abort");
+
+       else if (ldns_resolver_push_nameserver_rr_list(res, addrs) !=
+           LDNS_STATUS_OK)
+
+               error("Error adding new nameservers");
+       else {
+               ldns_rr_list_deep_free(addrs);
+               return true;
+       }
+       add_rr_list_to_referrals(referrals, addrs);
+       ldns_rr_list_deep_free(addrs);
+       return false;
+}
+
 /**
  * trace down from the root to name
  */
 
 /* same naive method as in drill0.9 
- * We resolver _ALL_ the names, which is ofcourse not needed
+ * We resolve _ALL_ the names, which is of course not needed.
  * We _do_ use the local resolver to do that, so it still is
- * fast, but it can be made to run much faster
+ * fast, but it can be made to run much faster.
  */
-ldns_pkt *
+void
 do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
                ldns_rr_class c)
 {
-       ldns_resolver *res;
-       ldns_pkt *p;
-       ldns_rr_list *new_nss_a;
-       ldns_rr_list *new_nss_aaaa;
+
+       static uint8_t zero[1] = { 0 };
+       static const ldns_rdf root_dname = { 1, LDNS_RDF_TYPE_DNAME, &zero };
+
+       ldns_resolver *res = NULL;
+       ldns_pkt *p = NULL;
        ldns_rr_list *final_answer;
        ldns_rr_list *new_nss;
-       ldns_rr_list *ns_addr;
+       ldns_rr_list *cname = NULL;
+       ldns_rr_list *answers = NULL;
        uint16_t loop_count;
-       ldns_rdf *pop; 
        ldns_status status;
-       size_t i;
+       ldns_dnssec_zone* referrals = NULL;
+       ldns_rdf *addr;
        
        loop_count = 0;
-       new_nss_a = NULL;
-       new_nss_aaaa = NULL;
-       new_nss = NULL;
-       ns_addr = NULL;
        final_answer = NULL;
-       p = ldns_pkt_new();
        res = ldns_resolver_new();
 
-       if (!p) {
-               if (res) {
-                       ldns_resolver_free(res);
-               }
-                error("Memory allocation failed");
-                return NULL;
-       }
        if (!res) {
-               ldns_pkt_free(p);
                 error("Memory allocation failed");
-                return NULL;
+               goto cleanup;
         }
 
        /* transfer some properties of local_res to res,
@@ -74,6 +186,8 @@ do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
                        ldns_resolver_usevc(local_res));
        ldns_resolver_set_random(res, 
                        ldns_resolver_random(local_res));
+       ldns_resolver_set_source(res,
+                       ldns_resolver_source(local_res));
        ldns_resolver_set_recursive(res, false);
 
        /* setup the root nameserver in the new resolver */
@@ -81,16 +195,13 @@ do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
        if (status != LDNS_STATUS_OK) {
                fprintf(stderr, "Error adding root servers to resolver: %s\n", ldns_get_errorstr_by_id(status));
                ldns_rr_list_print(stdout, global_dns_root);
-               ldns_resolver_free(res);
-               ldns_pkt_free(p);
-               return NULL;
+               goto cleanup;
        }
 
        /* this must be a real query to local_res */
-       status = ldns_resolver_send(&p, res, ldns_dname_new_frm_str("."), LDNS_RR_TYPE_NS, c, 0);
+       status = ldns_resolver_send(&p, res, &root_dname, LDNS_RR_TYPE_NS, c, 0);
        /* p can still be NULL */
 
-
        if (ldns_pkt_empty(p)) {
                warning("No root server information received");
        } 
@@ -99,111 +210,95 @@ do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
                if (!ldns_pkt_empty(p)) {
                        drill_pkt_print(stdout, local_res, p);
                }
+               referrals = ldns_dnssec_zone_new();
+               add_referrals(referrals, p);
        } else {
                error("cannot use local resolver");
-               return NULL;
+               goto cleanup;
        }
-
+       if (! set_nss_for_name(res, referrals, name, local_res, c)) {
+               goto cleanup;
+       }
+       ldns_pkt_free(p);
+       p = NULL;
        status = ldns_resolver_send(&p, res, name, t, c, 0);
-
        while(status == LDNS_STATUS_OK && 
              ldns_pkt_reply_type(p) == LDNS_PACKET_REFERRAL) {
 
                if (!p) {
-                       /* some error occurred, bail out */
-                       return NULL;
+                       /* some error occurred -- bail out */
+                       goto cleanup;
                }
+               add_referrals(referrals, p);
 
-               new_nss_a = ldns_pkt_rr_list_by_type(p,
-                               LDNS_RR_TYPE_A, LDNS_SECTION_ADDITIONAL);
-               new_nss_aaaa = ldns_pkt_rr_list_by_type(p,
-                               LDNS_RR_TYPE_AAAA, LDNS_SECTION_ADDITIONAL);
-               new_nss = ldns_pkt_rr_list_by_type(p,
-                               LDNS_RR_TYPE_NS, LDNS_SECTION_AUTHORITY);
-
-               if (verbosity != -1) {
-                       ldns_rr_list_print(stdout, new_nss);
-               }
                /* checks itself for verbosity */
                drill_pkt_print_footer(stdout, local_res, p);
                
-               /* remove the old nameserver from the resolver */
-               while(ldns_resolver_pop_nameserver(res)) { /* do it */ }
-
-               /* also check for new_nss emptyness */
-
-               if (!new_nss_aaaa && !new_nss_a) {
-                       /* 
-                        * no nameserver found!!! 
-                        * try to resolve the names we do got 
-                        */
-                       for(i = 0; i < ldns_rr_list_rr_count(new_nss); i++) {
-                               /* get the name of the nameserver */
-                               pop = ldns_rr_rdf(ldns_rr_list_rr(new_nss, i), 0);
-                               if (!pop) {
-                                       break;
-                               }
+               if (! set_nss_for_name(res, referrals, name, local_res, c)) {
+                       goto cleanup;
+               }
+               if (loop_count++ > 20) {
+                       /* unlikely that we are doing anything useful */
+                       error("Looks like we are looping");
+                       goto cleanup;
+               }
+               ldns_pkt_free(p);
+               p = NULL;
+               status = ldns_resolver_send(&p, res, name, t, c, 0);
 
-                               ldns_rr_list_print(stdout, new_nss);
-                               ldns_rdf_print(stdout, pop);
-                               /* retrieve it's addresses */
-                               ns_addr = ldns_rr_list_cat_clone(ns_addr,
-                                       ldns_get_rr_list_addr_by_name(local_res, pop, c, 0));
-                       }
+               /* Exit trace on error */
+               if (status != LDNS_STATUS_OK)
+                       break;
 
-                       if (ns_addr) {
-                               if (ldns_resolver_push_nameserver_rr_list(res, ns_addr) != 
-                                               LDNS_STATUS_OK) {
-                                       error("Error adding new nameservers");
-                                       ldns_pkt_free(p); 
-                                       return NULL;
-                               }
-                               ldns_rr_list_free(ns_addr);
-                       } else {
-                               ldns_rr_list_print(stdout, ns_addr);
-                               error("Could not find the nameserver ip addr; abort");
-                               ldns_pkt_free(p);
-                               return NULL;
-                       }
-               }
+               /* An answer might be the desired answer (and no referral) */
+               if (ldns_pkt_reply_type(p) != LDNS_PACKET_ANSWER)
+                       continue;
 
-               /* add the new ones */
-               if (new_nss_aaaa) {
-                       if (ldns_resolver_push_nameserver_rr_list(res, new_nss_aaaa) != 
-                                       LDNS_STATUS_OK) {
-                               error("adding new nameservers");
-                               ldns_pkt_free(p); 
-                               return NULL;
-                       }
-               }
-               if (new_nss_a) {
-                       if (ldns_resolver_push_nameserver_rr_list(res, new_nss_a) != 
-                                       LDNS_STATUS_OK) {
-                               error("adding new nameservers");
-                               ldns_pkt_free(p); 
-                               return NULL;
-                       }
+               /* Exit trace when the requested type is found */
+               answers = ldns_pkt_rr_list_by_type(p, t, LDNS_SECTION_ANSWER);
+               if (answers && ldns_rr_list_rr_count(answers) > 0) {
+                       ldns_rr_list_free(answers);
+                       answers = NULL;
+                       break;
                }
+               ldns_rr_list_free(answers);
+               answers = NULL;
 
-               if (loop_count++ > 20) {
-                       /* unlikely that we are doing something usefull */
-                       error("Looks like we are looping");
-                       ldns_pkt_free(p); 
-                       return NULL;
-               }
-               
+               /* Get the CNAMEs from the answer */
+               cname = ldns_pkt_rr_list_by_type(
+                   p, LDNS_RR_TYPE_CNAME, LDNS_SECTION_ANSWER);
+
+               /* No CNAME either: exit trace */
+               if (ldns_rr_list_rr_count(cname) == 0)
+                       break;
+
+               /* Print CNAME referral */
+               ldns_rr_list_print(stdout, cname);
+
+               /* restart with the CNAME */
+               name = ldns_rr_rdf(ldns_rr_list_rr(cname, 0), 0);
+               ldns_rr_list_free(cname);
+               cname = NULL;
+
+               /* remove the old nameserver from the resolver */
+               while((addr = ldns_resolver_pop_nameserver(res)))
+                       ldns_rdf_deep_free(addr);
+
+               /* Restart trace from the root up */
+               (void) ldns_resolver_push_nameserver_rr_list(
+                   res, global_dns_root);
+
+               ldns_pkt_free(p);
+               p = NULL;
                status = ldns_resolver_send(&p, res, name, t, c, 0);
-               new_nss_aaaa = NULL;
-               new_nss_a = NULL;
-               ns_addr = NULL;
        }
 
+       ldns_pkt_free(p);
+       p = NULL;
        status = ldns_resolver_send(&p, res, name, t, c, 0);
-
        if (!p) {
-               return NULL;
+               goto cleanup;
        }
-
        new_nss = ldns_pkt_authority(p);
        final_answer = ldns_pkt_answer(p);
 
@@ -213,8 +308,16 @@ do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
 
        }
        drill_pkt_print_footer(stdout, local_res, p);
-       ldns_pkt_free(p); 
-       return NULL;
+cleanup:
+       if (res) {
+               while((addr = ldns_resolver_pop_nameserver(res)))
+                       ldns_rdf_deep_free(addr);
+               ldns_resolver_free(res);
+       }
+       if (referrals)
+               ldns_dnssec_zone_deep_free(referrals);
+       if (p)
+               ldns_pkt_free(p); 
 }
 
 
@@ -235,8 +338,7 @@ do_chase(ldns_resolver *res,
            ldns_rr_list *trusted_keys,
            ldns_pkt *pkt_o,
            uint16_t qflags,
-           ldns_rr_list * ATTR_UNUSED(prev_key_list),
-           int verbosity)
+           ldns_rr_list * ATTR_UNUSED(prev_key_list))
 {
        ldns_rr_list *rrset = NULL;
        ldns_status result;
index 574c8b9..3a9482b 100644 (file)
 #include <openssl/err.h>
 #endif
 
-#define IP6_ARPA_MAX_LEN 65
-
 /* query debug, 2 hex dumps */
 int            verbosity;
 
+static int
+is_ixfr_with_serial(const char* name, uint32_t *serial)
+{
+       char* end;
+       if (strlen(name) > 5 &&
+               strncasecmp(name, "IXFR", 4) == 0 &&
+               name[4] == '=') {
+               *serial = (uint32_t) strtol((name+5), &end, 10);
+               return 1;
+       }
+       return 0;
+}
+
 static void
 usage(FILE *stream, const char *progname)
 {
@@ -31,8 +42,9 @@ usage(FILE *stream, const char *progname)
        fprintf(stream, "\t-D\t\tenable DNSSEC (DO bit)\n");
 #ifdef HAVE_SSL
        fprintf(stream, "\t-T\t\ttrace from the root down to <name>\n");
-       fprintf(stream, "\t-S\t\tchase signature(s) from <name> to a know key [*]\n");
+       fprintf(stream, "\t-S\t\tchase signature(s) from <name> to a known key [*]\n");
 #endif /*HAVE_SSL*/
+       fprintf(stream, "\t-I <address>\tsource address to query from\n");
        fprintf(stream, "\t-V <number>\tverbosity (0-5)\n");
        fprintf(stream, "\t-Q\t\tquiet mode (overrules -V)\n");
        fprintf(stream, "\n");
@@ -103,15 +115,16 @@ main(int argc, char *argv[])
         ldns_pkt       *pkt;
         ldns_pkt       *qpkt;
         char           *serv;
+        char           *src = NULL;
         const char     *name;
-        char           *name2;
        char            *progname;
        char            *query_file = NULL;
        char            *answer_file = NULL;
        ldns_buffer     *query_buffer = NULL;
        ldns_rdf        *serv_rdf;
-        ldns_rr_type   type;
-        ldns_rr_class  clas;
+       ldns_rdf        *src_rdf = NULL;
+       ldns_rr_type    type;
+       ldns_rr_class   clas;
 #if 0
        ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
 #endif
@@ -127,7 +140,7 @@ main(int argc, char *argv[])
        ldns_rr         *axfr_rr;
        ldns_status     status;
        char *type_str;
-       
+       uint32_t        serial = 0;
        /* list of keys used in dnssec operations */
        ldns_rr_list    *key_list = ldns_rr_list_new(); 
        /* what key verify the current answer */
@@ -150,6 +163,9 @@ main(int argc, char *argv[])
 
        int             result = 0;
 
+       uint8_t         s6addr[16];
+       char            ip6_arpa_str[74];
+
 #ifdef USE_WINSOCK
        int r;
        WSADATA wsa_data;
@@ -157,7 +173,7 @@ main(int argc, char *argv[])
 
        int_type = -1; serv = NULL; type = 0; 
        int_clas = -1; name = NULL; clas = 0;
-       qname = NULL; 
+       qname = NULL; src = NULL;
        progname = strdup(argv[0]);
 
 #ifdef USE_WINSOCK
@@ -185,17 +201,11 @@ main(int argc, char *argv[])
 
        ldns_init_random(NULL, 0);
 
-       if (argc == 0) {
-               usage(stdout, progname);
-               result = EXIT_FAILURE;
-               goto exit;
-       }
-
        /* string from orig drill: "i:w:I46Sk:TNp:b:DsvhVcuaq:f:xr" */
        /* global first, query opt next, option with parm's last
         * and sorted */ /*  "46DITSVQf:i:w:q:achuvxzy:so:p:b:k:" */
                                       
-       while ((c = getopt(argc, argv, "46ab:c:d:Df:hi:Ik:o:p:q:Qr:sStTuvV:w:xy:z")) != -1) {
+       while ((c = getopt(argc, argv, "46ab:c:d:Df:hi:I:k:o:p:q:Qr:sStTuvV:w:xy:z")) != -1) {
                switch(c) {
                        /* global options */
                        case '4':
@@ -208,7 +218,7 @@ main(int argc, char *argv[])
                                qdnssec = true;
                                break;
                        case 'I':
-                               /* reserved for backward compatibility */
+                               src = optarg;
                                break;
                        case 'T':
                                if (PURPOSE == DRILL_CHASE) {
@@ -360,9 +370,7 @@ main(int argc, char *argv[])
                                                tsig_algorithm[strlen(optarg) - tsig_separator2 - 1] = '\0';
                                        } else {
                                                tsig_separator2 = strlen(optarg);
-                                               tsig_algorithm = xmalloc(26);
-                                               strncpy(tsig_algorithm, "hmac-md5.sig-alg.reg.int.", 25);
-                                               tsig_algorithm[25] = '\0';
+                                               tsig_algorithm = strdup("hmac-md5.sig-alg.reg.int");
                                        }
                                        tsig_name = xmalloc(tsig_separator + 1);
                                        tsig_data = xmalloc(tsig_separator2 - tsig_separator);
@@ -450,6 +458,10 @@ main(int argc, char *argv[])
                        if (type != 0) {
                                int_type = 0;
                                continue;
+                       } else if (is_ixfr_with_serial(argv[i], &serial)) {
+                               type = LDNS_RR_TYPE_IXFR;
+                               int_type = 0;
+                               continue;
                        }
                }
                /* if it matches a class, it's a class */
@@ -482,9 +494,23 @@ main(int argc, char *argv[])
                }
        }
 
+       if (src) {
+               src_rdf = ldns_rdf_new_addr_frm_str(src);
+               if(!src_rdf) {
+                       fprintf(stderr, "-I must be a valid IP[v6] address.\n");
+                       exit(EXIT_FAILURE);
+               }
+               if (ldns_rdf_size(src_rdf) == 4) {
+                       qfamily = LDNS_RESOLV_INET;
+
+               } else if (ldns_rdf_size(src_rdf) == 16) {
+                       qfamily = LDNS_RESOLV_INET6;
+               }
+       }
+
        /* set the nameserver to use */
        if (!serv) {
-               /* no server given make a resolver from /etc/resolv.conf */
+               /* no server given -- make a resolver from /etc/resolv.conf */
                status = ldns_resolver_new_frm_file(&res, resolv_conf_file);
                if (status != LDNS_STATUS_OK) {
                        warning("Could not create a resolver structure: %s (%s)\n"
@@ -505,7 +531,7 @@ main(int argc, char *argv[])
                if (!serv_rdf) {
                        /* try to resolv the name if possible */
                        status = ldns_resolver_new_frm_file(&cmdline_res, resolv_conf_file);
-                       
+
                        if (status != LDNS_STATUS_OK) {
                                error("%s", "@server ip could not be converted");
                        }
@@ -513,6 +539,7 @@ main(int argc, char *argv[])
                        ldns_resolver_set_ip6(cmdline_res, qfamily);
                        ldns_resolver_set_fallback(cmdline_res, qfallback);
                        ldns_resolver_set_usevc(cmdline_res, qusevc);
+                       ldns_resolver_set_source(cmdline_res, src_rdf);
 
                        cmdline_dname = ldns_dname_new_frm_str(serv);
 
@@ -542,7 +569,9 @@ main(int argc, char *argv[])
                }
        }
        /* set the resolver options */
+       ldns_resolver_set_ixfr_serial(res, serial);
        ldns_resolver_set_port(res, qport);
+       ldns_resolver_set_source(res, src_rdf);
        if (verbosity >= 5) {
                ldns_resolver_set_debug(res, true);
        } else {
@@ -568,6 +597,39 @@ main(int argc, char *argv[])
        }
 
        if (tsig_name && tsig_data) {
+               /* With dig TSIG keys are also specified with -y,
+                * but format with drill is: -y <name:key[:algo]>
+                *             and with dig: -y [hmac:]name:key
+                *
+                * When we detect an unknown tsig algorithm in algo,
+                * but a known algorithm in name, we cane assume dig
+                * order was used.
+                *
+                * Following if statement is to anticipate and correct dig order
+                */
+               if (   strcasecmp(tsig_algorithm, "hmac-md5.sig-alg.reg.int")
+                   && strcasecmp(tsig_algorithm, "hmac-md5")
+                   && strcasecmp(tsig_algorithm, "hmac-sha1")
+                   && strcasecmp(tsig_algorithm, "hmac-sha256")
+                   && (
+                      strcasecmp(tsig_name, "hmac-md5.sig-alg.reg.int")  == 0
+                   || strcasecmp(tsig_name, "hmac-md5")                  == 0
+                   || strcasecmp(tsig_name, "hmac-sha1")                 == 0
+                   || strcasecmp(tsig_name, "hmac-sha256")               == 0
+                      )) {
+
+                       /* Roll options */
+                       char *tmp_tsig_algorithm = tsig_name;
+                       tsig_name      = tsig_data;
+                       tsig_data      = tsig_algorithm;
+                       tsig_algorithm = tmp_tsig_algorithm;
+               }
+
+               if (strcasecmp(tsig_algorithm, "hmac-md5") == 0) {
+                       free(tsig_algorithm);
+                       tsig_algorithm = strdup("hmac-md5.sig-alg.reg.int");
+               }
+
                ldns_resolver_set_tsig_keyname(res, tsig_name);
                ldns_resolver_set_tsig_keydata(res, tsig_data);
                ldns_resolver_set_tsig_algorithm(res, tsig_algorithm);
@@ -585,7 +647,7 @@ main(int argc, char *argv[])
                                error("%s", "parsing query name");
                        }
                        /* don't care about return packet */
-                       (void)do_trace(res, qname, type, clas);
+                       do_trace(res, qname, type, clas);
                        clear_root();
                        break;
                case DRILL_SECTRACE:
@@ -613,10 +675,17 @@ main(int argc, char *argv[])
                        ldns_resolver_set_dnssec_cd(res, true);
                        /* set dnssec implies udp_size of 4096 */
                        ldns_resolver_set_edns_udp_size(res, 4096);
-                       pkt = ldns_resolver_query(res, qname, type, clas, qflags);
-                       
+                       pkt = NULL;
+                       status = ldns_resolver_query_status(
+                                       &pkt, res, qname, type, clas, qflags);
+                       if (status != LDNS_STATUS_OK) {
+                               error("error sending query: %s",
+                                       ldns_get_errorstr_by_id(status));
+                       }
                        if (!pkt) {
-                               error("%s", "error pkt sending");
+                               if (status == LDNS_STATUS_OK) {
+                                       error("%s", "error pkt sending");
+                               }
                                result = EXIT_FAILURE;
                        } else {
                                if (verbosity >= 3) {
@@ -630,8 +699,7 @@ main(int argc, char *argv[])
                                        ldns_resolver_set_dnssec_anchors(res, ldns_rr_list_clone(key_list));
                                        result = do_chase(res, qname, type,
                                                          clas, key_list, 
-                                                         pkt, qflags, NULL,
-                                                                  verbosity);
+                                                         pkt, qflags, NULL);
                                        if (result == LDNS_STATUS_OK) {
                                                if (verbosity != -1) {
                                                        mesg("Chase successful");
@@ -662,7 +730,6 @@ main(int argc, char *argv[])
                        if (!qname) {
                                error("%s", "making qname");
                        }
-
                        status = ldns_resolver_prepare_query_pkt(&qpkt, res, qname, type, clas, qflags);
                        if(status != LDNS_STATUS_OK) {
                                error("%s", "making query: %s", 
@@ -676,55 +743,48 @@ main(int argc, char *argv[])
                case DRILL_REVERSE:
                        /* ipv4 or ipv6 addr? */
                        if (strchr(name, ':')) {
-                               if (strchr(name, '.')) {
-                                       error("Syntax error: both '.' and ':' seen in address\n");
-                               }
-                               name2 = malloc(IP6_ARPA_MAX_LEN + 20);
-                               c = 0;
-                               for (i=0; i<(int)strlen(name); i++) {
-                                       if (i >= IP6_ARPA_MAX_LEN) {
-                                               error("%s", "reverse argument to long");
-                                       }
-                                       if (name[i] == ':') {
-                                               if (i < (int) strlen(name) && name[i + 1] == ':') {
-                                                       error("%s", ":: not supported (yet)");
-                                               } else {
-                                                       if (i + 2 == (int) strlen(name) || name[i + 2] == ':') {
-                                                               name2[c++] = '0';
-                                                               name2[c++] = '.';
-                                                               name2[c++] = '0';
-                                                               name2[c++] = '.';
-                                                               name2[c++] = '0';
-                                                               name2[c++] = '.';
-                                                       } else if (i + 3 == (int) strlen(name) || name[i + 3] == ':') {
-                                                               name2[c++] = '0';
-                                                               name2[c++] = '.';
-                                                               name2[c++] = '0';
-                                                               name2[c++] = '.';
-                                                       } else if (i + 4 == (int) strlen(name) || name[i + 4] == ':') {
-                                                               name2[c++] = '0';
-                                                               name2[c++] = '.';
-                                                       }
-                                               }
-                                       } else {
-                                               name2[c++] = name[i];
-                                               name2[c++] = '.';
-                                       }
-                               }
-                               name2[c++] = '\0';
-
-                               qname = ldns_dname_new_frm_str(name2);
-                               qname_tmp = ldns_dname_reverse(qname);
-                               ldns_rdf_deep_free(qname);
-                               qname = qname_tmp;
-                               qname_tmp = ldns_dname_new_frm_str("ip6.arpa.");
-                               status = ldns_dname_cat(qname, qname_tmp);
-                               if (status != LDNS_STATUS_OK) {
-                                       error("%s", "could not create reverse address for ip6: %s\n", ldns_get_errorstr_by_id(status));
+                               if (!inet_pton(AF_INET6, name, &s6addr)) {
+                                       error("Syntax error: cannot parse IPv6 address\n");
                                }
-                               ldns_rdf_deep_free(qname_tmp);
+                               (void) snprintf(ip6_arpa_str, sizeof(ip6_arpa_str),
+                                   "%x.%x.%x.%x.%x.%x.%x.%x."
+                                   "%x.%x.%x.%x.%x.%x.%x.%x."
+                                   "%x.%x.%x.%x.%x.%x.%x.%x."
+                                   "%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa.",
+                                   (unsigned int)(s6addr[15] & 0x0F),
+                                   (unsigned int)(s6addr[15] >> 4),
+                                   (unsigned int)(s6addr[14] & 0x0F),
+                                   (unsigned int)(s6addr[14] >> 4),
+                                   (unsigned int)(s6addr[13] & 0x0F),
+                                   (unsigned int)(s6addr[13] >> 4),
+                                   (unsigned int)(s6addr[12] & 0x0F),
+                                   (unsigned int)(s6addr[12] >> 4),
+                                   (unsigned int)(s6addr[11] & 0x0F),
+                                   (unsigned int)(s6addr[11] >> 4),
+                                   (unsigned int)(s6addr[10] & 0x0F),
+                                   (unsigned int)(s6addr[10] >> 4),
+                                   (unsigned int)(s6addr[9] & 0x0F),
+                                   (unsigned int)(s6addr[9] >> 4),
+                                   (unsigned int)(s6addr[8] & 0x0F),
+                                   (unsigned int)(s6addr[8] >> 4),
+                                   (unsigned int)(s6addr[7] & 0x0F),
+                                   (unsigned int)(s6addr[7] >> 4),
+                                   (unsigned int)(s6addr[6] & 0x0F),
+                                   (unsigned int)(s6addr[6] >> 4),
+                                   (unsigned int)(s6addr[5] & 0x0F),
+                                   (unsigned int)(s6addr[5] >> 4),
+                                   (unsigned int)(s6addr[4] & 0x0F),
+                                   (unsigned int)(s6addr[4] >> 4),
+                                   (unsigned int)(s6addr[3] & 0x0F),
+                                   (unsigned int)(s6addr[3] >> 4),
+                                   (unsigned int)(s6addr[2] & 0x0F),
+                                   (unsigned int)(s6addr[2] >> 4),
+                                   (unsigned int)(s6addr[1] & 0x0F),
+                                   (unsigned int)(s6addr[1] >> 4),
+                                   (unsigned int)(s6addr[0] & 0x0F),
+                                   (unsigned int)(s6addr[0] >> 4));
 
-                               free(name2);
+                               qname = ldns_dname_new_frm_str(ip6_arpa_str);
                        } else {
                                qname = ldns_dname_new_frm_str(name);
                                qname_tmp = ldns_dname_reverse(qname);
@@ -742,9 +802,17 @@ main(int argc, char *argv[])
                        }
                        
                        /* create a packet and set the RD flag on it */
-                     &nb