mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
3341. [func] New "dnssec-verify" command checks a signed zone
to ensure correctness of signatures and of NSEC/NSEC3
chains. [RT #23673]
This commit is contained in:
parent
8811ab3ca6
commit
ad127d839d
26 changed files with 2578 additions and 707 deletions
4
CHANGES
4
CHANGES
|
|
@ -1,3 +1,7 @@
|
|||
3341. [func] New "dnssec-verify" command checks a signed zone
|
||||
to ensure correctness of signatures and of NSEC/NSEC3
|
||||
chains. [RT #23673]
|
||||
|
||||
3340. [func] Added new 'fast' zone file format, which is an image
|
||||
of a zone database that can be loaded directly into
|
||||
memory via mmap(), allowing much faster zone loading.
|
||||
|
|
|
|||
1
bin/dnssec/.gitignore
vendored
1
bin/dnssec/.gitignore
vendored
|
|
@ -6,4 +6,5 @@ dnssec-revoke
|
|||
dnssec-settime
|
||||
dnssec-signkey
|
||||
dnssec-signzone
|
||||
dnssec-verify
|
||||
.libs
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: Makefile.in,v 1.42 2009/12/05 23:31:40 each Exp $
|
||||
# $Id: Makefile.in,v 1.42.332.1 2011/03/16 06:37:51 each Exp $
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
|
@ -44,19 +44,23 @@ NOSYMLIBS = ${DNSLIBS} ${ISCNOSYMLIBS} @LIBS@
|
|||
# Alphabetically
|
||||
TARGETS = dnssec-keygen@EXEEXT@ dnssec-signzone@EXEEXT@ \
|
||||
dnssec-keyfromlabel@EXEEXT@ dnssec-dsfromkey@EXEEXT@ \
|
||||
dnssec-revoke@EXEEXT@ dnssec-settime@EXEEXT@
|
||||
dnssec-revoke@EXEEXT@ dnssec-settime@EXEEXT@ \
|
||||
dnssec-verify@EXEEXT@
|
||||
|
||||
OBJS = dnssectool.@O@
|
||||
|
||||
SRCS = dnssec-dsfromkey.c dnssec-keyfromlabel.c dnssec-keygen.c \
|
||||
dnssec-revoke.c dnssec-settime.c dnssec-signzone.c dnssectool.c
|
||||
dnssec-revoke.c dnssec-settime.c dnssec-signzone.c \
|
||||
dnssec-verify.c dnssectool.c
|
||||
|
||||
MANPAGES = dnssec-dsfromkey.8 dnssec-keyfromlabel.8 dnssec-keygen.8 \
|
||||
dnssec-revoke.8 dnssec-settime.8 dnssec-signzone.8
|
||||
dnssec-revoke.8 dnssec-settime.8 dnssec-signzone.8 \
|
||||
dnssec-verify.8
|
||||
|
||||
HTMLPAGES = dnssec-dsfromkey.html dnssec-keyfromlabel.html \
|
||||
dnssec-keygen.html dnssec-revoke.html \
|
||||
dnssec-settime.html dnssec-signzone.html
|
||||
dnssec-settime.html dnssec-signzone.html \
|
||||
dnssec-verify.html
|
||||
|
||||
MANOBJS = ${MANPAGES} ${HTMLPAGES}
|
||||
|
||||
|
|
@ -82,6 +86,14 @@ dnssec-signzone@EXEEXT@: dnssec-signzone.@O@ ${OBJS} ${DEPLIBS}
|
|||
export BASEOBJS="dnssec-signzone.@O@ ${OBJS}"; \
|
||||
${FINALBUILDCMD}
|
||||
|
||||
dnssec-verify.@O@: dnssec-verify.c
|
||||
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" \
|
||||
-c ${srcdir}/dnssec-verify.c
|
||||
|
||||
dnssec-verify@EXEEXT@: dnssec-verify.@O@ ${OBJS} ${DEPLIBS}
|
||||
export BASEOBJS="dnssec-verify.@O@ ${OBJS}"; \
|
||||
${FINALBUILDCMD}
|
||||
|
||||
dnssec-revoke@EXEEXT@: dnssec-revoke.@O@ ${OBJS} ${DEPLIBS}
|
||||
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
|
||||
dnssec-revoke.@O@ ${OBJS} ${LIBS}
|
||||
|
|
|
|||
|
|
@ -189,10 +189,6 @@ static isc_boolean_t output_stdout = ISC_FALSE;
|
|||
static void
|
||||
sign(isc_task_t *task, isc_event_t *event);
|
||||
|
||||
#define check_dns_dbiterator_current(result) \
|
||||
check_result((result == DNS_R_NEWORIGIN) ? ISC_R_SUCCESS : result, \
|
||||
"dns_dbiterator_current()")
|
||||
|
||||
static void
|
||||
dumpnode(dns_name_t *name, dns_dbnode_t *node) {
|
||||
dns_rdataset_t rds;
|
||||
|
|
@ -997,26 +993,6 @@ loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
|
|||
return (result);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
delegation(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t *ttlp) {
|
||||
dns_rdataset_t nsset;
|
||||
isc_result_t result;
|
||||
|
||||
if (dns_name_equal(name, gorigin))
|
||||
return (ISC_FALSE);
|
||||
|
||||
dns_rdataset_init(&nsset);
|
||||
result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_ns,
|
||||
0, 0, &nsset, NULL);
|
||||
if (dns_rdataset_isassociated(&nsset)) {
|
||||
if (ttlp != NULL)
|
||||
*ttlp = nsset.ttl;
|
||||
dns_rdataset_disassociate(&nsset);
|
||||
}
|
||||
|
||||
return (ISC_TF(result == ISC_R_SUCCESS));
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
secure(dns_name_t *name, dns_dbnode_t *node) {
|
||||
dns_rdataset_t dsset;
|
||||
|
|
@ -1052,7 +1028,7 @@ signname(dns_dbnode_t *node, dns_name_t *name) {
|
|||
/*
|
||||
* Determine if this is a delegation point.
|
||||
*/
|
||||
if (delegation(name, node, NULL))
|
||||
if (is_delegation(gdb, gversion, gorigin, name, node, NULL))
|
||||
isdelegation = ISC_TRUE;
|
||||
|
||||
/*
|
||||
|
|
@ -1385,453 +1361,6 @@ postsign(void) {
|
|||
dns_dbiterator_destroy(&gdbiter);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
goodsig(dns_rdata_t *sigrdata, dns_name_t *name, dns_rdataset_t *keyrdataset,
|
||||
dns_rdataset_t *rdataset)
|
||||
{
|
||||
dns_rdata_dnskey_t key;
|
||||
dns_rdata_rrsig_t sig;
|
||||
dst_key_t *dstkey = NULL;
|
||||
isc_result_t result;
|
||||
|
||||
dns_rdata_tostruct(sigrdata, &sig, NULL);
|
||||
|
||||
for (result = dns_rdataset_first(keyrdataset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(keyrdataset)) {
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdataset_current(keyrdataset, &rdata);
|
||||
dns_rdata_tostruct(&rdata, &key, NULL);
|
||||
result = dns_dnssec_keyfromrdata(gorigin, &rdata, mctx,
|
||||
&dstkey);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (ISC_FALSE);
|
||||
if (sig.algorithm != key.algorithm ||
|
||||
sig.keyid != dst_key_id(dstkey) ||
|
||||
!dns_name_equal(&sig.signer, gorigin)) {
|
||||
dst_key_free(&dstkey);
|
||||
continue;
|
||||
}
|
||||
result = dns_dnssec_verify(name, rdataset, dstkey, ISC_FALSE,
|
||||
mctx, sigrdata);
|
||||
dst_key_free(&dstkey);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
return(ISC_TRUE);
|
||||
}
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
verifyset(dns_rdataset_t *rdataset, dns_name_t *name, dns_dbnode_t *node,
|
||||
dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms,
|
||||
unsigned char *bad_algorithms)
|
||||
{
|
||||
unsigned char set_algorithms[256];
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
char algbuf[80];
|
||||
char typebuf[80];
|
||||
dns_rdataset_t sigrdataset;
|
||||
dns_rdatasetiter_t *rdsiter = NULL;
|
||||
isc_result_t result;
|
||||
int i;
|
||||
|
||||
dns_rdataset_init(&sigrdataset);
|
||||
result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
|
||||
check_result(result, "dns_db_allrdatasets()");
|
||||
for (result = dns_rdatasetiter_first(rdsiter);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdatasetiter_next(rdsiter)) {
|
||||
dns_rdatasetiter_current(rdsiter, &sigrdataset);
|
||||
if (sigrdataset.type == dns_rdatatype_rrsig &&
|
||||
sigrdataset.covers == rdataset->type)
|
||||
break;
|
||||
dns_rdataset_disassociate(&sigrdataset);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_name_format(name, namebuf, sizeof(namebuf));
|
||||
type_format(rdataset->type, typebuf, sizeof(typebuf));
|
||||
fprintf(stderr, "no signatures for %s/%s\n", namebuf, typebuf);
|
||||
for (i = 0; i < 256; i++)
|
||||
if (ksk_algorithms[i] != 0)
|
||||
bad_algorithms[i] = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
memset(set_algorithms, 0, sizeof(set_algorithms));
|
||||
for (result = dns_rdataset_first(&sigrdataset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(&sigrdataset)) {
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_rrsig_t sig;
|
||||
|
||||
dns_rdataset_current(&sigrdataset, &rdata);
|
||||
dns_rdata_tostruct(&rdata, &sig, NULL);
|
||||
if (rdataset->ttl != sig.originalttl) {
|
||||
dns_name_format(name, namebuf, sizeof(namebuf));
|
||||
type_format(rdataset->type, typebuf, sizeof(typebuf));
|
||||
fprintf(stderr, "TTL mismatch for %s %s keytag %u\n",
|
||||
namebuf, typebuf, sig.keyid);
|
||||
continue;
|
||||
}
|
||||
if ((set_algorithms[sig.algorithm] != 0) ||
|
||||
(ksk_algorithms[sig.algorithm] == 0))
|
||||
continue;
|
||||
if (goodsig(&rdata, name, keyrdataset, rdataset))
|
||||
set_algorithms[sig.algorithm] = 1;
|
||||
}
|
||||
dns_rdatasetiter_destroy(&rdsiter);
|
||||
if (memcmp(set_algorithms, ksk_algorithms, sizeof(set_algorithms))) {
|
||||
dns_name_format(name, namebuf, sizeof(namebuf));
|
||||
type_format(rdataset->type, typebuf, sizeof(typebuf));
|
||||
for (i = 0; i < 256; i++)
|
||||
if ((ksk_algorithms[i] != 0) &&
|
||||
(set_algorithms[i] == 0)) {
|
||||
dns_secalg_format(i, algbuf, sizeof(algbuf));
|
||||
fprintf(stderr, "Missing %s signature for "
|
||||
"%s %s\n", algbuf, namebuf, typebuf);
|
||||
bad_algorithms[i] = 1;
|
||||
}
|
||||
}
|
||||
dns_rdataset_disassociate(&sigrdataset);
|
||||
}
|
||||
|
||||
static void
|
||||
verifynode(dns_name_t *name, dns_dbnode_t *node, isc_boolean_t delegation,
|
||||
dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms,
|
||||
unsigned char *bad_algorithms)
|
||||
{
|
||||
dns_rdataset_t rdataset;
|
||||
dns_rdatasetiter_t *rdsiter = NULL;
|
||||
isc_result_t result;
|
||||
|
||||
result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
|
||||
check_result(result, "dns_db_allrdatasets()");
|
||||
result = dns_rdatasetiter_first(rdsiter);
|
||||
dns_rdataset_init(&rdataset);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdatasetiter_current(rdsiter, &rdataset);
|
||||
if (rdataset.type != dns_rdatatype_rrsig &&
|
||||
rdataset.type != dns_rdatatype_dnskey &&
|
||||
(!delegation || rdataset.type == dns_rdatatype_ds ||
|
||||
rdataset.type == dns_rdatatype_nsec)) {
|
||||
verifyset(&rdataset, name, node, keyrdataset,
|
||||
ksk_algorithms, bad_algorithms);
|
||||
}
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
result = dns_rdatasetiter_next(rdsiter);
|
||||
}
|
||||
if (result != ISC_R_NOMORE)
|
||||
fatal("rdataset iteration failed: %s",
|
||||
isc_result_totext(result));
|
||||
dns_rdatasetiter_destroy(&rdsiter);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Verify that certain things are sane:
|
||||
*
|
||||
* The apex has a DNSKEY RRset with at least one KSK, and at least
|
||||
* one ZSK if the -x flag was not used.
|
||||
*
|
||||
* The DNSKEY record was signed with at least one of the KSKs in
|
||||
* the DNSKEY RRset.
|
||||
*
|
||||
* The rest of the zone was signed with at least one of the ZSKs
|
||||
* present in the DNSKEY RRset.
|
||||
*/
|
||||
static void
|
||||
verifyzone(void) {
|
||||
char algbuf[80];
|
||||
dns_dbiterator_t *dbiter = NULL;
|
||||
dns_dbnode_t *node = NULL, *nextnode = NULL;
|
||||
dns_fixedname_t fname, fnextname, fzonecut;
|
||||
dns_name_t *name, *nextname, *zonecut;
|
||||
dns_rdata_dnskey_t dnskey;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdataset_t keyset, soaset;
|
||||
dns_rdataset_t keysigs, soasigs;
|
||||
int i;
|
||||
isc_boolean_t done = ISC_FALSE;
|
||||
isc_boolean_t first = ISC_TRUE;
|
||||
isc_boolean_t goodksk = ISC_FALSE;
|
||||
isc_result_t result;
|
||||
unsigned char revoked_ksk[256];
|
||||
unsigned char revoked_zsk[256];
|
||||
unsigned char standby_ksk[256];
|
||||
unsigned char standby_zsk[256];
|
||||
unsigned char ksk_algorithms[256];
|
||||
unsigned char zsk_algorithms[256];
|
||||
unsigned char bad_algorithms[256];
|
||||
|
||||
if (disable_zone_check)
|
||||
return;
|
||||
|
||||
result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fatal("failed to find the zone's origin: %s",
|
||||
isc_result_totext(result));
|
||||
|
||||
dns_rdataset_init(&keyset);
|
||||
dns_rdataset_init(&keysigs);
|
||||
dns_rdataset_init(&soaset);
|
||||
dns_rdataset_init(&soasigs);
|
||||
|
||||
result = dns_db_findrdataset(gdb, node, gversion,
|
||||
dns_rdatatype_dnskey,
|
||||
0, 0, &keyset, &keysigs);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fatal("Zone contains no DNSSEC keys\n");
|
||||
|
||||
result = dns_db_findrdataset(gdb, node, gversion,
|
||||
dns_rdatatype_soa,
|
||||
0, 0, &soaset, &soasigs);
|
||||
dns_db_detachnode(gdb, &node);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fatal("Zone contains no SOA record\n");
|
||||
|
||||
if (!dns_rdataset_isassociated(&keysigs))
|
||||
fatal("DNSKEY is not signed (keys offline or inactive?)\n");
|
||||
|
||||
if (!dns_rdataset_isassociated(&soasigs))
|
||||
fatal("SOA is not signed (keys offline or inactive?)\n");
|
||||
|
||||
memset(revoked_ksk, 0, sizeof(revoked_ksk));
|
||||
memset(revoked_zsk, 0, sizeof(revoked_zsk));
|
||||
memset(standby_ksk, 0, sizeof(standby_ksk));
|
||||
memset(standby_zsk, 0, sizeof(standby_zsk));
|
||||
memset(ksk_algorithms, 0, sizeof(ksk_algorithms));
|
||||
memset(zsk_algorithms, 0, sizeof(zsk_algorithms));
|
||||
memset(bad_algorithms, 0, sizeof(bad_algorithms));
|
||||
|
||||
/*
|
||||
* Check that the DNSKEY RR has at least one self signing KSK
|
||||
* and one ZSK per algorithm in it (or, if -x was used, one
|
||||
* self-signing KSK).
|
||||
*/
|
||||
for (result = dns_rdataset_first(&keyset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(&keyset)) {
|
||||
dns_rdataset_current(&keyset, &rdata);
|
||||
result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
|
||||
check_result(result, "dns_rdata_tostruct");
|
||||
|
||||
if ((dnskey.flags & DNS_KEYOWNER_ZONE) == 0)
|
||||
;
|
||||
else if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) {
|
||||
if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
|
||||
!dns_dnssec_selfsigns(&rdata, gorigin, &keyset,
|
||||
&keysigs, ISC_FALSE,
|
||||
mctx)) {
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
char buffer[1024];
|
||||
isc_buffer_t buf;
|
||||
|
||||
dns_name_format(gorigin, namebuf,
|
||||
sizeof(namebuf));
|
||||
isc_buffer_init(&buf, buffer, sizeof(buffer));
|
||||
result = dns_rdata_totext(&rdata, NULL, &buf);
|
||||
check_result(result, "dns_rdata_totext");
|
||||
fatal("revoked KSK is not self signed:\n"
|
||||
"%s DNSKEY %.*s", namebuf,
|
||||
(int)isc_buffer_usedlength(&buf), buffer);
|
||||
}
|
||||
if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
|
||||
revoked_ksk[dnskey.algorithm] != 255)
|
||||
revoked_ksk[dnskey.algorithm]++;
|
||||
else if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 &&
|
||||
revoked_zsk[dnskey.algorithm] != 255)
|
||||
revoked_zsk[dnskey.algorithm]++;
|
||||
} else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) {
|
||||
if (dns_dnssec_selfsigns(&rdata, gorigin, &keyset,
|
||||
&keysigs, ISC_FALSE, mctx)) {
|
||||
if (ksk_algorithms[dnskey.algorithm] != 255)
|
||||
ksk_algorithms[dnskey.algorithm]++;
|
||||
goodksk = ISC_TRUE;
|
||||
} else {
|
||||
if (standby_ksk[dnskey.algorithm] != 255)
|
||||
standby_ksk[dnskey.algorithm]++;
|
||||
}
|
||||
} else if (dns_dnssec_selfsigns(&rdata, gorigin, &keyset,
|
||||
&keysigs, ISC_FALSE,
|
||||
mctx)) {
|
||||
if (zsk_algorithms[dnskey.algorithm] != 255)
|
||||
zsk_algorithms[dnskey.algorithm]++;
|
||||
} else if (dns_dnssec_signs(&rdata, gorigin, &soaset,
|
||||
&soasigs, ISC_FALSE, mctx)) {
|
||||
if (zsk_algorithms[dnskey.algorithm] != 255)
|
||||
zsk_algorithms[dnskey.algorithm]++;
|
||||
} else {
|
||||
if (standby_zsk[dnskey.algorithm] != 255)
|
||||
standby_zsk[dnskey.algorithm]++;
|
||||
}
|
||||
dns_rdata_freestruct(&dnskey);
|
||||
dns_rdata_reset(&rdata);
|
||||
}
|
||||
dns_rdataset_disassociate(&keysigs);
|
||||
dns_rdataset_disassociate(&soaset);
|
||||
dns_rdataset_disassociate(&soasigs);
|
||||
|
||||
if (!goodksk)
|
||||
fatal("No self-signed KSK DNSKEY found. Supply an active\n"
|
||||
"key with the KSK flag set, or use '-P'.");
|
||||
|
||||
fprintf(stderr, "Verifying the zone using the following algorithms:");
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (ksk_algorithms[i] != 0) {
|
||||
dns_secalg_format(i, algbuf, sizeof(algbuf));
|
||||
fprintf(stderr, " %s", algbuf);
|
||||
}
|
||||
}
|
||||
fprintf(stderr, ".\n");
|
||||
|
||||
if (!ignore_kskflag && !keyset_kskonly) {
|
||||
for (i = 0; i < 256; i++) {
|
||||
/*
|
||||
* The counts should both be zero or both be non-zero.
|
||||
* Mark the algorithm as bad if this is not met.
|
||||
*/
|
||||
if ((ksk_algorithms[i] != 0) ==
|
||||
(zsk_algorithms[i] != 0))
|
||||
continue;
|
||||
dns_secalg_format(i, algbuf, sizeof(algbuf));
|
||||
fprintf(stderr, "Missing %s for algorithm %s\n",
|
||||
(ksk_algorithms[i] != 0)
|
||||
? "ZSK"
|
||||
: "self signing KSK",
|
||||
algbuf);
|
||||
bad_algorithms[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that all the other records were signed by keys that are
|
||||
* present in the DNSKEY RRSET.
|
||||
*/
|
||||
|
||||
dns_fixedname_init(&fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
dns_fixedname_init(&fnextname);
|
||||
nextname = dns_fixedname_name(&fnextname);
|
||||
dns_fixedname_init(&fzonecut);
|
||||
zonecut = NULL;
|
||||
|
||||
result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
|
||||
check_result(result, "dns_db_createiterator()");
|
||||
|
||||
result = dns_dbiterator_first(dbiter);
|
||||
check_result(result, "dns_dbiterator_first()");
|
||||
|
||||
while (!done) {
|
||||
isc_boolean_t isdelegation = ISC_FALSE;
|
||||
|
||||
result = dns_dbiterator_current(dbiter, &node, name);
|
||||
check_dns_dbiterator_current(result);
|
||||
if (!dns_name_issubdomain(name, gorigin)) {
|
||||
dns_db_detachnode(gdb, &node);
|
||||
result = dns_dbiterator_next(dbiter);
|
||||
if (result == ISC_R_NOMORE)
|
||||
done = ISC_TRUE;
|
||||
else
|
||||
check_result(result, "dns_dbiterator_next()");
|
||||
continue;
|
||||
}
|
||||
if (delegation(name, node, NULL)) {
|
||||
zonecut = dns_fixedname_name(&fzonecut);
|
||||
dns_name_copy(name, zonecut, NULL);
|
||||
isdelegation = ISC_TRUE;
|
||||
}
|
||||
verifynode(name, node, isdelegation, &keyset,
|
||||
ksk_algorithms, bad_algorithms);
|
||||
result = dns_dbiterator_next(dbiter);
|
||||
nextnode = NULL;
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
result = dns_dbiterator_current(dbiter, &nextnode,
|
||||
nextname);
|
||||
check_dns_dbiterator_current(result);
|
||||
if (!dns_name_issubdomain(nextname, gorigin) ||
|
||||
(zonecut != NULL &&
|
||||
dns_name_issubdomain(nextname, zonecut)))
|
||||
{
|
||||
dns_db_detachnode(gdb, &nextnode);
|
||||
result = dns_dbiterator_next(dbiter);
|
||||
continue;
|
||||
}
|
||||
dns_db_detachnode(gdb, &nextnode);
|
||||
break;
|
||||
}
|
||||
if (result == ISC_R_NOMORE) {
|
||||
done = ISC_TRUE;
|
||||
} else if (result != ISC_R_SUCCESS)
|
||||
fatal("iterating through the database failed: %s",
|
||||
isc_result_totext(result));
|
||||
dns_db_detachnode(gdb, &node);
|
||||
}
|
||||
|
||||
dns_dbiterator_destroy(&dbiter);
|
||||
|
||||
result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
|
||||
check_result(result, "dns_db_createiterator()");
|
||||
|
||||
for (result = dns_dbiterator_first(dbiter);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_dbiterator_next(dbiter) ) {
|
||||
result = dns_dbiterator_current(dbiter, &node, name);
|
||||
check_dns_dbiterator_current(result);
|
||||
verifynode(name, node, ISC_FALSE, &keyset,
|
||||
ksk_algorithms, bad_algorithms);
|
||||
dns_db_detachnode(gdb, &node);
|
||||
}
|
||||
dns_dbiterator_destroy(&dbiter);
|
||||
|
||||
dns_rdataset_disassociate(&keyset);
|
||||
|
||||
/*
|
||||
* If we made it this far, we have what we consider a properly signed
|
||||
* zone. Set the good flag.
|
||||
*/
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (bad_algorithms[i] != 0) {
|
||||
if (first)
|
||||
fprintf(stderr, "The zone is not fully signed "
|
||||
"for the following algorithms:");
|
||||
dns_secalg_format(i, algbuf, sizeof(algbuf));
|
||||
fprintf(stderr, " %s", algbuf);
|
||||
first = ISC_FALSE;
|
||||
}
|
||||
}
|
||||
if (!first) {
|
||||
fprintf(stderr, ".\n");
|
||||
fatal("DNSSEC completeness test failed.");
|
||||
}
|
||||
|
||||
if (goodksk || ignore_kskflag) {
|
||||
/*
|
||||
* Print the success summary.
|
||||
*/
|
||||
fprintf(stderr, "Zone signing complete:\n");
|
||||
for (i = 0; i < 256; i++) {
|
||||
if ((ksk_algorithms[i] != 0) ||
|
||||
(standby_ksk[i] != 0) ||
|
||||
(revoked_zsk[i] != 0) ||
|
||||
(zsk_algorithms[i] != 0) ||
|
||||
(standby_zsk[i] != 0) ||
|
||||
(revoked_zsk[i] != 0)) {
|
||||
dns_secalg_format(i, algbuf, sizeof(algbuf));
|
||||
fprintf(stderr, "Algorithm: %s: KSKs: "
|
||||
"%u active, %u stand-by, %u revoked\n",
|
||||
algbuf, ksk_algorithms[i],
|
||||
standby_ksk[i], revoked_ksk[i]);
|
||||
fprintf(stderr, "%*sZSKs: "
|
||||
"%u active, %u %s, %u revoked\n",
|
||||
(int) strlen(algbuf) + 13, "",
|
||||
zsk_algorithms[i],
|
||||
standby_zsk[i],
|
||||
keyset_kskonly ? "present" : "stand-by",
|
||||
revoked_zsk[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*%
|
||||
* Sign the apex of the zone.
|
||||
* Note the origin may not be the first node if there are out of zone
|
||||
|
|
@ -1929,7 +1458,7 @@ assignwork(isc_task_t *task, isc_task_t *worker) {
|
|||
if (dns_name_issubdomain(name, gorigin) &&
|
||||
(zonecut == NULL ||
|
||||
!dns_name_issubdomain(name, zonecut))) {
|
||||
if (delegation(name, node, NULL)) {
|
||||
if (is_delegation(gdb, gversion, gorigin, name, node, NULL)) {
|
||||
dns_fixedname_init(&fzonecut);
|
||||
zonecut = dns_fixedname_name(&fzonecut);
|
||||
dns_name_copy(name, zonecut, NULL);
|
||||
|
|
@ -2187,7 +1716,7 @@ nsecify(void) {
|
|||
if (dns_name_equal(name, gorigin))
|
||||
remove_records(node, dns_rdatatype_nsec3param);
|
||||
|
||||
if (delegation(name, node, &nsttl)) {
|
||||
if (is_delegation(gdb, gversion, gorigin, name, node, &nsttl)) {
|
||||
zonecut = dns_fixedname_name(&fzonecut);
|
||||
dns_name_copy(name, zonecut, NULL);
|
||||
if (generateds)
|
||||
|
|
@ -2622,7 +2151,9 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
|
|||
result = dns_dbiterator_next(dbiter);
|
||||
continue;
|
||||
}
|
||||
if (delegation(nextname, nextnode, &nsttl)) {
|
||||
if (is_delegation(gdb, gversion, gorigin,
|
||||
nextname, nextnode, &nsttl))
|
||||
{
|
||||
zonecut = dns_fixedname_name(&fzonecut);
|
||||
dns_name_copy(nextname, zonecut, NULL);
|
||||
if (generateds)
|
||||
|
|
@ -2750,7 +2281,9 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
|
|||
result = dns_dbiterator_next(dbiter);
|
||||
continue;
|
||||
}
|
||||
if (delegation(nextname, nextnode, NULL)) {
|
||||
if (is_delegation(gdb, gversion, gorigin,
|
||||
nextname, nextnode, NULL))
|
||||
{
|
||||
zonecut = dns_fixedname_name(&fzonecut);
|
||||
dns_name_copy(nextname, zonecut, NULL);
|
||||
if (OPTOUT(nsec3flags) &&
|
||||
|
|
@ -3469,9 +3002,10 @@ main(int argc, char *argv[]) {
|
|||
isc_boolean_t set_salt = ISC_FALSE;
|
||||
isc_boolean_t set_optout = ISC_FALSE;
|
||||
isc_boolean_t set_iter = ISC_FALSE;
|
||||
isc_boolean_t nonsecify = ISC_FALSE;
|
||||
|
||||
#define CMDLINE_FLAGS \
|
||||
"3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:L:l:m:n:N:o:O:PpRr:s:ST:tuUv:X:xz"
|
||||
"3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:L:l:m:n:N:o:O:PpRr:s:ST:tuUv:X:xzZ:"
|
||||
|
||||
/*
|
||||
* Process memory debugging argument first.
|
||||
|
|
@ -3741,6 +3275,10 @@ main(int argc, char *argv[]) {
|
|||
fprintf(stderr, "%s: unhandled option -%c\n",
|
||||
program, isc_commandline_option);
|
||||
exit(1);
|
||||
case 'Z': /* Undocumented test options */
|
||||
if (!strcmp(isc_commandline_argument, "nonsecify"))
|
||||
nonsecify = ISC_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3995,11 +3533,13 @@ main(int argc, char *argv[]) {
|
|||
|
||||
remove_duplicates();
|
||||
|
||||
if (IS_NSEC3)
|
||||
nsec3ify(dns_hash_sha1, nsec3iter, salt, salt_length,
|
||||
&hashlist);
|
||||
else
|
||||
nsecify();
|
||||
if (!nonsecify) {
|
||||
if (IS_NSEC3)
|
||||
nsec3ify(dns_hash_sha1, nsec3iter, salt, salt_length,
|
||||
&hashlist);
|
||||
else
|
||||
nsecify();
|
||||
}
|
||||
|
||||
if (!nokeys) {
|
||||
writeset("dsset-", dns_rdatatype_ds);
|
||||
|
|
@ -4086,9 +3626,12 @@ main(int argc, char *argv[]) {
|
|||
isc_mem_put(mctx, tasks, ntasks * sizeof(isc_task_t *));
|
||||
postsign();
|
||||
TIME_NOW(&sign_finish);
|
||||
verifyzone();
|
||||
|
||||
if (outputformat == dns_masterformat_raw) {
|
||||
if (!disable_zone_check)
|
||||
verifyzone(gdb, gversion, gorigin, mctx,
|
||||
ignore_kskflag, keyset_kskonly);
|
||||
|
||||
if (outputformat != dns_masterformat_text) {
|
||||
dns_masterrawheader_t header;
|
||||
dns_master_initrawheader(&header);
|
||||
if (rawversion == 0U)
|
||||
|
|
|
|||
97
bin/dnssec/dnssec-verify.8
Normal file
97
bin/dnssec/dnssec-verify.8
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
.\" Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and/or distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
.\" PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.hy 0
|
||||
.ad l
|
||||
.\" Title: dnssec\-verify
|
||||
.\" Author:
|
||||
.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
|
||||
.\" Date: April 12, 2012
|
||||
.\" Manual: BIND9
|
||||
.\" Source: BIND9
|
||||
.\"
|
||||
.TH "DNSSEC\-VERIFY" "8" "April 12, 2012" "BIND9" "BIND9"
|
||||
.\" disable hyphenation
|
||||
.nh
|
||||
.\" disable justification (adjust text to left margin only)
|
||||
.ad l
|
||||
.SH "NAME"
|
||||
dnssec\-verify \- DNSSEC zone verification tool
|
||||
.SH "SYNOPSIS"
|
||||
.HP 14
|
||||
\fBdnssec\-verify\fR [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-x\fR] [\fB\-z\fR] {zonefile}
|
||||
.SH "DESCRIPTION"
|
||||
.PP
|
||||
\fBdnssec\-verify\fR
|
||||
verifies that a zone is fully signed for each algorithm found in the DNSKEY RRset for the zone, and that the NSEC / NSEC3 chains are complete.
|
||||
.SH "OPTIONS"
|
||||
.PP
|
||||
\-c \fIclass\fR
|
||||
.RS 4
|
||||
Specifies the DNS class of the zone.
|
||||
.RE
|
||||
.PP
|
||||
\-I \fIinput\-format\fR
|
||||
.RS 4
|
||||
The format of the input zone file. Possible formats are
|
||||
\fB"text"\fR
|
||||
(default) and
|
||||
\fB"raw"\fR. This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non\-text format containing updates can be verified independently. The use of this option does not make much sense for non\-dynamic zones.
|
||||
.RE
|
||||
.PP
|
||||
\-o \fIorigin\fR
|
||||
.RS 4
|
||||
The zone origin. If not specified, the name of the zone file is assumed to be the origin.
|
||||
.RE
|
||||
.PP
|
||||
\-v \fIlevel\fR
|
||||
.RS 4
|
||||
Sets the debugging level.
|
||||
.RE
|
||||
.PP
|
||||
\-x
|
||||
.RS 4
|
||||
Only verify that the DNSKEY RRset is signed with key\-signing keys. Without this flag, it is assumed that the DNSKEY RRset will be signed by all active keys. When this flag is set, it will not be an error if the DNSKEY RRset is not signed by zone\-signing keys. This corresponds to the
|
||||
\fB\-x\fR
|
||||
option in
|
||||
\fBdnssec\-signzone\fR.
|
||||
.RE
|
||||
.PP
|
||||
\-z
|
||||
.RS 4
|
||||
Ignore the KSK flag on the keys when determining whether the zone if correctly signed. Without this flag it is assumed that there will be a non\-revoked, self\-signed DNSKEY with the KSK flag set for each algorithm and that RRsets other than DNSKEY RRset will be signed with a different DNSKEY without the KSK flag set.
|
||||
.sp
|
||||
With this flag set, we only require that for each algorithm, there will be at least one non\-revoked, self\-signed DNSKEY, regardless of the KSK flag state, and that other RRsets will be signed by a non\-revoked key for the same algorithm that includes the self\-signed key; the same key may be used for both purposes. This corresponds to the
|
||||
\fB\-z\fR
|
||||
option in
|
||||
\fBdnssec\-signzone\fR.
|
||||
.RE
|
||||
.PP
|
||||
zonefile
|
||||
.RS 4
|
||||
The file containing the zone to be signed.
|
||||
.RE
|
||||
.SH "SEE ALSO"
|
||||
.PP
|
||||
\fBdnssec\-signzone\fR(8),
|
||||
BIND 9 Administrator Reference Manual,
|
||||
RFC 4033.
|
||||
.SH "AUTHOR"
|
||||
.PP
|
||||
Internet Systems Consortium
|
||||
.SH "COPYRIGHT"
|
||||
Copyright \(co 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
.br
|
||||
325
bin/dnssec/dnssec-verify.c
Normal file
325
bin/dnssec/dnssec-verify.c
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
|
||||
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: dnssec-verify.c,v 1.1.2.1 2011/03/16 06:37:51 each Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <isc/app.h>
|
||||
#include <isc/base32.h>
|
||||
#include <isc/commandline.h>
|
||||
#include <isc/entropy.h>
|
||||
#include <isc/event.h>
|
||||
#include <isc/file.h>
|
||||
#include <isc/hash.h>
|
||||
#include <isc/hex.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/mutex.h>
|
||||
#include <isc/os.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/random.h>
|
||||
#include <isc/rwlock.h>
|
||||
#include <isc/serial.h>
|
||||
#include <isc/stdio.h>
|
||||
#include <isc/stdlib.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/time.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/db.h>
|
||||
#include <dns/dbiterator.h>
|
||||
#include <dns/diff.h>
|
||||
#include <dns/dnssec.h>
|
||||
#include <dns/ds.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/keyvalues.h>
|
||||
#include <dns/log.h>
|
||||
#include <dns/master.h>
|
||||
#include <dns/masterdump.h>
|
||||
#include <dns/nsec.h>
|
||||
#include <dns/nsec3.h>
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdatalist.h>
|
||||
#include <dns/rdataset.h>
|
||||
#include <dns/rdataclass.h>
|
||||
#include <dns/rdatasetiter.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/rdatatype.h>
|
||||
#include <dns/result.h>
|
||||
#include <dns/soa.h>
|
||||
#include <dns/time.h>
|
||||
|
||||
#include <dst/dst.h>
|
||||
|
||||
#include "dnssectool.h"
|
||||
|
||||
const char *program = "dnssec-verify";
|
||||
int verbose;
|
||||
|
||||
static isc_stdtime_t now;
|
||||
static isc_mem_t *mctx = NULL;
|
||||
static isc_entropy_t *ectx = NULL;
|
||||
static dns_masterformat_t inputformat = dns_masterformat_text;
|
||||
static dns_db_t *gdb; /* The database */
|
||||
static dns_dbversion_t *gversion; /* The database version */
|
||||
static dns_rdataclass_t gclass; /* The class */
|
||||
static dns_name_t *gorigin; /* The database origin */
|
||||
static isc_boolean_t ignore_kskflag = ISC_FALSE;
|
||||
static isc_boolean_t keyset_kskonly = ISC_FALSE;
|
||||
|
||||
/*%
|
||||
* Load the zone file from disk
|
||||
*/
|
||||
static void
|
||||
loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
|
||||
isc_buffer_t b;
|
||||
int len;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name;
|
||||
isc_result_t result;
|
||||
|
||||
len = strlen(origin);
|
||||
isc_buffer_init(&b, origin, len);
|
||||
isc_buffer_add(&b, len);
|
||||
|
||||
dns_fixedname_init(&fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fatal("failed converting name '%s' to dns format: %s",
|
||||
origin, isc_result_totext(result));
|
||||
|
||||
result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone,
|
||||
rdclass, 0, NULL, db);
|
||||
check_result(result, "dns_db_create()");
|
||||
|
||||
result = dns_db_load2(*db, file, inputformat);
|
||||
if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE)
|
||||
fatal("failed loading zone from '%s': %s",
|
||||
file, isc_result_totext(result));
|
||||
}
|
||||
|
||||
ISC_PLATFORM_NORETURN_PRE static void
|
||||
usage(void) ISC_PLATFORM_NORETURN_POST;
|
||||
|
||||
static void
|
||||
usage(void) {
|
||||
fprintf(stderr, "Usage:\n");
|
||||
fprintf(stderr, "\t%s [options] zonefile [keys]\n", program);
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "Version: %s\n", VERSION);
|
||||
|
||||
fprintf(stderr, "Options: (default value in parenthesis) \n");
|
||||
fprintf(stderr, "\t-v debuglevel (0)\n");
|
||||
fprintf(stderr, "\t-o origin:\n");
|
||||
fprintf(stderr, "\t\tzone origin (name of zonefile)\n");
|
||||
fprintf(stderr, "\t-I format:\n");
|
||||
fprintf(stderr, "\t\tfile format of input zonefile (text)\n");
|
||||
fprintf(stderr, "\t-c class (IN)\n");
|
||||
fprintf(stderr, "\t-E engine:\n");
|
||||
#ifdef USE_PKCS11
|
||||
fprintf(stderr, "\t\tname of an OpenSSL engine to use "
|
||||
"(default is \"pkcs11\")\n");
|
||||
#else
|
||||
fprintf(stderr, "\t\tname of an OpenSSL engine to use\n");
|
||||
#endif
|
||||
fprintf(stderr, "\t-x:\tDNSKEY record signed with KSKs only, "
|
||||
"not ZSKs\n");
|
||||
fprintf(stderr, "\t-z:\tAll records signed with KSKs\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
char *origin = NULL, *file = NULL;
|
||||
char *inputformatstr = NULL;
|
||||
isc_result_t result;
|
||||
isc_log_t *log = NULL;
|
||||
#ifdef USE_PKCS11
|
||||
const char *engine = "pkcs11";
|
||||
#else
|
||||
const char *engine = NULL;
|
||||
#endif
|
||||
char *classname = NULL;
|
||||
dns_rdataclass_t rdclass;
|
||||
char ch, *endp;
|
||||
|
||||
#define CMDLINE_FLAGS \
|
||||
"m:o:I:c:E:v:xz"
|
||||
|
||||
/*
|
||||
* Process memory debugging argument first.
|
||||
*/
|
||||
while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
|
||||
switch (ch) {
|
||||
case 'm':
|
||||
if (strcasecmp(isc_commandline_argument, "record") == 0)
|
||||
isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
|
||||
if (strcasecmp(isc_commandline_argument, "trace") == 0)
|
||||
isc_mem_debugging |= ISC_MEM_DEBUGTRACE;
|
||||
if (strcasecmp(isc_commandline_argument, "usage") == 0)
|
||||
isc_mem_debugging |= ISC_MEM_DEBUGUSAGE;
|
||||
if (strcasecmp(isc_commandline_argument, "size") == 0)
|
||||
isc_mem_debugging |= ISC_MEM_DEBUGSIZE;
|
||||
if (strcasecmp(isc_commandline_argument, "mctx") == 0)
|
||||
isc_mem_debugging |= ISC_MEM_DEBUGCTX;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
isc_commandline_reset = ISC_TRUE;
|
||||
check_result(isc_app_start(), "isc_app_start");
|
||||
|
||||
result = isc_mem_create(0, 0, &mctx);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fatal("out of memory");
|
||||
|
||||
dns_result_register();
|
||||
|
||||
isc_commandline_errprint = ISC_FALSE;
|
||||
|
||||
while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
classname = isc_commandline_argument;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
engine = isc_commandline_argument;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage();
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
inputformatstr = isc_commandline_argument;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
origin = isc_commandline_argument;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
endp = NULL;
|
||||
verbose = strtol(isc_commandline_argument, &endp, 0);
|
||||
if (*endp != '\0')
|
||||
fatal("verbose level must be numeric");
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
keyset_kskonly = ISC_TRUE;
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
ignore_kskflag = ISC_TRUE;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
if (isc_commandline_option != '?')
|
||||
fprintf(stderr, "%s: invalid argument -%c\n",
|
||||
program, isc_commandline_option);
|
||||
usage();
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: unhandled option -%c\n",
|
||||
program, isc_commandline_option);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (ectx == NULL)
|
||||
setup_entropy(mctx, NULL, &ectx);
|
||||
|
||||
result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fatal("could not create hash context");
|
||||
|
||||
result = dst_lib_init2(mctx, ectx, engine, ISC_ENTROPY_BLOCKING);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fatal("could not initialize dst: %s",
|
||||
isc_result_totext(result));
|
||||
|
||||
isc_stdtime_get(&now);
|
||||
|
||||
rdclass = strtoclass(classname);
|
||||
|
||||
setup_logging(verbose, mctx, &log);
|
||||
|
||||
argc -= isc_commandline_index;
|
||||
argv += isc_commandline_index;
|
||||
|
||||
if (argc < 1)
|
||||
usage();
|
||||
|
||||
file = argv[0];
|
||||
|
||||
argc -= 1;
|
||||
argv += 1;
|
||||
|
||||
if (origin == NULL)
|
||||
origin = file;
|
||||
|
||||
if (inputformatstr != NULL) {
|
||||
if (strcasecmp(inputformatstr, "text") == 0)
|
||||
inputformat = dns_masterformat_text;
|
||||
else if (strcasecmp(inputformatstr, "raw") == 0)
|
||||
inputformat = dns_masterformat_raw;
|
||||
else
|
||||
fatal("unknown file format: %s\n", inputformatstr);
|
||||
}
|
||||
|
||||
gdb = NULL;
|
||||
fprintf(stderr, "Loading zone '%s' from file '%s'\n", origin, file);
|
||||
loadzone(file, origin, rdclass, &gdb);
|
||||
gorigin = dns_db_origin(gdb);
|
||||
gclass = dns_db_class(gdb);
|
||||
|
||||
gversion = NULL;
|
||||
result = dns_db_newversion(gdb, &gversion);
|
||||
check_result(result, "dns_db_newversion()");
|
||||
|
||||
verifyzone(gdb, gversion, gorigin, mctx,
|
||||
ignore_kskflag, keyset_kskonly);
|
||||
|
||||
dns_db_closeversion(gdb, &gversion, ISC_FALSE);
|
||||
dns_db_detach(&gdb);
|
||||
|
||||
cleanup_logging(&log);
|
||||
dst_lib_destroy();
|
||||
isc_hash_destroy();
|
||||
cleanup_entropy(&ectx);
|
||||
dns_name_destroy();
|
||||
if (verbose > 10)
|
||||
isc_mem_stats(mctx, stdout);
|
||||
isc_mem_destroy(&mctx);
|
||||
|
||||
(void) isc_app_finish();
|
||||
|
||||
return (0);
|
||||
}
|
||||
186
bin/dnssec/dnssec-verify.docbook
Normal file
186
bin/dnssec/dnssec-verify.docbook
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
|
||||
[<!ENTITY mdash "—">]>
|
||||
<!--
|
||||
- Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
|
||||
- Copyright (C) 2000-2003 Internet Software Consortium.
|
||||
-
|
||||
- Permission to use, copy, modify, and/or distribute this software for any
|
||||
- purpose with or without fee is hereby granted, provided that the above
|
||||
- copyright notice and this permission notice appear in all copies.
|
||||
-
|
||||
- THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
- AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
- PERFORMANCE OF THIS SOFTWARE.
|
||||
-->
|
||||
|
||||
<!-- $Id: dnssec-verify.docbook,v 1.52 2011/12/22 07:32:40 each Exp $ -->
|
||||
<refentry id="man.dnssec-verify">
|
||||
<refentryinfo>
|
||||
<date>April 12, 2012</date>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle><application>dnssec-verify</application></refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
<refmiscinfo>BIND9</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname><application>dnssec-verify</application></refname>
|
||||
<refpurpose>DNSSEC zone verification tool</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<docinfo>
|
||||
<copyright>
|
||||
<year>2012</year>
|
||||
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
|
||||
</copyright>
|
||||
</docinfo>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>dnssec-verify</command>
|
||||
<arg><option>-c <replaceable class="parameter">class</replaceable></option></arg>
|
||||
<arg><option>-E <replaceable class="parameter">engine</replaceable></option></arg>
|
||||
<arg><option>-I <replaceable class="parameter">input-format</replaceable></option></arg>
|
||||
<arg><option>-o <replaceable class="parameter">origin</replaceable></option></arg>
|
||||
<arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
|
||||
<arg><option>-x</option></arg>
|
||||
<arg><option>-z</option></arg>
|
||||
<arg choice="req">zonefile</arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
<title>DESCRIPTION</title>
|
||||
<para><command>dnssec-verify</command>
|
||||
verifies that a zone is fully signed for each algorithm found
|
||||
in the DNSKEY RRset for the zone, and that the NSEC / NSEC3
|
||||
chains are complete.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>OPTIONS</title>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>-c <replaceable class="parameter">class</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specifies the DNS class of the zone.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-I <replaceable class="parameter">input-format</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The format of the input zone file.
|
||||
Possible formats are <command>"text"</command> (default)
|
||||
and <command>"raw"</command>.
|
||||
This option is primarily intended to be used for dynamic
|
||||
signed zones so that the dumped zone file in a non-text
|
||||
format containing updates can be verified independently.
|
||||
The use of this option does not make much sense for
|
||||
non-dynamic zones.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-o <replaceable class="parameter">origin</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The zone origin. If not specified, the name of the zone file
|
||||
is assumed to be the origin.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-v <replaceable class="parameter">level</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the debugging level.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-x</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Only verify that the DNSKEY RRset is signed with key-signing
|
||||
keys. Without this flag, it is assumed that the DNSKEY RRset
|
||||
will be signed by all active keys. When this flag is set,
|
||||
it will not be an error if the DNSKEY RRset is not signed
|
||||
by zone-signing keys. This corresponds to the <option>-x</option>
|
||||
option in <command>dnssec-signzone</command>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-z</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Ignore the KSK flag on the keys when determining whether
|
||||
the zone if correctly signed. Without this flag it is
|
||||
assumed that there will be a non-revoked, self-signed
|
||||
DNSKEY with the KSK flag set for each algorithm and
|
||||
that RRsets other than DNSKEY RRset will be signed with
|
||||
a different DNSKEY without the KSK flag set.
|
||||
</para>
|
||||
<para>
|
||||
With this flag set, we only require that for each algorithm,
|
||||
there will be at least one non-revoked, self-signed DNSKEY,
|
||||
regardless of the KSK flag state, and that other RRsets
|
||||
will be signed by a non-revoked key for the same algorithm
|
||||
that includes the self-signed key; the same key may be used
|
||||
for both purposes. This corresponds to the <option>-z</option>
|
||||
option in <command>dnssec-signzone</command>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>zonefile</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The file containing the zone to be signed.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>SEE ALSO</title>
|
||||
<para>
|
||||
<citerefentry>
|
||||
<refentrytitle>dnssec-signzone</refentrytitle><manvolnum>8</manvolnum>
|
||||
</citerefentry>,
|
||||
<citetitle>BIND 9 Administrator Reference Manual</citetitle>,
|
||||
<citetitle>RFC 4033</citetitle>.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>AUTHOR</title>
|
||||
<para><corpauthor>Internet Systems Consortium</corpauthor>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
</refentry><!--
|
||||
- Local variables:
|
||||
- mode: sgml
|
||||
- End:
|
||||
-->
|
||||
117
bin/dnssec/dnssec-verify.html
Normal file
117
bin/dnssec/dnssec-verify.html
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
<!--
|
||||
- Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
-
|
||||
- Permission to use, copy, modify, and/or distribute this software for any
|
||||
- purpose with or without fee is hereby granted, provided that the above
|
||||
- copyright notice and this permission notice appear in all copies.
|
||||
-
|
||||
- THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
- AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
- PERFORMANCE OF THIS SOFTWARE.
|
||||
-->
|
||||
<!-- $Id$ -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>dnssec-verify</title>
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
|
||||
<a name="man.dnssec-verify"></a><div class="titlepage"></div>
|
||||
<div class="refnamediv">
|
||||
<h2>Name</h2>
|
||||
<p><span class="application">dnssec-verify</span> — DNSSEC zone verification tool</p>
|
||||
</div>
|
||||
<div class="refsynopsisdiv">
|
||||
<h2>Synopsis</h2>
|
||||
<div class="cmdsynopsis"><p><code class="command">dnssec-verify</code> [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] [<code class="option">-I <em class="replaceable"><code>input-format</code></em></code>] [<code class="option">-o <em class="replaceable"><code>origin</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-x</code>] [<code class="option">-z</code>] {zonefile}</p></div>
|
||||
</div>
|
||||
<div class="refsect1" lang="en">
|
||||
<a name="id2543390"></a><h2>DESCRIPTION</h2>
|
||||
<p><span><strong class="command">dnssec-verify</strong></span>
|
||||
verifies that a zone is fully signed for each algorithm found
|
||||
in the DNSKEY RRset for the zone, and that the NSEC / NSEC3
|
||||
chains are complete.
|
||||
</p>
|
||||
</div>
|
||||
<div class="refsect1" lang="en">
|
||||
<a name="id2543402"></a><h2>OPTIONS</h2>
|
||||
<div class="variablelist"><dl>
|
||||
<dt><span class="term">-c <em class="replaceable"><code>class</code></em></span></dt>
|
||||
<dd><p>
|
||||
Specifies the DNS class of the zone.
|
||||
</p></dd>
|
||||
<dt><span class="term">-I <em class="replaceable"><code>input-format</code></em></span></dt>
|
||||
<dd><p>
|
||||
The format of the input zone file.
|
||||
Possible formats are <span><strong class="command">"text"</strong></span> (default)
|
||||
and <span><strong class="command">"raw"</strong></span>.
|
||||
This option is primarily intended to be used for dynamic
|
||||
signed zones so that the dumped zone file in a non-text
|
||||
format containing updates can be verified independently.
|
||||
The use of this option does not make much sense for
|
||||
non-dynamic zones.
|
||||
</p></dd>
|
||||
<dt><span class="term">-o <em class="replaceable"><code>origin</code></em></span></dt>
|
||||
<dd><p>
|
||||
The zone origin. If not specified, the name of the zone file
|
||||
is assumed to be the origin.
|
||||
</p></dd>
|
||||
<dt><span class="term">-v <em class="replaceable"><code>level</code></em></span></dt>
|
||||
<dd><p>
|
||||
Sets the debugging level.
|
||||
</p></dd>
|
||||
<dt><span class="term">-x</span></dt>
|
||||
<dd><p>
|
||||
Only verify that the DNSKEY RRset is signed with key-signing
|
||||
keys. Without this flag, it is assumed that the DNSKEY RRset
|
||||
will be signed by all active keys. When this flag is set,
|
||||
it will not be an error if the DNSKEY RRset is not signed
|
||||
by zone-signing keys. This corresponds to the <code class="option">-x</code>
|
||||
option in <span><strong class="command">dnssec-signzone</strong></span>.
|
||||
</p></dd>
|
||||
<dt><span class="term">-z</span></dt>
|
||||
<dd>
|
||||
<p>
|
||||
Ignore the KSK flag on the keys when determining whether
|
||||
the zone if correctly signed. Without this flag it is
|
||||
assumed that there will be a non-revoked, self-signed
|
||||
DNSKEY with the KSK flag set for each algorithm and
|
||||
that RRsets other than DNSKEY RRset will be signed with
|
||||
a different DNSKEY without the KSK flag set.
|
||||
</p>
|
||||
<p>
|
||||
With this flag set, we only require that for each algorithm,
|
||||
there will be at least one non-revoked, self-signed DNSKEY,
|
||||
regardless of the KSK flag state, and that other RRsets
|
||||
will be signed by a non-revoked key for the same algorithm
|
||||
that includes the self-signed key; the same key may be used
|
||||
for both purposes. This corresponds to the <code class="option">-z</code>
|
||||
option in <span><strong class="command">dnssec-signzone</strong></span>.
|
||||
</p>
|
||||
</dd>
|
||||
<dt><span class="term">zonefile</span></dt>
|
||||
<dd><p>
|
||||
The file containing the zone to be signed.
|
||||
</p></dd>
|
||||
</dl></div>
|
||||
</div>
|
||||
<div class="refsect1" lang="en">
|
||||
<a name="id2543543"></a><h2>SEE ALSO</h2>
|
||||
<p>
|
||||
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
|
||||
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
|
||||
<em class="citetitle">RFC 4033</em>.
|
||||
</p>
|
||||
</div>
|
||||
<div class="refsect1" lang="en">
|
||||
<a name="id2543637"></a><h2>AUTHOR</h2>
|
||||
<p><span class="corpauthor">Internet Systems Consortium</span>
|
||||
</p>
|
||||
</div>
|
||||
</div></body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -25,6 +25,11 @@
|
|||
#include <dns/rdatastruct.h>
|
||||
#include <dst/dst.h>
|
||||
|
||||
#define check_dns_dbiterator_current(result) \
|
||||
check_result((result == DNS_R_NEWORIGIN) ? ISC_R_SUCCESS : result, \
|
||||
"dns_dbiterator_current()")
|
||||
|
||||
|
||||
typedef void (fatalcallback_t)(void);
|
||||
|
||||
ISC_PLATFORM_NORETURN_PRE void
|
||||
|
|
@ -81,4 +86,12 @@ isc_boolean_t
|
|||
key_collision(dst_key_t *key, dns_name_t *name, const char *dir,
|
||||
isc_mem_t *mctx, isc_boolean_t *exact);
|
||||
|
||||
isc_boolean_t
|
||||
is_delegation(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
|
||||
dns_name_t *name, dns_dbnode_t *node, isc_uint32_t *ttlp);
|
||||
|
||||
void
|
||||
verifyzone(dns_db_t *db, dns_dbversion_t *ver,
|
||||
dns_name_t *origin, isc_mem_t *mctx,
|
||||
isc_boolean_t ignore_kskflag, isc_boolean_t keyset_kskonly);
|
||||
#endif /* DNSSEC_DNSSECTOOL_H */
|
||||
|
|
|
|||
|
|
@ -21,256 +21,228 @@ SYSTEMTESTTOP=../..
|
|||
|
||||
RANDFILE=../random.data
|
||||
|
||||
zone=secure.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
dumpit () {
|
||||
echo "D:${debug}: dumping ${1}"
|
||||
cat "${1}" | sed 's/^/D:/'
|
||||
}
|
||||
|
||||
setup () {
|
||||
echo "I:setting up zone: $1"
|
||||
debug="$1"
|
||||
zone="$1"
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
n=`expr ${n:-0} + 1`
|
||||
}
|
||||
|
||||
setup secure.example
|
||||
cp $infile $zonefile
|
||||
ksk=`$KEYGEN -3 -q -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -3 -q -r $RANDFILE $zone > /dev/null
|
||||
ksk=`$KEYGEN -3 -q -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
$KEYGEN -3 -q -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$DSFROMKEY $ksk.key > dsset-${zone}.
|
||||
|
||||
#
|
||||
# NSEC3/NSEC test zone
|
||||
#
|
||||
zone=secure.nsec3.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
setup secure.nsec3.example
|
||||
cp $infile $zonefile
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > /dev/null
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$DSFROMKEY $ksk.key > dsset-${zone}.
|
||||
|
||||
#
|
||||
# NSEC3/NSEC3 test zone
|
||||
#
|
||||
zone=nsec3.nsec3.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
setup nsec3.nsec3.example
|
||||
cp $infile $zonefile
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > /dev/null
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$DSFROMKEY $ksk.key > dsset-${zone}.
|
||||
|
||||
#
|
||||
# OPTOUT/NSEC3 test zone
|
||||
#
|
||||
zone=optout.nsec3.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
setup optout.nsec3.example
|
||||
cp $infile $zonefile
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > /dev/null
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$DSFROMKEY $ksk.key > dsset-${zone}.
|
||||
|
||||
#
|
||||
# A nsec3 zone (non-optout).
|
||||
#
|
||||
zone=nsec3.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
setup nsec3.example
|
||||
cat $infile dsset-*.${zone}. > $zonefile
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > /dev/null
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$DSFROMKEY $ksk.key > dsset-${zone}.
|
||||
|
||||
#
|
||||
# An NSEC3 zone, with NSEC3 parameters set prior to signing
|
||||
#
|
||||
zone=autonsec3.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
setup autonsec3.example
|
||||
cat $infile > $zonefile
|
||||
ksk=`$KEYGEN -G -q -3 -r $RANDFILE -fk $zone`
|
||||
ksk=`$KEYGEN -G -q -3 -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
echo $ksk > ../autoksk.key
|
||||
zsk=`$KEYGEN -G -q -3 -r $RANDFILE $zone`
|
||||
zsk=`$KEYGEN -G -q -3 -r $RANDFILE $zone 2> kg.out` || dumpit kg.out
|
||||
echo $zsk > ../autozsk.key
|
||||
$DSFROMKEY $ksk.key > dsset-${zone}.
|
||||
|
||||
#
|
||||
# OPTOUT/NSEC test zone
|
||||
#
|
||||
zone=secure.optout.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
setup secure.optout.example
|
||||
cp $infile $zonefile
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > /dev/null
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$DSFROMKEY $ksk.key > dsset-${zone}.
|
||||
|
||||
#
|
||||
# OPTOUT/NSEC3 test zone
|
||||
#
|
||||
zone=nsec3.optout.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
setup nsec3.optout.example
|
||||
cp $infile $zonefile
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > /dev/null
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$DSFROMKEY $ksk.key > dsset-${zone}.
|
||||
|
||||
#
|
||||
# OPTOUT/OPTOUT test zone
|
||||
#
|
||||
zone=optout.optout.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
setup optout.optout.example
|
||||
cp $infile $zonefile
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > /dev/null
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$DSFROMKEY $ksk.key > dsset-${zone}.
|
||||
|
||||
#
|
||||
# A optout nsec3 zone.
|
||||
#
|
||||
zone=optout.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
setup optout.example
|
||||
cat $infile dsset-*.${zone}. > $zonefile
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > /dev/null
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$DSFROMKEY $ksk.key > dsset-${zone}.
|
||||
|
||||
#
|
||||
# A RSASHA256 zone.
|
||||
#
|
||||
zone=rsasha256.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
setup rsasha256.example
|
||||
cp $infile $zonefile
|
||||
ksk=`$KEYGEN -q -a RSASHA256 -b 2048 -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -q -a RSASHA256 -b 1024 -r $RANDFILE $zone > /dev/null
|
||||
ksk=`$KEYGEN -q -a RSASHA256 -b 2048 -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
$KEYGEN -q -a RSASHA256 -b 1024 -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$DSFROMKEY $ksk.key > dsset-${zone}.
|
||||
|
||||
#
|
||||
# A RSASHA512 zone.
|
||||
#
|
||||
zone=rsasha512.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
setup rsasha512.example
|
||||
cp $infile $zonefile
|
||||
ksk=`$KEYGEN -q -a RSASHA512 -b 2048 -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -q -a RSASHA512 -b 1024 -r $RANDFILE $zone > /dev/null
|
||||
ksk=`$KEYGEN -q -a RSASHA512 -b 2048 -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
$KEYGEN -q -a RSASHA512 -b 1024 -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$DSFROMKEY $ksk.key > dsset-${zone}.
|
||||
|
||||
#
|
||||
# NSEC-only zone.
|
||||
#
|
||||
zone=nsec.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
setup nsec.example
|
||||
cp $infile $zonefile
|
||||
ksk=`$KEYGEN -q -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -q -r $RANDFILE $zone > /dev/null
|
||||
ksk=`$KEYGEN -q -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
$KEYGEN -q -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$DSFROMKEY $ksk.key > dsset-${zone}.
|
||||
|
||||
#
|
||||
# Signature refresh test zone. Signatures are set to expire long
|
||||
# in the past; they should be updated by autosign.
|
||||
#
|
||||
zone=oldsigs.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
setup oldsigs.example
|
||||
cp $infile $zonefile
|
||||
ksk=`$KEYGEN -q -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -q -r $RANDFILE $zone > /dev/null
|
||||
$SIGNER -PS -s now-1y -e now-6mo -o $zone -f $zonefile $infile > /dev/null 2>&1
|
||||
$KEYGEN -q -r $RANDFILE -fk $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$KEYGEN -q -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$SIGNER -PS -s now-1y -e now-6mo -o $zone -f $zonefile $infile > s.out 2>&1 || dumpit s.out
|
||||
|
||||
#
|
||||
# NSEC3->NSEC transition test zone.
|
||||
#
|
||||
zone=nsec3-to-nsec.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
#cp $infile $zonefile
|
||||
ksk=`$KEYGEN -q -a RSASHA512 -b 2048 -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -q -a RSASHA512 -b 1024 -r $RANDFILE $zone > /dev/null
|
||||
$SIGNER -S -3 beef -A -o $zone -f $zonefile $infile > /dev/null 2>&1
|
||||
setup nsec3-to-nsec.example
|
||||
$KEYGEN -q -a RSASHA512 -b 2048 -r $RANDFILE -fk $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$KEYGEN -q -a RSASHA512 -b 1024 -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$SIGNER -S -3 beef -A -o $zone -f $zonefile $infile > s.out 2>&1 || dumpit s.out
|
||||
|
||||
#
|
||||
# secure-to-insecure transition test zone; used to test removal of
|
||||
# keys via nsupdate
|
||||
#
|
||||
zone=secure-to-insecure.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
ksk=`$KEYGEN -q -r $RANDFILE -fk $zone`
|
||||
$KEYGEN -q -r $RANDFILE $zone > /dev/null
|
||||
$SIGNER -S -o $zone -f $zonefile $infile > /dev/null 2>&1
|
||||
setup secure-to-insecure.example
|
||||
$KEYGEN -q -r $RANDFILE -fk $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$KEYGEN -q -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$SIGNER -S -o $zone -f $zonefile $infile > s.out 2>&1 || dumpit s.out
|
||||
|
||||
#
|
||||
# another secure-to-insecure transition test zone; used to test
|
||||
# removal of keys on schedule.
|
||||
#
|
||||
zone=secure-to-insecure2.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone`
|
||||
setup secure-to-insecure2.example
|
||||
ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
echo $ksk > ../del1.key
|
||||
zsk=`$KEYGEN -q -3 -r $RANDFILE $zone`
|
||||
zsk=`$KEYGEN -q -3 -r $RANDFILE $zone 2> kg.out` || dumpit kg.out
|
||||
echo $zsk > ../del2.key
|
||||
$SIGNER -S -3 beef -o $zone -f $zonefile $infile > /dev/null 2>&1
|
||||
$SIGNER -S -3 beef -o $zone -f $zonefile $infile > s.out 2>&1 || dumpit s.out
|
||||
|
||||
#
|
||||
# Introducing a pre-published key test.
|
||||
#
|
||||
zone=prepub.example
|
||||
zonefile="${zone}.db"
|
||||
$KEYGEN -3 -q -r $RANDFILE -fk $zone > /dev/null
|
||||
$KEYGEN -3 -q -r $RANDFILE $zone > /dev/null
|
||||
$SIGNER -S -3 beef -o $zone -f $zonefile $infile > /dev/null 2>&1
|
||||
setup prepub.example
|
||||
infile="secure-to-insecure2.example.db.in"
|
||||
$KEYGEN -3 -q -r $RANDFILE -fk $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$KEYGEN -3 -q -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$SIGNER -S -3 beef -o $zone -f $zonefile $infile > s.out 2>&1 || dumpit s.out
|
||||
|
||||
#
|
||||
# Key TTL tests.
|
||||
#
|
||||
|
||||
# no default key TTL; DNSKEY should get SOA TTL
|
||||
zone=ttl1.example
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
$KEYGEN -3 -q -r $RANDFILE -fk $zone > /dev/null
|
||||
$KEYGEN -3 -q -r $RANDFILE $zone > /dev/null
|
||||
setup ttl1.example
|
||||
$KEYGEN -3 -q -r $RANDFILE -fk $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$KEYGEN -3 -q -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
cp $infile $zonefile
|
||||
|
||||
# default key TTL should be used
|
||||
zone=ttl2.example
|
||||
zonefile="${zone}.db"
|
||||
$KEYGEN -3 -q -r $RANDFILE -fk -L 60 $zone > /dev/null
|
||||
$KEYGEN -3 -q -r $RANDFILE -L 60 $zone > /dev/null
|
||||
setup ttl2.example
|
||||
$KEYGEN -3 -q -r $RANDFILE -fk -L 60 $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$KEYGEN -3 -q -r $RANDFILE -L 60 $zone > kg.out 2>&1 || dumpit kg.out
|
||||
cp $infile $zonefile
|
||||
|
||||
# mismatched key TTLs, should use shortest
|
||||
zone=ttl3.example
|
||||
zonefile="${zone}.db"
|
||||
$KEYGEN -3 -q -r $RANDFILE -fk -L 30 $zone > /dev/null
|
||||
$KEYGEN -3 -q -r $RANDFILE -L 60 $zone > /dev/null
|
||||
setup ttl3.example
|
||||
$KEYGEN -3 -q -r $RANDFILE -fk -L 30 $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$KEYGEN -3 -q -r $RANDFILE -L 60 $zone > kg.out 2>&1 || dumpit kg.out
|
||||
cp $infile $zonefile
|
||||
|
||||
# existing DNSKEY RRset, should retain TTL
|
||||
zone=ttl4.example
|
||||
zonefile="${zone}.db"
|
||||
$KEYGEN -3 -q -r $RANDFILE -L 30 -fk $zone > /dev/null
|
||||
setup ttl4.example
|
||||
$KEYGEN -3 -q -r $RANDFILE -L 30 -fk $zone > kg.out 2>&1 || dumpit kg.out
|
||||
cat ${infile} K${zone}.+*.key > $zonefile
|
||||
$KEYGEN -3 -q -r $RANDFILE -L 180 $zone > /dev/null
|
||||
$KEYGEN -3 -q -r $RANDFILE -L 180 $zone > kg.out 2>&1 || dumpit kg.out
|
||||
|
||||
#
|
||||
# A zone with a DNSKEY RRset that is published before it's activated
|
||||
#
|
||||
zone=delay.example
|
||||
zonefile="${zone}.db"
|
||||
ksk=`$KEYGEN -G -q -3 -r $RANDFILE -fk $zone`
|
||||
setup delay.example
|
||||
ksk=`$KEYGEN -G -q -3 -r $RANDFILE -fk $zone 2> kg.out` || dumpit kg.out
|
||||
echo $ksk > ../delayksk.key
|
||||
zsk=`$KEYGEN -G -q -3 -r $RANDFILE $zone`
|
||||
zsk=`$KEYGEN -G -q -3 -r $RANDFILE $zone 2> kg.out` || dumpit kg.out
|
||||
echo $zsk > ../delayzsk.key
|
||||
|
||||
#
|
||||
# A zone with signatures that are already expired, and the private ZSK
|
||||
# is missing.
|
||||
#
|
||||
zone=nozsk.example
|
||||
zonefile="${zone}.db"
|
||||
$KEYGEN -q -3 -r $RANDFILE -fk $zone > /dev/null
|
||||
setup nozsk.example
|
||||
$KEYGEN -q -3 -r $RANDFILE -fk $zone > kg.out 2>&1 || dumpit kg.out
|
||||
zsk=`$KEYGEN -q -3 -r $RANDFILE $zone`
|
||||
$SIGNER -S -P -s now-1mo -e now-1mi -o $zone -f $zonefile ${zonefile}.in > /dev/null 2>&1
|
||||
$SIGNER -S -P -s now-1mo -e now-1mi -o $zone -f $zonefile ${zonefile}.in > s.out 2>&1 || dumpit s.out
|
||||
echo $zsk > ../missingzsk.key
|
||||
rm -f ${zsk}.private
|
||||
|
||||
|
|
@ -278,19 +250,17 @@ rm -f ${zsk}.private
|
|||
# A zone with signatures that are already expired, and the private ZSK
|
||||
# is inactive.
|
||||
#
|
||||
zone=inaczsk.example
|
||||
zonefile="${zone}.db"
|
||||
$KEYGEN -q -3 -r $RANDFILE -fk $zone > /dev/null
|
||||
setup inaczsk.example
|
||||
$KEYGEN -q -3 -r $RANDFILE -fk $zone > kg.out 2>&1 || dumpit kg.out
|
||||
zsk=`$KEYGEN -q -3 -r $RANDFILE $zone`
|
||||
$SIGNER -S -P -s now-1mo -e now-1mi -o $zone -f $zonefile ${zonefile}.in > /dev/null 2>&1
|
||||
$SIGNER -S -P -s now-1mo -e now-1mi -o $zone -f $zonefile ${zonefile}.in > s.out 2>&1 || dumpit s.out
|
||||
echo $zsk > ../inactivezsk.key
|
||||
$SETTIME -I now $zsk > /dev/null
|
||||
$SETTIME -I now $zsk > st.out 2>&1 || dumpit st.out
|
||||
|
||||
#
|
||||
# A zone that is set to 'auto-dnssec maintain' during a recofnig
|
||||
#
|
||||
zone=reconf.example
|
||||
zonefile="${zone}.db"
|
||||
setup reconf.example
|
||||
cp secure.example.db.in $zonefile
|
||||
$KEYGEN -q -3 -r $RANDFILE -fk $zone > /dev/null
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > /dev/null
|
||||
$KEYGEN -q -3 -r $RANDFILE -fk $zone > kg.out 2>&1 || dumpit kg.out
|
||||
$KEYGEN -q -3 -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ PK11GEN="$TOP/bin/pkcs11/pkcs11-keygen -s 0 -p 1234"
|
|||
PK11LIST="$TOP/bin/pkcs11/pkcs11-list -s 0 -p 1234"
|
||||
PK11DEL="$TOP/bin/pkcs11/pkcs11-destroy -s 0 -p 1234"
|
||||
JOURNALPRINT=$TOP/bin/tools/named-journalprint
|
||||
VERIFY=$TOP/bin/dnssec/dnssec-verify
|
||||
|
||||
# The "stress" test is not run by default since it creates enough
|
||||
# load on the machine to make it unusable to other users.
|
||||
|
|
|
|||
7
bin/tests/system/verify/.gitignore
vendored
Normal file
7
bin/tests/system/verify/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
random.data
|
||||
verify.out.*
|
||||
zones/*.good
|
||||
zones/*.bad
|
||||
zones/K*
|
||||
zones/dsset-*
|
||||
zones/s.out*
|
||||
9
bin/tests/system/verify/clean.sh
Normal file
9
bin/tests/system/verify/clean.sh
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
rm -f zones/*.good
|
||||
rm -f zones/*.good.tmp
|
||||
rm -f zones/*.bad
|
||||
rm -f zones/*.bad.tmp
|
||||
rm -f zones/*.out*
|
||||
rm -f zones/dsset-*
|
||||
rm -f zones/K*
|
||||
rm -f random.data
|
||||
rm -f verify.out*
|
||||
23
bin/tests/system/verify/setup.sh
Normal file
23
bin/tests/system/verify/setup.sh
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh -e
|
||||
#
|
||||
# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: setup.sh,v 1.20 2011/02/15 22:02:36 marka Exp $
|
||||
|
||||
sh clean.sh
|
||||
|
||||
../../../tools/genrandom 400 random.data
|
||||
|
||||
(cd zones && sh genzones.sh)
|
||||
81
bin/tests/system/verify/tests.sh
Normal file
81
bin/tests/system/verify/tests.sh
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
|
||||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
failed () {
|
||||
cat verify.out.$n | sed 's/^/D:/';
|
||||
echo "I:failed";
|
||||
status=1;
|
||||
}
|
||||
|
||||
n=0
|
||||
status=0
|
||||
|
||||
for file in zones/*.good
|
||||
do
|
||||
n=`expr $n + 1`
|
||||
zone=`expr "$file" : 'zones/\(.*\).good'`
|
||||
echo "I:checking supposedly good zone: $zone ($n)"
|
||||
ret=0
|
||||
case $zone in
|
||||
zsk-only.*) only=-z;;
|
||||
ksk-only.*) only=-z;;
|
||||
*) only=;;
|
||||
esac
|
||||
$VERIFY ${only} -o $zone $file > verify.out.$n 2>&1 || ret=1
|
||||
[ $ret = 0 ] || failed
|
||||
done
|
||||
|
||||
for file in zones/*.bad
|
||||
do
|
||||
n=`expr $n + 1`
|
||||
zone=`expr "$file" : 'zones/\(.*\).bad'`
|
||||
echo "I:checking supposedly bad zone: $zone ($n)"
|
||||
ret=0
|
||||
dumpit=0
|
||||
case $zone in
|
||||
zsk-only.*) only=-z;;
|
||||
ksk-only.*) only=-z;;
|
||||
*) only=;;
|
||||
esac
|
||||
expect1= expect2=
|
||||
case $zone in
|
||||
*.dnskeyonly)
|
||||
expect1="DNSKEY is not signed"
|
||||
;;
|
||||
*.expired)
|
||||
expect1="signature has expired"
|
||||
expect2="No self-signed .*DNSKEY found"
|
||||
;;
|
||||
*.ksk-expired)
|
||||
expect1="signature has expired"
|
||||
expect2="No self-signed .*DNSKEY found"
|
||||
;;
|
||||
*.out-of-zone-nsec|*.below-bottom-of-zone-nsec)
|
||||
expect1="unexpected NSEC RRset at"
|
||||
;;
|
||||
*.nsec.broken-chain)
|
||||
expect1="Bad record NSEC record for.*, next name mismatch"
|
||||
;;
|
||||
*.bad-bitmap)
|
||||
expect1="bit map mismatch"
|
||||
;;
|
||||
*.missing-empty)
|
||||
expect1="Missing NSEC3 record for";
|
||||
;;
|
||||
unsigned)
|
||||
expect1="Zone contains no DNSSEC keys"
|
||||
;;
|
||||
*.extra-nsec3)
|
||||
expect1="Expected and found NSEC3 chains not equal";
|
||||
;;
|
||||
*)
|
||||
dumpit=1
|
||||
;;
|
||||
esac
|
||||
$VERIFY ${only} -o $zone $file > verify.out.$n 2>&1 && ret=1
|
||||
grep "${expect1:-.}" verify.out.$n > /dev/null || ret=1
|
||||
grep "${expect2:-.}" verify.out.$n > /dev/null || ret=1
|
||||
[ $ret = 0 ] || failed
|
||||
[ $dumpit = 1 ] && cat verify.out.$n
|
||||
done
|
||||
exit $status
|
||||
175
bin/tests/system/verify/zones/genzones.sh
Normal file
175
bin/tests/system/verify/zones/genzones.sh
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
SYSTEMTESTTOP=../..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
|
||||
RANDFILE=../random.data
|
||||
|
||||
dumpit () {
|
||||
echo "D:${debug}: dumping ${1}"
|
||||
cat "${1}" | sed 's/^/D:/'
|
||||
}
|
||||
setup () {
|
||||
echo "I:setting up $2 zone: $1"
|
||||
debug="$1"
|
||||
zone="$1"
|
||||
file="$1.$2"
|
||||
n=`expr ${n:-0} + 1`
|
||||
}
|
||||
|
||||
# A unsigned zone should fail validation.
|
||||
setup unsigned bad
|
||||
cp unsigned.db unsigned.bad
|
||||
|
||||
# A set of nsec zones.
|
||||
setup zsk-only.nsec good
|
||||
$KEYGEN -r $RANDFILE ${zone}> kg.out$n 2>&1 || dumpit kg.out$n
|
||||
$SIGNER -SP -o ${zone} -f ${file} unsigned.db > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
setup ksk-only.nsec good
|
||||
$KEYGEN -r $RANDFILE -fK ${zone} > kg.out$n 2>&1 || dumpit kg.out$n
|
||||
$SIGNER -SPz -o ${zone} -f ${file} unsigned.db > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
setup ksk+zsk.nsec good
|
||||
$KEYGEN -r $RANDFILE ${zone} > kg1.out$n 2>&1 || dumpit kg1.out$n
|
||||
$KEYGEN -r $RANDFILE -fK ${zone} > kg2.out$n 2>&1 || dumpit kg2.out$n
|
||||
$SIGNER -SPx -o ${zone} -f ${file} unsigned.db > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
# A set of nsec3 zones.
|
||||
setup zsk-only.nsec3 good
|
||||
$KEYGEN -3 -r $RANDFILE ${zone}> kg.out$n 2>&1 || dumpit kg.out$n
|
||||
$SIGNER -3 - -SP -o ${zone} -f ${file} unsigned.db > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
setup ksk-only.nsec3 good
|
||||
$KEYGEN -3 -r $RANDFILE -fK ${zone} > kg.out$n 2>&1 || dumpit kg.out$n
|
||||
$SIGNER -3 - -SPz -o ${zone} -f ${file} unsigned.db > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
setup ksk+zsk.nsec3 good
|
||||
$KEYGEN -3 -r $RANDFILE ${zone} > kg1.out$n 2>&1 || dumpit kg1.out$n
|
||||
$KEYGEN -3 -r $RANDFILE -fK ${zone} > kg2.out$n 2>&1 || dumpit kg2.out$n
|
||||
$SIGNER -3 - -SPx -o ${zone} -f ${file} unsigned.db > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
setup ksk+zsk.outout good
|
||||
$KEYGEN -3 -r $RANDFILE ${zone} > kg1.out$n 2>&1 || dumpit kg1.out$n
|
||||
$KEYGEN -3 -r $RANDFILE -fK ${zone} > kg2.out$n 2>&1 || dumpit kg2.out$n
|
||||
$SIGNER -3 - -A -SPx -o ${zone} -f ${file} unsigned.db > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
# A set of zones with only DNSKEY records.
|
||||
setup zsk-only.dnskeyonly bad
|
||||
key1=`$KEYGEN -r $RANDFILE ${zone} 2>kg.out` || dumpit kg.out$n
|
||||
cat unsigned.db $key1.key > ${file}
|
||||
|
||||
setup ksk-only.dnskeyonly bad
|
||||
key1=`$KEYGEN -r $RANDFILE -fK ${zone} 2>kg.out` || dumpit kg.out$n
|
||||
cat unsigned.db $key1.key > ${file}
|
||||
|
||||
setup ksk+zsk.dnskeyonly bad
|
||||
key1=`$KEYGEN -r $RANDFILE ${zone} 2>kg.out` || dumpit kg.out$n
|
||||
key2=`$KEYGEN -r $RANDFILE -fK ${zone} 2>kg.out` || dumpit kg.out$n
|
||||
cat unsigned.db $key1.key $key2.key > ${file}
|
||||
|
||||
# A set of zones with expired records
|
||||
s="-s -2678400"
|
||||
setup zsk-only.nsec.expired bad
|
||||
$KEYGEN -r $RANDFILE ${zone}> kg.out$n 2>&1 || dumpit kg.out$n
|
||||
$SIGNER -SP ${s} -o ${zone} -f ${file} unsigned.db > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
setup ksk-only.nsec.expired bad
|
||||
$KEYGEN -r $RANDFILE -fK ${zone} > kg.out$n 2>&1 || dumpit kg.out$n
|
||||
$SIGNER -SPz ${s} -o ${zone} -f ${file} unsigned.db > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
setup ksk+zsk.nsec.expired bad
|
||||
$KEYGEN -r $RANDFILE ${zone} > kg1.out$n 2>&1 || dumpit kg1.out$n
|
||||
$KEYGEN -r $RANDFILE -fK ${zone} > kg2.out$n 2>&1 || dumpit kg2.out$n
|
||||
$SIGNER -SP ${s} -o ${zone} -f ${file} unsigned.db > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
setup zsk-only.nsec3.expired bad
|
||||
$KEYGEN -3 -r $RANDFILE ${zone}> kg.out$n 2>&1 || dumpit kg.out$n
|
||||
$SIGNER -3 - ${s} -SP -o ${zone} -f ${file} unsigned.db > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
setup ksk-only.nsec3.expired bad
|
||||
$KEYGEN -3 -r $RANDFILE -fK ${zone} > kg.out$n 2>&1 || dumpit kg.out$n
|
||||
$SIGNER -3 - ${s} -SPz -o ${zone} -f ${file} unsigned.db > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
setup ksk+zsk.nsec3.expired bad
|
||||
$KEYGEN -3 -r $RANDFILE ${zone} > kg1.out$n 2>&1 || dumpit kg1.out$n
|
||||
$KEYGEN -3 -r $RANDFILE -fK ${zone} > kg2.out$n 2>&1 || dumpit kg2.out$n
|
||||
$SIGNER -3 - ${s} -SPx -o ${zone} -f ${file} unsigned.db > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
# ksk expired
|
||||
setup ksk+zsk.nsec.ksk-expired bad
|
||||
zsk=`$KEYGEN -r $RANDFILE ${zone} 2> kg1.out$n` || dumpit kg1.out$n
|
||||
ksk=`$KEYGEN -r $RANDFILE -fK ${zone} 2> kg2.out$n` || dumpit kg2.out$n
|
||||
cat unsigned.db $ksk.key $zsk.key > $file
|
||||
$SIGNER -Px -o ${zone} -f ${file} ${file} $zsk > s.out$n 2>&1 || dumpit s.out$n
|
||||
$SIGNER ${s} -P -O full -o ${zone} -f ${file} ${file} $ksk > s.out$n 2>&1 || dumpit s.out$n
|
||||
now=`date -u +%Y%m%d%H%M%S`
|
||||
exp=`awk '$4 == "RRSIG" && $5 == "DNSKEY" { print $9;}' ${file}`
|
||||
[ "${exp:-40001231246060}" -lt ${now:-0} ] || dumpit $file
|
||||
|
||||
setup ksk+zsk.nsec3.ksk-expired bad
|
||||
zsk=`$KEYGEN -3 -r $RANDFILE ${zone} 2> kg1.out$n` || dumpit kg1.out$n
|
||||
ksk=`$KEYGEN -3 -r $RANDFILE -fK ${zone} 2> kg2.out$n` || dumpit kg2.out$n
|
||||
cat unsigned.db $ksk.key $zsk.key > $file
|
||||
$SIGNER -3 - -Px -o ${zone} -f ${file} ${file} $zsk > s.out$n 2>&1 || dumpit s.out$n
|
||||
$SIGNER -3 - ${s} -P -O full -o ${zone} -f ${file} ${file} $ksk > s.out$n 2>&1 || dumpit s.out$n
|
||||
now=`date -u +%Y%m%d%H%M%S`
|
||||
exp=`awk '$4 == "RRSIG" && $5 == "DNSKEY" { print $9;}' ${file}`
|
||||
[ "${exp:-40001231246060}" -lt ${now:-0} ] || dumpit $file
|
||||
|
||||
# broken nsec chain
|
||||
setup ksk+zsk.nsec.broken-chain bad
|
||||
zsk=`$KEYGEN -r $RANDFILE ${zone} 2> kg1.out$n` || dumpit kg1.out$n
|
||||
ksk=`$KEYGEN -r $RANDFILE -fK ${zone} 2> kg2.out$n` || dumpit kg2.out$n
|
||||
cat unsigned.db $ksk.key $zsk.key > $file
|
||||
$SIGNER -P -O full -o ${zone} -f ${file} ${file} $ksk > s.out$n 2>&1 || dumpit s.out$n
|
||||
awk '$4 == "NSEC" { $5 = "'$zone'."; print } { print }' ${file} > ${file}.tmp
|
||||
$SIGNER -Px -Z nonsecify -o ${zone} -f ${file} ${file}.tmp $zsk > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
# bad nsec bitmap
|
||||
setup ksk+zsk.nsec.bad-bitmap bad
|
||||
zsk=`$KEYGEN -r $RANDFILE ${zone} 2> kg1.out$n` || dumpit kg1.out$n
|
||||
ksk=`$KEYGEN -r $RANDFILE -fK ${zone} 2> kg2.out$n` || dumpit kg2.out$n
|
||||
cat unsigned.db $ksk.key $zsk.key > $file
|
||||
$SIGNER -P -O full -o ${zone} -f ${file} ${file} $ksk > s.out$n 2>&1 || dumpit s.out$n
|
||||
awk '$4 == "NSEC" && /SOA/ { $6=""; print } { print }' ${file} > ${file}.tmp
|
||||
$SIGNER -Px -Z nonsecify -o ${zone} -f ${file} ${file}.tmp $zsk > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
# extra NSEC record out side of zone
|
||||
setup ksk+zsk.nsec.out-of-zone-nsec bad
|
||||
zsk=`$KEYGEN -r $RANDFILE ${zone} 2> kg1.out$n` || dumpit kg1.out$n
|
||||
ksk=`$KEYGEN -r $RANDFILE -fK ${zone} 2> kg2.out$n` || dumpit kg2.out$n
|
||||
cat unsigned.db $ksk.key $zsk.key > $file
|
||||
$SIGNER -P -O full -o ${zone} -f ${file} ${file} $ksk > s.out$n 2>&1 || dumpit s.out$n
|
||||
echo "out-of-zone. 3600 IN NSEC ${zone}. A" >> ${file}
|
||||
$SIGNER -Px -Z nonsecify -O full -o ${zone} -f ${file} ${file} $zsk > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
# extra NSEC record below bottom of one
|
||||
setup ksk+zsk.nsec.below-bottom-of-zone-nsec bad
|
||||
zsk=`$KEYGEN -r $RANDFILE ${zone} 2> kg1.out$n` || dumpit kg1.out$n
|
||||
ksk=`$KEYGEN -r $RANDFILE -fK ${zone} 2> kg2.out$n` || dumpit kg2.out$n
|
||||
cat unsigned.db $ksk.key $zsk.key > $file
|
||||
$SIGNER -P -O full -o ${zone} -f ${file} ${file} $ksk > s.out$n 2>&1 || dumpit s.out$n
|
||||
echo "ns.sub.${zone}. 3600 IN NSEC ${zone}. A AAAA" >> ${file}
|
||||
$SIGNER -Px -Z nonsecify -O full -o ${zone} -f ${file}.tmp ${file} $zsk > s.out$n 2>&1 || dumpit s.out$n
|
||||
# dnssec-signzone signs any node with a NSEC record.
|
||||
awk '$1 ~ /^ns.sub/ && $4 == "RRSIG" && $5 != "NSEC" { next; } { print; }' ${file}.tmp > ${file}
|
||||
|
||||
# missing NSEC3 record at empty node
|
||||
setup ksk+zsk.nsec3.missing-empty bad
|
||||
zsk=`$KEYGEN -3 -r $RANDFILE ${zone} 2> kg1.out$n` || dumpit kg1.out$n
|
||||
ksk=`$KEYGEN -3 -r $RANDFILE -fK ${zone} 2> kg2.out$n` || dumpit kg2.out$n
|
||||
cat unsigned.db $ksk.key $zsk.key > $file
|
||||
$SIGNER -3 - -P -O full -o ${zone} -f ${file} ${file} $ksk > s.out$n 2>&1 || dumpit s.out$n
|
||||
awk '$4 == "NSEC3" && NF == 9 { next; } { print; }' ${file} > ${file}.tmp
|
||||
$SIGNER -3 - -Px -Z nonsecify -O full -o ${zone} -f ${file} ${file}.tmp $zsk > s.out$n 2>&1 || dumpit s.out$n
|
||||
|
||||
# extra NSEC3 record
|
||||
setup ksk+zsk.nsec3.extra-nsec3 bad
|
||||
zsk=`$KEYGEN -3 -r $RANDFILE ${zone} 2> kg1.out$n` || dumpit kg1.out$n
|
||||
ksk=`$KEYGEN -3 -r $RANDFILE -fK ${zone} 2> kg2.out$n` || dumpit kg2.out$n
|
||||
cat unsigned.db $ksk.key $zsk.key > $file
|
||||
$SIGNER -3 - -P -O full -o ${zone} -f ${file} ${file} $ksk > s.out$n 2>&1 || dumpit s.out$n
|
||||
awk -v ZONE=${zone}. '$4 == "NSEC3" && NF == 9 {
|
||||
$1 = "H9P7U7TR2U91D0V0LJS9L1GIDNP90U3H." ZONE;
|
||||
$9 = "H9P7U7TR2U91D0V0LJS9L1GIDNP90U3I";
|
||||
print; }' ${file} >> ${file}
|
||||
$SIGNER -3 - -Px -Z nonsecify -O full -o ${zone} -f ${file} ${file} $zsk > s.out$n 2>&1 || dumpit s.out$n
|
||||
17
bin/tests/system/verify/zones/unsigned.db
Normal file
17
bin/tests/system/verify/zones/unsigned.db
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
$TTL 3600
|
||||
@ SOA . . 0 0 0 2419200 3600 ; 28 day expire
|
||||
@ NS .
|
||||
data A 1.2.3.4
|
||||
dname DNAME data
|
||||
longttl 2419200 A 1.2.3.4
|
||||
sub.dname TXT sub.dname
|
||||
sub.empty TXT sub.empty
|
||||
sub NS ns.sub
|
||||
ns.sub A 1.2.3.4
|
||||
ns.sub AAAA 2002::1.2.3.4
|
||||
other.sub TXT other.sub
|
||||
secure NS secure
|
||||
secure DS 1312 50 100 96EEB2FFD9B00CD4694E78278B5EFDAB0A80446567B69F634DA078F0
|
||||
secure A 1.2.3.4
|
||||
secure AAAA 2002::1.2.3.4
|
||||
out-of-zone. A 1.2.3.4
|
||||
|
|
@ -3022,7 +3022,7 @@ AC_ARG_WITH(docbook-xsl,
|
|||
case "$docbook_path" in
|
||||
auto)
|
||||
AC_MSG_RESULT(auto)
|
||||
docbook_xsl_trees="/usr/pkg/share/xsl/docbook /usr/local/share/xsl/docbook /usr/share/xsl/docbook"
|
||||
docbook_xsl_trees="/usr/pkg/share/xsl/docbook /usr/local/share/xsl/docbook /usr/share/xsl/docbook /opt/local/share/xsl/docbook-xsl/"
|
||||
;;
|
||||
*)
|
||||
docbook_xsl_trees="$withval"
|
||||
|
|
|
|||
|
|
@ -16879,6 +16879,7 @@ zone "example.com" {
|
|||
<xi:include href="../../bin/dnssec/dnssec-revoke.docbook"/>
|
||||
<xi:include href="../../bin/dnssec/dnssec-settime.docbook"/>
|
||||
<xi:include href="../../bin/dnssec/dnssec-signzone.docbook"/>
|
||||
<xi:include href="../../bin/dnssec/dnssec-verify.docbook"/>
|
||||
<xi:include href="../../bin/check/named-checkconf.docbook"/>
|
||||
<xi:include href="../../bin/check/named-checkzone.docbook"/>
|
||||
<xi:include href="../../bin/named/named.docbook"/>
|
||||
|
|
|
|||
25
doc/design/verify
Normal file
25
doc/design/verify
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
dnssec-verify a tool to verify a zone is correctly signed.
|
||||
|
||||
* check that every record that should be signed has a valid RRSIG set.
|
||||
* check that every record that shouldn't be signed isn't.
|
||||
* check that each RRSIG set has a valid RRSIG and that all DNSKEY algorithms
|
||||
in use are checked.
|
||||
* provide a mechanism to mark DNSKEY algorithms to be ignored to support
|
||||
verification of zones that are in the processs of adding/removing
|
||||
support for a algorithm.
|
||||
* provide a mechanism to check the zone as of a specified date and time.
|
||||
* check that RRSIG won't expire within the TTL interval.
|
||||
* check that original TTL matches.
|
||||
|
||||
NSEC:
|
||||
* check that every node with data within the zone has a NSEC RRset.
|
||||
* check that empty nodes don't have a NSEC record.
|
||||
* check that nodes outside the zone do not have a NSEC record.
|
||||
* check that the NSEC chain is valid.
|
||||
|
||||
NSEC3: for each NSEC3 chain
|
||||
* check that every node with data within the zone has a NSEC3 RRset.
|
||||
* check that empty nodes within the zone have a NSEC3 record.
|
||||
* check that nodes outside the zone do not have a NSEC3 record.
|
||||
* check that each NSEC3 in the NSEC3PARAM record is valid.
|
||||
|
|
@ -799,6 +799,10 @@ dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
|||
* that it is correct. This only affects answers returned from the
|
||||
* cache.
|
||||
*
|
||||
* \li In the #DNS_DBFIND_FORCENSEC3 option is set, then we are looking
|
||||
* in the NSEC3 tree and not the main tree. Without this option being
|
||||
* set NSEC3 records will not be found.
|
||||
*
|
||||
* \li To respond to a query for SIG records, the caller should create a
|
||||
* rdataset iterator and extract the signatures from each rdataset.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -76,6 +76,28 @@ dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version,
|
|||
* 'answer' to be non NULL.
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw,
|
||||
unsigned int max_type);
|
||||
/*%<
|
||||
* Convert a raw bitmap into a compressed windowed bit map. 'map' and 'raw'
|
||||
* may overlap.
|
||||
*
|
||||
* Returns the length of the compressed windowed bit map.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit);
|
||||
/*%<
|
||||
* Set type bit in raw 'array' to 'bit'.
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
dns_nsec_isset(const unsigned char *array, unsigned int type);
|
||||
/*%<
|
||||
* Test if the corresponding 'type' bit is set in 'array'.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_NSEC_H */
|
||||
|
|
|
|||
|
|
@ -41,28 +41,61 @@
|
|||
goto failure; \
|
||||
} while (0)
|
||||
|
||||
static void
|
||||
set_bit(unsigned char *array, unsigned int index, unsigned int bit) {
|
||||
void
|
||||
dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit) {
|
||||
unsigned int shift, mask;
|
||||
|
||||
shift = 7 - (index % 8);
|
||||
shift = 7 - (type % 8);
|
||||
mask = 1 << shift;
|
||||
|
||||
if (bit != 0)
|
||||
array[index / 8] |= mask;
|
||||
array[type / 8] |= mask;
|
||||
else
|
||||
array[index / 8] &= (~mask & 0xFF);
|
||||
array[type / 8] &= (~mask & 0xFF);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
bit_isset(unsigned char *array, unsigned int index) {
|
||||
isc_boolean_t
|
||||
dns_nsec_isset(const unsigned char *array, unsigned int type) {
|
||||
unsigned int byte, shift, mask;
|
||||
|
||||
byte = array[index / 8];
|
||||
shift = 7 - (index % 8);
|
||||
byte = array[type / 8];
|
||||
shift = 7 - (type % 8);
|
||||
mask = 1 << shift;
|
||||
|
||||
return ((byte & mask) != 0);
|
||||
return (ISC_TF(byte & mask));
|
||||
}
|
||||
|
||||
unsigned int
|
||||
dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw,
|
||||
unsigned int max_type)
|
||||
{
|
||||
unsigned char *start = map;
|
||||
unsigned int window;
|
||||
int octet;
|
||||
|
||||
if (raw == NULL)
|
||||
return (0);
|
||||
|
||||
for (window = 0; window < 256; window++) {
|
||||
if (window * 256 > max_type)
|
||||
break;
|
||||
for (octet = 31; octet >= 0; octet--)
|
||||
if (*(raw + octet) != 0)
|
||||
break;
|
||||
if (octet < 0) {
|
||||
raw += 32;
|
||||
continue;
|
||||
}
|
||||
*map++ = window;
|
||||
*map++ = octet + 1;
|
||||
/*
|
||||
* Note: potential overlapping move.
|
||||
*/
|
||||
memmove(map, raw, octet + 1);
|
||||
map += octet + 1;
|
||||
raw += 32;
|
||||
}
|
||||
return (map - start);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
|
@ -73,8 +106,7 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
|||
isc_result_t result;
|
||||
dns_rdataset_t rdataset;
|
||||
isc_region_t r;
|
||||
unsigned int i, window;
|
||||
int octet;
|
||||
unsigned int i;
|
||||
|
||||
unsigned char *nsec_bits, *bm;
|
||||
unsigned int max_type;
|
||||
|
|
@ -90,8 +122,8 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
|||
*/
|
||||
bm = r.base + r.length + 512;
|
||||
nsec_bits = r.base + r.length;
|
||||
set_bit(bm, dns_rdatatype_rrsig, 1);
|
||||
set_bit(bm, dns_rdatatype_nsec, 1);
|
||||
dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1);
|
||||
dns_nsec_setbit(bm, dns_rdatatype_nsec, 1);
|
||||
max_type = dns_rdatatype_nsec;
|
||||
dns_rdataset_init(&rdataset);
|
||||
rdsiter = NULL;
|
||||
|
|
@ -108,7 +140,7 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
|||
rdataset.type != dns_rdatatype_rrsig) {
|
||||
if (rdataset.type > max_type)
|
||||
max_type = rdataset.type;
|
||||
set_bit(bm, rdataset.type, 1);
|
||||
dns_nsec_setbit(bm, rdataset.type, 1);
|
||||
}
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
}
|
||||
|
|
@ -116,12 +148,12 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
|||
/*
|
||||
* At zone cuts, deny the existence of glue in the parent zone.
|
||||
*/
|
||||
if (bit_isset(bm, dns_rdatatype_ns) &&
|
||||
! bit_isset(bm, dns_rdatatype_soa)) {
|
||||
if (dns_nsec_isset(bm, dns_rdatatype_ns) &&
|
||||
! dns_nsec_isset(bm, dns_rdatatype_soa)) {
|
||||
for (i = 0; i <= max_type; i++) {
|
||||
if (bit_isset(bm, i) &&
|
||||
if (dns_nsec_isset(bm, i) &&
|
||||
! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
|
||||
set_bit(bm, i, 0);
|
||||
dns_nsec_setbit(bm, i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -129,22 +161,8 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
|||
if (result != ISC_R_NOMORE)
|
||||
return (result);
|
||||
|
||||
for (window = 0; window < 256; window++) {
|
||||
if (window * 256 > max_type)
|
||||
break;
|
||||
for (octet = 31; octet >= 0; octet--)
|
||||
if (bm[window * 32 + octet] != 0)
|
||||
break;
|
||||
if (octet < 0)
|
||||
continue;
|
||||
nsec_bits[0] = window;
|
||||
nsec_bits[1] = octet + 1;
|
||||
/*
|
||||
* Note: potential overlapping move.
|
||||
*/
|
||||
memmove(&nsec_bits[2], &bm[window * 32], octet + 1);
|
||||
nsec_bits += 3 + octet;
|
||||
}
|
||||
nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type);
|
||||
|
||||
r.length = nsec_bits - r.base;
|
||||
INSIST(r.length <= DNS_NSEC_BUFFERSIZE);
|
||||
dns_rdata_fromregion(rdata,
|
||||
|
|
@ -155,7 +173,6 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
|||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
isc_result_t
|
||||
dns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node,
|
||||
dns_name_t *target, dns_ttl_t ttl)
|
||||
|
|
@ -216,8 +233,8 @@ dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type) {
|
|||
if ((window + 1) * 256 <= type)
|
||||
continue;
|
||||
if (type < (window * 256) + len * 8)
|
||||
present = ISC_TF(bit_isset(&nsecstruct.typebits[i],
|
||||
type % 256));
|
||||
present = ISC_TF(dns_nsec_isset(&nsecstruct.typebits[i],
|
||||
type % 256));
|
||||
break;
|
||||
}
|
||||
dns_rdata_freestruct(&nsecstruct);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include <dns/dbiterator.h>
|
||||
#include <dns/diff.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/nsec.h>
|
||||
#include <dns/nsec3.h>
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdatalist.h>
|
||||
|
|
@ -52,30 +53,6 @@
|
|||
#define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0)
|
||||
#define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
|
||||
|
||||
static void
|
||||
set_bit(unsigned char *array, unsigned int index, unsigned int bit) {
|
||||
unsigned int shift, mask;
|
||||
|
||||
shift = 7 - (index % 8);
|
||||
mask = 1 << shift;
|
||||
|
||||
if (bit != 0)
|
||||
array[index / 8] |= mask;
|
||||
else
|
||||
array[index / 8] &= (~mask & 0xFF);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
bit_isset(unsigned char *array, unsigned int index) {
|
||||
unsigned int byte, shift, mask;
|
||||
|
||||
byte = array[index / 8];
|
||||
shift = 7 - (index % 8);
|
||||
mask = 1 << shift;
|
||||
|
||||
return ((byte & mask) != 0);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
||||
dns_dbnode_t *node, unsigned int hashalg,
|
||||
|
|
@ -87,8 +64,7 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
|||
isc_result_t result;
|
||||
dns_rdataset_t rdataset;
|
||||
isc_region_t r;
|
||||
unsigned int i, window;
|
||||
int octet;
|
||||
unsigned int i;
|
||||
isc_boolean_t found;
|
||||
isc_boolean_t found_ns;
|
||||
isc_boolean_t need_rrsig;
|
||||
|
|
@ -156,7 +132,7 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
|||
rdataset.type != dns_rdatatype_rrsig) {
|
||||
if (rdataset.type > max_type)
|
||||
max_type = rdataset.type;
|
||||
set_bit(bm, rdataset.type, 1);
|
||||
dns_nsec_setbit(bm, rdataset.type, 1);
|
||||
/*
|
||||
* Work out if we need to set the RRSIG bit for
|
||||
* this node. We set the RRSIG bit if either of
|
||||
|
|
@ -179,18 +155,18 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
|||
if ((found && !found_ns) || need_rrsig) {
|
||||
if (dns_rdatatype_rrsig > max_type)
|
||||
max_type = dns_rdatatype_rrsig;
|
||||
set_bit(bm, dns_rdatatype_rrsig, 1);
|
||||
dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* At zone cuts, deny the existence of glue in the parent zone.
|
||||
*/
|
||||
if (bit_isset(bm, dns_rdatatype_ns) &&
|
||||
! bit_isset(bm, dns_rdatatype_soa)) {
|
||||
if (dns_nsec_isset(bm, dns_rdatatype_ns) &&
|
||||
! dns_nsec_isset(bm, dns_rdatatype_soa)) {
|
||||
for (i = 0; i <= max_type; i++) {
|
||||
if (bit_isset(bm, i) &&
|
||||
if (dns_nsec_isset(bm, i) &&
|
||||
! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
|
||||
set_bit(bm, i, 0);
|
||||
dns_nsec_setbit(bm, i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -199,22 +175,7 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
|||
return (result);
|
||||
|
||||
collapse_bitmap:
|
||||
for (window = 0; window < 256; window++) {
|
||||
if (window * 256 > max_type)
|
||||
break;
|
||||
for (octet = 31; octet >= 0; octet--)
|
||||
if (bm[window * 32 + octet] != 0)
|
||||
break;
|
||||
if (octet < 0)
|
||||
continue;
|
||||
nsec_bits[0] = window;
|
||||
nsec_bits[1] = octet + 1;
|
||||
/*
|
||||
* Note: potentially overlapping move.
|
||||
*/
|
||||
memmove(&nsec_bits[2], &bm[window * 32], octet + 1);
|
||||
nsec_bits += 3 + octet;
|
||||
}
|
||||
nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type);
|
||||
r.length = nsec_bits - r.base;
|
||||
INSIST(r.length <= DNS_NSEC3_BUFFERSIZE);
|
||||
dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r);
|
||||
|
|
@ -249,8 +210,8 @@ dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) {
|
|||
if ((window + 1) * 256 <= type)
|
||||
continue;
|
||||
if (type < (window * 256) + len * 8)
|
||||
present = ISC_TF(bit_isset(&nsec3.typebits[i],
|
||||
type % 256));
|
||||
present = ISC_TF(dns_nsec_isset(&nsec3.typebits[i],
|
||||
type % 256));
|
||||
break;
|
||||
}
|
||||
dns_rdata_freestruct(&nsec3);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare,
|
|||
* storage method. When the heap elements are deleted space is not freed
|
||||
* but will be reused when new elements are inserted.
|
||||
*
|
||||
* Heap elements are indexed from 1.
|
||||
*
|
||||
* Requires:
|
||||
*\li "mctx" is valid.
|
||||
*\li "compare" is a function which takes two void * arguments and
|
||||
|
|
|
|||
Loading…
Reference in a new issue