[validns/f17] * Fri Aug 24 2012 Paul Wouters <pwouters at redhat.com> - 0.5-2 - Patch for handling NSEC/NSEC3 camelca

Paul Wouters pwouters at fedoraproject.org
Fri Aug 24 15:44:59 UTC 2012


commit fae1f4013767169f1c5362cf9289c209429fbb73
Author: Paul Wouters <pwouters at redhat.com>
Date:   Fri Aug 24 11:43:48 2012 -0400

    * Fri Aug 24 2012 Paul Wouters <pwouters at redhat.com> - 0.5-2
    - Patch for handling NSEC/NSEC3 camelcasing
    - Support TLSA records

 validns-0.5-tlsa-nsec.patch | 3797 +++++++++++++++++++++++++++++++++++++++++++
 validns.spec                |    8 +-
 2 files changed, 3804 insertions(+), 1 deletions(-)
---
diff --git a/validns-0.5-tlsa-nsec.patch b/validns-0.5-tlsa-nsec.patch
new file mode 100644
index 0000000..5cadfda
--- /dev/null
+++ b/validns-0.5-tlsa-nsec.patch
@@ -0,0 +1,3797 @@
+diff --git a/Changes b/Changes
+index b9c4cab..068078a 100644
+--- a/Changes
++++ b/Changes
+@@ -1,5 +1,9 @@
+ Revision history for validns.
+ 
++0.6 - in progress
++	Support TLSA records.
++	Minor bug fixes.
++
+ 0.5 Thu Jun  7 15:45:55 CEST 2012
+ 	Parallelize signature verification (-n option)
+ 
+diff --git a/LICENSE b/LICENSE
+index ce67f2e..74d6ee2 100644
+--- a/LICENSE
++++ b/LICENSE
+@@ -1,4 +1,4 @@
+-Copyright (c) 2011, Anton Berezin "<tobez at tobez.org>". All rights
++Copyright (c) 2011, 2012 Anton Berezin "<tobez at tobez.org>". All rights
+ reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+diff --git a/Makefile b/Makefile
+index 9f02db8..5a9ae86 100644
+--- a/Makefile
++++ b/Makefile
+@@ -9,7 +9,7 @@ validns: main.o carp.o mempool.o textparse.o base64.o base32hex.o \
+ 	naptr.o srv.o nsec3param.o nsec3.o ds.o \
+ 	hinfo.o loc.o nsec3checks.o ptr.o \
+ 	sshfp.o threads.o rp.o spf.o cert.o \
+-	dname.o
++	dname.o tlsa.o nid.o l32.o l64.o lp.o
+ 	$(CC) $(CFLAGS) $(OPTIMIZE) -o validns \
+ 	    main.o carp.o mempool.o textparse.o base64.o base32hex.o \
+ 	    rr.o soa.o a.o cname.o mx.o ns.o \
+@@ -17,7 +17,7 @@ validns: main.o carp.o mempool.o textparse.o base64.o base32hex.o \
+ 	    naptr.o srv.o nsec3param.o nsec3.o ds.o \
+ 	    hinfo.o loc.o nsec3checks.o ptr.o \
+ 	    sshfp.o threads.o rp.o spf.o cert.o \
+-	    dname.o \
++	    dname.o tlsa.o nid.o l32.o l64.o lp.o \
+ 	    -L/usr/local/lib -L/opt/local/lib -lJudy -lcrypto
+ 
+ clean:
+@@ -27,7 +27,8 @@ clean:
+ 	-rm -f naptr.o srv.o nsec3param.o nsec3.o ds.o
+ 	-rm -f hinfo.o loc.o nsec3checks.o ptr.o
+ 	-rm -f sshfp.o base32hex.o base64.o threads.o
+-	-rm -f rp.o spf.o cert.o dname.o
++	-rm -f rp.o spf.o cert.o dname.o tlsa.o
++	-rm -f nid.o l32.o l64.o lp.o
+ 	-rm -f validns.core core
+ 	@echo ':-)'
+ 
+@@ -124,6 +125,21 @@ cert.o: cert.c common.h textparse.h mempool.h carp.h rr.h
+ dname.o: dname.c common.h textparse.h mempool.h carp.h rr.h
+ 	$(CC) $(CFLAGS) $(OPTIMIZE) -c -o dname.o dname.c $(INCPATH)
+ 
++tlsa.o: tlsa.c common.h textparse.h mempool.h carp.h rr.h
++	$(CC) $(CFLAGS) $(OPTIMIZE) -c -o tlsa.o tlsa.c $(INCPATH)
++
++nid.o: nid.c common.h textparse.h mempool.h carp.h rr.h
++	$(CC) $(CFLAGS) $(OPTIMIZE) -c -o nid.o nid.c $(INCPATH)
++
++l32.o: l32.c common.h textparse.h mempool.h carp.h rr.h
++	$(CC) $(CFLAGS) $(OPTIMIZE) -c -o l32.o l32.c $(INCPATH)
++
++l64.o: l64.c common.h textparse.h mempool.h carp.h rr.h
++	$(CC) $(CFLAGS) $(OPTIMIZE) -c -o l64.o l64.c $(INCPATH)
++
++lp.o: lp.c common.h textparse.h mempool.h carp.h rr.h
++	$(CC) $(CFLAGS) $(OPTIMIZE) -c -o lp.o lp.c $(INCPATH)
++
+ threads.o: threads.c
+ 	$(CC) $(CFLAGS) $(OPTIMIZE) -c -o threads.o threads.c $(INCPATH)
+ 
+diff --git a/a.c b/a.c
+index b2a6212..28c942d 100644
+--- a/a.c
++++ b/a.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/aaaa.c b/aaaa.c
+index 408ac45..e5a4fd0 100644
+--- a/aaaa.c
++++ b/aaaa.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/base32hex.c b/base32hex.c
+index b07c910..6e54774 100644
+--- a/base32hex.c
++++ b/base32hex.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/base32hex.h b/base32hex.h
+index 79118ca..d6bd24c 100644
+--- a/base32hex.h
++++ b/base32hex.h
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/base64.c b/base64.c
+index a3ebb04..4bed2c6 100644
+--- a/base64.c
++++ b/base64.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/base64.h b/base64.h
+index 02bd371..a8095ba 100644
+--- a/base64.h
++++ b/base64.h
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/carp.c b/carp.c
+index 0514cfb..c60cdf6 100644
+--- a/carp.c
++++ b/carp.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/carp.h b/carp.h
+index 2ecd9a4..ddd0c0c 100644
+--- a/carp.h
++++ b/carp.h
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/cert.c b/cert.c
+index 9b66f28..ee80e65 100644
+--- a/cert.c
++++ b/cert.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -123,7 +123,7 @@ static char* cert_human(struct rr *rrv)
+ 	RRCAST(cert);
+     char s[1024];
+ 
+-    snprintf(s, 1024, "CERT %d %d %d ...",
++    snprintf(s, 1024, "%d %d %d ...",
+ 		rr->type, rr->key_tag, rr->algorithm);
+     return quickstrdup_temp(s);
+ }
+diff --git a/cname.c b/cname.c
+index 51e69f5..956f729 100644
+--- a/cname.c
++++ b/cname.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -21,7 +21,7 @@ static struct rr *cname_parse(char *name, long ttl, int type, char *s)
+ {
+ 	struct rr_cname *rr = getmem(sizeof(*rr));
+ 
+-	rr->cname = extract_name(&s, "cname");
++	rr->cname = extract_name(&s, "cname", 0);
+ 	if (!rr->cname)
+ 		return NULL;
+ 	if (*s) {
+diff --git a/common.h b/common.h
+index 70c6f42..023af1a 100644
+--- a/common.h
++++ b/common.h
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -21,7 +21,7 @@ struct file_info
+ 
+ extern struct file_info *file_info;
+ 
+-#define N_POLICY_CHECKS 8
++#define N_POLICY_CHECKS 9
+ 
+ #define POLICY_SINGLE_NS 0
+ #define POLICY_CNAME_OTHER_DATA 1
+@@ -31,6 +31,7 @@ extern struct file_info *file_info;
+ #define POLICY_RP_TXT_EXISTS 5
+ #define POLICY_DNAME 6
+ #define POLICY_DNSKEY 7
++#define POLICY_TLSA_HOST 8
+ 
+ struct globals {
+ 	struct stats {
+@@ -65,4 +66,10 @@ struct globals {
+ 
+ extern struct globals G;
+ 
++#define SHA1_BYTES 20
++#define SHA256_BYTES 32
++#define SHA512_BYTES 64
++/* GOST R 34.11-94 - 32 bytes */
++#define GOST_BYTES 32
++
+ #endif
+diff --git a/dname.c b/dname.c
+index 10e31e3..c7bc061 100644
+--- a/dname.c
++++ b/dname.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -23,7 +23,7 @@ static struct rr *dname_parse(char *name, long ttl, int type, char *s)
+ {
+ 	struct rr_dname *rr = getmem(sizeof(*rr));
+ 
+-	rr->target = extract_name(&s, "dname target");
++	rr->target = extract_name(&s, "dname target", 0);
+ 	if (!rr->target)
+ 		return NULL;
+ 	if (*s) {
+diff --git a/dnskey.c b/dnskey.c
+index f0bae0b..3ec6b4e 100644
+--- a/dnskey.c
++++ b/dnskey.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/ds.c b/ds.c
+index a7f4d26..7f3cdfa 100644
+--- a/ds.c
++++ b/ds.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -39,25 +39,20 @@ static struct rr* ds_parse(char *name, long ttl, int type, char *s)
+ 
+ 	/* See http://www.iana.org/assignments/ds-rr-types/ds-rr-types.xml
+ 	 * for valid digest types. */
+-	/*
+-		SHA-1 20 bytes
+-		SHA-256 32 bytes
+-		GOST R 34.11-94 32 bytes
+-	*/
+ 	switch (digest_type) {
+ 	case 1:
+-		if (rr->digest.length != 20) {
+-			return bitch("wrong SHA-1 digest length: %d bytes found, %d bytes expected", rr->digest.length, 20);
++		if (rr->digest.length != SHA1_BYTES) {
++			return bitch("wrong SHA-1 digest length: %d bytes found, %d bytes expected", rr->digest.length, SHA1_BYTES);
+ 		}
+ 		break;
+ 	case 2:
+-		if (rr->digest.length != 32) {
+-			return bitch("wrong SHA-256 digest length: %d bytes found, %d bytes expected", rr->digest.length, 32);
++		if (rr->digest.length != SHA256_BYTES) {
++			return bitch("wrong SHA-256 digest length: %d bytes found, %d bytes expected", rr->digest.length, SHA256_BYTES);
+ 		}
+ 		break;
+ 	case 3:
+-		if (rr->digest.length != 32) {
+-			return bitch("wrong GOST R 34.11-94 digest length: %d bytes found, %d bytes expected", rr->digest.length, 32);
++		if (rr->digest.length != GOST_BYTES) {
++			return bitch("wrong GOST R 34.11-94 digest length: %d bytes found, %d bytes expected", rr->digest.length, GOST_BYTES);
+ 		}
+ 		break;
+ 	default:
+diff --git a/hinfo.c b/hinfo.c
+index 882e49c..980426e 100644
+--- a/hinfo.c
++++ b/hinfo.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/l32.c b/l32.c
+new file mode 100644
+index 0000000..13e7bf6
+--- /dev/null
++++ b/l32.c
+@@ -0,0 +1,60 @@
++/*
++ * Part of DNS zone file validator `validns`.
++ *
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
++ * Modified BSD license.
++ * (See LICENSE file in the distribution.)
++ *
++ */
++#include <sys/types.h>
++#include <stdio.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++
++#include "common.h"
++#include "textparse.h"
++#include "mempool.h"
++#include "carp.h"
++#include "rr.h"
++
++static struct rr *l32_parse(char *name, long ttl, int type, char *s)
++{
++	struct rr_l32 *rr = getmem(sizeof(*rr));
++	struct in_addr ipv4_like;
++	int preference;
++
++	rr->preference = preference = extract_integer(&s, "L32 preference");
++	if (preference < 0)
++		return NULL;
++	if (extract_ipv4(&s, "Locator32", &ipv4_like) <= 0)
++		return NULL;
++	rr->locator32 = ipv4_like.s_addr;
++
++	if (*s) {
++		return bitch("garbage after valid L32 data");
++	}
++
++	return store_record(type, name, ttl, rr);
++}
++
++static char* l32_human(struct rr *rrv)
++{
++	RRCAST(l32);
++    char s[1024];
++
++    snprintf(s, 1024, "%d %d.%d.%d.%d",
++	     rr->preference,
++		 (rr->locator32 >> 24) & 0xff,
++		 (rr->locator32 >> 16) & 0xff,
++		 (rr->locator32 >> 8) & 0xff,
++		 (rr->locator32 >> 0) & 0xff);
++    return quickstrdup_temp(s);
++}
++
++static struct binary_data l32_wirerdata(struct rr *rrv)
++{
++	RRCAST(l32);
++    return compose_binary_data("24", 1, rr->preference, rr->locator32);
++}
++
++struct rr_methods l32_methods = { l32_parse, l32_human, l32_wirerdata, NULL, NULL };
+diff --git a/l64.c b/l64.c
+new file mode 100644
+index 0000000..bccf25d
+--- /dev/null
++++ b/l64.c
+@@ -0,0 +1,58 @@
++/*
++ * Part of DNS zone file validator `validns`.
++ *
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
++ * Modified BSD license.
++ * (See LICENSE file in the distribution.)
++ *
++ */
++#include <sys/types.h>
++#include <stdio.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++
++#include "common.h"
++#include "textparse.h"
++#include "mempool.h"
++#include "carp.h"
++#include "rr.h"
++
++static struct rr *l64_parse(char *name, long ttl, int type, char *s)
++{
++	struct rr_l64 *rr = getmem(sizeof(*rr));
++	int preference;
++
++	rr->preference = preference = extract_integer(&s, "L64 preference");
++	if (preference < 0)
++		return NULL;
++	if (extract_u64(&s, "Locator64", &rr->locator64) < 0)
++		return NULL;
++
++	if (*s) {
++		return bitch("garbage after valid L64 data");
++	}
++
++	return store_record(type, name, ttl, rr);
++}
++
++static char* l64_human(struct rr *rrv)
++{
++	RRCAST(l64);
++    char s[1024];
++
++    snprintf(s, 1024, "%d %x:%x:%x:%x",
++	     rr->preference,
++		 (unsigned)(rr->locator64 >> 48) & 0xffff,
++		 (unsigned)(rr->locator64 >> 32) & 0xffff,
++		 (unsigned)(rr->locator64 >> 16) & 0xffff,
++		 (unsigned)(rr->locator64 >> 0) & 0xffff);
++    return quickstrdup_temp(s);
++}
++
++static struct binary_data l64_wirerdata(struct rr *rrv)
++{
++	RRCAST(l64);
++    return compose_binary_data("28", 1, rr->preference, rr->locator64);
++}
++
++struct rr_methods l64_methods = { l64_parse, l64_human, l64_wirerdata, NULL, NULL };
+diff --git a/loc.c b/loc.c
+index 079afa3..17a949b 100644
+--- a/loc.c
++++ b/loc.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/lp.c b/lp.c
+new file mode 100644
+index 0000000..20f1eae
+--- /dev/null
++++ b/lp.c
+@@ -0,0 +1,56 @@
++/*
++ * Part of DNS zone file validator `validns`.
++ *
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
++ * Modified BSD license.
++ * (See LICENSE file in the distribution.)
++ *
++ */
++#include <sys/types.h>
++#include <stdio.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++
++#include "common.h"
++#include "textparse.h"
++#include "mempool.h"
++#include "carp.h"
++#include "rr.h"
++
++static struct rr *lp_parse(char *name, long ttl, int type, char *s)
++{
++	struct rr_lp *rr = getmem(sizeof(*rr));
++	int preference;
++
++	rr->preference = preference = extract_integer(&s, "LP preference");
++	if (preference < 0)
++		return NULL;
++	rr->fqdn = extract_name(&s, "LP fqdn", 0);
++	if (!rr->fqdn)
++		return NULL;
++
++	if (*s) {
++		return bitch("garbage after valid LP data");
++	}
++
++	return store_record(type, name, ttl, rr);
++}
++
++static char* lp_human(struct rr *rrv)
++{
++	RRCAST(lp);
++	char s[1024];
++
++	snprintf(s, 1024, "%d %s",
++			 rr->preference, rr->fqdn);
++	return quickstrdup_temp(s);
++}
++
++static struct binary_data lp_wirerdata(struct rr *rrv)
++{
++	RRCAST(lp);
++    return compose_binary_data("2d", 1,
++		rr->preference, name2wire_name(rr->fqdn));
++}
++
++struct rr_methods lp_methods = { lp_parse, lp_human, lp_wirerdata, NULL, NULL };
+diff --git a/main.c b/main.c
+index 98d8ce3..80005b1 100644
+--- a/main.c
++++ b/main.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -41,7 +41,7 @@ static char *process_directive(char *s)
+ 			return bitch("bad $ORIGIN format");
+ 		}
+ 		s = skip_white_space(s);
+-		o = extract_name(&s, "$ORIGIN value");
++		o = extract_name(&s, "$ORIGIN value", 0);
+ 		if (!o) {
+ 			return NULL;
+ 		}
+@@ -112,7 +112,7 @@ read_zone_file(void)
+ 					continue;
+ 				} else {
+ 					/* <domain-name> */
+-					name = extract_name(&s, "record name");
++					name = extract_name(&s, "record name", 0);
+ 					if (!name)
+ 						continue;
+ 				}
+@@ -270,21 +270,25 @@ static void initialize_globals(void)
+ 	for (i = 0; i <= T_MAX; i++) {
+ 		rr_methods[i] = unknown_methods;
+ 	}
+-	rr_methods[T_A]            =          a_methods;
+ 	rr_methods[T_AAAA]         =       aaaa_methods;
++	rr_methods[T_A]            =          a_methods;
+ 	rr_methods[T_CERT]         =       cert_methods;
+ 	rr_methods[T_CNAME]        =      cname_methods;
+ 	rr_methods[T_DNAME]        =      dname_methods;
+ 	rr_methods[T_DNSKEY]       =     dnskey_methods;
+ 	rr_methods[T_DS]           =         ds_methods;
+ 	rr_methods[T_HINFO]        =      hinfo_methods;
++	rr_methods[T_L32]          =        l32_methods;
++	rr_methods[T_L64]          =        l64_methods;
+ 	rr_methods[T_LOC]          =        loc_methods;
++	rr_methods[T_LP]           =         lp_methods;
+ 	rr_methods[T_MX]           =         mx_methods;
+ 	rr_methods[T_NAPTR]        =      naptr_methods;
+-	rr_methods[T_NS]           =         ns_methods;
+-	rr_methods[T_NSEC]         =       nsec_methods;
+-	rr_methods[T_NSEC3]        =      nsec3_methods;
++	rr_methods[T_NID]          =        nid_methods;
+ 	rr_methods[T_NSEC3PARAM]   = nsec3param_methods;
++	rr_methods[T_NSEC3]        =      nsec3_methods;
++	rr_methods[T_NSEC]         =       nsec_methods;
++	rr_methods[T_NS]           =         ns_methods;
+ 	rr_methods[T_PTR]          =        ptr_methods;
+ 	rr_methods[T_RP]           =         rp_methods;
+ 	rr_methods[T_RRSIG]        =      rrsig_methods;
+@@ -292,6 +296,7 @@ static void initialize_globals(void)
+ 	rr_methods[T_SPF]          =        spf_methods;
+ 	rr_methods[T_SRV]          =        srv_methods;
+ 	rr_methods[T_SSHFP]        =      sshfp_methods;
++	rr_methods[T_TLSA]         =       tlsa_methods;
+ 	rr_methods[T_TXT]          =        txt_methods;
+ }
+ 
+@@ -341,6 +346,8 @@ main(int argc, char **argv)
+ 				G.opt.policy_checks[POLICY_NS_ALIAS] = 1;
+ 			} else if (strcmp(optarg, "rp-txt-exists") == 0) {
+ 				G.opt.policy_checks[POLICY_RP_TXT_EXISTS] = 1;
++			} else if (strcmp(optarg, "tlsa-host") == 0) {
++				G.opt.policy_checks[POLICY_TLSA_HOST] = 1;
+ 			} else {
+ 				usage("unknown policy name");
+ 			}
+diff --git a/mempool.c b/mempool.c
+index 6e8ff96..2fbb6d0 100644
+--- a/mempool.c
++++ b/mempool.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/mempool.h b/mempool.h
+index bd653e9..c887aac 100644
+--- a/mempool.h
++++ b/mempool.h
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/mx.c b/mx.c
+index 6f89581..70f4b12 100644
+--- a/mx.c
++++ b/mx.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -25,7 +25,7 @@ static struct rr *mx_parse(char *name, long ttl, int type, char *s)
+ 	if (rr->preference < 0)
+ 		return NULL;
+ 	/* XXX preference range check */
+-	rr->exchange = extract_name(&s, "MX exchange");
++	rr->exchange = extract_name(&s, "MX exchange", 0);
+ 	if (!rr->exchange)
+ 		return NULL;
+ 	if (*s) {
+diff --git a/naptr.c b/naptr.c
+index 457d549..4534ded 100644
+--- a/naptr.c
++++ b/naptr.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -58,7 +58,7 @@ static struct rr *naptr_parse(char *name, long ttl, int type, char *s)
+ 		return NULL;
+ 	rr->regexp = text;
+ 
+-	rr->replacement = extract_name(&s, "replacement");
++	rr->replacement = extract_name(&s, "replacement", 0);
+ 	if (!rr->replacement)
+ 		return NULL;
+ 
+diff --git a/nid.c b/nid.c
+new file mode 100644
+index 0000000..3cc8c41
+--- /dev/null
++++ b/nid.c
+@@ -0,0 +1,58 @@
++/*
++ * Part of DNS zone file validator `validns`.
++ *
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
++ * Modified BSD license.
++ * (See LICENSE file in the distribution.)
++ *
++ */
++#include <sys/types.h>
++#include <stdio.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++
++#include "common.h"
++#include "textparse.h"
++#include "mempool.h"
++#include "carp.h"
++#include "rr.h"
++
++static struct rr *nid_parse(char *name, long ttl, int type, char *s)
++{
++	struct rr_nid *rr = getmem(sizeof(*rr));
++	int preference;
++
++	rr->preference = preference = extract_integer(&s, "NID preference");
++	if (preference < 0)
++		return NULL;
++	if (extract_u64(&s, "NodeID", &rr->node_id) < 0)
++		return NULL;
++
++	if (*s) {
++		return bitch("garbage after valid NID data");
++	}
++
++	return store_record(type, name, ttl, rr);
++}
++
++static char* nid_human(struct rr *rrv)
++{
++	RRCAST(nid);
++    char s[1024];
++
++    snprintf(s, 1024, "%d %x:%x:%x:%x",
++	     rr->preference,
++		 (unsigned)(rr->node_id >> 48) & 0xffff,
++		 (unsigned)(rr->node_id >> 32) & 0xffff,
++		 (unsigned)(rr->node_id >> 16) & 0xffff,
++		 (unsigned)(rr->node_id >> 0) & 0xffff);
++    return quickstrdup_temp(s);
++}
++
++static struct binary_data nid_wirerdata(struct rr *rrv)
++{
++	RRCAST(nid);
++    return compose_binary_data("28", 1, rr->preference, rr->node_id);
++}
++
++struct rr_methods nid_methods = { nid_parse, nid_human, nid_wirerdata, NULL, NULL };
+diff --git a/ns.c b/ns.c
+index 3f486db..e920eae 100644
+--- a/ns.c
++++ b/ns.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -22,7 +22,7 @@ static struct rr *ns_parse(char *name, long ttl, int type, char *s)
+ 	struct rr_ns *rr = getmem(sizeof(*rr));
+ 	struct rr *ret_rr;
+ 
+-	rr->nsdname = extract_name(&s, "name server domain name");
++	rr->nsdname = extract_name(&s, "name server domain name", 0);
+ 	if (!rr->nsdname)
+ 		return NULL;
+ 	if (*s) {
+diff --git a/nsec.c b/nsec.c
+index 789b29d..d76b6ad 100644
+--- a/nsec.c
++++ b/nsec.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -25,7 +25,7 @@ static struct rr* nsec_parse(char *name, long ttl, int type, char *s)
+ 	char *str_type = NULL;
+ 	int ltype;
+ 
+-    rr->next_domain = extract_name(&s, "next domain");
++    rr->next_domain = extract_name(&s, "next domain", KEEP_CAPITALIZATION);
+ 	/* TODO: validate next_domain, http://tools.ietf.org/html/rfc4034#section-4.1.1 */
+ 
+ 	bitmap = new_set();
+@@ -33,6 +33,8 @@ static struct rr* nsec_parse(char *name, long ttl, int type, char *s)
+ 		str_type = extract_label(&s, "type list", "temporary");
+ 		if (!str_type) return NULL;
+ 		ltype = str2rdtype(str_type);
++		if (ltype < 0)
++			return NULL;
+ 		add_bit_to_set(&bitmap, ltype);
+ 	}
+ 	if (!s)
+diff --git a/nsec3.c b/nsec3.c
+index c390cdc..a7b8acb 100644
+--- a/nsec3.c
++++ b/nsec3.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -86,6 +86,8 @@ static struct rr* nsec3_parse(char *name, long ttl, int type, char *s)
+ 		str_type = extract_label(&s, "type list", "temporary");
+ 		if (!str_type) return NULL;
+ 		ltype = str2rdtype(str_type);
++		if (ltype < 0)
++			return NULL;
+ 		add_bit_to_set(&bitmap, ltype);
+ 	}
+ 	if (!s)
+diff --git a/nsec3checks.c b/nsec3checks.c
+index e9d157b..ef54ab2 100644
+--- a/nsec3checks.c
++++ b/nsec3checks.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -91,6 +91,7 @@ void perform_remaining_nsec3checks(void)
+ 	while (named_rr_p) {
+ 		named_rr = *named_rr_p;
+ 		if ((named_rr->flags & mask) == NAME_FLAG_KIDS_WITH_RECORDS) {
++//fprintf(stderr, "--- need nsec3, kids with records: %s\n", named_rr->name);
+ needs_nsec3:
+ 			freeall_temp();
+ 			hash = name2hash(named_rr->name, nsec3param);
+@@ -119,10 +120,24 @@ needs_nsec3:
+ 					(NAME_FLAG_NOT_AUTHORITATIVE|NAME_FLAG_SIGNED_DELEGATION)) ==
+ 				   NAME_FLAG_SIGNED_DELEGATION)
+ 		{
++//fprintf(stderr, "--- need nsec3, signed delegation: %s\n", named_rr->name);
+ 			goto needs_nsec3;
+-		} else if (!G.nsec3_opt_out_present && (named_rr->flags & NAME_FLAG_DELEGATION))
++		} else if (!G.nsec3_opt_out_present && (named_rr->flags &
++					(NAME_FLAG_APEX_PARENT|NAME_FLAG_NOT_AUTHORITATIVE|NAME_FLAG_DELEGATION|NAME_FLAG_HAS_RECORDS)) ==
++				   0)
+ 		{
++//fprintf(stderr, "--- need nsec3, empty non-term: %s\n", named_rr->name);
+ 			goto needs_nsec3;
++		} else if (!G.nsec3_opt_out_present && (named_rr->flags & (NAME_FLAG_DELEGATION|NAME_FLAG_NOT_AUTHORITATIVE))==NAME_FLAG_DELEGATION)
++		{
++//fprintf(stderr, "--- need nsec3, no opt-out: %s\n", named_rr->name);
++			goto needs_nsec3;
++		} else if (!G.nsec3_opt_out_present && (named_rr->flags & (NAME_FLAG_THIS_WITH_RECORDS|NAME_FLAG_NOT_AUTHORITATIVE)) == NAME_FLAG_THIS_WITH_RECORDS)
++		{
++//fprintf(stderr, "--- need nsec3, this with records: %s\n", named_rr->name);
++			goto needs_nsec3;
++		} else {
++//fprintf(stderr, "--- NO need for nsec3: %s\n", named_rr->name);
+ 		}
+ next:
+ 		JSLN(named_rr_p, zone_data, sorted_name);
+diff --git a/nsec3param.c b/nsec3param.c
+index 3c24162..539ef80 100644
+--- a/nsec3param.c
++++ b/nsec3param.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/ptr.c b/ptr.c
+index 8cf1c96..8164ef2 100644
+--- a/ptr.c
++++ b/ptr.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -21,7 +21,7 @@ static struct rr *ptr_parse(char *name, long ttl, int type, char *s)
+ {
+ 	struct rr_ptr *rr = getmem(sizeof(*rr));
+ 
+-	rr->ptrdname = extract_name(&s, "name server domain name");
++	rr->ptrdname = extract_name(&s, "name server domain name", 0);
+ 	if (!rr->ptrdname)
+ 		return NULL;
+ 	if (*s) {
+diff --git a/rp.c b/rp.c
+index 6c2a5fd..9f77c49 100644
+--- a/rp.c
++++ b/rp.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -22,11 +22,11 @@ static struct rr *rp_parse(char *name, long ttl, int type, char *s)
+ {
+ 	struct rr_rp *rr = getmem(sizeof(*rr));
+ 
+-	rr->mbox_dname = extract_name(&s, "mbox domain name");
++	rr->mbox_dname = extract_name(&s, "mbox domain name", 0);
+ 	if (!rr->mbox_dname)
+ 		return NULL;
+ 
+-	rr->txt_dname = extract_name(&s, "txt domain name");
++	rr->txt_dname = extract_name(&s, "txt domain name", 0);
+ 	if (!rr->txt_dname)
+ 		return NULL;
+ 
+diff --git a/rr.c b/rr.c
+index 9ab475f..f47328d 100644
+--- a/rr.c
++++ b/rr.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -71,12 +71,19 @@ static char* rdtype2str_map[T_MAX+1] = {
+ 	"DHCID",
+ 	"NSEC3", /* 50 */
+ 	"NSEC3PARAM",
+-	0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 */
++	"TLSA",
++	      0, 0, 0, 0, 0, 0, 0, 0, /* 60 */
+ 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70 */
+ 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 */
+ 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 */
+ 	0, 0, 0, 0, 0, 0, 0, 0,
+-	"SPF"
++	"SPF",
++	                           0, /* 100 */
++	0, 0, 0,
++	"NID",
++	"L32",
++	"L64",
++	"LP",
+ };
+ void *zone_data = NULL;
+ char *zone_apex = NULL;
+@@ -474,6 +481,12 @@ int str2rdtype(char *rdtype)
+ 	case 'l':
+ 		if (strcmp(rdtype, "loc") == 0) {
+ 			return T_LOC;
++		} else if (strcmp(rdtype, "l32") == 0) {
++			return T_L32;
++		} else if (strcmp(rdtype, "l64") == 0) {
++			return T_L64;
++		} else if (strcmp(rdtype, "lp") == 0) {
++			return T_LP;
+ 		}
+ 		break;
+ 	case 'm':
+@@ -490,6 +503,8 @@ int str2rdtype(char *rdtype)
+ 			return T_NSEC;
+ 		} else if (strcmp(rdtype, "nsec3") == 0) {
+ 			return T_NSEC3;
++		} else if (strcmp(rdtype, "nid") == 0) {
++			return T_NID;
+ 		} else if (strcmp(rdtype, "nsec3param") == 0) {
+ 			return T_NSEC3PARAM;
+ 		}
+@@ -520,6 +535,8 @@ int str2rdtype(char *rdtype)
+ 	case 't':
+ 		if (strcmp(rdtype, "txt") == 0) {
+ 			return T_TXT;
++		} else if (strcmp(rdtype, "tlsa") == 0) {
++			return T_TLSA;
+ 		} else if (strncmp(rdtype, "type", 4) == 0) {
+ 			long type = strtol(rdtype+4, NULL, 10);
+ 			if (type <= 0 || type > 65535)
+@@ -560,12 +577,43 @@ void validate_rrset(struct rr_set *rr_set)
+ 	}
+ }
+ 
++void debug(struct named_rr *named_rr, char *s)
++{
++	fprintf(stderr, "%s %s", s, named_rr->name);
++	if ((named_rr->flags & NAME_FLAG_APEX))
++		fprintf(stderr, ", apex");
++	if ((named_rr->flags & NAME_FLAG_HAS_RECORDS))
++		fprintf(stderr, ", has records");
++	if ((named_rr->flags & NAME_FLAG_DELEGATION))
++		fprintf(stderr, ", delegation");
++	if ((named_rr->flags & NAME_FLAG_NOT_AUTHORITATIVE))
++		fprintf(stderr, ", not auth");
++	if ((named_rr->flags & NAME_FLAG_NSEC3_ONLY))
++		fprintf(stderr, ", nsec3 only");
++	if ((named_rr->flags & NAME_FLAG_KIDS_WITH_RECORDS))
++		fprintf(stderr, ", kid records");
++	if ((named_rr->flags & NAME_FLAG_SIGNED_DELEGATION))
++		fprintf(stderr, ", signed delegation");
++	if ((named_rr->flags & NAME_FLAG_APEX_PARENT))
++		fprintf(stderr, ", apex parent");
++	fprintf(stderr, "\n");
++}
++
+ void validate_named_rr(struct named_rr *named_rr)
+ {
+ 	Word_t rdtype;
+ 	struct rr_set **rr_set_p;
+ 	int nsec3_present = 0;
+ 	int nsec3_only = 1;
++	static int seen_apex = 0;
++
++	rdtype = 0;
++	JLF(rr_set_p, named_rr->rr_sets, rdtype);
++
++	if ((named_rr->flags & NAME_FLAG_APEX))
++		seen_apex = 1;
++	if (!seen_apex)
++		named_rr->flags |= NAME_FLAG_APEX_PARENT;
+ 
+ 	if (named_rr->parent && (named_rr->parent->flags & (NAME_FLAG_DELEGATION|NAME_FLAG_NOT_AUTHORITATIVE)) != 0) {
+ 		named_rr->flags |= NAME_FLAG_NOT_AUTHORITATIVE;
+@@ -573,24 +621,30 @@ void validate_named_rr(struct named_rr *named_rr)
+ 			G.stats.not_authoritative++;
+ 		}
+ 	}
+-	rdtype = 0;
+-	JLF(rr_set_p, named_rr->rr_sets, rdtype);
++//debug(named_rr, ">>>>");
++
+ 	while (rr_set_p) {
+ 		validate_rrset(*rr_set_p);
+ 		if (rdtype == T_NSEC3)
+ 			nsec3_present = 1;
+ 		else if (rdtype != T_RRSIG)
+ 			nsec3_only = 0;
++		if (rdtype != T_NSEC3 && rdtype != T_RRSIG && rdtype != T_NS)
++			named_rr->flags |= NAME_FLAG_THIS_WITH_RECORDS;
+ 		if ((named_rr->flags & NAME_FLAG_NOT_AUTHORITATIVE) == 0 &&
+ 			rdtype != T_NS && rdtype != T_NSEC3 && rdtype != T_RRSIG)
+ 		{
+ 			struct named_rr *nrr = named_rr;
++			int skip_first = rdtype == T_NS;
++
+ 			while (nrr && (nrr->flags & NAME_FLAG_KIDS_WITH_RECORDS) == 0) {
+ 				if ((nrr->flags & NAME_FLAG_APEX_PARENT) || strlen(nrr->name) < zone_apex_l) {
+ 					nrr->flags |= NAME_FLAG_APEX_PARENT;
+ 					break;
+ 				}
+-				nrr->flags |= NAME_FLAG_KIDS_WITH_RECORDS;
++				if (!skip_first)
++					nrr->flags |= NAME_FLAG_KIDS_WITH_RECORDS;
++				skip_first = 0;
+ 				nrr = nrr->parent;
+ 			}
+ 		}
+@@ -607,6 +661,7 @@ void validate_named_rr(struct named_rr *named_rr)
+ 	if (nsec3_present && nsec3_only) {
+ 		named_rr->flags |= NAME_FLAG_NSEC3_ONLY;
+ 	}
++//debug(named_rr, "<<<<");
+ }
+ 
+ 
+@@ -633,7 +688,7 @@ static void* nsec_validate_pass2(struct rr *rrv)
+ 		break;
+ 	}
+ 
+-	if (strcmp(rr->next_domain, zone_apex) == 0) {
++	if (strcasecmp(rr->next_domain, zone_apex) == 0) {
+ 		if (next_named_rr) {
+ 			return moan(rr->rr.file_name, rr->rr.line, "NSEC says %s is the last name, but %s exists",
+ 						named_rr->name, next_named_rr->name);
+@@ -642,7 +697,7 @@ static void* nsec_validate_pass2(struct rr *rrv)
+ 		if (!next_named_rr) {
+ 			return moan(rr->rr.file_name, rr->rr.line, "NSEC says %s comes after %s, but nothing does",
+ 						rr->next_domain, named_rr->name);
+-		} else if (strcmp(rr->next_domain, next_named_rr->name) != 0) {
++		} else if (strcasecmp(rr->next_domain, next_named_rr->name) != 0) {
+ 			return moan(rr->rr.file_name, rr->rr.line, "NSEC says %s comes after %s, but %s does",
+ 						rr->next_domain, named_rr->name, next_named_rr->name);
+ 		}
+diff --git a/rr.h b/rr.h
+index 35abd6d..7685eff 100644
+--- a/rr.h
++++ b/rr.h
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -31,8 +31,13 @@
+ #define T_DNSKEY	48
+ #define T_NSEC3	50
+ #define T_NSEC3PARAM	51
++#define T_TLSA	52
+ #define T_SPF	99
+-#define T_MAX	99
++#define T_NID	104
++#define T_L32	105
++#define T_L64	106
++#define T_LP	107
++#define T_MAX	107
+ 
+ #define ALG_DSA                  3
+ #define ALG_RSASHA1              5
+@@ -96,14 +101,15 @@ struct binary_data name2wire_name(char *s);
+ int algorithm_type(int alg);
+ int extract_algorithm(char **s, char *what);
+ 
+-#define NAME_FLAG_APEX                1
+-#define NAME_FLAG_HAS_RECORDS         2
+-#define NAME_FLAG_DELEGATION          4
+-#define NAME_FLAG_NOT_AUTHORITATIVE   8
+-#define NAME_FLAG_NSEC3_ONLY          16
+-#define NAME_FLAG_KIDS_WITH_RECORDS   32
+-#define NAME_FLAG_SIGNED_DELEGATION   64
++#define NAME_FLAG_APEX                  1
++#define NAME_FLAG_HAS_RECORDS           2
++#define NAME_FLAG_DELEGATION            4
++#define NAME_FLAG_NOT_AUTHORITATIVE     8
++#define NAME_FLAG_NSEC3_ONLY           16
++#define NAME_FLAG_KIDS_WITH_RECORDS    32
++#define NAME_FLAG_SIGNED_DELEGATION    64
+ #define NAME_FLAG_APEX_PARENT         128
++#define NAME_FLAG_THIS_WITH_RECORDS   256
+ 
+ struct named_rr
+ {
+@@ -171,11 +177,53 @@ extern struct rr_methods ns_methods;
+ struct rr_txt
+ {
+     struct rr rr;
+-	int count;
++    int count;
+     struct binary_data txt[1];
+ };
+ extern struct rr_methods txt_methods;
+ 
++struct rr_tlsa
++{
++    struct rr rr;
++    uint8_t cert_usage;
++    uint8_t selector;
++    uint8_t matching_type;
++    struct binary_data association_data;
++};
++extern struct rr_methods tlsa_methods;
++
++struct rr_nid
++{
++    struct rr rr;
++    uint16_t preference;
++    uint64_t node_id;
++};
++extern struct rr_methods nid_methods;
++
++struct rr_l32
++{
++    struct rr rr;
++    uint16_t preference;
++    uint32_t locator32;
++};
++extern struct rr_methods l32_methods;
++
++struct rr_l64
++{
++    struct rr rr;
++    uint16_t preference;
++    uint64_t locator64;
++};
++extern struct rr_methods l64_methods;
++
++struct rr_lp
++{
++    struct rr rr;
++    uint16_t preference;
++    char *fqdn;
++};
++extern struct rr_methods lp_methods;
++
+ struct rr_naptr
+ {
+     struct rr rr;
+diff --git a/rrsig.c b/rrsig.c
+index 8e7930a..81befa6 100644
+--- a/rrsig.c
++++ b/rrsig.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -84,7 +84,7 @@ static struct rr* rrsig_parse(char *name, long ttl, int type, char *s)
+ 	if (key_tag < 0)	return NULL;
+ 	rr->key_tag = key_tag;
+ 
+-	rr->signer = extract_name(&s, "signer name");
++	rr->signer = extract_name(&s, "signer name", 0);
+ 	if (!rr->signer) return NULL;
+ 	/* TODO validate signer name, http://tools.ietf.org/html/rfc4034#section-3.1.7 */
+ 
+diff --git a/soa.c b/soa.c
+index 1bc9a42..9e70a09 100644
+--- a/soa.c
++++ b/soa.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -22,9 +22,9 @@ static struct rr* soa_parse(char *name, long ttl, int type, char *s)
+ 	struct rr_soa *rr = getmem(sizeof(*rr));
+ 	long long i;
+ 
+-	rr->mname = extract_name(&s, "mname");
++	rr->mname = extract_name(&s, "mname", 0);
+ 	if (!rr->mname) return NULL;
+-	rr->rname = extract_name(&s, "rname");
++	rr->rname = extract_name(&s, "rname", 0);
+ 	if (!rr->rname) return NULL;
+ 	i = extract_integer(&s, "serial");
+ 	if (i < 0) return NULL;
+diff --git a/spf.c b/spf.c
+index efe76c5..5cb1c82 100644
+--- a/spf.c
++++ b/spf.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/srv.c b/srv.c
+index 4683003..e606354 100644
+--- a/srv.c
++++ b/srv.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -45,7 +45,7 @@ static struct rr *srv_parse(char *name, long ttl, int type, char *s)
+ 		return bitch("port range is not valid");
+ 	rr->port = i;
+ 
+-	rr->target = extract_name(&s, "target");
++	rr->target = extract_name(&s, "target", 0);
+ 	if (!rr->target)
+ 		return NULL;
+ 
+diff --git a/sshfp.c b/sshfp.c
+index b10a5ff..ec9c03f 100644
+--- a/sshfp.c
++++ b/sshfp.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -36,9 +36,9 @@ static struct rr* sshfp_parse(char *name, long ttl, int type, char *s)
+ 
+ 	rr->fingerprint = extract_hex_binary_data(&s, "fingerprint", EXTRACT_EAT_WHITESPACE);
+ 	if (rr->fingerprint.length < 0)	return NULL;
+-	if (rr->fingerprint.length != 20) {
++	if (rr->fingerprint.length != SHA1_BYTES) {
+ 		return bitch("wrong SHA-1 fingerprint length: %d bytes found, %d bytes expected",
+-					 rr->fingerprint.length, 20);
++					 rr->fingerprint.length, SHA1_BYTES);
+ 	}
+ 
+ 	if (*s) {
+diff --git a/t/issues/21-nsec3-without-corresponding/Kexample.sec.+008+48381.key b/t/issues/21-nsec3-without-corresponding/Kexample.sec.+008+48381.key
+new file mode 100644
+index 0000000..e9cd610
+--- /dev/null
++++ b/t/issues/21-nsec3-without-corresponding/Kexample.sec.+008+48381.key
+@@ -0,0 +1 @@
++example.sec. IN DNSKEY 256 3 8 AwEAAdZOvnLtTdQjfdIqqH3stb7vI6bJlg273Tp4oRpnmnmgizDFtLQh nIv1Mr3AuwSWVIDeavuiyWIAtfvwy0f3EYIv8Ys5kDiKs8PE1k90yQwf C53hxyH10GzGnAx4Sutrdkh1w4HM1nMBdlTMa0g9yxjJ0vm/T7qHzj+3 dTUi84s8Du2mfMD6noy+leZ2IuX7lFca8SzDNmhUPTkXuFrB/QUuoY2F yThfidT+nhOQpzftVtLcta0E0Uv3PcVDp1d7vBXsAEYGHr54r2vb3eXd OTmoFyh/byehUlPq1gDEH0mBRlWbUHqbGnKyolz0dR01u8SJYP6ULwx0 mZ0p5BmoMH8=
+diff --git a/t/issues/21-nsec3-without-corresponding/Kexample.sec.+008+48381.private b/t/issues/21-nsec3-without-corresponding/Kexample.sec.+008+48381.private
+new file mode 100644
+index 0000000..5beec83
+--- /dev/null
++++ b/t/issues/21-nsec3-without-corresponding/Kexample.sec.+008+48381.private
+@@ -0,0 +1,10 @@
++Private-key-format: v1.2
++Algorithm: 8 (RSASHA256)
++Modulus: 1k6+cu1N1CN90iqofey1vu8jpsmWDbvdOnihGmeaeaCLMMW0tCGci/UyvcC7BJZUgN5q+6LJYgC1+/DLR/cRgi/xizmQOIqzw8TWT3TJDB8LneHHIfXQbMacDHhK62t2SHXDgczWcwF2VMxrSD3LGMnS+b9PuofOP7d1NSLzizwO7aZ8wPqejL6V5nYi5fuUVxrxLMM2aFQ9ORe4WsH9BS6hjYXJOF+J1P6eE5CnN+1W0ty1rQTRS/c9xUOnV3u8FewARgYevniva9vd5d05OagXKH9vJ6FSU+rWAMQfSYFGVZtQepsacrKiXPR1HTW7xIlg/pQvDHSZnSnkGagwfw==
++PublicExponent: AQAB
++PrivateExponent: LOxwy9Km3/NYqre6fjsilhW3GX1kcRiSdXFYBBr3rMtUojKvgJsTH9uUeWZvTbTdne4B6yHiqSKRA3Eki79k8i9uqMq2SsP4ju8yJZHLmzjezIfJoHrQ6BxyFcMZoWPzdZkKFKmFwrHpxjjbvFcHvfiAu025Pta9C2o/rZXYC7V3BWQowqYBfukdpZkCEhzFzEtC1ROXN4jPJBwNIma52QTLH6jK5BOfOJ5DhS1SF+r/EkuvXnylApVfjPfUIC8ocVvpn5WLoabWL+eURIi6MvVT59ppzc6WRUT2PxDskT2WUWfw3zq5B7JCM8/qfYIDUHvt1h6JcJHTAOz9Hr2f4Q==
++Prime1: 8UNey2U7voMhZmVUMpH5C8q7+hp6PQ6dUYd+hjaQVnsDOLPBT+zZf8R3str7pY/xlOOHy+DxYmZ0e17OumSOXTeQR4VSdsr/tpWc/qd2jd1I5N58R4G/yZHgTm8pm6VRb7NwZ7Eg6o2z0G2UEykFeberyg4U6SHBDP6DZNvGrQk=
++Prime2: 42XeoQUBshFkTYekdeqPfGqC1YXsK0URLGAbPbk8HlOiG7ueVmUnsAS47lyuEJPzIUgqqBbDM+CCdW8AvPJFDXa09l4akfCrLRyAdkreGj3bgmUs5wUFbDZyOHvRFSxdUI8LOcAhXthy86l+wErKwm6sWfd1oPGvMmC1qiSsW0c=
++Exponent1: JpdjK1+3DcNF7W4Z6LjmwFceeGQR14Bl86ubtnY14k9s9X3zVwiIxeI0T1yt0g7TUsCOcTM7CUVgLne8053QE+MWZgpSZYQVISyPX0CEOy8BQPLBqGJ9vg1idslbO3VXMGngegWgQUSHVbihbesq4AxcI0bbW2s1yRFRDSoGfpk=
++Exponent2: NbR7bd/21I1S+RSN/ONW2/VzzOYCLv3y3l4cUOmMj0UFRjN7Y8AkLWgQHQt6eKPYigW3PVeS5o+hgAalT/qP4GwmtQDomYsTgmX22Pk5l00AqL0oa6895p69PyXO7Yc6yqnd5te/idzo2S8wpk2DsYPd5KmS+F3cGLPKc9KRekU=
++Coefficient: ev+8Aj3u6mICRe6Y0NqYTGrXSBMDXf92dI4+CZtwy43cyTvvZSABWvlLTTXf8XAlnnPxszSpG7+e8bQk4A7ZIagcDFSUjzwtVoLqKqbyLPMNjJKqvGW2iTwfpXAHTadd9EmvTPsEVCJnZAvkyn9XQ49phL9IkFzj9kmSrGqnN4Q=
+diff --git a/t/issues/21-nsec3-without-corresponding/dsset-example.sec. b/t/issues/21-nsec3-without-corresponding/dsset-example.sec.
+new file mode 100644
+index 0000000..b4019ef
+--- /dev/null
++++ b/t/issues/21-nsec3-without-corresponding/dsset-example.sec.
+@@ -0,0 +1,2 @@
++example.sec.		IN DS 48381 8 1 99477B577BF885AB2512B8DCA052D7B71DD968BA
++example.sec.		IN DS 48381 8 2 E5411AAE0758711B164730F9069CCFA3CAB00391FDD76D04EB3E8610 CAA09E93
+diff --git a/t/issues/21-nsec3-without-corresponding/example.sec b/t/issues/21-nsec3-without-corresponding/example.sec
+new file mode 100644
+index 0000000..352b4e6
+--- /dev/null
++++ b/t/issues/21-nsec3-without-corresponding/example.sec
+@@ -0,0 +1,17 @@
++$TTL    1d
++$INCLUDE Kexample.sec.+008+48381.key
++@       IN      SOA     ns.example.sec. hostmaster.example.sec. (
++                              1         ; Serial
++                         604800         ; Refresh
++                          86400         ; Retry
++                        2419200         ; Expire
++                         604800 )       ; Negative Cache TTL
++
++        IN      NS      ns1.example.net.
++1.1.1.1.1.1.1.1.1.1.33  IN      NS      ns1.example.net.
++
++6.5.4.3.2.33  IN      NS      ns1.example.net.
++9.8.7.6.5.4.3.2.33  IN      NS      ns1.example.net.
++
++
++bebe.meme IN A 1.2.3.4
+diff --git a/t/issues/21-nsec3-without-corresponding/example.sec.signed b/t/issues/21-nsec3-without-corresponding/example.sec.signed
+new file mode 100644
+index 0000000..c574155
+--- /dev/null
++++ b/t/issues/21-nsec3-without-corresponding/example.sec.signed
+@@ -0,0 +1,334 @@
++; File written on Fri Aug 24 16:33:53 2012
++; dnssec_signzone version 9.8.3
++example.sec.		86400	IN SOA	ns.example.sec. hostmaster.example.sec. (
++					1          ; serial
++					604800     ; refresh (1 week)
++					86400      ; retry (1 day)
++					2419200    ; expire (4 weeks)
++					604800     ; minimum (1 week)
++					)
++			86400	RRSIG	SOA 8 2 86400 20120923133353 (
++					20120824133353 48381 example.sec.
++					QySkSzvLPglLtsg976XY0GAdDCzZY9IEiVrn
++					PAsFloXokhd3sYDi+/Wg+XNNPasoqvUv75c9
++					JYbXyV9ZF0axe7TVvCmynNi2fn5xvfU3MbiX
++					bQqkoJq708xLtxkDjkKj4wo7aLfNXqItdvlG
++					8MBNI7lUMd9V1EAp1+sKz4oCbAm67dUZsJTs
++					NNQewA2NTkZG8SLU12ueBoEm3SFIkDaGf3pr
++					BqFKnKo7Dpi5quPydRyZv23lDkAFv86eMBky
++					7Ftz5JSnTrxQ96J5idVzc+8V2VJJLCMps/Lg
++					0f8EWXU13oy8hVNHgsbMkMgwuhK0TpoAQ3Xu
++					12I+iB9gXmOB7S1TWw== )
++			86400	NS	ns1.example.net.
++			86400	RRSIG	NS 8 2 86400 20120923133353 (
++					20120824133353 48381 example.sec.
++					jq61ICTW2ofwSICLNMF5DiPO1wH6Y8t/oDO6
++					5Rz07pV02fSbEZXHpap4MLne0ikOqKPtFhsP
++					qdircIdp9SccoXq1biKu+6yw0sGRwbR82Foq
++					4LIgz9yoSr0W2bUICSaa7SZDtnqpTj9tyVVx
++					9hFWM1DemqyU9k6wi3Qtvqyge9NRH2IbQstr
++					Z6IhlpKlxeNR9P+H0aoYEoqfYIb8rSlv9KFq
++					wB6HeBCgBl0rJ/EpHQI9P9SZzgvgVjzAgWzb
++					yXCmwkDUoFNDaIt+6rbWIWxTO3NETVOPcCRh
++					fWFJpahmKqy+7sQOdXYtOkUp4T48bMttktMN
++					jGx0TDN6hDUWPOGKrA== )
++			86400	DNSKEY	256 3 8 (
++					AwEAAdZOvnLtTdQjfdIqqH3stb7vI6bJlg27
++					3Tp4oRpnmnmgizDFtLQhnIv1Mr3AuwSWVIDe
++					avuiyWIAtfvwy0f3EYIv8Ys5kDiKs8PE1k90
++					yQwfC53hxyH10GzGnAx4Sutrdkh1w4HM1nMB
++					dlTMa0g9yxjJ0vm/T7qHzj+3dTUi84s8Du2m
++					fMD6noy+leZ2IuX7lFca8SzDNmhUPTkXuFrB
++					/QUuoY2FyThfidT+nhOQpzftVtLcta0E0Uv3
++					PcVDp1d7vBXsAEYGHr54r2vb3eXdOTmoFyh/
++					byehUlPq1gDEH0mBRlWbUHqbGnKyolz0dR01
++					u8SJYP6ULwx0mZ0p5BmoMH8=
++					) ; key id = 48381
++			86400	RRSIG	DNSKEY 8 2 86400 20120923133353 (
++					20120824133353 48381 example.sec.
++					CxJvtfEuhQr694uCQg6fyz2sAg+TqH242DnL
++					BSidvv9GzKZdHiZs+iFfcrGC4nJ3pTeWMv5/
++					zp2AXXkpJeCdW5Gy1xy9aexDRJuUMaFzE4xN
++					v/QTdDzBWJBujDNM1C/HstntlQvOGLLTFGsY
++					JCfVguYs0qqSPNd9fbDs7/edhMDe3f6v68+O
++					UISrEgfy2PJpGeg5idX+63G4GE0OOa08dwUw
++					LJQAGpobUjk3TjSh08jllQ21iQIdUV1pxfrC
++					qBu2HH8ZMlSpk4ZoTsDKCNGy5VMQcRxtOOa6
++					9kTcmhNakfxnK+24Wu+xjqmmIWBPKxtmhYfw
++					IlzGSu2uuGd7PvwovA== )
++			0	NSEC3PARAM 1 0 1 94CD
++			0	RRSIG	NSEC3PARAM 8 2 0 20120923133353 (
++					20120824133353 48381 example.sec.
++					N5gosx8Suslg27+3wPYAP8gXeH91Wc4ebH5H
++					mZMkEL5b0ODgSvVgPhwTRRE1/SJGzXGWXSpW
++					VopGKMh6SLBNAmfi6gsRtIfPutJA6hmqRtqK
++					JiKEi6Sy3gRLKPJC1Hd/v8K2rslSoCFFsive
++					w5cZBonS85f7n+BA9VglfQmPqux2/LvykcGS
++					/tVGz5zZXWRdPPapj5e+TKrBfVglmcaIL9uk
++					c4uMHtSkdwlKrXV2SCPK6H9meYIsEg8SvIXN
++					Kx2Wfo3hvD9XINYRKwsN6FGFYrOvHpdJI/Mz
++					QUZ70+nUQU4sbV3Y4yoHhI9Y8Dn8khdCqjCg
++					ynbFt1GVrA0QobO9WQ== )
++9.8.7.6.5.4.3.2.33.example.sec.	86400 IN NS ns1.example.net.
++1.1.1.1.1.1.1.1.1.1.33.example.sec. 86400 IN NS	ns1.example.net.
++6.5.4.3.2.33.example.sec. 86400	IN NS	ns1.example.net.
++0A8475SNU6T5P84AMC4I7KAEAMKCMIAF.example.sec. 604800 IN	NSEC3 1 0 1 94CD 1F02V227102AEBUICGPQNPFSMSQ56UNC
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					mipK0k5i2YVpsDosay3tcOBgvykaBn9gaDJN
++					/otEJTXurcfGkRria5C3AsTrq68PIhM9Ct5v
++					bJxgaz0ab1hBHhDe8AZNVzrqrYWmmSgpNrBk
++					VJTx3YnYUuO25MYEEh00/1/JYyHwaGdtjkoD
++					KAwAUt7NqlLZjEHWlZUap+2sxeq1T6l6owDu
++					xt/FNpb8QdUXYK5lsaqCWbNTHWQ3F8n49h1Y
++					ve+m5NtbFL8+7qxrBRSC68eBTPrQfsAym4oB
++					yU05KTFLgHgI7CrexI1dyx+mb19LA0IVKGas
++					bo8lD20VQdiGuEflZj04rihXmJYGU/rNrV4r
++					BhyABAvc26GMfGIa1w== )
++4H7F6LT6O2L8EJJEK17S0MPTF3G1GMS3.example.sec. 604800 IN	NSEC3 1 0 1 94CD 6MMR4M238C6KQ7OL4J0HD33VSF2RBFE6
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					lX7thD4OK1v7YDU4waKvTR/YZN0c/jpLcZRh
++					vEw/wVY6o2ZjC4DPmFlhHNDGcNil1Dtwxxnq
++					iO4T6iNZOWWnnGy3WprLlO9hN6eZvC3c0jio
++					uDynQyHytpwNIUtLSiHEqhNZUUt2f4BK0C6o
++					oMFepT/+dKBuyK+FWWkjVswrhmPbpTvnKUOh
++					ob2ONOh1UcOhjtTjl8kr51DnDe6/xOACCi4L
++					a8UvTLRROvWUoQt4U7A8n4svrc7oYTh+lIfb
++					I/6NYX6loVa9g1hiipx+Kn7VkcGGSTWP5lFv
++					jx3nl9QyrqZYUMeCyF4FgYv2R029bxRJM4xN
++					e03+Kwof3LuK6RiRhg== )
++ANUH4A3TCIVO884LMD5SA3S1563VKCOG.example.sec. 604800 IN	NSEC3 1 0 1 94CD B23STANUG8J6J7Q86S978IDEOHR9SKOK NS SOA RRSIG DNSKEY NSEC3PARAM
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					z8HofxVlX+519QE5aW0uywdOA6O+YP8y5Yr5
++					wJlyyLefw5Fti0dmU7qGzR5NoOxTfyH+lJDb
++					7IPB5DaA4OI3wA6XCHJ1CVrNZJ7kKOt35L0N
++					vR1cq89V0wISlfVSMa4Lh6qOvfjEFcpZOziQ
++					+G9s2hYdKQIxHEAmX35H+ZK3yDuWKgGvZCiP
++					wARqDipOzAbsgMUXUFT4/q1YhXENU44yxMGv
++					QoZWskJ5bfrHWvZY/PDPQX18JziMM5zkL+sJ
++					32HtIl2Ji3bPboqbGKrfXg35v6LR2oNl56Bq
++					TTFFmGwUr0GOhJhtJOHxtxJ7gc6JBkn6MdG0
++					Rm41tHPCdsJqi2eYZA== )
++B48FHI6PGSEKSCPQHI53K69GG9QPT86F.example.sec. 604800 IN	NSEC3 1 0 1 94CD BUA7DPQPLLPMOFP3570HUGOCO0PMK9TI
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					ByAqe7JjTyKwuudzVHqZTQCtJLT3NSlKVGvQ
++					EcpOVPr6f4VXHCpJ2U0uw1SgdzZgw/trIo0z
++					MWY0MU94NDPZ0jt0G4Bz9CXF+MJSOmXF/G8D
++					+DEvC0rdeAi3tMupIGMyAkkeL3hLiyo7FCBx
++					SsuqWu0FQ5Gd2PTYUXiSX3ZG9NlTtDgjHtPS
++					doAfO5ZtIJyLXUK6hWgEdNrfJOM/yDh7AS0y
++					L7oHhk7xoGz+6U2ZoiScEIZ/wg2Ry02fvRgl
++					CdkfQUAWctgpeBybCkImdlE18Ww3jPmknTcw
++					fFpIsMGvdHW/yh7YMPibf9brn+l53DC52wQF
++					hXENXf1Igy5KfMIgDQ== )
++B23STANUG8J6J7Q86S978IDEOHR9SKOK.example.sec. 604800 IN	NSEC3 1 0 1 94CD B48FHI6PGSEKSCPQHI53K69GG9QPT86F
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					YpjhuKP/CxZi1+/xsnYlq3Hb6KmxjXu7NaZ7
++					wL2+m1f5ffB8cu+1VMdMjXd9rA87KM+nZmIH
++					ZgkM13BjscZYfZrD1QxTHZOpK98DsP0BVjab
++					V3YxS99SrpWIWbsSGSnGuVnTIFg4Rc2Q7UY0
++					cPz2aPbTSjaYtmE+b4DS5KtZpsQUOc/mlPU5
++					1RiMkMOJqSnflQY922C43Xg/DaywBWaI18b1
++					gyL5wMyZ2OU+I1EVK1e/Hgp3xTU+VZFfH981
++					ooZvbHxTqvR2RPN/CiRmkb1j8OR8rtzQlAUq
++					zE/N2G225694CXjbhnuxtMQDnARZ+YY59efI
++					qRVe3R3RVwiIvnxubQ== )
++1F02V227102AEBUICGPQNPFSMSQ56UNC.example.sec. 604800 IN	NSEC3 1 0 1 94CD 4H7F6LT6O2L8EJJEK17S0MPTF3G1GMS3
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					Sl0o9shH2wSZ11t342nNF8umWjmCc6aFTPab
++					mhRnFDzzG2d++Cx4dXMsasDtUVspKQheiowA
++					j6HZZSGYEQfmW8XFs5Hf4h0NVkQ83i3euXGl
++					S1zbM0DiaGbNueIPSEyUBOyR1zzaBjzyhf6P
++					axvora+y5Yb/UeiFQgvZY6JKBib9RHT61Dpk
++					8C30CK+KpBRIAa3nu+oESqP+qe+UDF6Gia8t
++					Mn/8BMP+j070A38lrMFjfGmKq5QzMKP86Jnl
++					dG88wXSmUe1EzvUM7Y/djimPvGfSfIFl7J8t
++					rhQ3Cfs/Etu92HfQEqAhCg94BCv95RJXf9rj
++					6P2IRl7fn7tz8DPtcg== )
++71FH7088MFQ3GHCT8F0NKT9PF3BT46CC.example.sec. 604800 IN	NSEC3 1 0 1 94CD ANUH4A3TCIVO884LMD5SA3S1563VKCOG
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					bFgJbtvnx6+ICYygvHrxhuCgZxcgUFA24pQl
++					XwVUJqVgP+t8AfJ0GNURvoli4sxAa1ujJH/1
++					pdDrSTUSswqBClKM+n0C5Z1ZVEDdGLMsjxfH
++					hRcnUaup5dwC2gwvxUg7ZYxUjxeCiLOc2UEA
++					7A/ASY/qwtMunGeXKFycY93k0F6udeFqnIFG
++					jqR2yAoi271PbTkj7osSIJZJGi5bGIGlKDpu
++					ht30LBfG243IlZeAm2nxg2vE9d4Nd+ZRlMJ0
++					8H9vahBubbT0yfJiREnILL14i4FvST++5i1y
++					iaSRJPH2rMUp4oSsTvh8W07LjiytOG8IJkyY
++					T1A2UFL/DOBxD2O8nw== )
++IR5OEOOO61L2NLSFRK4OLKUJ6FEARD1Q.example.sec. 604800 IN	NSEC3 1 0 1 94CD K9KP0QD9J3T0F3DH2LQPPB37CPPNP3PF
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					scrCa9zRBY4h4gHoe/esvDALkI7c6x6vXY4F
++					pA7AnTb+L5WCrfp6tXiINwQ1Uvv16Olut162
++					QHdAe7GW1XQGdbuJ8tzBtQ9YkS6DvArSYYjb
++					KiHMFND1dvy5UBc7BWJwM7ysLwdjEfiYkKBs
++					WIZ/bfE3MbT3qRou/Kv8WQa33ELlkZ7x6sEs
++					5Era4soZ7SRzN4jba5r9TBwJoP9VQn7uNl2r
++					h0hFclD4grfUcMZRcun3voVoVmpY/72xStsc
++					r7btSUfDrzbcJP9W1WYcPDbsmyobY4QrYSCO
++					VUzBP17DjEzIMztg+u5R7FhClb9lZ6qhrikW
++					KtcOq3+nKs2JauRM4Q== )
++BUA7DPQPLLPMOFP3570HUGOCO0PMK9TI.example.sec. 604800 IN	NSEC3 1 0 1 94CD DGRBPEHGU29PPOAAQS0TK0K8KJLI60CF NS
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					EveB6krVUhecm3eWRh55oiDuHOfceimuJSAy
++					4KNd59B/+8FBB7U6KyaLm9YGZDP5d3wyP5Py
++					4G8z6j7vdTGbLTFsHyOxHwU1MGEqZU4vIB7N
++					LX3P42CjD9FKFfTLS8ig0HJaxa/wYRMoxvxa
++					fIPZZxuC/NR6ULLr6t7YIWp+rktew0vXAaPP
++					tgmfEU9zAMqYsnKhyTttTT543btuXfHBg9th
++					csf9dEz+p/lq1WZbyTTR4hs7ZkRYLA6TCI9q
++					vxee5Hsfhjv2k1B7YA1AFCikAt3xqbxcuhir
++					KpW66JXjbrp5ZxONejbYb3SLdY3PpWg2Al2W
++					WHSV6e0cVZ47QsIFzw== )
++K9KP0QD9J3T0F3DH2LQPPB37CPPNP3PF.example.sec. 604800 IN	NSEC3 1 0 1 94CD MQAMDNGOIK8QUBPB4GDEG0EVOK91DQJ6
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					UFg9mb+GA3lmzuN/bJUdHf1o65i729zK0NUZ
++					wQGscZD8q6vY+cPuaCGZxPBdIe0Jaf2XXzjp
++					rJVyLwbdYVIR4IuoUZJLQbCfGOrBxp5BHTf8
++					ybft2+7foWAAQc8GNvhYKkmEpHdyfUWLrj8x
++					Z4U+NP1fdBvO43TN0upQyeYTNa6E4umgQtYa
++					zkMXeeQWf4+vf0Ue14rCEtCOFN2BDksL4mJF
++					c93c1MfRMkTYX/2L7dtAfDgwcywdU+ndqXJv
++					XC60MFEJfj/7oHO3LUQd1XdkNqg4gnyx6TgN
++					zBcUXgN40FUZzRTHf5sXikmhm1Jm5Akaaune
++					NB0mJ4DVzw8XLdDy2A== )
++MQAMDNGOIK8QUBPB4GDEG0EVOK91DQJ6.example.sec. 604800 IN	NSEC3 1 0 1 94CD PFQHTQGF3T3O7NQ37E7APPJS4E7G6FQI
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					aREhBMyCg3PaF9cbN2jS8Imj3GrfwrM2C3gU
++					zVcJqD1SxPOGwr0UQq+IJxp2jf/4gKyGIU1V
++					TQ2jFkdNLuF4tHtu4OQCAYwG7ngtawm/bT5J
++					R7ecSVRQOmowEZa9/VbF8qN8EuTmB7L9wB2W
++					2Efj6moE/Yt0SLJ5UIbRoKN5mJZaxjzWOif5
++					F+xE7yi2JVOve4mbAkxV/cqYInksWedvrKZt
++					SMBkIYbritHml3EHhI4MkDzAyDhw6rgY6P8I
++					tWCgVZf/8NSTW8J89hon9y4Z5CZuQHZigdkx
++					DVmcd6tsNyPlTP8HT4D+z5SaSD1GFKONjk5Z
++					vYu3LXMlw2OT+8UsXA== )
++6MMR4M238C6KQ7OL4J0HD33VSF2RBFE6.example.sec. 604800 IN	NSEC3 1 0 1 94CD 71FH7088MFQ3GHCT8F0NKT9PF3BT46CC NS
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					gH3QQQEbhWs3lNZn7yL+BMg8jOeILxZCMW4e
++					0iOBAfWpMxyxgvv9Jy3X9SQxui3zso6CfaoU
++					av6bMupDNYvGsRb2e9I9K3KQKv48wI8Z7UN+
++					/z1RqXy7izL4MX7Df4EYnKvhi0eLGI4hBJLq
++					my2AR4wswQiPG1tnBDa7lbx+o85GtHlX62lO
++					MD8lS5CvkSxDMBb5bChR5DYl8NChdtaSMxRD
++					yH7DZ6CI6t7ICUTKQs2aV8S6OTHmUQvDyA3U
++					KThFvxPdSv9Cf+FAQzN9kwNSGC4gxjJYQtjA
++					XjEIc+2ZPtOYI8+YJpAlNtR0kcy9TO5M9ioZ
++					tEvquxTTQooWNuxdTQ== )
++DGRBPEHGU29PPOAAQS0TK0K8KJLI60CF.example.sec. 604800 IN	NSEC3 1 0 1 94CD E7Q5FM6A5MAMV8HQ7O6A8F5RIF1VJGMO
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					xH7j5GQt3bah8ezTmXZ7/LsWLHw2PDCrmBtA
++					bEuqpKS/O7HvwVkQ1tQp1xznzpifDye2TqKH
++					tnEY6sWJ+hbByDrP87j5oP6ZuRTnzCtwUU6c
++					qqfEUV0JrAptkx+kxC4kLGjdB1OvaAiXvRg0
++					fhBaY458MLwQh7AxFsqv9Jd4KtJeVtm7PcWK
++					VoHPckh2LdZJQyiUl7+5zUKhsGBzEqU7BZck
++					OLPd6ccVJrNkOXfyrsYHj5NXILFtjJ/+avaY
++					kiTYYp8ix9bSLG6LBbWuaDNcjgGV3hI2Woo2
++					onBRmHmuklKgmmmbZ+YRT94FZnkrQRtUlRo1
++					nRLQN21PBXCOfwYQAA== )
++GGTEST9KCG7P1MNV2U653M6CIGD9Q6UJ.example.sec. 604800 IN	NSEC3 1 0 1 94CD IR5OEOOO61L2NLSFRK4OLKUJ6FEARD1Q A RRSIG
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					vAQghXrUpaoGUONOUjKRSxBIno5udi5R9GhP
++					L/ocMnuUYtIjtkPqFNmuIFpqMKOy34aox/TD
++					SPuZjfb4+OMcdHw0Zz9FT6U/jw2B2aAWcrDf
++					oU6HasH3e2lCUZizwiaCPPhFMuBdZjuwMqHN
++					BMCW9JfsJ9ohKl+OJ7i/eS0MgAWU7/o/hmAl
++					NRA4Q9fCUlivMQ+ZW+GUBLDzZh3tDMsIXhTK
++					EenhqSZdL563ZmRnxe9hg2+rjp7T42UxtzUu
++					MCt71MGnp+Q4ki8RjubLyDsjNbW9oXs02EwT
++					B7Exydd4GHGXBiYdUt2fFHp1pJ5sgObvSoue
++					FTw3xBWZ+TCnuohK/A== )
++E7Q5FM6A5MAMV8HQ7O6A8F5RIF1VJGMO.example.sec. 604800 IN	NSEC3 1 0 1 94CD GGTEST9KCG7P1MNV2U653M6CIGD9Q6UJ
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					NtTit77tk2WR/L0n3LcBnzceSfceR0y8bJjx
++					65oUXd+y+nu+c8I+OxmRDeoZHcHFvjH7TOpK
++					/bET+/KUbs/43wMYsq5pIRAq6iY+pNZnnkOQ
++					8P4lhKm15dpFb4dO1y3rXQxhT278BMoRDrMH
++					sOTveerXFOVI7hi7dSXsZp34to7hhdVrsF36
++					u00ogWJERVIZll3sCQOvKWyfFI8f8M69vWw1
++					o0U4OR3iWmz9L0zgIgxxSHHKnBZmW7cP+zW9
++					D746pMchP2TAYB43LZAMotU6jPLgWCcF0olz
++					73KJdziRJnko4ARx+iMgiWOUw0ujvCwK5kDo
++					lTmrDPe6/z8aXM/roQ== )
++VJ5SSNKSNS2CP5O6DCDDHK8HLH6N7CVC.example.sec. 604800 IN	NSEC3 1 0 1 94CD 0A8475SNU6T5P84AMC4I7KAEAMKCMIAF
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					nP9dmjAs6A4GdtsD9Xk3S0WOt5Tg9cSXJQDT
++					Ff+bd95AJKUeDRk0L71iUa60CYAHfDLI60gp
++					M5JgO0YgCloLzV9UFvkDj7Fe+v7Ptyl9mdEk
++					e7KwLBSVJyRsKMbgB+BgvenXEOH9hIiG+8CE
++					uokdOvUEERaUYk3zaoA5SScFGoVy6v9GwCcq
++					adUC16d5/WyNuaO2InVl2ug8dX1WtnZzdl09
++					evjhKiDiLABJ4Z1sLvkJsaNrwFpYn+Xkdv/W
++					MIb08A9FypXXavAV3zJJZyB2eyQG2Ae8ozNs
++					r7H06agUsiZKKMYtusq8FI7ISmgHPKbOu3ZZ
++					dT6l4pFLmuXimm5LmQ== )
++PFQHTQGF3T3O7NQ37E7APPJS4E7G6FQI.example.sec. 604800 IN	NSEC3 1 0 1 94CD PII3ACEVPP84TH3B1FCEUBN9E8R1PQT6
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					t3PvXIfG9zqm90xrzWhYYcvSB8ZO26ia3c71
++					uXs+3XS94BJF8cnvecAq26YTmbwCkm4y6AQg
++					1P3VmM5fZqHHq5eGthdSMgACpGYk/1KL+ZtU
++					qJ08LbtGFLS/Ai1YNOu+xVFj7Z1D27rAghGb
++					30z+qjkkgNKgF8RrtUrQtuZZHYljjypJ0bhU
++					ehZitu87s0tLIGZIK8EvZ1lkAr+RcdOau37x
++					HGIYSX262YOd7QZ/XytwhpnxjU6z99EefOKf
++					sP9e5U1Q76czO9iptn8m17lkEKIFEEP8jUtF
++					KGR1Qsb6PgDkAV82giZDxgFlq4WarIk6olu0
++					K03HV9skBS5BV2HqOg== )
++PII3ACEVPP84TH3B1FCEUBN9E8R1PQT6.example.sec. 604800 IN	NSEC3 1 0 1 94CD UB3H790SAMOQSDHHGOFHG1SBHU35K00O
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					0RfXq4uTIqZJQzcGQ4s1FzIyafMn8Y9gO7zp
++					Lf59a81Wr7feYG+KuOXc9sJC8Kk1Aerd1bSv
++					bAmskxHxBI2cjjI4S8JDSGVezymeqMsopoEH
++					c8jiACBjc9rCx2Z97YcXElo8PxE9AkC/a6/V
++					PHXGr0aS3P6QB1O9AHE1rIv5t9mrATJkE1TF
++					CH/ravS0ZaSZKPCLw7zSDObT9K4OazvRJHFO
++					VAqd1rX8J5SHBs3ss9p3kBfnedaMNb2GLfjo
++					Tky+WTIYoHexC2s4Kxdfj/8wWqlhw6JIcO9X
++					g7Tc500A4/58YU7JqmLfu7a3H0kVF2oXwxkA
++					KPlfulSsPGFYjB+5ng== )
++UB3H790SAMOQSDHHGOFHG1SBHU35K00O.example.sec. 604800 IN	NSEC3 1 0 1 94CD VJ5SSNKSNS2CP5O6DCDDHK8HLH6N7CVC
++			604800	RRSIG	NSEC3 8 3 604800 20120923133353 (
++					20120824133353 48381 example.sec.
++					kWKeBzW7N07cmtm7TtqzJfPJOcxNHqr7nQpJ
++					XqyRe2SvNlaUJpxqgTOQn3SjrsG4GUA5+j6Y
++					Y/MjScGeSME0xIWiPV1ZBGnm/9mB8FEePK58
++					PvBLa7SlKj2v3mvlMlZQzJa657NtV5hbaVcx
++					JP8YbK2W4zTGS8htg2VZMvRSfSV8gQwgKQlB
++					BGeIeM+xfYkrxvklRfLl6+ogZlJVfPH71SLO
++					PiEXrvfxU0HWbvej1HsNXdQDjv3Ix5vd8xZ9
++					QW4pyl+BHe22+Dx/TpAAoSXGdntuKuZqPF6P
++					bpBZrMZcqdPlODnEUBgzGB3ChaZvaf4BlHzs
++					vYqwsj87D5atXL3pOQ== )
++bebe.meme.example.sec.	86400	IN A	1.2.3.4
++			86400	RRSIG	A 8 4 86400 20120923133353 (
++					20120824133353 48381 example.sec.
++					vIeL1Bu8xiDbEn25Uard5kbWnI44qm7zMm7c
++					ZRTHlvfBlEfo0uAqdOEsABmIDuj6bYfqifHC
++					6YpsPU246RKOLwZ+FGZn9hTiWkixCu4gi/Cg
++					ynKCgRNprJdvRTiGTQ5glS2q0wNwn6SSgBAD
++					F5W6wu/R6k2MHCzJHoR45xLwwsDBqPAvPMlB
++					NgrtQh+L++zhvC5bw78WBnLY6h2wxlgby/6O
++					qwiYbHborqhQLzIYmneOluceptx5gk9F5B10
++					8QTG8wDtACj2TcKUT5vQ8+ZzmC8l3CNKVoKO
++					B2PrrtfNEaCNfYIjfW5d9feZkjxxqLSzrMTg
++					FZT6ntGLpEOxDRgYxw== )
+diff --git a/t/issues/24-delegated-nsec3/Kexample.sec.+008+48381.key b/t/issues/24-delegated-nsec3/Kexample.sec.+008+48381.key
+new file mode 100644
+index 0000000..e9cd610
+--- /dev/null
++++ b/t/issues/24-delegated-nsec3/Kexample.sec.+008+48381.key
+@@ -0,0 +1 @@
++example.sec. IN DNSKEY 256 3 8 AwEAAdZOvnLtTdQjfdIqqH3stb7vI6bJlg273Tp4oRpnmnmgizDFtLQh nIv1Mr3AuwSWVIDeavuiyWIAtfvwy0f3EYIv8Ys5kDiKs8PE1k90yQwf C53hxyH10GzGnAx4Sutrdkh1w4HM1nMBdlTMa0g9yxjJ0vm/T7qHzj+3 dTUi84s8Du2mfMD6noy+leZ2IuX7lFca8SzDNmhUPTkXuFrB/QUuoY2F yThfidT+nhOQpzftVtLcta0E0Uv3PcVDp1d7vBXsAEYGHr54r2vb3eXd OTmoFyh/byehUlPq1gDEH0mBRlWbUHqbGnKyolz0dR01u8SJYP6ULwx0 mZ0p5BmoMH8=
+diff --git a/t/issues/24-delegated-nsec3/Kexample.sec.+008+48381.private b/t/issues/24-delegated-nsec3/Kexample.sec.+008+48381.private
+new file mode 100644
+index 0000000..5beec83
+--- /dev/null
++++ b/t/issues/24-delegated-nsec3/Kexample.sec.+008+48381.private
+@@ -0,0 +1,10 @@
++Private-key-format: v1.2
++Algorithm: 8 (RSASHA256)
++Modulus: 1k6+cu1N1CN90iqofey1vu8jpsmWDbvdOnihGmeaeaCLMMW0tCGci/UyvcC7BJZUgN5q+6LJYgC1+/DLR/cRgi/xizmQOIqzw8TWT3TJDB8LneHHIfXQbMacDHhK62t2SHXDgczWcwF2VMxrSD3LGMnS+b9PuofOP7d1NSLzizwO7aZ8wPqejL6V5nYi5fuUVxrxLMM2aFQ9ORe4WsH9BS6hjYXJOF+J1P6eE5CnN+1W0ty1rQTRS/c9xUOnV3u8FewARgYevniva9vd5d05OagXKH9vJ6FSU+rWAMQfSYFGVZtQepsacrKiXPR1HTW7xIlg/pQvDHSZnSnkGagwfw==
++PublicExponent: AQAB
++PrivateExponent: LOxwy9Km3/NYqre6fjsilhW3GX1kcRiSdXFYBBr3rMtUojKvgJsTH9uUeWZvTbTdne4B6yHiqSKRA3Eki79k8i9uqMq2SsP4ju8yJZHLmzjezIfJoHrQ6BxyFcMZoWPzdZkKFKmFwrHpxjjbvFcHvfiAu025Pta9C2o/rZXYC7V3BWQowqYBfukdpZkCEhzFzEtC1ROXN4jPJBwNIma52QTLH6jK5BOfOJ5DhS1SF+r/EkuvXnylApVfjPfUIC8ocVvpn5WLoabWL+eURIi6MvVT59ppzc6WRUT2PxDskT2WUWfw3zq5B7JCM8/qfYIDUHvt1h6JcJHTAOz9Hr2f4Q==
++Prime1: 8UNey2U7voMhZmVUMpH5C8q7+hp6PQ6dUYd+hjaQVnsDOLPBT+zZf8R3str7pY/xlOOHy+DxYmZ0e17OumSOXTeQR4VSdsr/tpWc/qd2jd1I5N58R4G/yZHgTm8pm6VRb7NwZ7Eg6o2z0G2UEykFeberyg4U6SHBDP6DZNvGrQk=
++Prime2: 42XeoQUBshFkTYekdeqPfGqC1YXsK0URLGAbPbk8HlOiG7ueVmUnsAS47lyuEJPzIUgqqBbDM+CCdW8AvPJFDXa09l4akfCrLRyAdkreGj3bgmUs5wUFbDZyOHvRFSxdUI8LOcAhXthy86l+wErKwm6sWfd1oPGvMmC1qiSsW0c=
++Exponent1: JpdjK1+3DcNF7W4Z6LjmwFceeGQR14Bl86ubtnY14k9s9X3zVwiIxeI0T1yt0g7TUsCOcTM7CUVgLne8053QE+MWZgpSZYQVISyPX0CEOy8BQPLBqGJ9vg1idslbO3VXMGngegWgQUSHVbihbesq4AxcI0bbW2s1yRFRDSoGfpk=
++Exponent2: NbR7bd/21I1S+RSN/ONW2/VzzOYCLv3y3l4cUOmMj0UFRjN7Y8AkLWgQHQt6eKPYigW3PVeS5o+hgAalT/qP4GwmtQDomYsTgmX22Pk5l00AqL0oa6895p69PyXO7Yc6yqnd5te/idzo2S8wpk2DsYPd5KmS+F3cGLPKc9KRekU=
++Coefficient: ev+8Aj3u6mICRe6Y0NqYTGrXSBMDXf92dI4+CZtwy43cyTvvZSABWvlLTTXf8XAlnnPxszSpG7+e8bQk4A7ZIagcDFSUjzwtVoLqKqbyLPMNjJKqvGW2iTwfpXAHTadd9EmvTPsEVCJnZAvkyn9XQ49phL9IkFzj9kmSrGqnN4Q=
+diff --git a/t/issues/24-delegated-nsec3/dsset-example.sec. b/t/issues/24-delegated-nsec3/dsset-example.sec.
+new file mode 100644
+index 0000000..b4019ef
+--- /dev/null
++++ b/t/issues/24-delegated-nsec3/dsset-example.sec.
+@@ -0,0 +1,2 @@
++example.sec.		IN DS 48381 8 1 99477B577BF885AB2512B8DCA052D7B71DD968BA
++example.sec.		IN DS 48381 8 2 E5411AAE0758711B164730F9069CCFA3CAB00391FDD76D04EB3E8610 CAA09E93
+diff --git a/t/issues/24-delegated-nsec3/example.sec b/t/issues/24-delegated-nsec3/example.sec
+new file mode 100644
+index 0000000..659c640
+--- /dev/null
++++ b/t/issues/24-delegated-nsec3/example.sec
+@@ -0,0 +1,15 @@
++$TTL    1d
++$INCLUDE Kexample.sec.+008+48381.key
++@       IN      SOA     ns.example.sec. hostmaster.example.sec. (
++                              1         ; Serial
++                         604800         ; Refresh
++                          86400         ; Retry
++                        2419200         ; Expire
++                         604800 )       ; Negative Cache TTL
++
++                IN      NS      ns1.example.net.
++sub             IN      NS      ns1.example.net.
++test.sub        IN      A       127.0.0.1
++
++sub2	IN	NS	ns1.sub2
++ns1.sub2	IN	A	1.2.3.4
+diff --git a/t/issues/24-delegated-nsec3/example.sec.signed b/t/issues/24-delegated-nsec3/example.sec.signed
+new file mode 100644
+index 0000000..0994375
+--- /dev/null
++++ b/t/issues/24-delegated-nsec3/example.sec.signed
+@@ -0,0 +1,114 @@
++; File written on Fri Aug 24 16:21:37 2012
++; dnssec_signzone version 9.8.3
++example.sec.		86400	IN SOA	ns.example.sec. hostmaster.example.sec. (
++					1          ; serial
++					604800     ; refresh (1 week)
++					86400      ; retry (1 day)
++					2419200    ; expire (4 weeks)
++					604800     ; minimum (1 week)
++					)
++			86400	RRSIG	SOA 8 2 86400 20120923132137 (
++					20120824132137 48381 example.sec.
++					tbjigL7HBI1uY1R5m/QrGVGYv0pWNz0TJiMl
++					5s600fiDV/0t4eZO0sLsa14gNWSycaHzZpeH
++					AA29ZV07g+i/WE2BrNj00JzqfGeX3r8hd+LP
++					vTF7pHAG4syGweqokn9F0ePG/HvW3263i3eN
++					OuFJS7yeo1ey0REsCpkaMvmiTGYy4Ns/J3ft
++					kIT92X7p9Ok4ECm2jvYUykXSa8oChWK65EIQ
++					3VbMn+X7od686gw8disrBIgHYSlWO5cPHIe+
++					T60PqGB9RM6INT+8x8t1hyYDgZcWlL9J0bM+
++					QNp24ug1E3nKNgtg8Uf9jvA4HGzRxuB4L0PH
++					RCLY5Mv64LoNcuGmPA== )
++			86400	NS	ns1.example.net.
++			86400	RRSIG	NS 8 2 86400 20120923132137 (
++					20120824132137 48381 example.sec.
++					uZ3XcCp2Ko/NqC184GE+3Vl0kaxFRs1QkpAB
++					cZRS3DvTlFTJQFpAOpBD3YBiP4QTz6weJh9W
++					seg0/ykNlfxzRJjLTMijsAK5M3CEIfIA+1hV
++					5AiqEXIsD1VvwB4bmeMZY2HgYteyfP9waNmS
++					KE6hZG4VV4lHMdfxy6ovsi6UOGQrfA6+RdZ4
++					rRbMrQy4TofLPYWFA18TwcJRND+KMiLrbEB0
++					nsE7wtw09E6Fo/p9rfOJSId9zpkivSywvN60
++					dx5lH3RDM7dRKedLT26uWodoc+sm5ksma4b3
++					lVpkvVuRYsjx5380MC6Q3Ffi5lgGg+S6U+0x
++					BNsl65g/cBi52Mx3sg== )
++			86400	DNSKEY	256 3 8 (
++					AwEAAdZOvnLtTdQjfdIqqH3stb7vI6bJlg27
++					3Tp4oRpnmnmgizDFtLQhnIv1Mr3AuwSWVIDe
++					avuiyWIAtfvwy0f3EYIv8Ys5kDiKs8PE1k90
++					yQwfC53hxyH10GzGnAx4Sutrdkh1w4HM1nMB
++					dlTMa0g9yxjJ0vm/T7qHzj+3dTUi84s8Du2m
++					fMD6noy+leZ2IuX7lFca8SzDNmhUPTkXuFrB
++					/QUuoY2FyThfidT+nhOQpzftVtLcta0E0Uv3
++					PcVDp1d7vBXsAEYGHr54r2vb3eXdOTmoFyh/
++					byehUlPq1gDEH0mBRlWbUHqbGnKyolz0dR01
++					u8SJYP6ULwx0mZ0p5BmoMH8=
++					) ; key id = 48381
++			86400	RRSIG	DNSKEY 8 2 86400 20120923132137 (
++					20120824132137 48381 example.sec.
++					vMI5/h3OOEYXPyz2EuTd1UTuOXArx80fDXR3
++					aqAg0VXxuDj5aCNNtrumGac8VQJSbcOFS6en
++					zavsQbdF4GynuqVouq0+Cg+AKqbkf91mwoRo
++					9FfYjD+FiCH3AsTgY1sivgx96jxbUJrwlheV
++					Aq0sRNt25oejEnytF7zkxg4gfAmwszym2iy9
++					eYUCo5J7lMd5PGWOeTaWM6B1dhTu3db70GNg
++					s994rEqv9OM87d4XS9U+CrCbwQbj8VtHjUWv
++					ne5eSVqIh0RgMkPaLISYE2MUG2JNcs6eqYuq
++					z4LgGJAK3EE4QzsMGs5tmIK7rLbdIwUpLhlH
++					gwW2y4E10Hz7KLOjAA== )
++			0	NSEC3PARAM 1 0 1 94CD
++			0	RRSIG	NSEC3PARAM 8 2 0 20120923132137 (
++					20120824132137 48381 example.sec.
++					TMvS8oUX2NkG/VZ1/LFh5NzGNgmuj1KORpjQ
++					6xLuuZ5EFvV97L5lG/QIeqDYBaeYbbxx6PuO
++					q35aV3BRxcGkoDlWRC2cFyR3RNzeTjj1q50n
++					o3RgqtMkvJE/gyl1/oXL4IjSnlw5xYdYGa7n
++					G2mGQdc/0vh/De8VMh/n0Dq2WbuJ6vqsv3+i
++					M3oiMrapG91EYnAcFB4ymBbkbuBqTwu4Gwkf
++					dkweQRkufWI/d0WP8ziP6g3pX6uqJjwvDd4h
++					wcLgQgajZ7wOzfnsqS/v+CMc1Hu4B44PN7BB
++					50IKaviAkYCftfyTIy1FSYnAt4MHFrrQBKzX
++					c9ymqDL681D6zTNQtg== )
++test.sub.example.sec.	86400	IN A	127.0.0.1
++ns1.sub2.example.sec.	86400	IN A	1.2.3.4
++sub.example.sec.	86400	IN NS	ns1.example.net.
++sub2.example.sec.	86400	IN NS	ns1.sub2.example.sec.
++VT6TVPSQUE085J73EUKCPVB32N894AUB.example.sec. 604800 IN	NSEC3 1 0 1 94CD ANUH4A3TCIVO884LMD5SA3S1563VKCOG NS
++			604800	RRSIG	NSEC3 8 3 604800 20120923132137 (
++					20120824132137 48381 example.sec.
++					eaQxYQX+q0DDG03cLYyG9L+WmleExeZWQLb4
++					rBCuJO1rRkzxtC3SAD6MLQ2NVpiv9c0IbbNQ
++					EUCDXaA4/McY+CemogZV0pumI/xhzJ5Pd5k8
++					s8jxY0JNaaQ5cHDpUjyu6sWOTn4BwcZJaPtn
++					fBESTP7cy6uVQWRXiT5TJ33bBk2CeFCgMxD9
++					x5yvl5fWH+ZBl7AVYXamh4TsU5l8kL+HD19v
++					vauj4kQVEapBaaUEN3oS7S5lkUJ01ANHf39L
++					D36sRF6cZ2BEjiv3axl5IW4uQVnmo46XSP9Y
++					dX+0gjLFwfzUnt6bKO59pfZ1kAQnkpjvXC/h
++					DFcnQ1TZMn+MjSimNg== )
++L2BLRUARIR23VEOTUN998OLLATNAI6EE.example.sec. 604800 IN	NSEC3 1 0 1 94CD VT6TVPSQUE085J73EUKCPVB32N894AUB NS
++			604800	RRSIG	NSEC3 8 3 604800 20120923132137 (
++					20120824132137 48381 example.sec.
++					AU3924oCXsSm2yxkSzikdMHrKBgOCnTPQ8QQ
++					Cv/+ROYGWedvkf5jivUuqRi4wqsx+dK6UAPB
++					cmxb3zmebGfbzZtO1FI51z9tGSFPvahvTVcK
++					LkMlbzDmdcNFUpl/npagQLz5FTumi8gD2Ozl
++					dCdPATDlpoL1Won8t2rBIqPGaClahCHeub+2
++					FwAuWzjiNMsSAqUpIwHbUrf03AEYafVsacnI
++					1t6qELwFMIa2UUDXGsFSR4BIfAvDK3wFq/Pb
++					i4nzKyINGmCPTaUphh2+uLQ8CIUAArVtgAj3
++					WcIGO8p8fHE3R9CneWANo6jPEjURzMxFLUjA
++					RD31yV95Xj5SLwAGSg== )
++ANUH4A3TCIVO884LMD5SA3S1563VKCOG.example.sec. 604800 IN	NSEC3 1 0 1 94CD L2BLRUARIR23VEOTUN998OLLATNAI6EE NS SOA RRSIG DNSKEY NSEC3PARAM
++			604800	RRSIG	NSEC3 8 3 604800 20120923132137 (
++					20120824132137 48381 example.sec.
++					kTRt2QfhcT+N+2MyDWz1kFpu0fpqa8AyXH7l
++					GDgMUjILF6dSwSTH6OCYYk9HIrdleNwq352I
++					LerDlaOOszwVrdyGnSFnyT0MYhXFEFUVDibl
++					svZlpePqbHnMkCEWMGmZHa9k10xNa8e6lUd+
++					8lpUhuNSdi7GihEmYo0ZNlDv3913cz7iqNmg
++					0dZk1Vs5GFZGZp5R5y36zBgS8TS+OiYNXL+9
++					YSsJukXnW93WcEUSvT5saUoxWD24rP41w6ro
++					9n9J5XUgNmfaLMFj0AiaAtlVz30q3Nbv5v2T
++					w18A7ybrH2AiuSoRvL8ISQyIrA8P0pDIyftA
++					5e4wKXX9LZ/1E9laWw== )
+diff --git a/t/issues/25-nsec/Kexample.sec.+008+48381.key b/t/issues/25-nsec/Kexample.sec.+008+48381.key
+new file mode 100644
+index 0000000..e9cd610
+--- /dev/null
++++ b/t/issues/25-nsec/Kexample.sec.+008+48381.key
+@@ -0,0 +1 @@
++example.sec. IN DNSKEY 256 3 8 AwEAAdZOvnLtTdQjfdIqqH3stb7vI6bJlg273Tp4oRpnmnmgizDFtLQh nIv1Mr3AuwSWVIDeavuiyWIAtfvwy0f3EYIv8Ys5kDiKs8PE1k90yQwf C53hxyH10GzGnAx4Sutrdkh1w4HM1nMBdlTMa0g9yxjJ0vm/T7qHzj+3 dTUi84s8Du2mfMD6noy+leZ2IuX7lFca8SzDNmhUPTkXuFrB/QUuoY2F yThfidT+nhOQpzftVtLcta0E0Uv3PcVDp1d7vBXsAEYGHr54r2vb3eXd OTmoFyh/byehUlPq1gDEH0mBRlWbUHqbGnKyolz0dR01u8SJYP6ULwx0 mZ0p5BmoMH8=
+diff --git a/t/issues/25-nsec/Kexample.sec.+008+48381.private b/t/issues/25-nsec/Kexample.sec.+008+48381.private
+new file mode 100644
+index 0000000..5beec83
+--- /dev/null
++++ b/t/issues/25-nsec/Kexample.sec.+008+48381.private
+@@ -0,0 +1,10 @@
++Private-key-format: v1.2
++Algorithm: 8 (RSASHA256)
++Modulus: 1k6+cu1N1CN90iqofey1vu8jpsmWDbvdOnihGmeaeaCLMMW0tCGci/UyvcC7BJZUgN5q+6LJYgC1+/DLR/cRgi/xizmQOIqzw8TWT3TJDB8LneHHIfXQbMacDHhK62t2SHXDgczWcwF2VMxrSD3LGMnS+b9PuofOP7d1NSLzizwO7aZ8wPqejL6V5nYi5fuUVxrxLMM2aFQ9ORe4WsH9BS6hjYXJOF+J1P6eE5CnN+1W0ty1rQTRS/c9xUOnV3u8FewARgYevniva9vd5d05OagXKH9vJ6FSU+rWAMQfSYFGVZtQepsacrKiXPR1HTW7xIlg/pQvDHSZnSnkGagwfw==
++PublicExponent: AQAB
++PrivateExponent: LOxwy9Km3/NYqre6fjsilhW3GX1kcRiSdXFYBBr3rMtUojKvgJsTH9uUeWZvTbTdne4B6yHiqSKRA3Eki79k8i9uqMq2SsP4ju8yJZHLmzjezIfJoHrQ6BxyFcMZoWPzdZkKFKmFwrHpxjjbvFcHvfiAu025Pta9C2o/rZXYC7V3BWQowqYBfukdpZkCEhzFzEtC1ROXN4jPJBwNIma52QTLH6jK5BOfOJ5DhS1SF+r/EkuvXnylApVfjPfUIC8ocVvpn5WLoabWL+eURIi6MvVT59ppzc6WRUT2PxDskT2WUWfw3zq5B7JCM8/qfYIDUHvt1h6JcJHTAOz9Hr2f4Q==
++Prime1: 8UNey2U7voMhZmVUMpH5C8q7+hp6PQ6dUYd+hjaQVnsDOLPBT+zZf8R3str7pY/xlOOHy+DxYmZ0e17OumSOXTeQR4VSdsr/tpWc/qd2jd1I5N58R4G/yZHgTm8pm6VRb7NwZ7Eg6o2z0G2UEykFeberyg4U6SHBDP6DZNvGrQk=
++Prime2: 42XeoQUBshFkTYekdeqPfGqC1YXsK0URLGAbPbk8HlOiG7ueVmUnsAS47lyuEJPzIUgqqBbDM+CCdW8AvPJFDXa09l4akfCrLRyAdkreGj3bgmUs5wUFbDZyOHvRFSxdUI8LOcAhXthy86l+wErKwm6sWfd1oPGvMmC1qiSsW0c=
++Exponent1: JpdjK1+3DcNF7W4Z6LjmwFceeGQR14Bl86ubtnY14k9s9X3zVwiIxeI0T1yt0g7TUsCOcTM7CUVgLne8053QE+MWZgpSZYQVISyPX0CEOy8BQPLBqGJ9vg1idslbO3VXMGngegWgQUSHVbihbesq4AxcI0bbW2s1yRFRDSoGfpk=
++Exponent2: NbR7bd/21I1S+RSN/ONW2/VzzOYCLv3y3l4cUOmMj0UFRjN7Y8AkLWgQHQt6eKPYigW3PVeS5o+hgAalT/qP4GwmtQDomYsTgmX22Pk5l00AqL0oa6895p69PyXO7Yc6yqnd5te/idzo2S8wpk2DsYPd5KmS+F3cGLPKc9KRekU=
++Coefficient: ev+8Aj3u6mICRe6Y0NqYTGrXSBMDXf92dI4+CZtwy43cyTvvZSABWvlLTTXf8XAlnnPxszSpG7+e8bQk4A7ZIagcDFSUjzwtVoLqKqbyLPMNjJKqvGW2iTwfpXAHTadd9EmvTPsEVCJnZAvkyn9XQ49phL9IkFzj9kmSrGqnN4Q=
+diff --git a/t/issues/25-nsec/dsset-example.sec. b/t/issues/25-nsec/dsset-example.sec.
+new file mode 100644
+index 0000000..b4019ef
+--- /dev/null
++++ b/t/issues/25-nsec/dsset-example.sec.
+@@ -0,0 +1,2 @@
++example.sec.		IN DS 48381 8 1 99477B577BF885AB2512B8DCA052D7B71DD968BA
++example.sec.		IN DS 48381 8 2 E5411AAE0758711B164730F9069CCFA3CAB00391FDD76D04EB3E8610 CAA09E93
+diff --git a/t/issues/25-nsec/example.sec b/t/issues/25-nsec/example.sec
+new file mode 100644
+index 0000000..76922f5
+--- /dev/null
++++ b/t/issues/25-nsec/example.sec
+@@ -0,0 +1,13 @@
++$TTL    1d
++$INCLUDE Kexample.sec.+008+48381.key
++@       IN      SOA     ns.example.sec. hostmaster.example.sec. (
++                              1         ; Serial
++                         604800         ; Refresh
++                          86400         ; Retry
++                        2419200         ; Expire
++                         604800 )       ; Negative Cache TTL
++                IN      NS      ns1.example.net.
++subA            IN      NS      ns1.example.net.
++subb            IN      NS      ns1.example.net.
++subC            IN      NS      ns1.example.net.
++myMX	IN	MX 5 mx.example.net.
+diff --git a/t/issues/25-nsec/example.sec.signed b/t/issues/25-nsec/example.sec.signed
+new file mode 100644
+index 0000000..d51f828
+--- /dev/null
++++ b/t/issues/25-nsec/example.sec.signed
+@@ -0,0 +1,139 @@
++; File written on Fri Aug 24 15:30:38 2012
++; dnssec_signzone version 9.8.3-P2
++example.sec.		86400	IN SOA	ns.example.sec. hostmaster.example.sec. (
++					1          ; serial
++					604800     ; refresh (1 week)
++					86400      ; retry (1 day)
++					2419200    ; expire (4 weeks)
++					604800     ; minimum (1 week)
++					)
++			86400	RRSIG	SOA 8 2 86400 20121220000000 (
++					20120820000000 48381 example.sec.
++					qzY4pxbPjaFEQyE960A1GD918TUlhq4RoJ+B
++					QT5pkYo8RvqsN5g2MnfCegfe6ZS2/kwTMmWC
++					XLFyP4bglatyq6YpSb/nCNLsp7GHvkA1lkzb
++					VhvenUbYIvOjUXx6ME165fZbpP0NaUETvG6P
++					LKncqB2ts+Ru7ZsXZqBeAokxvc0Nf3q7JKHO
++					SHIV97zEeGxEbUqnbAVkjJzDeaUuIK6BBL0d
++					2cRpi385lVcAbDk0byH9l7nVzVeSf7NO06lX
++					j4Nr7kWvDrp3+8G0ArawsjwuSf8++B8fqxPH
++					hjvfw5hpvsKt99muko/gTsL/N3x7bAH9QQRe
++					U+jSnD27HBChCJSFXg== )
++			86400	NS	ns1.example.net.
++			86400	RRSIG	NS 8 2 86400 20121220000000 (
++					20120820000000 48381 example.sec.
++					thEwFRgijT/clJZq37540NFYrb/qPEMXdiuM
++					z1QsNXzNumsuVmPyxTwv0YFOEh1yMesFQGhf
++					AEVS+V9AoE+xA/r+eM64p+OMrxHmd476jyAi
++					eEGUOiNx9sZBEIYXB8tr0RRadWzoRtovpJ72
++					S6mJ2vBT9BIHFt14BVbQayLwf9mqpD4zQ5MU
++					gL33OxNXRdSsxRIxTyeC9RSSUd5hmCkNxjdX
++					k2ZbY4AlCZPcFOcdI8ZhLWd1mBD+e3xBwPwn
++					OILFQ/VpL5BCTB8Zw4yGAX8W0O2g7eXITD1p
++					/WVKj8ssLW8mlEjBvTC7SBPiPo0T+wt7jJUT
++					kcQz/cwfgGcGBgY0oQ== )
++			604800	NSEC	myMX.example.sec. NS SOA RRSIG NSEC DNSKEY
++			604800	RRSIG	NSEC 8 2 604800 20121220000000 (
++					20120820000000 48381 example.sec.
++					m3GzdLzAPvf5ZUUWISV5cKGyNgDUZSbtKm2K
++					vZ3Pm0vcBTvanrVsi4cyG9lpr0P+LnrRUgZ+
++					KgoBK3WG24vtLmPRHxdmRctYQ0HsxfEq474N
++					ifwQzaHenv70OTy4luViH1fbBtyUUH1AFeJ7
++					28Jj9gf6bJ0ZdUNPg0nU5uxqUiP98dEHn6JX
++					MMBGRMWrKzLM0QF8BP5P2BQ89JHnHVxDrzog
++					CzG9Uf1+bbd4j4QVvWjk3m7Wqf4Cb/fezMsm
++					lyme5u4yo3phrPgYCWWCgd+IssU7dNaxMnWE
++					uaycDuVSRmBotgfm03ANUiEbKb9arcfukSbg
++					IgGDyvfpvTzcpYi7cQ== )
++			86400	DNSKEY	256 3 8 (
++					AwEAAdZOvnLtTdQjfdIqqH3stb7vI6bJlg27
++					3Tp4oRpnmnmgizDFtLQhnIv1Mr3AuwSWVIDe
++					avuiyWIAtfvwy0f3EYIv8Ys5kDiKs8PE1k90
++					yQwfC53hxyH10GzGnAx4Sutrdkh1w4HM1nMB
++					dlTMa0g9yxjJ0vm/T7qHzj+3dTUi84s8Du2m
++					fMD6noy+leZ2IuX7lFca8SzDNmhUPTkXuFrB
++					/QUuoY2FyThfidT+nhOQpzftVtLcta0E0Uv3
++					PcVDp1d7vBXsAEYGHr54r2vb3eXdOTmoFyh/
++					byehUlPq1gDEH0mBRlWbUHqbGnKyolz0dR01
++					u8SJYP6ULwx0mZ0p5BmoMH8=
++					) ; key id = 48381
++			86400	RRSIG	DNSKEY 8 2 86400 20121220000000 (
++					20120820000000 48381 example.sec.
++					G2GT1BOwgV/uTbJf93jmUvl7bmu9I9gaV3B9
++					Iol/FeOE8/GQhpKYCM6zF6gT8iZtFJ37IYgD
++					tF5Zi+9nWE6HfvVtB6cltAL5Ud0Tkzuwf2XY
++					XsqnwiBmFlkJJgzNG7po0gkCWWrUpv+kg0Mn
++					0JJfmSOvo3srOyEg42pAWcEJ7dvAz/DgcOCk
++					ef9i4cxlRRtgWE4a4QkHH/V7pFDAOEvWkXg3
++					RUih5VIFM0POxnqgS/QRbca2Zm6FyCgkbHR1
++					QF+ojRSKGVKkE2VbIcPX7yUcBagg6WdkWjri
++					ZHZlwgF0bzbBNTc61MYiSK/PyDQpS1/m2JPd
++					OVidiTu6ajWJpUo6jQ== )
++myMX.example.sec.	86400	IN MX	5 mx.example.net.
++			86400	RRSIG	MX 8 3 86400 20121220000000 (
++					20120820000000 48381 example.sec.
++					iDUsHGQ4Zj9vEDUsojq08tVxOG6s+wjs3Qtf
++					DFXVPeqXmThdaMIVALzUyJYwnU0a4RNaM0lQ
++					FcFiK3y8fGuvMYQVUhheKBDLc0MmAht9CjJi
++					faUNJaNSTw/rjWtduJidzEaWUk5lh75YV3hc
++					YPk54jEbgTYTEJKCbfgDfRVShxAk64TM++Sh
++					xKSSW+4s2jKr98coYCcWYsHE6WlJXi0EJuDb
++					o84YG0MKoaURNcvEwWBwHhpxLnzT+7Yg7/AN
++					2bmogQLy40Yr8bS9DiyBZikXJt01Bj+2sTrw
++					t4JIxBPCPy08YayZzYcMLJ2M4FL0f633bWzX
++					4CPKb0ZLimqsAPXbPQ== )
++			604800	NSEC	subA.example.sec. MX RRSIG NSEC
++			604800	RRSIG	NSEC 8 3 604800 20121220000000 (
++					20120820000000 48381 example.sec.
++					ljtWqo0kh1F5NZ1vNGaLipgKCxEQ+c5deq0I
++					0wK8xOUSCjT5q8Ac8tIX6B50NIjw65YpOfQu
++					wzPVJM8PSsBA6eZuKIBKKy0MzD+X+eirunvS
++					wpJ6PHix8C4/eChrNZlEJs4AX6Q6nVuCH4b4
++					rIDClNiOTC7cXiWSK3FWgCzWpgWpG5yusRdb
++					EzDCyb5UTfnzcCZdjBRjXRA1c22nODgIlgS2
++					rqEJqn2o79CU8bYMx/LCQ96CO9y4XyVwAayK
++					ekSo6f7w7YPcwb9aFURN2mQ7ZP1sGxWUifVx
++					zpLE7aqM4fhlanG8OGEyvCZd2uXbtkdlw2m9
++					LGN/2omLoKgBK77JCg== )
++subA.example.sec.	86400	IN NS	ns1.example.net.
++			604800	NSEC	subb.example.sec. NS RRSIG NSEC
++			604800	RRSIG	NSEC 8 3 604800 20121220000000 (
++					20120820000000 48381 example.sec.
++					t68GfTtpxY7WZ8TVWBEEQdcsORVdG8a7hgL2
++					MMQgMW5K2DmdURAW3mEf8m8uXU2AwKJ+xCWL
++					/LXVfkxqFMVI4dyn6YGLbCyVv8RggATIt6b1
++					saEFTvByo2WThWnJU3r8Sq4LV35NurjruZ/o
++					DJVhTc//zPSSIQpUrz2kuUcOsL+djG3hJi+/
++					TB7CsrLGdEaD9elTwwAk9lvy0ZvfVhN63w0Q
++					BPMtSRPkARNfsHLJS6m8zutcUIbAPBF7FZDp
++					PUly5LNvZYbUQvFwo7A8JaZBUOBjFZ1apagt
++					FV3dBVtRXuBIBraFwJjUuKIApX177uYpxD8l
++					kDTfWeD/JD95z3a9Gg== )
++subb.example.sec.	86400	IN NS	ns1.example.net.
++			604800	NSEC	subC.example.sec. NS RRSIG NSEC
++			604800	RRSIG	NSEC 8 3 604800 20121220000000 (
++					20120820000000 48381 example.sec.
++					LJZFwPB4Aw4dLfqUnjmv3zeoKm/3ZZyHRusN
++					NniNNct8zaH7rqfTZHQoSBMH//YyyeJwQ7uO
++					7YIRIJvIi3z1iM2FpxuHihtUE9fIHPOGpjo/
++					t42bh611Lod+OReiukOaUOkhavg0wMfYEX99
++					Bw2V+Sk5z4UrLwJd/slQYjow4ZnFIubpJhqt
++					gw0fsygW6wb3XN9zs+nNo0XD1ksdQOyKu4tA
++					ZmYXWYCEbw/BIg8BDw3TnqUxbV44namLTSUg
++					97rA/90Nh/s1tsDQ3RbL7iaCbBH8ylSyCz5m
++					av1L+WK51LUJNgzm/fNJvI9kFzUG8s9oespe
++					f+r2hqgomotK4WdxMQ== )
++subC.example.sec.	86400	IN NS	ns1.example.net.
++			604800	NSEC	example.sec. NS RRSIG NSEC
++			604800	RRSIG	NSEC 8 3 604800 20121220000000 (
++					20120820000000 48381 example.sec.
++					twkPkw069EOqYcUugvM2qD7+/Yk51+91WRnz
++					Cq8AR8P4KlaBvahWg997haey4q8wV1rXsAXu
++					lMc9iNgmX6TaIiHoq9kMXumELWzE8Oxa/ymH
++					vvQnMOk2j0zcKh/7lyGeTX7cpSvXhz450XH3
++					3EfQeb6BLzlwyXgfnx/kGLS/lIez66Py/92v
++					2M87By7Gx69dv1vbBleeVxsYKmKe+sal7Ayl
++					ZPP9+NlOqZqDBrCXvwOmn+ScfCbeYxgMzmcf
++					2LMBEGxpDHRfBuV35hOzOVCce47CCip1Xian
++					Jmnh1A3dqZJXCrxFZidvAYVm7jEtAI8FS1OL
++					VjBf8zzsLfQKiMpeGA== )
+diff --git a/t/test.pl b/t/test.pl
+index 8ba2a66..29ff525 100644
+--- a/t/test.pl
++++ b/t/test.pl
+@@ -75,6 +75,26 @@ like(shift @e, qr/IPv6 address is not valid/, "not an IP in AAAA");
+ like(shift @e, qr/MX preference expected/, "empty MX");
+ like(shift @e, qr/MX exchange expected/, "MX without exchange");
+ like(shift @e, qr/garbage after valid MX data/, "bad MX");
++
++like(shift @e, qr/bad SHA-256 hash length/, "TLSA SHA-256");
++like(shift @e, qr/bad SHA-512 hash length/, "TLSA SHA-512");
++like(shift @e, qr/certificate association data: hex data does not represent whole number of bytes/, "TLSA nibbles");
++
++like(shift @e, qr/bad certificate usage field/, "TLSA certificate usage");
++like(shift @e, qr/TTL is not valid/, "TLSA certificate usage fallout");
++like(shift @e, qr/certificate usage field expected/, "TLSA certificate usage");
++like(shift @e, qr/TTL is not valid/, "TLSA certificate usage fallout");
++
++like(shift @e, qr/bad selector field/, "TLSA selector");
++like(shift @e, qr/TTL is not valid/, "TLSA selector fallout");
++like(shift @e, qr/selector field expected/, "TLSA selector");
++like(shift @e, qr/TTL is not valid/, "TLSA selector fallout");
++
++like(shift @e, qr/bad matching type field/, "TLSA matching type");
++like(shift @e, qr/TTL is not valid/, "TLSA matching type fallout");
++like(shift @e, qr/matching type field expected/, "TLSA matching type");
++like(shift @e, qr/TTL is not valid/, "TLSA matching type fallout");
++
+ like(shift @e, qr/outside.org. does not belong to zone galaxyplus.org./, "outsider");
+ like(shift @e, qr/long.outside.org. does not belong to zone galaxyplus.org./, "long outsider");
+ like(shift @e, qr/outsidegalaxyplus.org. does not belong to zone galaxyplus.org./, "tricky outsider");
+@@ -97,6 +117,9 @@ like(shift @e, qr/garbage after valid DNAME data/, "DNAME garbage");
+ like(shift @e, qr/CNAME and other data/, "CNAME+CNAME");
+ like(shift @e, qr/CNAME and other data/, "CNAME+something else");
+ like(shift @e, qr/there should be at least two NS records/, "NS limit");
++like(shift @e, qr/not a proper prefixed DNS domain name/, "TLSA host 1");
++like(shift @e, qr/not a proper prefixed DNS domain name/, "TLSA host 2");
++
+ like(shift @e, qr/TTL values differ within an RR set/, "TTL conflict");
+ like(shift @e, qr/multiple DNAMEs/, "Multiple DNAMEs");
+ like(shift @e, qr/DNAME must not have any children \(but something.zzzz3.galaxyplus.org. exists\)/, "DNAME with children");
+@@ -191,6 +214,19 @@ isnt(rc, 0, 'dnskey extra checks fail');
+ like(shift @e, qr/leading zero octets in public key exponent/, "leading zeroes in exponent 1");
+ like(shift @e, qr/leading zero octets in public key exponent/, "leading zeroes in exponent 2");
+ is(+ at e, 0, "no unaccounted errors for DNSKEY policy checks");
++
++# issue 21: https://github.com/tobez/validns/issues/21
++run('./validns', @threads, '-t1345815800', 't/issues/21-nsec3-without-corresponding/example.sec.signed');
++is(rc, 0, 'issue 21 did not come back');
++
++# issue 24: https://github.com/tobez/validns/issues/24
++run('./validns', @threads, '-t1345815800', 't/issues/24-delegated-nsec3/example.sec.signed');
++is(rc, 0, 'issue 24 did not come back');
++
++# issue 25: https://github.com/tobez/validns/issues/25
++run('./validns', @threads, '-t1345815800', 't/issues/25-nsec/example.sec.signed');
++is(rc, 0, 'issue 25 did not come back');
++
+ }
+ 
+ done_testing;
+diff --git a/t/zones/example.sec b/t/zones/example.sec
+index fe4b300..e361a4d 100644
+--- a/t/zones/example.sec
++++ b/t/zones/example.sec
+@@ -20,6 +20,19 @@ ns2		A	5.6.7.8
+ mail	A	2.3.4.5
+ www     CNAME example.sec.
+ 
++_443._tcp.www IN TLSA (
++      0 0 1 d2abde240d7cd3ee6b4b28c54df034b9
++            7983a1d16e8a410e4561cb106618e971 )
++
++_8443._tcp.www.example.sec. IN TLSA (
++      1 1 2 92003ba34942dc74152e2f2c408d29ec
++            a5a520e7f2e06bb944f4dca346baf63c
++            1b177615d466f6c4b71c216a50292bd5
++            8c9ebdd2f74e38fe51ffd48c43326cbc )
++
++_25._tcp.mail IN TLSA (
++      3 0 0 30820307308201efa003020102020123 )
++
+ delegation NS ns1
+ delegation NS ns2
+ delegation DS 60485 5 1 ( 2BB183AF5F22588179A53B0A
+@@ -51,3 +64,18 @@ cert	CERT URI 0 0 V2Ugc2hhbGwgbmVlZCBhIG51bWJlciBvZiBtYXRoZW1hdGljYWwgaWRlYXMgYW
+ 
+ alias DNAME anotherone.sec.
+ 
++host1	IN NID 10 0014:4fff:ff20:ee64
++host1	IN NID 20 0015:5fff:ff21:ee65
++host2	IN NID 10 0016:6fff:ff22:ee66
++
++host1	IN L32 10 10.1.02.0
++host1	IN L32 20 10.1.04.0
++host2	IN L32 10 10.1.08.0
++
++host1	IN L64 10 2001:0DB8:1140:1000
++host1	IN L64 20 2001:0DB8:2140:2000
++host2	IN L64 10 2001:0DB8:4140:4000
++
++host1	IN LP 10 l64-subnet1.example.com.
++host1	IN LP 10 l64-subnet2.example.com.
++host1	IN LP 20 l32-subnet1.example.com.
+diff --git a/t/zones/example.sec.signed b/t/zones/example.sec.signed
+index 38d9732..5bb8b0c 100644
+--- a/t/zones/example.sec.signed
++++ b/t/zones/example.sec.signed
+@@ -1,5 +1,5 @@
+-; File written on Thu Mar 22 15:19:14 2012
+-; dnssec_signzone version 9.8.1-P1
++; File written on Tue Jul 17 12:11:38 2012
++; dnssec_signzone version 9.8.3
+ example.sec.		300	IN SOA	ns1.example.sec. hostmaster.example.sec. (
+ 					42         ; serial
+ 					3600       ; refresh (1 hour)
+@@ -372,39 +372,271 @@ delegation4.example.sec. 300	IN NS	delegation4.example.sec.
+ 					gFnrAa3A1fLKuUf4G53MjTlu6BKYJQtEqxwo
+ 					0yE/8rePwZLK8Itgy3Io2V8MvHlU5NmUEWLq
+ 					At4YSicAUv2CpVOcqw== )
+-delegation2.example.sec. 300	IN NS	a.ns.delegation2.example.sec.
+-			300	NSEC	delegation3.example.sec. NS RRSIG NSEC
++delegation.example.sec.	300	IN NS	ns1.example.sec.
++			300	IN NS	ns2.example.sec.
++			300	DS	60485 5 1 (
++					2BB183AF5F22588179A53B0A98631FAD1A29
++					2118 )
++			300	RRSIG	DS 5 3 300 20121212121212 (
++					20111010101010 516 example.sec.
++					uEf2xsca1/OJwovwMVGyFB4/6OUmutAWlWvG
++					qM9JDtvUPMhUV8dzRRiwpWfz3YkPU60Hqn8n
++					QX981RtNc23oiwjmo1ehp1DW7R9dqcqxH4KM
++					5gYrdJT+lJAoN3ii43rQNl0N7OfObYxlZj+N
++					K7aMVBHESqQd5ZaRfkiut8XW49M= )
++			300	RRSIG	DS 5 3 300 20121212121212 (
++					20111010101010 44427 example.sec.
++					GIx0C0s5HJdizOCjIFnqf3BvhIwKaJZW9id0
++					vcQAyd3qzbiiuWecM5pdyiJahFpnKmGxTdLM
++					ZCEwNczhZZf+RE6SlOu8j/VcFujTlaq47JMZ
++					uaU2KETUVZzOhFP6Vrddax35icNcO1Qfu2US
++					B501hzVzyAjr4QL9j0KKlYBe3n3/349dHIiT
++					trruNmkB0c/M8KOkApnUbO8/42Xaz5QCBvXT
++					nyx3jp2WHTCCLLC2o0LTD++w6LkqhTXvWcbo
++					oIMBUXD9hXm/NnYjPxR5+8IhIzPjgjL1vzw7
++					RZrtCBVuI6PIsCRhyXxJ2XoxB293M0GxOmnh
++					VBZ0feqy7wVmo+hklw== )
++			300	RRSIG	DS 8 3 300 20121212121212 (
++					20111010101010 48381 example.sec.
++					D6eEY7RttRgccoDGLh1/JJ2Q8Xt8fbnNVzXG
++					WhLlMMeEc1S1FzJG8/SKUrvYVKtrU8wPZpLq
++					qV/2jEjHk81vOqj4S+NZh3hV94h5p27Pngqf
++					3fNzd0aO940zkFC30aAiz0BBd7MX28AOowLL
++					1UWoiTCuERpPAQTuRQRbAR2zf+205PJLjbU2
++					764FVJYEzp6Kal66lWOYlB2EqGWdrv3irPpJ
++					lyTYMaFpNvh4qOkRaBgmT06lzGQuG6E/tUmF
++					nR6tQA4oFaGMs4QGWv05iMYYKleBBNlC6OYM
++					0At5mmxZIfiC1viIGDTGvHaKDS3YjWO2YLIq
++					4EQZCBQJAnbb3rHmWA== )
++			300	NSEC	delegation2.example.sec. NS DS RRSIG NSEC
+ 			300	RRSIG	NSEC 5 3 300 20121212121212 (
+ 					20111010101010 516 example.sec.
+-					alXox/n3U8q3S7BezOkumPPVxQekZSPZ34nY
+-					w9JL0qX5h1NOuAR7SG0B/sKz8XKe1gpoTpZ6
+-					oCYSZ/4LAw1oWryRe1W4+K63fNHy1BpZJMGn
+-					0toviZnfH8DrmTnwcDAXkPd6IhdX2Ok7ztef
+-					M3yeP8heSWCvyBukpa4EBvwv5mA= )
++					iG8wud8jrvX0STdk/BPdIHUCMgeIExOklQEO
++					Ah+K6e4LJakFKjuI+G1tTLdHOP2GauWkb3GQ
++					0Ozj8r7+jQEz886ZQmCR8RigqW5/CsnwPc9V
++					oc7TbNntOs+M4NyOiqC9NfmafrpqIrmbLMBW
++					THN6XGPUMdc5riMr8miTKtLDMF0= )
+ 			300	RRSIG	NSEC 5 3 300 20121212121212 (
+ 					20111010101010 44427 example.sec.
+-					5e7KvcXLAy5uVdD/hAZuNl7mC+qITTiihlmU
+-					dh/KIachaEFMMqRoDsY61kjY+cSpkn/n2dp9
+-					OozcWUFfhfXY2D5EFaRmkWKtP4N37ryVWZUw
+-					maJ5ZDCLcRa/vWfJGWlTrG108ijGkfUPE3lE
+-					euYkc0d00yjmbcz72uAW8NUmixRUU+3Payly
+-					GZSDVcG7vZ/qaf1dXG6cToY2n0DDIf/526eC
+-					xH5NhhDJgq6O1ZCEtS9r6Hb9vpR9Ed9wJvgt
+-					a7VZltV0TlLaiFGSGZA+OgZV9l0HerOCh8uW
+-					nn3L8d+jMAOmrk8/Jn47uTpZub1/j8eZo5pA
+-					jFyHUZ1b0h957vC6XQ== )
++					Hw2H90l/QMOJYJPO+B1eCpGQXJGXOd5MoUfR
++					Fc4budW2eesImgWQ6TR8Bvwjz95niA8lpGyq
++					QEXjJ6cEf5JEKYw/4xOVlmFNDHyG//iQ1kpf
++					2+aT8IuiM0evbBgiej/VhYZFScUQ4Ibslna/
++					BFMyoJ7ugLmLelYiolB9g30a3q/3ULYwfn1j
++					OKUbYUeWClKQ+l+i37wRuBIPX6aT6//CetOX
++					uCecmaDTXl94NKi2pw+fZKs504Ed7xT6FtJF
++					9FYJAlsFloV7T6epZ/d5pl82QYaEshZpMePa
++					nqah+amBETh/kd3vokG1lzzFzSbwrWjxgtq8
++					XYCG9CbCOcJz1N0bXg== )
+ 			300	RRSIG	NSEC 8 3 300 20121212121212 (
+ 					20111010101010 48381 example.sec.
+-					rQwfcCjBLlYDpe6DC2d1w2qVYAUYFqcfbwHy
+-					gbjXT4RI2nV4E5q34jwEgi3TFb5OmYZviGwF
+-					cJvyii25oYSt2qcKPlTGGnrD3vAMb9lgX9L2
+-					hyeHWcmOfB397CySJKMXNbWtZz2YLu4YLrc9
+-					K1e+2eQD9MZbVIBrn2f5Krf306FMNd9L4n/p
+-					yNrW/6EUfHmRtFsD5vGYytoRRBKoPv5Rxfoj
+-					pbhhuyC8MlntVH0IhDe1zvKAmzlBj6E6oB93
+-					zG8SqT/gNIuTUpa/qw37tcOw3fCRh7uG3TBk
+-					+ylUmRz+hcTUxjSqoQKxVT61hXcrKAogspaY
+-					QZ3Mctyg3Se9NhUd6A== )
++					yc2VoV4VVT+Wo/rVo6brdb7LfxMOslatW8Lo
++					ldBOGkVuiz21DskK5LUMGkH/4+NZ2L/aaDCt
++					JyiARZXabIqeMMY47QbNB1DouT1yKvR1Bc4D
++					Hgo7vK3eL4nf+3x0AXxTOdmdq6ZifxBkI5V/
++					fFKADNX1Mj1Xh1yVelJnXPLU/ZkAvtakWmJ5
++					Dj2I2EETshpkC19lqOP8i97jMR0OWfTCjbzT
++					SL8t0AcbDEWo/TFRXkMP0MaC8NMXmWtkSMH0
++					96nYIS3YA35OeV+gr6LtEb0VJd6E0c+FnM2s
++					T3Up4g+99W8Fs+FIYxYisan296LXff0eNCgQ
++					fNw1Tj+4tWl4lh333w== )
++cert.example.sec.	300	IN CERT	URI 0 0 (
++					V2Ugc2hhbGwgbmVlZCBhIG51bWJlciBvZiBt
++					YXRoZW1hdGljYWwgaWRlYXMgYW5kIG5vdGF0
++					aW9ucyBjb25jZXJuaW5nIGZ1bmN0aW9ucyBp
++					biBnZW5lcmFsLg== )
++			300	RRSIG	CERT 5 3 300 20121212121212 (
++					20111010101010 516 example.sec.
++					kTmXaHROKWMOssXq+UTQZM8FOVyhgtqyZm81
++					LUHbIForbI6FSvZG5yw1U8us1WttnJ4w1oBI
++					m7gZjRD4O3RKgnD2PkV0JDS4y/itMeJ49Z5E
++					sLXSaPwkwuMJK81HfsmwTF1Mglzk0KgXOrBi
++					sdd5yLxCnngdncLqKIkLiYob+iA= )
++			300	RRSIG	CERT 5 3 300 20121212121212 (
++					20111010101010 44427 example.sec.
++					rc8pVuuLiLEOiyR1SrD+Vos+1JEcqBUCVdaU
++					NtOU4jOM9jhJqEjfO6iRTPG5b+nIQcYX+4gw
++					MOsQwwsLHVtVmWnKZ1jml+M6npi/W+NmKy3I
++					Y2jOJz1I+JIFjlLu1UsEzxeV0tScIlyUCxx9
++					tMN/bUE2wNHnjZTLaJ+pmt5EvaK0VDulSKoD
++					PF6ThirWFt+K2W3oNtQATL3XjTNprhzgtRYX
++					Y4nfbHUOA3isbuP3jsH2Lp3IZfN+s2lg07mr
++					GaVkrYLNbgYaCGa6TM10cvTbrwgH4+c4ZjZ6
++					cBkrNa4LRh4cDEJEKgWqPQlRf5LGEiH+rrqv
++					KMtGiXSbW+4sVUCfFQ== )
++			300	RRSIG	CERT 8 3 300 20121212121212 (
++					20111010101010 48381 example.sec.
++					Lmg2cuJHEQYh3JxJUT51BNu1ytK2AdHSo+Rj
++					cu7CTSgNv+JSv4JbhMLgEEOTN6nwL4uI9ZPa
++					TqdKUG4c0Ae8LF1LgDzbkpbpGpVaq0aaXMJf
++					EZuL8SvIANMm2mNItlrnU1cj5d3EVB1Rewj+
++					4zuQawhJPNwbTkeVsj8TdUUr5VuBb7EbJ0JS
++					J8g/NS3SmL4L2Ifi25CxURcKr5pzcl/FDANL
++					BmTL1VE9vlqhjWbUTuiKhz2T7oQd/y139feA
++					oATbSx/6lel9pDVhxOXhf1kTDx3FdY3PS1Wh
++					W/FPUQkKQaxIGNkZH9dkKEEgNhnY5fVaP2MV
++					e9QK6ZMvhhx3IABwvA== )
++			300	NSEC	delegation.example.sec. CERT RRSIG NSEC
++			300	RRSIG	NSEC 5 3 300 20121212121212 (
++					20111010101010 516 example.sec.
++					aCbWibwSZKkYONdUM5Uu6rYkUtPKARhA3LsP
++					yWRLhFYIVXcHpa5gG7mv8QD0jVqAAd7530tF
++					c/fdmoCri7qqELICwZz09FwRNhtgSj6wRCaF
++					vKGt7mPM4ODWKGpUvo/0Sf3l9PtWCV3QmcBi
++					OZbRi6V/znv3bwwXF7jpkVuEors= )
++			300	RRSIG	NSEC 5 3 300 20121212121212 (
++					20111010101010 44427 example.sec.
++					vGaDvMuBuy18IzuDR17zAtYpDTDHaA8ZQe4R
++					9pxpDdvLzzXAWHEnXaTmsDrNBHaD6a7lWpMd
++					ONWZH7l8iUSTQGTXsqCQPoQXGcVPdBJwojT0
++					Dk8CG+Hp7pbKututKnnQpZdxy6OTdxc43K+h
++					IZYgn+pS3i+NloM5eQQXvAoL0V05fDYTC+Z6
++					igN2b66Fc5jxG9Snu4VjbNKLn+3H41WiGm9S
++					YrmoLLMdHHxTnRggfOtxD43G3RM/sMjAelF4
++					vXqAetGWwoNWtt5fpC7IA8Vxbp2FYAa6dZ21
++					nCPaveB2Bo4V1tFwkn9C972NZ74+pWngOFSw
++					L6jY4rtMUyNQCALy+A== )
++			300	RRSIG	NSEC 8 3 300 20121212121212 (
++					20111010101010 48381 example.sec.
++					xga8+N3U/2hEz/HkOL/paiHSYSK1tyFOSqIe
++					FbafrJB696y4lxf8IC6VMyop6gmVkYXPZD5m
++					v0ngdjQsfLqCz7nOlHmcvaW1SCQ1m0qN2Flp
++					tCMmhi6+baN59SYtP7iB/Kk9b1xi5M+y4eS3
++					pb0+Z9lZgD7C28oBcO0lzdxNr1Suz0sugiHN
++					tDG2tfodUKxsCbT6jortxAwX7D3gcJuNg5sW
++					RlFTfCfAWU45QKAqvIrjau4DgOSWWYLPpA3C
++					POF1Qx4+vM0VXvE21jIDQAehGeNXl092FHI3
++					NmFvnaCcVmYdC1Qbmuh0kk/jWChLK10Puhdr
++					bKqFTWsOUIdc83q8/A== )
++ns1.example.sec.	300	IN A	1.2.3.4
++			300	RRSIG	A 5 3 300 20121212121212 (
++					20111010101010 516 example.sec.
++					Jz66qNND9eWmodjPcTD9VNb4G5BIqd1MPcMb
++					9g+J69b1T21cNqAuIom5Y4cECyz/zNJOno89
++					b7KKcpItUnsdyBHb5WuDeJapT1s4FyEYDEms
++					diPzaEDEJCTmjyOx/5ADZ5L6I8EN8a3V+iWh
++					A2YMtWWWjZykqXHeVLPZwqbMJS8= )
++			300	RRSIG	A 5 3 300 20121212121212 (
++					20111010101010 44427 example.sec.
++					RzfNZ0Pu4Vxk5xpCycv3ZSDDMViw+h6nR1uY
++					Jls1+oSygJfeQn0xeTcVzaZQvvZc0gtnecHT
++					5UopyFB36R/qeNkPp5fFHGb+ZpMAaNmjrxGI
++					/1OhxvES4jwTaihetjVWEQyN0M0+Pgw0BNsN
++					tbz92zBczpUFTbe8FxldePwLcJFZ5CAvp8NC
++					VuzqAHVMGAt7DYvr9qTknrW/X8wszxwUuL0H
++					mwitcRF397E6H9SA06uDNum/s8RST9lsV1A2
++					GsssmglqqKICY8+g89SDqkSuxk1bsFJ+dvFx
++					kfXRlzBBvpuFt8sORt6LPJXSlFy/tgtRI1lq
++					oJi9S51V6XElb0vu1Q== )
++			300	RRSIG	A 8 3 300 20121212121212 (
++					20111010101010 48381 example.sec.
++					Q2LBOCx0Ol+UX8yBrpWvoZEPu4bGDJfznS6d
++					uYWDHZc70kjSBipMO+vmzHTPXiax4LTXXznm
++					u6gtzSh05FTmQUx2QPctCwwLW3Lfa4xRBnQw
++					KV+HH0AyXUlKy8gNRBNgJmcQyvyKLr5T8UhP
++					PYQI60UZxU+vCa8Z38Wffy3X0+AraXFwMc3M
++					YClGU7HFn7cCKeIrdWl50PEYpa8qUj4ec5XS
++					1QYZu2v8LE6GmChCCFIJsdkU+JzUJ9mOGYrr
++					l/aI8G+DPa17NxKwihgzQ6fQIS/AXOx0rUNq
++					ObP7mpqqn76X6BnfJFTGs9BUCms4W/sVNvra
++					hbAKFCLCNJAz9EO9Xw== )
++			300	NSEC	ns2.example.sec. A RRSIG NSEC
++			300	RRSIG	NSEC 5 3 300 20121212121212 (
++					20111010101010 516 example.sec.
++					MPFeioCIJDe03C9RD6Kux0g08JgJYH7xtyFF
++					4OOOZVHD1mrI+BmjxtWwhb1c7Uqd8+/J9NLF
++					qywR/OzLW58FsNjznhl3Btr6HsfIfLrEOrTf
++					kbFlOOSP7gA5ngsC4nMqrWDPjSJwjJ5b3XIT
++					12C2Efq87MFneqOEzUzIpqDeSdM= )
++			300	RRSIG	NSEC 5 3 300 20121212121212 (
++					20111010101010 44427 example.sec.
++					kUQ26M/bdHkAbREgxC8kBkgxEpnXkQldxwki
++					0S9mvnmJToiGjnvBIkDixX9BWrx2s8Nzt5tc
++					xfWqmzlbdbea+BitXMN2o9hnAWNJ0uFmQFaN
++					M2li2EH5FlCFPpN40w9hazRY25cBvciUJzNE
++					CaMTtDPRB9GUmZKjE/ZP0N4QnrxvrOqIMJlu
++					dCsLQ3of+NyBWYpsQQfQvbAvx2WNpolOjqMt
++					woCsfZhjvedlAAszdaNKCm2qcxYuSKvkw9hl
++					n9RuZkgYCf+4o0k/DRP6zSwacMo1Rcb6S1D3
++					b/AXMhBxwtytfaKPh0gAFB2fWck0TLpc/5EG
++					AuCcy6aJR66j0frDBg== )
++			300	RRSIG	NSEC 8 3 300 20121212121212 (
++					20111010101010 48381 example.sec.
++					Rktfcj5WkoW+7lt1iMFsQXr70zjRdHCUBDf5
++					zqet9JtQU6r9HSdto4gJAXwwH+gYVWU1zMAo
++					ZrurdsYhkCrUnUYdO/g6Q+xDIdvPQY4UeUaq
++					1lZbumzCGAQD21l+nrjxwkD3kvyDtfnAnxU0
++					eL+/8TqZ/Oo/2cEf2hkuQbOfQqpXImig0n88
++					e1+xBTJV+fPeORGxnAVL0QMRRabTyOqCPiwj
++					rcuXpIxRjKWOAEseoFHJbdvFc3MNGwfBC/BR
++					qI5xzREGVG3yUpY6o1EVkJTNMHdtahZsMOWl
++					hb1dFARcQSFHUdEEwZwc1gtIa4snPxpplgCd
++					ZetiK9mOJTMhVhGQSA== )
++_25._tcp.mail.example.sec. 300	IN NSEC	ns1.example.sec. RRSIG NSEC TLSA
++			300	RRSIG	NSEC 5 5 300 20121212121212 (
++					20111010101010 516 example.sec.
++					br40QG5xW5g8hBGCPt2SJ7LPYfthNcwWVyHB
++					B7XLb3DyWsPIJgL53OmkBugwGGgDDEKHXz2O
++					mHcDEVk+ACBbswG0DFJfqM9uPPXoMbLl7k8P
++					L0E1dKO8eYZeyqE54O9xfYDWHx4nLwGP1vGp
++					tOIRXnuthA3HvEiNVNtRE7095S0= )
++			300	RRSIG	NSEC 5 5 300 20121212121212 (
++					20111010101010 44427 example.sec.
++					xaRKCccf5698Uyq6+4qDG0IOGJRFP75JkQSz
++					BFbPQL48FS16pj1UdIjApO/a0zQZsqzOdZyM
++					ts4MK7g+qpzbCdi16OCQIoqN4PjtM6jGOjNw
++					Hnpq4qt1fE7FiVdW9g6vgmd3lqAtZxuDsyyJ
++					3X116mOrLZhhO7TwuLhxTTip5IzHA5VVhXjH
++					7MbhqN+P83180ghqpzXsu441rr+Xsk/aRfOy
++					/5/Ll0VzvO5842y8li8qfCnO2Bo6yXqZPDms
++					UTYQwlHPSux5L9Wng/Fxg5kCyzi+gvOuOJeT
++					5xHerZUjG4OUdshMIisogVGp/HLO9T+4gTbR
++					CHgOG8y2yscno+R3sg== )
++			300	RRSIG	NSEC 8 5 300 20121212121212 (
++					20111010101010 48381 example.sec.
++					xbsJoGws3mKDuU4TutUK/ewddXv34FKBGjg9
++					D8/96yj9eVjLUBhAwLZRS0KhH4Dg6PPsAIAJ
++					huvAd70rf/Ph6Zp3We7QjWAtZqyDAXA+4Fao
++					165XRD/5ilnBNgvIaANDWWsxPUK61g7aoR4O
++					eTl09w/bxFt26w+zT+oDx85r19fDfH4F9iqE
++					koU/bMphpvCNIGEvLCe2fqGlI3wE5a8J3QXP
++					36mizyKQQNcWS3ahujzpoEijESbizUSVMa29
++					bvhacwNS4afL7WgF3espHPknv1zmvowgsc7I
++					Y7LpC4nfxtmiUHP9kLvs7q1SkVoX2LBKdO6i
++					Df2mF2J6liXDNFdtQQ== )
++			300	TLSA	3 0 0 (
++					30820307308201EFA003020102020123 )
++			300	RRSIG	TLSA 5 5 300 20121212121212 (
++					20111010101010 516 example.sec.
++					DnP6DjlWI+yDT0V/X+yDt09WWl+NYtDxPhD7
++					STjsEIXqSCr1v0IFykeAaqZ/GJP3vOQEh3Nb
++					g+5kjv51Bmc+Ax9IVGUhYTUyx7fVk7VaaCpq
++					Rhc0GgjMn+JtwkQT/PJ/jtwGubRW6tWQjjwu
++					RfMpVC1cWRJ/2hKMmRTHn9Y8ysI= )
++			300	RRSIG	TLSA 5 5 300 20121212121212 (
++					20111010101010 44427 example.sec.
++					Dez59FOkjLV3Kbhwf5P8qxoVM20ibxQAdf/D
++					PH8FM5TqHpkFv/BZKzaMMuK5V/lUOG84t9Hh
++					MvoUSZoWXdFvS2emNJPCiMne2+ZjALLX8T0p
++					1rN3OtowrDCejBWAK021dxqSEdHax/s0vLgG
++					NJvYp2pGt3zVSnKSU9+7lNHzJ/cVk1qtrdmG
++					FY8o7ifHXcmktVMq67L9rqC/DtYRR8kDBioG
++					NCBly0XfkUllftfdtaLC6RvsF0f0OTPndWwx
++					um7CeBOsGC28yFqnS1bW8p3icMqqEpg/UB3Q
++					8s0tmItraLSW9NZzKhT5rqBDDr/05ZYzx6Pf
++					AY43VJ/OR0AY7LXWHg== )
++			300	RRSIG	TLSA 8 5 300 20121212121212 (
++					20111010101010 48381 example.sec.
++					nRVrRC3Pqm4VD+j0n7syYhGB5uvxl2Y1rM1f
++					B9Tz933zRZP041JGLbWmZV6v2PaKzmF4C0Mr
++					WsLykDX2dCIKdvysgxcFKzkmHtXn9yommvaa
++					sVMAg/cKOwYfJgQYBi2R/bkiBdjRokyCxH+/
++					BB6hHNX8W1OgjNavsI5u/y2P7d2n3TBRNAkL
++					kzujqfwJZ+e2bLJ7Dbya22hzSr0ARmC1tufX
++					UfZTzV8BnPJpXwo1j+NNuX7u7kQ+UJpXJdsX
++					xRXq0Hq6dSeMwTDldHmy37rLCamtcY2MYrqw
++					j5mKV1c7Ag22KMq3yyQbNnk0FsgBbrUauiKz
++					UlUdXq/ySQnilm2SrA== )
+ alias.example.sec.	300	IN DNAME anotherone.sec.
+ 			300	RRSIG	DNAME 5 3 300 20121212121212 (
+ 					20111010101010 516 example.sec.
+@@ -469,6 +701,139 @@ alias.example.sec.	300	IN DNAME anotherone.sec.
+ 					enVIAG19JVA4/Zjqr59BC0+6qCNaFIlf6P+s
+ 					Tus52Ixc5MnPO3UuAah55oNwfvL0AU1Dl1al
+ 					ylAwck7ZX/jjQavikg== )
++_443._tcp.www.example.sec. 300	IN NSEC	_8443._tcp.www.example.sec. RRSIG NSEC TLSA
++			300	RRSIG	NSEC 5 5 300 20121212121212 (
++					20111010101010 516 example.sec.
++					DmW/7Gx7EvvU9gsoOxQssn9I5zBNq5gwGm+F
++					zwWZPfUxd+OeZFwfd+qCLXMpvWMN/JR5nu1p
++					Y68t+hqxAuiyLLwNF2D/wf69dSTunWPHKaXz
++					F1uMUkLmVDTaG11DtD5rz1Pfd/Mt8BX2/8OW
++					fXyqo53geg6GCfjAJv4pmY7BNZ4= )
++			300	RRSIG	NSEC 5 5 300 20121212121212 (
++					20111010101010 44427 example.sec.
++					1djWB8e86bYcMlr32K9gaAjFoiv3isY7mADC
++					FdJGu+AkyMG0qCR34qaDaK7EdM6fIMTVFdnE
++					FqF9OELcV1g/LhTKKHnLAoKrE0zHvrZktwMv
++					n5qh9j75eT8uf+6l0MtPhAcc/u74hcnDMz9f
++					hZvjbnpHBm3T9LGKVUeo2oX4n+Axh6N54cl1
++					47y/dR6PoPbKb6Wg8BkUyfAIWkv2mBCWYDGJ
++					W4Du6oiQLdBOAxvieafX9Xk1PwBe5CxV6X86
++					OSIemzLcHDA+E892UaT+e9TegKNWjL1UX1OL
++					NJdV6gsajNbeghLPwMdgwMVmxjmI4uQBgraw
++					NbR4OrdbLRw0dSr1JA== )
++			300	RRSIG	NSEC 8 5 300 20121212121212 (
++					20111010101010 48381 example.sec.
++					i+EVPPdKeaZAlNq9HPXz437Fs7PiCxHKKKFR
++					zVDf6M0UF0W7Wcl5jlnqllb6TwsB53Upf38v
++					PMJk/y7vE48On5wAb/XLmTUlBU+p+NJ2NiTP
++					5/x8dklBdzS+6v2iF4yTpLfD3K970sB2j5oe
++					+GysOWnA5dJWzBHZPKY1V5SHbEH7Tann4Gll
++					c4F9A7PgY0t6jUfpckW5YuWKaV6p/5dqMWuP
++					SDctW12paRW5cqkZ4bIQn0ei3R/Y+DNcPeD8
++					XVK2mt6lRDipcp0LlCyXtFDtBrTjlyujbm62
++					MktmWWiZK4A1BfUY44ZFdQEzr01CxoSwCEuF
++					WdLSfG6b12XfNNQa6g== )
++			300	TLSA	0 0 1 (
++					D2ABDE240D7CD3EE6B4B28C54DF034B97983
++					A1D16E8A410E4561CB106618E971 )
++			300	RRSIG	TLSA 5 5 300 20121212121212 (
++					20111010101010 516 example.sec.
++					EFJLOkZjiBVrGSxCbNc5k0ip1Mc1se72wFsr
++					0TYHg9TMpHRAB+8SU11r8f5V1KP5KXzF78kr
++					MDVrnp8ySCwCsYr++V9zh/Wt235OQ4KM8xMv
++					UfTiknkYuaVJkFnbS9C7CIVLxlThE+3vVg7l
++					sNiJIfUDh7SsD0+vO9N+00xIdlM= )
++			300	RRSIG	TLSA 5 5 300 20121212121212 (
++					20111010101010 44427 example.sec.
++					mpxahn8nXkV7k4xWIDAGT2/kVir3Z4WaKJqI
++					X6kKnsR0gbgJq0T1OIbA6WP4xyiAaqM3q/sO
++					Q/6Y6Z4JhwnJZXdPAMmmWfVbKc52sV/tMp7d
++					L4h98ND9QugIffpW9WEMVGBZhrPiiAE7w3Ri
++					GOwluu3K6yfGZvHg7eTr4tYmALWCnU4f6JaG
++					Ye1bvo4IGi8AlE2qxg0sduzSRtc4+FmCiWj0
++					mhPiNmnQObonkGA3xpuPqRPtcaga95ecbfmT
++					P0QVV3yJoswaO0kaQjxo7Prmiev5xk/fdwko
++					WgONMbgkKzLoeAgKlsQWJ6FgNOD7g1ZIZnCw
++					YVAVgzyaHGPO62g4PQ== )
++			300	RRSIG	TLSA 8 5 300 20121212121212 (
++					20111010101010 48381 example.sec.
++					pTd0fMqEiuKey73dCne7FCxjowMMuehhQ7dM
++					VRoPiuW51D33ay2gb6qisLoNUf8I5lUQPag1
++					Ia/7ArCJQr12aYhsoeQKU/3BqrMwkA+kpmhB
++					m5G+Lj6h+jtJ8LnqjYV5pPHL317abWiQN4th
++					mypwHhS9g9zu/RKExzzhHtmCJpH6R3exNOmx
++					S50REX6rvrTXiigRiI0D8yrRnJHfmeustTiG
++					OKdU+JNn21P7LDBYIT+C5gDfJ31zOejKEIpw
++					PX+XPdAZlWFtj8PEi9KerTyqLphhWCgxSM0z
++					8KqGLri2YUt2JeQkZ/zaHvtvjdpB9zWGT42d
++					vFIOdbcFli55DAmW2A== )
++delegation2.example.sec. 300	IN NS	a.ns.delegation2.example.sec.
++			300	NSEC	delegation3.example.sec. NS RRSIG NSEC
++			300	RRSIG	NSEC 5 3 300 20121212121212 (
++					20111010101010 516 example.sec.
++					alXox/n3U8q3S7BezOkumPPVxQekZSPZ34nY
++					w9JL0qX5h1NOuAR7SG0B/sKz8XKe1gpoTpZ6
++					oCYSZ/4LAw1oWryRe1W4+K63fNHy1BpZJMGn
++					0toviZnfH8DrmTnwcDAXkPd6IhdX2Ok7ztef
++					M3yeP8heSWCvyBukpa4EBvwv5mA= )
++			300	RRSIG	NSEC 5 3 300 20121212121212 (
++					20111010101010 44427 example.sec.
++					5e7KvcXLAy5uVdD/hAZuNl7mC+qITTiihlmU
++					dh/KIachaEFMMqRoDsY61kjY+cSpkn/n2dp9
++					OozcWUFfhfXY2D5EFaRmkWKtP4N37ryVWZUw
++					maJ5ZDCLcRa/vWfJGWlTrG108ijGkfUPE3lE
++					euYkc0d00yjmbcz72uAW8NUmixRUU+3Payly
++					GZSDVcG7vZ/qaf1dXG6cToY2n0DDIf/526eC
++					xH5NhhDJgq6O1ZCEtS9r6Hb9vpR9Ed9wJvgt
++					a7VZltV0TlLaiFGSGZA+OgZV9l0HerOCh8uW
++					nn3L8d+jMAOmrk8/Jn47uTpZub1/j8eZo5pA
++					jFyHUZ1b0h957vC6XQ== )
++			300	RRSIG	NSEC 8 3 300 20121212121212 (
++					20111010101010 48381 example.sec.
++					rQwfcCjBLlYDpe6DC2d1w2qVYAUYFqcfbwHy
++					gbjXT4RI2nV4E5q34jwEgi3TFb5OmYZviGwF
++					cJvyii25oYSt2qcKPlTGGnrD3vAMb9lgX9L2
++					hyeHWcmOfB397CySJKMXNbWtZz2YLu4YLrc9
++					K1e+2eQD9MZbVIBrn2f5Krf306FMNd9L4n/p
++					yNrW/6EUfHmRtFsD5vGYytoRRBKoPv5Rxfoj
++					pbhhuyC8MlntVH0IhDe1zvKAmzlBj6E6oB93
++					zG8SqT/gNIuTUpa/qw37tcOw3fCRh7uG3TBk
++					+ylUmRz+hcTUxjSqoQKxVT61hXcrKAogspaY
++					QZ3Mctyg3Se9NhUd6A== )
++delegation3.example.sec. 300	IN NS	delegation3.example.sec.
++			300	A	1.2.9.253
++			300	NSEC	delegation4.example.sec. NS RRSIG NSEC
++			300	RRSIG	NSEC 5 3 300 20121212121212 (
++					20111010101010 516 example.sec.
++					WuuwTT692DQs9iSoi8mMe3/r8IIrnKaKisRF
++					UZ5aC6qTb54FydtNsgWAOOwzN21EI/ucU0kX
++					iXRcaJ0jvNG30ICWk8oI3By1dXDhpMrZerZt
++					hMDvnitwa851ZjxGeDtyJsMf2NfAuN0p7V3W
++					UxEGVpiru6ZDNO2rqfwAd35+ixc= )
++			300	RRSIG	NSEC 5 3 300 20121212121212 (
++					20111010101010 44427 example.sec.
++					Vt/wOn+RgrH7e1m/E7XqhoF85i3q1JMnZ96K
++					E0WMA40MOmClX4+1oHwmdfeu/9U8dqxp4mJf
++					iJ2nz8tMoYYcJwa/NhOZs8UZSILUV+ACyhOR
++					g923yYViY41pyV4DCXxa17Cbc1GWizqDPvZl
++					yksNQTjGfVslH3IXlkGS6OPHY8HImnPKK0HZ
++					M4si1bZjFg+SU447VokQvz4gKxVHca20R3wD
++					8A9ZwPHN/97A8rQJzRBlEfAP0EqG8cjt7s5g
++					ku+ZoeK/sjeQoq3VGUxJWEZU2lXVYwCAv8Yh
++					9M+6PZ+O1pG2nfIgqpR+MGHJ79LAdTdRe6MJ
++					nrnROvz2DumLzi9kcg== )
++			300	RRSIG	NSEC 8 3 300 20121212121212 (
++					20111010101010 48381 example.sec.
++					bH5sNx6a1xTa4fafzO+Ur2CCz7W+RU8EiYhu
++					mRltM1GcqQ0Cz0k9VQyRzkCE9HGPkzb9lDIp
++					HiQS6zf70m5YyXVgMG3WBN0MteVb0/1ut3jq
++					JDkQkSMtjyYnJdZ363lpfI363eAI6c1l+XlN
++					mvEZrUbUWn6entMRj6ZQas2r/7dp61tkZj/x
++					PU+4SZeVZZPJIZdDf3QLzak+tXG/fs4OCDih
++					47F8MhlJ3i+L11FawFVoGXVo2NZ/SOhLoh85
++					aEGPu6j/whxLR6pw6JueK0euQWEeH6nDfXgB
++					PA1IYI06aExyLN+n4R1wC0q5iAS0ssA+MY/Z
++					cXye1Yt7SWn5oGXE/Q== )
+ jumphost.example.sec.	300	IN SSHFP 2 1 (
+ 					123456789ABCDEF67890123456789ABCDEF6
+ 					7890 )
+@@ -535,142 +900,202 @@ jumphost.example.sec.	300	IN SSHFP 2 1 (
+ 					8ijIr6Y/6vXt3/VjdLHI27nqtl5OIoB6ULtA
+ 					/GlkqlibigOI/isMnNhHRzb1IxmpvuhziqpC
+ 					m5cVXQkmoD9ubPphkA== )
+-cert.example.sec.	300	IN CERT	URI 0 0 (
+-					V2Ugc2hhbGwgbmVlZCBhIG51bWJlciBvZiBt
+-					YXRoZW1hdGljYWwgaWRlYXMgYW5kIG5vdGF0
+-					aW9ucyBjb25jZXJuaW5nIGZ1bmN0aW9ucyBp
+-					biBnZW5lcmFsLg== )
+-			300	RRSIG	CERT 5 3 300 20121212121212 (
++mail.example.sec.	300	IN A	2.3.4.5
++			300	RRSIG	A 5 3 300 20121212121212 (
+ 					20111010101010 516 example.sec.
+-					kTmXaHROKWMOssXq+UTQZM8FOVyhgtqyZm81
+-					LUHbIForbI6FSvZG5yw1U8us1WttnJ4w1oBI
+-					m7gZjRD4O3RKgnD2PkV0JDS4y/itMeJ49Z5E
+-					sLXSaPwkwuMJK81HfsmwTF1Mglzk0KgXOrBi
+-					sdd5yLxCnngdncLqKIkLiYob+iA= )
+-			300	RRSIG	CERT 5 3 300 20121212121212 (
++					LxovxXszIrJ0WqC4lryebK8Png85a1l62jvj
++					JHLNs25OP3I/CpsfLXmE2o+bGXdCoppA6k+u
++					+d0BmWG32UmOXQOkcu3haT5J8rJWPV1xynhJ
++					IsBCmF/UbEXp6PoAniCcytS4ZsHqrm31KBNI
++					i/ZXtU93D2CGrTDMpwX13xT4scE= )
++			300	RRSIG	A 5 3 300 20121212121212 (
+ 					20111010101010 44427 example.sec.
+-					rc8pVuuLiLEOiyR1SrD+Vos+1JEcqBUCVdaU
+-					NtOU4jOM9jhJqEjfO6iRTPG5b+nIQcYX+4gw
+-					MOsQwwsLHVtVmWnKZ1jml+M6npi/W+NmKy3I
+-					Y2jOJz1I+JIFjlLu1UsEzxeV0tScIlyUCxx9
+-					tMN/bUE2wNHnjZTLaJ+pmt5EvaK0VDulSKoD
+-					PF6ThirWFt+K2W3oNtQATL3XjTNprhzgtRYX
+-					Y4nfbHUOA3isbuP3jsH2Lp3IZfN+s2lg07mr
+-					GaVkrYLNbgYaCGa6TM10cvTbrwgH4+c4ZjZ6
+-					cBkrNa4LRh4cDEJEKgWqPQlRf5LGEiH+rrqv
+-					KMtGiXSbW+4sVUCfFQ== )
+-			300	RRSIG	CERT 8 3 300 20121212121212 (
++					LNe6/SJmAkohBYlRtofW0wYMPDVJ2ZTCmOwe
++					hwZBKvNrcxc8uYlzqSBqjD6Vtq4GpJSl+MV0
++					KY0GpsE2jz49l4ayUi5QIC8wRaJ1NeTDiwBp
++					EbA5ycNdzSpGtLFNs0qzDQntdrZdtvoaFCcV
++					WDPNGP4rvhvTMXfriPJuYJ2W5ZxmXp3DYNDZ
++					E+1xgJ3hvr6pdAy7UdROrhsOp3ohP15sE8/H
++					+sU/hmZ9hfBeodpGHhWYIc6FSMOca3pEBwQL
++					ifVL2Q06ijnqbh6iuJqJnqI++ZadCHIqEYNT
++					Tn96mylS3XQ4S3FZPPrXXhuM9HvKKxnDvvWX
++					ALsm728QZQi2keAKkg== )
++			300	RRSIG	A 8 3 300 20121212121212 (
+ 					20111010101010 48381 example.sec.
+-					Lmg2cuJHEQYh3JxJUT51BNu1ytK2AdHSo+Rj
+-					cu7CTSgNv+JSv4JbhMLgEEOTN6nwL4uI9ZPa
+-					TqdKUG4c0Ae8LF1LgDzbkpbpGpVaq0aaXMJf
+-					EZuL8SvIANMm2mNItlrnU1cj5d3EVB1Rewj+
+-					4zuQawhJPNwbTkeVsj8TdUUr5VuBb7EbJ0JS
+-					J8g/NS3SmL4L2Ifi25CxURcKr5pzcl/FDANL
+-					BmTL1VE9vlqhjWbUTuiKhz2T7oQd/y139feA
+-					oATbSx/6lel9pDVhxOXhf1kTDx3FdY3PS1Wh
+-					W/FPUQkKQaxIGNkZH9dkKEEgNhnY5fVaP2MV
+-					e9QK6ZMvhhx3IABwvA== )
+-			300	NSEC	delegation.example.sec. CERT RRSIG NSEC
++					tyz/WG3TB1pdIqpToluADGocPccrMuT7v/a5
++					sQ9RY6QKAzdf9YU/ikEH2SeEPkC4EwD2pPp8
++					RmURKjzSvSc3D8Q6b1KbC6IHEy7+MDUouZCX
++					xbQSqRPxLvUQLc2WvK+M6CzpnoqVpOTNqouU
++					XbwrNA9FyXsHGKOURAGQ9Viu97VNaWUyAkzV
++					9RoC2T5Y7C2T+Vd/pkhCdi8nvHWOvUxixyXA
++					mYekLx+TeEx1Ntr+Z7aT9kN1Hv0NsR19o5F7
++					JAwRTWZvYk/HpRavqbHTw76f1d0jOPq3WOKp
++					VtvqrklUy9GgPranPH8j7lplg6c1c0H5/7BQ
++					nFp6xgW2OVH137Hdwg== )
++			300	NSEC	_25._tcp.mail.example.sec. A RRSIG NSEC
+ 			300	RRSIG	NSEC 5 3 300 20121212121212 (
+ 					20111010101010 516 example.sec.
+-					aCbWibwSZKkYONdUM5Uu6rYkUtPKARhA3LsP
+-					yWRLhFYIVXcHpa5gG7mv8QD0jVqAAd7530tF
+-					c/fdmoCri7qqELICwZz09FwRNhtgSj6wRCaF
+-					vKGt7mPM4ODWKGpUvo/0Sf3l9PtWCV3QmcBi
+-					OZbRi6V/znv3bwwXF7jpkVuEors= )
++					Vz4HOiryi66iURI6LgU9qFqv9a0X9U++uPJ8
++					Owp3vZivOaYm2rAc10WqsjV1Fb2qJeQL8ips
++					bSuwhhEOQgBBeez+tfJSOjusfAY9SpwGN5D7
++					1zoLJl5VN6AAw7OLyEwrom0eO+8fltipfAUN
++					Ebff1fBbKiWta7Lk4ax6MowUSnI= )
+ 			300	RRSIG	NSEC 5 3 300 20121212121212 (
+ 					20111010101010 44427 example.sec.
+-					vGaDvMuBuy18IzuDR17zAtYpDTDHaA8ZQe4R
+-					9pxpDdvLzzXAWHEnXaTmsDrNBHaD6a7lWpMd
+-					ONWZH7l8iUSTQGTXsqCQPoQXGcVPdBJwojT0
+-					Dk8CG+Hp7pbKututKnnQpZdxy6OTdxc43K+h
+-					IZYgn+pS3i+NloM5eQQXvAoL0V05fDYTC+Z6
+-					igN2b66Fc5jxG9Snu4VjbNKLn+3H41WiGm9S
+-					YrmoLLMdHHxTnRggfOtxD43G3RM/sMjAelF4
+-					vXqAetGWwoNWtt5fpC7IA8Vxbp2FYAa6dZ21
+-					nCPaveB2Bo4V1tFwkn9C972NZ74+pWngOFSw
+-					L6jY4rtMUyNQCALy+A== )
++					fmn/QXc743TR/J5qs6DI+E+Kx3aq1KpQP/Gv
++					d2WleTSj0XFIyMwEjonZxmpSavFsLRqn8pl2
++					OFMe2q1aJxWUKFw2PUC/NfDVeJGqw/LwKjnv
++					Tz8V1Etn4feyidTB5W/fFNfCmXydgNaVcV5A
++					4yd88QdXwm/Tz1JYPKUSpEaLsM8niO8CamGU
++					/6mvS2Ek3Akn57MmiqxKa2JfJuHZpBKHSJdU
++					RAlrkpf/pjIlEgyD/7vEHhwCC189T+YTz3mE
++					+jtDNMTH21cE20YVBvWC7gXbTc+UUa6UhRxM
++					VuVkH32PIsa+/GJlcCckDU1s7kX97hL6BNo5
++					HCVGRqXBxrsODj8qjQ== )
+ 			300	RRSIG	NSEC 8 3 300 20121212121212 (
+ 					20111010101010 48381 example.sec.
+-					xga8+N3U/2hEz/HkOL/paiHSYSK1tyFOSqIe
+-					FbafrJB696y4lxf8IC6VMyop6gmVkYXPZD5m
+-					v0ngdjQsfLqCz7nOlHmcvaW1SCQ1m0qN2Flp
+-					tCMmhi6+baN59SYtP7iB/Kk9b1xi5M+y4eS3
+-					pb0+Z9lZgD7C28oBcO0lzdxNr1Suz0sugiHN
+-					tDG2tfodUKxsCbT6jortxAwX7D3gcJuNg5sW
+-					RlFTfCfAWU45QKAqvIrjau4DgOSWWYLPpA3C
+-					POF1Qx4+vM0VXvE21jIDQAehGeNXl092FHI3
+-					NmFvnaCcVmYdC1Qbmuh0kk/jWChLK10Puhdr
+-					bKqFTWsOUIdc83q8/A== )
+-delegation.example.sec.	300	IN NS	ns1.example.sec.
+-			300	IN NS	ns2.example.sec.
+-			300	DS	60485 5 1 (
+-					2BB183AF5F22588179A53B0A98631FAD1A29
+-					2118 )
+-			300	RRSIG	DS 5 3 300 20121212121212 (
++					vGM8jJKJ+F7wnp5fadGlI1DR6uoa6pissW2z
++					by1iA3eLY+yVTCd2ZD0dxBEke3zVZ0ML8sAN
++					69RoCXctvw1M9RR3ELUvNlebotQSl21NcwUS
++					KZYgv1/0QBa51EU/kCwJ9jsfLgFhvZRNKzSr
++					vdj/UTDp8vBsJXJ5KfdqMz2oOqz3dr1aSBuA
++					QYKzcIxkKI7pUpD6wWpl2BIHQNbavN58EvY8
++					ADz0KW8BRYMPuDmjSmRdWxQ5RrA2SSWnZpfL
++					Z7Z1EyrLU0lXD8ksviVQON1g/vD2iFK227iu
++					+0Poh9/WeiioJykRM9UJwHxwmzzXVU+nokUl
++					zc7nYxTMrxNvxFTvZg== )
++ns2.example.sec.	300	IN A	5.6.7.8
++			300	RRSIG	A 5 3 300 20121212121212 (
+ 					20111010101010 516 example.sec.
+-					uEf2xsca1/OJwovwMVGyFB4/6OUmutAWlWvG
+-					qM9JDtvUPMhUV8dzRRiwpWfz3YkPU60Hqn8n
+-					QX981RtNc23oiwjmo1ehp1DW7R9dqcqxH4KM
+-					5gYrdJT+lJAoN3ii43rQNl0N7OfObYxlZj+N
+-					K7aMVBHESqQd5ZaRfkiut8XW49M= )
+-			300	RRSIG	DS 5 3 300 20121212121212 (
++					kDQQNP+l0TqJq8Kfn8VU7HqED4wX+CVswCEH
++					TCSo+ByoaMhG7cWfIzV9d7euMtDWbLvnp/5p
++					qmmDkhlWjmh8/jDH0eoM5LsYJG+hQfoDGBmt
++					L/2eEBHcdwahbr5zzgE/z1Kvk4cLInp8iveq
++					Nlh1br2rMpLuIWZtYYjkOziqKC0= )
++			300	RRSIG	A 5 3 300 20121212121212 (
+ 					20111010101010 44427 example.sec.
+-					GIx0C0s5HJdizOCjIFnqf3BvhIwKaJZW9id0
+-					vcQAyd3qzbiiuWecM5pdyiJahFpnKmGxTdLM
+-					ZCEwNczhZZf+RE6SlOu8j/VcFujTlaq47JMZ
+-					uaU2KETUVZzOhFP6Vrddax35icNcO1Qfu2US
+-					B501hzVzyAjr4QL9j0KKlYBe3n3/349dHIiT
+-					trruNmkB0c/M8KOkApnUbO8/42Xaz5QCBvXT
+-					nyx3jp2WHTCCLLC2o0LTD++w6LkqhTXvWcbo
+-					oIMBUXD9hXm/NnYjPxR5+8IhIzPjgjL1vzw7
+-					RZrtCBVuI6PIsCRhyXxJ2XoxB293M0GxOmnh
+-					VBZ0feqy7wVmo+hklw== )
+-			300	RRSIG	DS 8 3 300 20121212121212 (
++					G3ZnC5ZXkcqBbBXM7jDtZ3zLggKW8P++ryWA
++					McqvywLUWXNGqu1VB+/mcyaEoi66T74hQV4+
++					bsWhQRNU1zXmPyoKYVoDeLgtnNymQEUi7TFB
++					mp0iBGGdW/tcZKP+UxrKmtR9nQoo/wuz/RKD
++					cWGHVAEjnK9DCPIhNwHG3frFimVoc+eoBG/r
++					okHgI9IWQMJ4z+GGxKwHZ+qIvPTaIXJpBWl0
++					tiJhj15B+QeShvGK0Au8KvafqXgUEB7o0oh5
++					KiHTeTx00i7lP+ieneccJNGONhi1grVuarum
++					cqNrVR1ddGLjz5yvkmzxXtRBCZmcqgRaCzkD
++					Yr0pMzvhxNzSfQ03pw== )
++			300	RRSIG	A 8 3 300 20121212121212 (
+ 					20111010101010 48381 example.sec.
+-					D6eEY7RttRgccoDGLh1/JJ2Q8Xt8fbnNVzXG
+-					WhLlMMeEc1S1FzJG8/SKUrvYVKtrU8wPZpLq
+-					qV/2jEjHk81vOqj4S+NZh3hV94h5p27Pngqf
+-					3fNzd0aO940zkFC30aAiz0BBd7MX28AOowLL
+-					1UWoiTCuERpPAQTuRQRbAR2zf+205PJLjbU2
+-					764FVJYEzp6Kal66lWOYlB2EqGWdrv3irPpJ
+-					lyTYMaFpNvh4qOkRaBgmT06lzGQuG6E/tUmF
+-					nR6tQA4oFaGMs4QGWv05iMYYKleBBNlC6OYM
+-					0At5mmxZIfiC1viIGDTGvHaKDS3YjWO2YLIq
+-					4EQZCBQJAnbb3rHmWA== )
+-			300	NSEC	delegation2.example.sec. NS DS RRSIG NSEC
++					WY7f+CDmncZvjqYEGlrgeRGuf06NZNc4vQ5h
++					1j3Ux1yjTY22CTCaQafETI8+e8W35l0FPTgm
++					sTKVnTMD9nloIgghiwMBhbuTgQZjAmatj5TV
++					ymcNkz1vIWOB7J7eYA1eLdNQ9NARk1N9NrSE
++					X6pfGzjWydsAhRSQVig779Mz/PPAxG/7rBXM
++					j3g6+GZwFvbaMJata9HuKP9zgIbf19CG5MLe
++					nGSzquzAJEIvPXvwvddSQCGg6ADuHppYwOJq
++					rkqsKga2T73Nrn5k9KrCrt+1iC1LJvbws2R8
++					jkB/N+49IlkzZOZXtI/KgL9riaOnbFCyI3iI
++					lJB/LXjunEB1h1Nr2A== )
++			300	NSEC	public.example.sec. A RRSIG NSEC
+ 			300	RRSIG	NSEC 5 3 300 20121212121212 (
+ 					20111010101010 516 example.sec.
+-					iG8wud8jrvX0STdk/BPdIHUCMgeIExOklQEO
+-					Ah+K6e4LJakFKjuI+G1tTLdHOP2GauWkb3GQ
+-					0Ozj8r7+jQEz886ZQmCR8RigqW5/CsnwPc9V
+-					oc7TbNntOs+M4NyOiqC9NfmafrpqIrmbLMBW
+-					THN6XGPUMdc5riMr8miTKtLDMF0= )
++					RLH4xaCk4HFnbQOEGFM8xTBllDyNolLE6u6W
++					5loi7NdPv+6F80w12oYENwVYRXC4cXa4x47l
++					aTAOTXEEf1LJeP6GT5hRUhRj3oTMC6InVlHq
++					ZfPONJgzsyaX958ha91Z2VkP8t1eliUA1mSc
++					PxbVOMzAsUkPbkHp8D2CRzHwMCo= )
+ 			300	RRSIG	NSEC 5 3 300 20121212121212 (
+ 					20111010101010 44427 example.sec.
+-					Hw2H90l/QMOJYJPO+B1eCpGQXJGXOd5MoUfR
+-					Fc4budW2eesImgWQ6TR8Bvwjz95niA8lpGyq
+-					QEXjJ6cEf5JEKYw/4xOVlmFNDHyG//iQ1kpf
+-					2+aT8IuiM0evbBgiej/VhYZFScUQ4Ibslna/
+-					BFMyoJ7ugLmLelYiolB9g30a3q/3ULYwfn1j
+-					OKUbYUeWClKQ+l+i37wRuBIPX6aT6//CetOX
+-					uCecmaDTXl94NKi2pw+fZKs504Ed7xT6FtJF
+-					9FYJAlsFloV7T6epZ/d5pl82QYaEshZpMePa
+-					nqah+amBETh/kd3vokG1lzzFzSbwrWjxgtq8
+-					XYCG9CbCOcJz1N0bXg== )
++					zl2+IlLPn/ab3nK68sCXibCB+lu8EES0wgzd
++					Vs9FyyP62V4sqjCrPaiGHHeoq/wS+gQwwBQo
++					6mRZ/gT0Y45RoQER4XgDi/HQWX7zaCeMJ4aH
++					P0qs9YfJ2odYPAYJbcV4uSRB25zxx+xPUtGQ
++					gIRKdyUTeXxjBujcraFxdDGMi4HGqFKS/qDg
++					9x3YnQW4DeA8VQuSCdIoH0zWARyJLfaN01Yc
++					iAvRGt4QLzvE6Wb3YqxbOMinsLkrnMPTaUjq
++					gSiM3pvopj6HVI9ElQVQFb0SFmc4IOusc/1u
++					F1nYngdhGjS+8LVcCPdXJajqiozkGTGN5ISJ
++					KgWWmA7G51peHjXXzg== )
+ 			300	RRSIG	NSEC 8 3 300 20121212121212 (
+ 					20111010101010 48381 example.sec.
+-					yc2VoV4VVT+Wo/rVo6brdb7LfxMOslatW8Lo
+-					ldBOGkVuiz21DskK5LUMGkH/4+NZ2L/aaDCt
+-					JyiARZXabIqeMMY47QbNB1DouT1yKvR1Bc4D
+-					Hgo7vK3eL4nf+3x0AXxTOdmdq6ZifxBkI5V/
+-					fFKADNX1Mj1Xh1yVelJnXPLU/ZkAvtakWmJ5
+-					Dj2I2EETshpkC19lqOP8i97jMR0OWfTCjbzT
+-					SL8t0AcbDEWo/TFRXkMP0MaC8NMXmWtkSMH0
+-					96nYIS3YA35OeV+gr6LtEb0VJd6E0c+FnM2s
+-					T3Up4g+99W8Fs+FIYxYisan296LXff0eNCgQ
+-					fNw1Tj+4tWl4lh333w== )
++					F9HM6TzOjWpVtiDblqGvcDDcpU5/flAM8OLR
++					YEIVoAqTiMGwGKMQ5Mqs0Fvnlk6+fTnQu75c
++					OYvGM4JGucdyWNmzyIQ03L9qonEbBFm3FewR
++					fL/0COs1GJGeglcHFW9dBIK2Elo4Q9q5mtxY
++					JCseGHbmjZIs1busGdm/W+JyaCYiHBPJi8xf
++					ijfk06miRoGaLS7/CraajQmGQLF3iF94DzEU
++					OuOdWZX2z81VrbI2DbCVRYlokjKz7cc3mm+d
++					zhJAKHcMXN4PTqcWg5mgdulkGvqL2qFgi5e2
++					WJxUFZxEDn1Zbqte40CZHVqMdv4I76f8mSns
++					dFXZVw7n478EjuVj2Q== )
++_8443._tcp.www.example.sec. 300	IN NSEC	example.sec. RRSIG NSEC TLSA
++			300	RRSIG	NSEC 5 5 300 20121212121212 (
++					20111010101010 516 example.sec.
++					fnXPjf7r3kCoArvAvDDS3auZjPpx73h0J+DP
++					4vcoRLlnw/EO22p637vl4qkr569ri5hgnfCp
++					5by0mEHIwvuQkmthglMC18BUAZfFUIV1VMdS
++					6ZSnRgalGiuUuisaVM1KzuGxrMiVdE3nUtBf
++					wL6eDaKZVje8bEKiyIx0k8b8RJU= )
++			300	RRSIG	NSEC 5 5 300 20121212121212 (
++					20111010101010 44427 example.sec.
++					5UlBCjG/8+046HNSKZnHLcMjdYsaghyD5nUy
++					kjzh4kg+hFw6buTLpCHEL9nun/912/2r75pw
++					kYQyRWeg37c1KAJg2j9V2c7zh5fqDHHPbpid
++					7edtFcqE4UaC/x20/QO4F0l+kmhY7R0/fjvz
++					9eDlnPpxBqVmYULgC4YGT0i003vQmB8zsASF
++					7nKjSk3/a1zLG/SkEGD5ioG4ZcZc7WxW47ns
++					qEWKmtnuZScK/G4VmgrajiLst9/q3Pouoct1
++					OB7MHv5dOYFhQv0/hxhSqeDXrvGNJ93Vvd8J
++					qTm+6SgovkyJ/rYLAprb3pV1Ahlni3zP832O
++					4Ulj151/xqih/93P1w== )
++			300	RRSIG	NSEC 8 5 300 20121212121212 (
++					20111010101010 48381 example.sec.
++					RMag/BsXGLEMs7IgVCmcqhfImK0BFlRyzHMW
++					REcuYTvZVgmvUd+Yziiy960kXYFEbUEconb1
++					6U57kpCYEnhQMb9hGDBUYlnt98jbFwBe/XN/
++					u7vxVQsojsD3MY7t9epqPaQ8CHfb55ldVuTK
++					p9GTOiAin3cwZoHN+t+wzLc+SI7O3ii1w84A
++					ZhCaugQlYtgCI/1WsGb0UitBtevcvDWK/u+6
++					3wWlWnyR4rXhpz0Z1UJtqEk+r3W0dbSmwodk
++					4zrkClRqM0ysE28mnoo8FFnlNa876dP2ErWv
++					hpeVPa30BD1hxwtdShL25VbDQ9lqJOmmYVuo
++					fQmf9uKqnvX+WS/lRg== )
++			300	TLSA	1 1 2 (
++					92003BA34942DC74152E2F2C408D29ECA5A5
++					20E7F2E06BB944F4DCA346BAF63C1B177615
++					D466F6C4B71C216A50292BD58C9EBDD2F74E
++					38FE51FFD48C43326CBC )
++			300	RRSIG	TLSA 5 5 300 20121212121212 (
++					20111010101010 516 example.sec.
++					lkKqiYh4cunZ61uN4dW+LvCxh2ILzzlBLEdf
++					IQv4PCVZLzhbWheZBBSQWPPp9wEzTo/40/kZ
++					pqfer7aUu5cyHBxB5pGJDbfbPamlEgAa7fLE
++					t9mMJ6cAp27mu4D68t+cp8fialXk+fe5DByU
++					47d6K5NMVoeQZTU4yv6L/sKAARc= )
++			300	RRSIG	TLSA 5 5 300 20121212121212 (
++					20111010101010 44427 example.sec.
++					YDul3IDmxdIt5XSBV3lGDIVCIEtHto5lfVM/
++					1+nYUd/z/LGvkoAMNieI7OFB+3/wEaDNGBzX
++					tZYPsCSGFZ3GGmI/FtOQ95LMC5zFEFkN7Run
++					xYokbrFrWeW78QkfiwbXsLWDewVxzJXEYo1H
++					1TtjGdhAVq4R8khRdlAytLQfmQvZCZtryYKp
++					KOCqU6tdilKNG/WF8lhG27hDDUYj5J6+QFp3
++					1x+Swah1biitJwQosXVVo+tUFquPQ0RJqWkr
++					zPVAgrb5FbtSieR5c5cP0usosUZaOpHzc2sJ
++					FepzF6xhdmgyDqaUqLnos8q3DyIHqM4Kaln3
++					Me4jWC1HRBnYaWecFw== )
++			300	RRSIG	TLSA 8 5 300 20121212121212 (
++					20111010101010 48381 example.sec.
++					r9ehTiWmpcAfojfJWBruAfd2B5WXYVswI8bz
++					Xt0j7ELVPnXKM15oDFpYYmKSREoiyrM6Q+1M
++					mITFsJwsGt7UmrHn8lVxXxTmWpvA7C/v+/Zt
++					kUZQsRWSPtVOrEu50plnscsRZcV5PIqqaPgC
++					S/066uLAaWiT4mWV53ZRDebaXnAvQ10VQ//k
++					HkVJeJMGHJdJyyfYZfotPTetJJN0JccJpx0B
++					3N/VSFlxWIyRZVn8VK2z4RADHuqzkXklynmM
++					6feVrOi91YywFcSFNmOs84lr7UYKFFf2pKTZ
++					/RDbD0xCIQV+cKqizp2NI4v1FTbdBzsqTRoN
++					/DwAW5qleHlQb9TqNQ== )
+ ghost.example.sec.	300	IN NS	ns1.example.sec.
+ 			300	IN NS	ns2.example.sec.
+ 			300	DS	50458 12 3 (
+@@ -835,168 +1260,6 @@ public.example.sec.	300	IN HINFO "i386" "FreeBSD"
+ 					DLIOZ1682IAviJ+htzGmCYTl6iZMlt8wJ5LO
+ 					Yfkzvd9UUt4w0OlOe26Kc/mBoVy2Lk3mn9BW
+ 					Ba3V48bTYWHHbIgOTQ== )
+-mail.example.sec.	300	IN A	2.3.4.5
+-			300	RRSIG	A 5 3 300 20121212121212 (
+-					20111010101010 516 example.sec.
+-					LxovxXszIrJ0WqC4lryebK8Png85a1l62jvj
+-					JHLNs25OP3I/CpsfLXmE2o+bGXdCoppA6k+u
+-					+d0BmWG32UmOXQOkcu3haT5J8rJWPV1xynhJ
+-					IsBCmF/UbEXp6PoAniCcytS4ZsHqrm31KBNI
+-					i/ZXtU93D2CGrTDMpwX13xT4scE= )
+-			300	RRSIG	A 5 3 300 20121212121212 (
+-					20111010101010 44427 example.sec.
+-					LNe6/SJmAkohBYlRtofW0wYMPDVJ2ZTCmOwe
+-					hwZBKvNrcxc8uYlzqSBqjD6Vtq4GpJSl+MV0
+-					KY0GpsE2jz49l4ayUi5QIC8wRaJ1NeTDiwBp
+-					EbA5ycNdzSpGtLFNs0qzDQntdrZdtvoaFCcV
+-					WDPNGP4rvhvTMXfriPJuYJ2W5ZxmXp3DYNDZ
+-					E+1xgJ3hvr6pdAy7UdROrhsOp3ohP15sE8/H
+-					+sU/hmZ9hfBeodpGHhWYIc6FSMOca3pEBwQL
+-					ifVL2Q06ijnqbh6iuJqJnqI++ZadCHIqEYNT
+-					Tn96mylS3XQ4S3FZPPrXXhuM9HvKKxnDvvWX
+-					ALsm728QZQi2keAKkg== )
+-			300	RRSIG	A 8 3 300 20121212121212 (
+-					20111010101010 48381 example.sec.
+-					tyz/WG3TB1pdIqpToluADGocPccrMuT7v/a5
+-					sQ9RY6QKAzdf9YU/ikEH2SeEPkC4EwD2pPp8
+-					RmURKjzSvSc3D8Q6b1KbC6IHEy7+MDUouZCX
+-					xbQSqRPxLvUQLc2WvK+M6CzpnoqVpOTNqouU
+-					XbwrNA9FyXsHGKOURAGQ9Viu97VNaWUyAkzV
+-					9RoC2T5Y7C2T+Vd/pkhCdi8nvHWOvUxixyXA
+-					mYekLx+TeEx1Ntr+Z7aT9kN1Hv0NsR19o5F7
+-					JAwRTWZvYk/HpRavqbHTw76f1d0jOPq3WOKp
+-					VtvqrklUy9GgPranPH8j7lplg6c1c0H5/7BQ
+-					nFp6xgW2OVH137Hdwg== )
+-			300	NSEC	ns1.example.sec. A RRSIG NSEC
+-			300	RRSIG	NSEC 5 3 300 20121212121212 (
+-					20111010101010 516 example.sec.
+-					CQt3t9eRRTC5mv5c46WsRDX6aZk4jW4RqsEg
+-					LWY5zSxShOBKsek/RiUzpcN+N+fu46NGKzpb
+-					Gmgu8Q6LfO49hIWv8Ng4VvAqPqTO6wXC+kIY
+-					p7VuVydrdHNI4lrz1Vb4Kb8B9x9bqopd7SDq
+-					w05X4E3NEnuEZpO4IBx0dq6WVtA= )
+-			300	RRSIG	NSEC 5 3 300 20121212121212 (
+-					20111010101010 44427 example.sec.
+-					yg7PqCc01WBqcyCjmsdoeaThprboseA5DA5u
+-					N++BVVcX9fqLHRe3gEdPQjrhaSIcOD3mK1xi
+-					l5v7g+33R483h6yliN6u8SCYxao7o0sBNIub
+-					ZFyneOyaJYkL83I72sTkARovPIymfJ9n4gZu
+-					SGl2opcJunj1eQAa+vKuhc3RUvZrgOpH1dMr
+-					TXYHUpxMl7IO+o5x90rVbSSU2QImuxwitQ5b
+-					Mt6wrM5uAdFtsRC/wequhP1uARE52ZEh7u22
+-					zUqd8xyjfIdKFmSCIMLBCzIimuNuXaAqT4Hw
+-					gYtrTcinj1GPo0OcaBHcGc0DI99pwatUv6ds
+-					CqJNUumYaNeGf85jWg== )
+-			300	RRSIG	NSEC 8 3 300 20121212121212 (
+-					20111010101010 48381 example.sec.
+-					acXn4lWozO7QD3vfPy+OV+WDFBUJXf1WGAl2
+-					FCWDf2IsOCHhlUNHEAwiHkORMY2AVlfZS9hG
+-					Z+RRW7b0uelYsmLPmfwZtN+9IsehcCjYg5F7
+-					ZfqiTXNGs9Er8IjV6Ogic9CiOYwWRHn+X2DP
+-					haE6UP4LYEqP2eFPTMVN/E5smm6SI4HVNrZW
+-					W9MgzvHdUl4RurWQYl8KyOTve1ElyJt+a2tw
+-					ydanT1Ncbi/limS5f61U4WckBMfyZ5vH+SfK
+-					fxMyIwpz9mWLGzy9wyBMYBLfSdNX0vI+wvR+
+-					/b0D0SDz11F1le+cERJhO4CBxEFEiVqQHpKG
+-					sR8RStNy8Bq0o6mpmw== )
+-ns2.example.sec.	300	IN A	5.6.7.8
+-			300	RRSIG	A 5 3 300 20121212121212 (
+-					20111010101010 516 example.sec.
+-					kDQQNP+l0TqJq8Kfn8VU7HqED4wX+CVswCEH
+-					TCSo+ByoaMhG7cWfIzV9d7euMtDWbLvnp/5p
+-					qmmDkhlWjmh8/jDH0eoM5LsYJG+hQfoDGBmt
+-					L/2eEBHcdwahbr5zzgE/z1Kvk4cLInp8iveq
+-					Nlh1br2rMpLuIWZtYYjkOziqKC0= )
+-			300	RRSIG	A 5 3 300 20121212121212 (
+-					20111010101010 44427 example.sec.
+-					G3ZnC5ZXkcqBbBXM7jDtZ3zLggKW8P++ryWA
+-					McqvywLUWXNGqu1VB+/mcyaEoi66T74hQV4+
+-					bsWhQRNU1zXmPyoKYVoDeLgtnNymQEUi7TFB
+-					mp0iBGGdW/tcZKP+UxrKmtR9nQoo/wuz/RKD
+-					cWGHVAEjnK9DCPIhNwHG3frFimVoc+eoBG/r
+-					okHgI9IWQMJ4z+GGxKwHZ+qIvPTaIXJpBWl0
+-					tiJhj15B+QeShvGK0Au8KvafqXgUEB7o0oh5
+-					KiHTeTx00i7lP+ieneccJNGONhi1grVuarum
+-					cqNrVR1ddGLjz5yvkmzxXtRBCZmcqgRaCzkD
+-					Yr0pMzvhxNzSfQ03pw== )
+-			300	RRSIG	A 8 3 300 20121212121212 (
+-					20111010101010 48381 example.sec.
+-					WY7f+CDmncZvjqYEGlrgeRGuf06NZNc4vQ5h
+-					1j3Ux1yjTY22CTCaQafETI8+e8W35l0FPTgm
+-					sTKVnTMD9nloIgghiwMBhbuTgQZjAmatj5TV
+-					ymcNkz1vIWOB7J7eYA1eLdNQ9NARk1N9NrSE
+-					X6pfGzjWydsAhRSQVig779Mz/PPAxG/7rBXM
+-					j3g6+GZwFvbaMJata9HuKP9zgIbf19CG5MLe
+-					nGSzquzAJEIvPXvwvddSQCGg6ADuHppYwOJq
+-					rkqsKga2T73Nrn5k9KrCrt+1iC1LJvbws2R8
+-					jkB/N+49IlkzZOZXtI/KgL9riaOnbFCyI3iI
+-					lJB/LXjunEB1h1Nr2A== )
+-			300	NSEC	public.example.sec. A RRSIG NSEC
+-			300	RRSIG	NSEC 5 3 300 20121212121212 (
+-					20111010101010 516 example.sec.
+-					RLH4xaCk4HFnbQOEGFM8xTBllDyNolLE6u6W
+-					5loi7NdPv+6F80w12oYENwVYRXC4cXa4x47l
+-					aTAOTXEEf1LJeP6GT5hRUhRj3oTMC6InVlHq
+-					ZfPONJgzsyaX958ha91Z2VkP8t1eliUA1mSc
+-					PxbVOMzAsUkPbkHp8D2CRzHwMCo= )
+-			300	RRSIG	NSEC 5 3 300 20121212121212 (
+-					20111010101010 44427 example.sec.
+-					zl2+IlLPn/ab3nK68sCXibCB+lu8EES0wgzd
+-					Vs9FyyP62V4sqjCrPaiGHHeoq/wS+gQwwBQo
+-					6mRZ/gT0Y45RoQER4XgDi/HQWX7zaCeMJ4aH
+-					P0qs9YfJ2odYPAYJbcV4uSRB25zxx+xPUtGQ
+-					gIRKdyUTeXxjBujcraFxdDGMi4HGqFKS/qDg
+-					9x3YnQW4DeA8VQuSCdIoH0zWARyJLfaN01Yc
+-					iAvRGt4QLzvE6Wb3YqxbOMinsLkrnMPTaUjq
+-					gSiM3pvopj6HVI9ElQVQFb0SFmc4IOusc/1u
+-					F1nYngdhGjS+8LVcCPdXJajqiozkGTGN5ISJ
+-					KgWWmA7G51peHjXXzg== )
+-			300	RRSIG	NSEC 8 3 300 20121212121212 (
+-					20111010101010 48381 example.sec.
+-					F9HM6TzOjWpVtiDblqGvcDDcpU5/flAM8OLR
+-					YEIVoAqTiMGwGKMQ5Mqs0Fvnlk6+fTnQu75c
+-					OYvGM4JGucdyWNmzyIQ03L9qonEbBFm3FewR
+-					fL/0COs1GJGeglcHFW9dBIK2Elo4Q9q5mtxY
+-					JCseGHbmjZIs1busGdm/W+JyaCYiHBPJi8xf
+-					ijfk06miRoGaLS7/CraajQmGQLF3iF94DzEU
+-					OuOdWZX2z81VrbI2DbCVRYlokjKz7cc3mm+d
+-					zhJAKHcMXN4PTqcWg5mgdulkGvqL2qFgi5e2
+-					WJxUFZxEDn1Zbqte40CZHVqMdv4I76f8mSns
+-					dFXZVw7n478EjuVj2Q== )
+-delegation3.example.sec. 300	IN NS	delegation3.example.sec.
+-			300	A	1.2.9.253
+-			300	NSEC	delegation4.example.sec. NS RRSIG NSEC
+-			300	RRSIG	NSEC 5 3 300 20121212121212 (
+-					20111010101010 516 example.sec.
+-					WuuwTT692DQs9iSoi8mMe3/r8IIrnKaKisRF
+-					UZ5aC6qTb54FydtNsgWAOOwzN21EI/ucU0kX
+-					iXRcaJ0jvNG30ICWk8oI3By1dXDhpMrZerZt
+-					hMDvnitwa851ZjxGeDtyJsMf2NfAuN0p7V3W
+-					UxEGVpiru6ZDNO2rqfwAd35+ixc= )
+-			300	RRSIG	NSEC 5 3 300 20121212121212 (
+-					20111010101010 44427 example.sec.
+-					Vt/wOn+RgrH7e1m/E7XqhoF85i3q1JMnZ96K
+-					E0WMA40MOmClX4+1oHwmdfeu/9U8dqxp4mJf
+-					iJ2nz8tMoYYcJwa/NhOZs8UZSILUV+ACyhOR
+-					g923yYViY41pyV4DCXxa17Cbc1GWizqDPvZl
+-					yksNQTjGfVslH3IXlkGS6OPHY8HImnPKK0HZ
+-					M4si1bZjFg+SU447VokQvz4gKxVHca20R3wD
+-					8A9ZwPHN/97A8rQJzRBlEfAP0EqG8cjt7s5g
+-					ku+ZoeK/sjeQoq3VGUxJWEZU2lXVYwCAv8Yh
+-					9M+6PZ+O1pG2nfIgqpR+MGHJ79LAdTdRe6MJ
+-					nrnROvz2DumLzi9kcg== )
+-			300	RRSIG	NSEC 8 3 300 20121212121212 (
+-					20111010101010 48381 example.sec.
+-					bH5sNx6a1xTa4fafzO+Ur2CCz7W+RU8EiYhu
+-					mRltM1GcqQ0Cz0k9VQyRzkCE9HGPkzb9lDIp
+-					HiQS6zf70m5YyXVgMG3WBN0MteVb0/1ut3jq
+-					JDkQkSMtjyYnJdZ363lpfI363eAI6c1l+XlN
+-					mvEZrUbUWn6entMRj6ZQas2r/7dp61tkZj/x
+-					PU+4SZeVZZPJIZdDf3QLzak+tXG/fs4OCDih
+-					47F8MhlJ3i+L11FawFVoGXVo2NZ/SOhLoh85
+-					aEGPu6j/whxLR6pw6JueK0euQWEeH6nDfXgB
+-					PA1IYI06aExyLN+n4R1wC0q5iAS0ssA+MY/Z
+-					cXye1Yt7SWn5oGXE/Q== )
+ www.example.sec.	300	IN CNAME example.sec.
+ 			300	RRSIG	CNAME 5 3 300 20121212121212 (
+ 					20111010101010 516 example.sec.
+@@ -1029,38 +1292,38 @@ www.example.sec.	300	IN CNAME example.sec.
+ 					8v9ej2F+rRBiwmJX5Td100sttLkHbQT+ltZr
+ 					Kp/IDck6EptYFdrTSiB9fnz4wiRWgMULdF8Y
+ 					Xo4310RHDB0R58Axew== )
+-			300	NSEC	example.sec. CNAME RRSIG NSEC
++			300	NSEC	_443._tcp.www.example.sec. CNAME RRSIG NSEC
+ 			300	RRSIG	NSEC 5 3 300 20121212121212 (
+ 					20111010101010 516 example.sec.
+-					EIvFwBTbyqOgIVQNRFVpEiDCdOO9yB1Kw8li
+-					7arpp2EC38D3cZh7fjf20cwrLNGjCL7s8UDH
+-					v5v5uE8iLm/nCTIBHjuKVlsAtuC8+cbBThhh
+-					S1ZO+lDraBcwBSjvZIClmzi9mcCy47z2jeEv
+-					xpmD8piD7LPObFZkocxp7x9wdYc= )
++					lC6797IgsOeBVWiBPVtc+BCFsk7uyFHLVlPm
++					Zi0T+3LkX7EeKKB3daEbYqIlEL9zzLDwzYTB
++					j2gXJ7+p5fMr/FsGKNvnCLTuY893GkZ7M+Fh
++					VjEIWQ0XsaFdsz3qHzaUUAF8ZXiGwGX9MV1u
++					Di6M3Kh69Hiu4vYeCoLBTwhIuO4= )
+ 			300	RRSIG	NSEC 5 3 300 20121212121212 (
+ 					20111010101010 44427 example.sec.
+-					bsb5tRHbvH1amKiZvpbSjglaqY+5mOS1mA2z
+-					eeauX7TgvgS+mXys3ywGxTtT9V5zG78luWL5
+-					ux4TtBabLhOOcr+qXqWLcMDa8XcIYDwGeBHb
+-					nAbaHfG6yvudd5syQh3B87m7/IATqB5kwr1X
+-					S/37XceeD4NGZtPkryakR6t3pEQMIaKAEO8H
+-					Y5K2p+uXAJGLUdRqS43UBz6E5YfHUdQQiM4x
+-					BWJDG5lyQlAiAFQb3UWfarFFVh0eFXCFxHRK
+-					k55VMk/b8R4DsbAiXlhtmmz3s346UTOjV0Ae
+-					Fn03PRMsCm7sI7OAXef9lzA5zjwxY1+a/Vzw
+-					VREjp174PHtOcpAY+Q== )
++					tiaAXshAPsCWzGS8dNxZ1Odh6jt/mim39w7B
++					mQTyKpzYwrux8HBPeg+N8ko7gGblVKexL56b
++					dHOfhkh2qIHIhg73sMEVaVd8epRfpDcrpzZN
++					+o+haVN8/8RbqbY/9DbMiuUKwG9m3iWCAkeo
++					OhN6wNMRO6ijJ4nmoCOa2wzqKDLoTBjoUKMT
++					zG5HbuUMSZbBA6TRqv3Fe6gyZiS7iusYvq5/
++					Hu2m8r9tSfhLLSjbZNhDE/fvYMYak3auOdfm
++					7idAue2oy1nsw131S4klMG2XlXm0pBKU4PVx
++					t0hELXyUVm99sO8hg2qKvdupWaxIQ0CC+hBK
++					kUc6BTdj/eEBMvLnaA== )
+ 			300	RRSIG	NSEC 8 3 300 20121212121212 (
+ 					20111010101010 48381 example.sec.
+-					p3+B5Ye7vtdxqVC5WgxrSC5sRb3/4vLLpVcT
+-					SDKcHtT7TA30Xp2zO113pDiknKzUZMhQj0dY
+-					ZfmsMnqH7YEKR6auvZ1gkgsIAetk7D20rbgM
+-					yogDZaueIIS5PVqcrzw49P4XeIAPGevyq3Cp
+-					kB03H/oLvFYh50qIk7+CvP+G2uaUkv1AUwwJ
+-					vYjQVh13JK0lWvqUDoJbtpFGcEixH/Gr0A2y
+-					rkkv0B6kDUNYuZ8UGywrzOBVHS+2oGMKFKoS
+-					nzrIEt6gDdPxVwITa0mFHwBvEtmKjXSPS+gO
+-					z5dS/fmdVn0IjvZWZsHviaXB2cCJesJTxZZg
+-					OtZaIgJVIwQlKosFRA== )
++					ncNaPn7TqvJUjiW3N5ETQXo5Lu0+I215t6r5
++					0fRAvh4FwZAgkbxzpKcHpobp3z4NVoMOZk21
++					4SoX8WxQhrNTyfmmzMzJ6+t4xA7Uu2H0Zul+
++					nGQHg4xPUWuMFymkKc514ycn3EsSmeCgZQXi
++					i7+x/R6GlGQNIx83VYJ3LOEd7OEUvJizv59n
++					+jTdekurwD/foWdf2CqDj5HRpTT52Ki5Zvze
++					b3VLrHuQiojyLiBOeoC1NTyrZHS/PNHA2b5v
++					ZOweSzrOywMwS99STlwZ4dPYE4AUL05KEmF5
++					jJ35+UI8vPozKHN2T68cdTkGKtKR7eFuJ/PY
++					bHm0zQxDhf+zGbiX5Q== )
+ lets.introduce.some.empty.terminals.example.sec. 300 IN	CNAME example.sec.
+ 			300	RRSIG	CNAME 5 7 300 20121212121212 (
+ 					20111010101010 516 example.sec.
+@@ -1125,67 +1388,3 @@ lets.introduce.some.empty.terminals.example.sec. 300 IN	CNAME example.sec.
+ 					+EFtzyZVGt0DrFpEQHKmq8L5cjjleMsfJRPx
+ 					2+K170ejOuPI7bCWmdZ1uyqxrUCNEu4UlR3z
+ 					9anMEzjdb2UGUcCRCg== )
+-ns1.example.sec.	300	IN A	1.2.3.4
+-			300	RRSIG	A 5 3 300 20121212121212 (
+-					20111010101010 516 example.sec.
+-					Jz66qNND9eWmodjPcTD9VNb4G5BIqd1MPcMb
+-					9g+J69b1T21cNqAuIom5Y4cECyz/zNJOno89
+-					b7KKcpItUnsdyBHb5WuDeJapT1s4FyEYDEms
+-					diPzaEDEJCTmjyOx/5ADZ5L6I8EN8a3V+iWh
+-					A2YMtWWWjZykqXHeVLPZwqbMJS8= )
+-			300	RRSIG	A 5 3 300 20121212121212 (
+-					20111010101010 44427 example.sec.
+-					RzfNZ0Pu4Vxk5xpCycv3ZSDDMViw+h6nR1uY
+-					Jls1+oSygJfeQn0xeTcVzaZQvvZc0gtnecHT
+-					5UopyFB36R/qeNkPp5fFHGb+ZpMAaNmjrxGI
+-					/1OhxvES4jwTaihetjVWEQyN0M0+Pgw0BNsN
+-					tbz92zBczpUFTbe8FxldePwLcJFZ5CAvp8NC
+-					VuzqAHVMGAt7DYvr9qTknrW/X8wszxwUuL0H
+-					mwitcRF397E6H9SA06uDNum/s8RST9lsV1A2
+-					GsssmglqqKICY8+g89SDqkSuxk1bsFJ+dvFx
+-					kfXRlzBBvpuFt8sORt6LPJXSlFy/tgtRI1lq
+-					oJi9S51V6XElb0vu1Q== )
+-			300	RRSIG	A 8 3 300 20121212121212 (
+-					20111010101010 48381 example.sec.
+-					Q2LBOCx0Ol+UX8yBrpWvoZEPu4bGDJfznS6d
+-					uYWDHZc70kjSBipMO+vmzHTPXiax4LTXXznm
+-					u6gtzSh05FTmQUx2QPctCwwLW3Lfa4xRBnQw
+-					KV+HH0AyXUlKy8gNRBNgJmcQyvyKLr5T8UhP
+-					PYQI60UZxU+vCa8Z38Wffy3X0+AraXFwMc3M
+-					YClGU7HFn7cCKeIrdWl50PEYpa8qUj4ec5XS
+-					1QYZu2v8LE6GmChCCFIJsdkU+JzUJ9mOGYrr
+-					l/aI8G+DPa17NxKwihgzQ6fQIS/AXOx0rUNq
+-					ObP7mpqqn76X6BnfJFTGs9BUCms4W/sVNvra
+-					hbAKFCLCNJAz9EO9Xw== )
+-			300	NSEC	ns2.example.sec. A RRSIG NSEC
+-			300	RRSIG	NSEC 5 3 300 20121212121212 (
+-					20111010101010 516 example.sec.
+-					MPFeioCIJDe03C9RD6Kux0g08JgJYH7xtyFF
+-					4OOOZVHD1mrI+BmjxtWwhb1c7Uqd8+/J9NLF
+-					qywR/OzLW58FsNjznhl3Btr6HsfIfLrEOrTf
+-					kbFlOOSP7gA5ngsC4nMqrWDPjSJwjJ5b3XIT
+-					12C2Efq87MFneqOEzUzIpqDeSdM= )
+-			300	RRSIG	NSEC 5 3 300 20121212121212 (
+-					20111010101010 44427 example.sec.
+-					kUQ26M/bdHkAbREgxC8kBkgxEpnXkQldxwki
+-					0S9mvnmJToiGjnvBIkDixX9BWrx2s8Nzt5tc
+-					xfWqmzlbdbea+BitXMN2o9hnAWNJ0uFmQFaN
+-					M2li2EH5FlCFPpN40w9hazRY25cBvciUJzNE
+-					CaMTtDPRB9GUmZKjE/ZP0N4QnrxvrOqIMJlu
+-					dCsLQ3of+NyBWYpsQQfQvbAvx2WNpolOjqMt
+-					woCsfZhjvedlAAszdaNKCm2qcxYuSKvkw9hl
+-					n9RuZkgYCf+4o0k/DRP6zSwacMo1Rcb6S1D3
+-					b/AXMhBxwtytfaKPh0gAFB2fWck0TLpc/5EG
+-					AuCcy6aJR66j0frDBg== )
+-			300	RRSIG	NSEC 8 3 300 20121212121212 (
+-					20111010101010 48381 example.sec.
+-					Rktfcj5WkoW+7lt1iMFsQXr70zjRdHCUBDf5
+-					zqet9JtQU6r9HSdto4gJAXwwH+gYVWU1zMAo
+-					ZrurdsYhkCrUnUYdO/g6Q+xDIdvPQY4UeUaq
+-					1lZbumzCGAQD21l+nrjxwkD3kvyDtfnAnxU0
+-					eL+/8TqZ/Oo/2cEf2hkuQbOfQqpXImig0n88
+-					e1+xBTJV+fPeORGxnAVL0QMRRabTyOqCPiwj
+-					rcuXpIxRjKWOAEseoFHJbdvFc3MNGwfBC/BR
+-					qI5xzREGVG3yUpY6o1EVkJTNMHdtahZsMOWl
+-					hb1dFARcQSFHUdEEwZwc1gtIa4snPxpplgCd
+-					ZetiK9mOJTMhVhGQSA== )
+diff --git a/t/zones/manyerrors.zone b/t/zones/manyerrors.zone
+index 79aa287..6682983 100644
+--- a/t/zones/manyerrors.zone
++++ b/t/zones/manyerrors.zone
+@@ -64,6 +64,54 @@ singlens	NS x.y.z
+ xy IN 300 A 194.28.255.11
+ xy IN 400 A 194.28.255.12
+ 
++; bad length for SHA-256
++_443._tcp.www IN TLSA (
++      0 0 1 d2abde240d7cd3ee6b4b28c54df034b9
++            7983a1d16e8a410e4561cb106618e9 )
++
++; bad length for SHA-512
++_8443._tcp.www IN TLSA (
++      1 1 2 92003ba34942dc74152e2f2c408d29ec
++            a5a520e7f2e06bb944f4dca346baf63c
++            1b177615d466f6c4b71c216a50292bd5
++            8c9ebdd2f74e38fe51ffd48c43326cbcaa )
++
++; bad hex encoding
++_25._tcp.mail IN TLSA (
++      3 0 0 30820307308201efa003020102020 )
++
++; bad certificate usage
++_1._tcp.www IN TLSA (
++      4 0 1 d2abde240d7cd3ee6b4b28c54df034b9
++            7983a1d16e8a410e4561cb106618e9 )
++_10._tcp.www IN TLSA (
++      x 0 1 d2abde240d7cd3ee6b4b28c54df034b9
++            7983a1d16e8a410e4561cb106618e9 )
++
++; bad selector
++_2._tcp.www IN TLSA (
++      0 2 1 d2abde240d7cd3ee6b4b28c54df034b9
++            7983a1d16e8a410e4561cb106618e9 )
++_20._tcp.www IN TLSA (
++      0 x 1 d2abde240d7cd3ee6b4b28c54df034b9
++            7983a1d16e8a410e4561cb106618e9 )
++
++; bad matching type
++_3._tcp.www IN TLSA (
++      0 0 3 d2abde240d7cd3ee6b4b28c54df034b9
++            7983a1d16e8a410e4561cb106618e9 )
++_30._tcp.www IN TLSA (
++      0 0 x d2abde240d7cd3ee6b4b28c54df034b9
++            7983a1d16e8a410e4561cb106618e9 )
++
++; policy  bad domain name for TLSA
++tlsa IN TLSA (
++      0 0 1 d2abde240d7cd3ee6b4b28c54df034b9
++            7983a1d16e8a410e4561cb106618e9aa )
++_30._xtp.www IN TLSA (
++      0 0 1 d2abde240d7cd3ee6b4b28c54df034b9
++            7983a1d16e8a410e4561cb106618e9aa )
++
+ outside.org. A 194.28.255.11
+ long.outside.org. A 194.28.255.11
+ outsidegalaxyplus.org. A 194.28.255.11
+diff --git a/textparse.c b/textparse.c
+index dc92ac2..78ab943 100644
+--- a/textparse.c
++++ b/textparse.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -69,7 +69,7 @@ char *skip_white_space(char *s)
+ 	return s;
+ }
+ 
+-static char *extract_name_slow(char **input, char *what)
++static char *extract_name_slow(char **input, char *what, int options)
+ {
+ 	char buf[1024];
+ 	char *t = buf;
+@@ -152,17 +152,19 @@ static char *extract_name_slow(char **input, char *what)
+ 	*input = skip_white_space(s);
+ 	if (!*input)
+ 		return NULL;  /* bitching's done elsewhere */
+-	t = buf;
+-	while (*t) {
+-		*t = tolower(*t);
+-		t++;
++	if (!(options & KEEP_CAPITALIZATION)) {
++		t = buf;
++		while (*t) {
++			*t = tolower(*t);
++			t++;
++		}
+ 	}
+ 
+ 	t = quickstrdup(buf);
+ 	return t;
+ }
+ 
+-char *extract_name(char **input, char *what)
++char *extract_name(char **input, char *what, int options)
+ {
+ 	char *s = *input;
+ 	char *r = NULL;
+@@ -185,7 +187,7 @@ char *extract_name(char **input, char *what)
+ 				wildcard = 1;
+ 			} else {
+ 				if (*s == '\\')
+-					return extract_name_slow(input, what);
++					return extract_name_slow(input, what, options);
+ 				return bitch("%s expected", what);
+ 			}
+ 		}
+@@ -194,7 +196,7 @@ char *extract_name(char **input, char *what)
+ 			s++;
+ 		if (*s && !isspace(*s) && *s != ';' && *s != ')') {
+ 			if (*s == '\\')
+-				return extract_name_slow(input, what);
++				return extract_name_slow(input, what, options);
+ 			return bitch("%s is not valid", what);
+ 		}
+ 		if (!*s)	end = s;
+@@ -222,10 +224,12 @@ char *extract_name(char **input, char *what)
+ 		if (!*input)
+ 			return NULL;  /* bitching's done elsewhere */
+ 	}
+-	s = r;
+-	while (*s) {
+-		*s = tolower(*s);
+-		s++;
++	if (!(options & KEEP_CAPITALIZATION)) {
++		s = r;
++		while (*s) {
++			*s = tolower(*s);
++			s++;
++		}
+ 	}
+ 	if (wildcard && r[1] != '.') {
+ 		return bitch("%s: bad wildcard", what);
+@@ -570,6 +574,47 @@ int extract_ipv6(char **input, char *what, struct in6_addr *addr)
+ 	return 1;
+ }
+ 
++int extract_u64(char **input, char *what, uint64_t *r)
++{
++	char *s = *input;
++	uint8_t result = 0;
++	unsigned u;
++
++	#define GETHEXBLOCK if (!isxdigit(*s)) { bitch("%s is not valid", what); return -1; } \
++		u = 0; \
++		while (isxdigit(*s)) { \
++			if (isdigit(*s)) { \
++				u = (u << 4) | (*s - '0'); \
++			} else if (*s >= 'a' && *s <= 'f') { \
++				u = (u << 4) | (*s - 'a' + 10); \
++			} else { \
++				u = (u << 4) | (*s - 'A' + 10); \
++			} \
++			s++; \
++		} \
++		result = (result << 16) | u;
++	#define SKIPCOLON if (*s != ':') { bitch("%s is not valid", what); return -1; } s++;
++
++	GETHEXBLOCK; SKIPCOLON;
++	GETHEXBLOCK; SKIPCOLON;
++	GETHEXBLOCK; SKIPCOLON;
++	GETHEXBLOCK;
++	*r = result;
++
++	#undef GETHEXBLOCK
++	#undef SKIPCOLON
++
++	if (*s && !isspace(*s) && *s != ';' && *s != ')') {
++		bitch("%s is not valid", what);
++		return -1;
++	}
++	*input = skip_white_space(s);
++	if (!*input) {
++		return -1;  /* bitching's done elsewhere */
++	}
++	return 1;
++}
++
+ struct binary_data bad_binary_data(void)
+ {
+ 	struct binary_data r;
+@@ -759,16 +804,18 @@ struct binary_data extract_hex_binary_data(char **input, char *what, int eat_whi
+ 		}
+ 		*input = s;
+ 	} else {
+-		bitch("%s: internal: invalid eat_whitespace");
++		bitch("%s: internal: invalid eat_whitespace", what);
+ 	}
+ 
+ 	if (!*input)
+ 		return r;  /* bitching's done elsewhere */
+ 
++	hb = hl % 2 ? 1 : 0;
++	if (hb == 0)
++		bitch("%s: hex data does not represent whole number of bytes", what);
+ 	r.data = getmem(hl/2);
+ 	r.length = hl/2;
+ 	bzero(r.data, r.length);
+-	hb = hl % 2 ? 1 : 0;
+ 	for (hi = 0; hi < hl-hb; hi++) {
+ 		r.data[hi/2] <<= 4;
+ 		r.data[hi/2] |= 0x0f & (isdigit(hex[hi+hb]) ? hex[hi+hb] - '0' : tolower(hex[hi+hb]) - 'a' + 10);
+@@ -840,6 +887,7 @@ struct binary_data compose_binary_data(const char *fmt, int tmp, ...)
+ 	uint8_t b1;
+ 	uint16_t b2;
+ 	uint32_t b4;
++	uint64_t b8;
+ 
+ 	va_start(ap, tmp);
+ 	args = fmt;
+@@ -858,6 +906,10 @@ struct binary_data compose_binary_data(const char *fmt, int tmp, ...)
+ 			va_arg(ap, unsigned int);
+ 			sz += 4;
+ 			break;
++		case '8':
++			va_arg(ap, uint64_t);
++			sz += 8;
++			break;
+ 		case 'd':
+ 			bd = va_arg(ap, struct binary_data);
+ 			sz += bd.length;
+@@ -902,6 +954,11 @@ struct binary_data compose_binary_data(const char *fmt, int tmp, ...)
+ 			memcpy(t, &b4, 4);
+ 			t += 4;
+ 			break;
++		case '8':
++			b8 = htonl(va_arg(ap, uint64_t));
++			memcpy(t, &b8, 8);
++			t += 8;
++			break;
+ 		case 'd':
+ 			bd = va_arg(ap, struct binary_data);
+ 			memcpy(t, bd.data, bd.length);
+diff --git a/textparse.h b/textparse.h
+index b4f647a..3fe802f 100644
+--- a/textparse.h
++++ b/textparse.h
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+@@ -9,6 +9,8 @@
+ #ifndef _TEXTPARSE_H_
+ #define _TEXTPARSE_H_
+ 
++#include <sys/types.h>
++
+ struct binary_data {
+ 	int length;
+ 	char *data;
+@@ -30,15 +32,18 @@ struct binary_data compose_binary_data(const char *fmt, int tmp, ...);
+  *
+  */
+ 
++#define KEEP_CAPITALIZATION 32
++
+ int empty_line_or_comment(char *s);
+ char *skip_white_space(char *s);
+-char *extract_name(char **input, char *what);
++char *extract_name(char **input, char *what, int options);
+ char *extract_label(char **input, char *what, void *is_temporary);
+ long long extract_integer(char **input, char *what);
+ long extract_timevalue(char **input, char *what);
+ long long extract_timestamp(char **input, char *what);
+ int extract_ipv4(char **input, char *what, struct in_addr *addr);
+ int extract_ipv6(char **input, char *what, struct in6_addr *addr);
++int extract_u64(char **input, char *what, uint64_t *r);
+ int extract_double(char **input, char *what, double *val, int skip_m);
+ struct binary_data extract_base32hex_binary_data(char **input, char *what);
+ struct binary_data extract_base64_binary_data(char **input, char *what);
+diff --git a/tlsa.c b/tlsa.c
+new file mode 100644
+index 0000000..d4cc53e
+--- /dev/null
++++ b/tlsa.c
+@@ -0,0 +1,121 @@
++/*
++ * Part of DNS zone file validator `validns`.
++ *
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
++ * Modified BSD license.
++ * (See LICENSE file in the distribution.)
++ *
++ */
++#include <sys/types.h>
++#include <stdio.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++#include <string.h>
++#include <ctype.h>
++
++#include "common.h"
++#include "textparse.h"
++#include "mempool.h"
++#include "carp.h"
++#include "rr.h"
++
++/* See http://www.rfc-editor.org/internet-drafts/draft-ietf-dane-protocol-23.txt
++ * for TLSA description.
++ */
++
++static struct rr* tlsa_parse(char *name, long ttl, int type, char *s)
++{
++	struct rr_tlsa *rr = getmem(sizeof(*rr));
++	int cert_usage, selector, matching_type;
++
++	cert_usage = extract_integer(&s, "certificate usage field");
++	if (cert_usage < 0)	return NULL;
++	if (cert_usage > 3)
++		return bitch("bad certificate usage field");
++	rr->cert_usage = cert_usage;
++
++	selector = extract_integer(&s, "selector field");
++	if (selector < 0)	return NULL;
++	if (selector > 1)
++		return bitch("bad selector field");
++	rr->selector = selector;
++
++	matching_type = extract_integer(&s, "matching type field");
++	if (matching_type < 0)	return NULL;
++	if (matching_type > 2)
++		return bitch("bad matching type field");
++	rr->matching_type = matching_type;
++
++	rr->association_data = extract_hex_binary_data(&s, "certificate association data", EXTRACT_EAT_WHITESPACE);
++	if (rr->association_data.length < 0)	return NULL;
++	switch (rr->matching_type) {
++	case 1:
++		if (rr->association_data.length != SHA256_BYTES)
++			return bitch("bad SHA-256 hash length");
++		break;
++	case 2:
++		if (rr->association_data.length != SHA512_BYTES)
++			return bitch("bad SHA-512 hash length");
++		break;
++	}
++
++	if (*s) {
++		return bitch("garbage after valid TLSA data");
++	}
++	return store_record(type, name, ttl, rr);
++}
++
++static char* tlsa_human(struct rr *rrv)
++{
++	RRCAST(tlsa);
++    char s[1024];
++
++    snprintf(s, 1024, "%d %d %d ...",
++		rr->cert_usage, rr->selector, rr->matching_type);
++    return quickstrdup_temp(s);
++}
++
++static struct binary_data tlsa_wirerdata(struct rr *rrv)
++{
++	RRCAST(tlsa);
++
++	return compose_binary_data("111d", 1,
++		rr->cert_usage, rr->selector, rr->matching_type,
++		rr->association_data);
++}
++
++static void* tlsa_validate_set(struct rr_set *rr_set)
++{
++	struct rr *rr;
++	struct named_rr *named_rr;
++	char *s;
++	int port = 0;
++	int len;
++
++	if (G.opt.policy_checks[POLICY_TLSA_HOST]) {
++		rr = rr_set->tail;
++		named_rr = rr_set->named_rr;
++
++		/* _25._tcp.mail.example.com. */
++		s = named_rr->name;
++		if (*s != '_') {
++not_a_prefixed_domain_name:
++			return moan(rr->file_name, rr->line, "not a proper prefixed DNS domain name");
++		}
++		s++;
++		while (isdigit(*s)) {
++			port = port * 10  + *s - '0';
++			s++;
++		}
++		if (port <= 0 || port > 65535)	goto not_a_prefixed_domain_name;
++		if (*s++ != '.')	goto not_a_prefixed_domain_name;
++		len = strlen(s);
++		if (len < 6)	goto not_a_prefixed_domain_name;
++		if (memcmp(s, "_tcp.", 5) != 0 &&
++			memcmp(s, "_udp.", 5) != 0 &&
++			memcmp(s, "_sctp.", 6) != 0)	goto not_a_prefixed_domain_name;
++	}
++	return NULL;
++}
++
++struct rr_methods tlsa_methods = { tlsa_parse, tlsa_human, tlsa_wirerdata, tlsa_validate_set, NULL };
+diff --git a/txt.c b/txt.c
+index 188d768..a26fe56 100644
+--- a/txt.c
++++ b/txt.c
+@@ -1,7 +1,7 @@
+ /*
+  * Part of DNS zone file validator `validns`.
+  *
+- * Copyright 2011, Anton Berezin <tobez at tobez.org>
++ * Copyright 2011, 2012 Anton Berezin <tobez at tobez.org>
+  * Modified BSD license.
+  * (See LICENSE file in the distribution.)
+  *
+diff --git a/usage.mdwn b/usage.mdwn
+index 33c0746..30a48c6 100644
+--- a/usage.mdwn
++++ b/usage.mdwn
+@@ -47,6 +47,7 @@ Coming soon.
+ 	- mx-alias
+ 	- ns-alias
+ 	- rp-txt-exists
++	- tlsa-host
+ 	- all
+ 
+ -n *N*
+@@ -125,6 +126,7 @@ Other basic checks include:
+ - NS nsdname should not be an alias
+ - TXT domain name mentioned in RP record must have
+   a corresponding TXT record if it is within the zone
++- domain name of a TLSA record must be a proper prefixed DNS name
+ 
+ # BUGS
+ 
+@@ -143,3 +145,31 @@ every unsigned delegation.
+ If this assumption is wrong for a zone,
+ `validns` will produce spurious validation
+ errors.
++
++# ACKNOWLEDGEMENTS
++
++Thanks go to
++Andy Holdaway,
++Daniel Stirnimann,
++Dennis Kjaer Jensen,
++Goran Bengtson,
++Hirohisa Yamaguchi,
++Hugo Salgado,
++Jakob Schlyter,
++Koh-ichi Ito,
++Mathieu Arnold,
++Miek Gieben,
++Patrik Wallstrom,
++Paul Wouters,
++Ryan Eby,
++Tony Finch,
++Willem Toorop,
++and YAMAGUCHI Takanori
++for bug reports, testing, discussions,
++and occasional patches.
++
++Special thanks to
++Stephane Bortzmeyer and Phil Regnauld.
++
++Thanks for AFNIC which funded major portion of the development.
++
+diff --git a/validns.1 b/validns.1
+index f6beb4f..ef645a6 100644
+--- a/validns.1
++++ b/validns.1
+@@ -51,6 +51,8 @@ ns-alias
+ .IP \[bu] 2
+ rp-txt-exists
+ .IP \[bu] 2
++tlsa-host
++.IP \[bu] 2
+ all
+ .RE
+ .TP
+@@ -172,6 +174,8 @@ NS nsdname should not be an alias
+ .IP \[bu] 2
+ TXT domain name mentioned in RP record must have a corresponding TXT
+ record if it is within the zone
++.IP \[bu] 2
++domain name of a TLSA record must be a proper prefixed DNS name
+ .SH BUGS
+ .IP \[bu] 2
+ textual segments in \f[I]TXT\f[] and \f[I]HINFO\f[] must be enclosed in
+@@ -190,5 +194,16 @@ This is done for reasons of efficiency, to avoid calculating
+ cryptographic hashes of every unsigned delegation.
+ If this assumption is wrong for a zone, \f[C]validns\f[] will produce
+ spurious validation errors.
++.SH ACKNOWLEDGEMENTS
++.PP
++Thanks go to Andy Holdaway, Daniel Stirnimann, Dennis Kjaer Jensen,
++Goran Bengtson, Hirohisa Yamaguchi, Hugo Salgado, Jakob Schlyter,
++Koh-ichi Ito, Mathieu Arnold, Miek Gieben, Patrik Wallstrom, Paul
++Wouters, Ryan Eby, Tony Finch, Willem Toorop, and YAMAGUCHI Takanori for
++bug reports, testing, discussions, and occasional patches.
++.PP
++Special thanks to Stephane Bortzmeyer and Phil Regnauld.
++.PP
++Thanks for AFNIC which funded major portion of the development.
+ .SH AUTHORS
+ Anton Berezin.
diff --git a/validns.spec b/validns.spec
index fa7ae40..894210b 100644
--- a/validns.spec
+++ b/validns.spec
@@ -1,10 +1,11 @@
 Summary: DNS and DNSSEC zone file validator
 Name: validns
 Version: 0.5
-Release: 1%{?dist}
+Release: 2%{?dist}
 License: BSD
 Url:  http://www.validns.net/
 Source: http://www.validns.net/download/%{name}-%{version}.tar.gz
+Patch1: validns-0.5-tlsa-nsec.patch
 Group: Applications/Internet
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: Judy-devel, openssl-devel
@@ -15,6 +16,7 @@ useful README or information, but it's a nice tool anyway :)
 
 %prep
 %setup -q 
+%patch1 -p1
 
 %build
 make %{?_smp_mflags}
@@ -35,6 +37,10 @@ rm -rf %{buildroot}
 %{_mandir}/man1/validns.1.gz
 
 %changelog
+* Fri Aug 24 2012 Paul Wouters <pwouters at redhat.com> - 0.5-2
+- Patch for handling NSEC/NSEC3 camelcasing
+- Support TLSA records
+
 * Thu Jun 07 2012 Paul Wouters <pwouters at redhat.com> - 0.5-1
 - Updated to 0.5 which supports Parallelize signature verification
 - Install man page


More information about the scm-commits mailing list