summaryrefslogtreecommitdiffstats
path: root/contrib/bind9/bin/dnssec
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/bin/dnssec')
-rw-r--r--contrib/bind9/bin/dnssec/Makefile.in26
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-dsfromkey.8124
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-dsfromkey.c396
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-dsfromkey.docbook214
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-dsfromkey.html133
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8149
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c327
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook265
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html171
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keygen.86
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keygen.c60
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keygen.docbook14
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-keygen.html14
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-signzone.819
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-signzone.c1094
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-signzone.docbook37
-rw-r--r--contrib/bind9/bin/dnssec/dnssec-signzone.html31
-rw-r--r--contrib/bind9/bin/dnssec/dnssectool.c6
-rw-r--r--contrib/bind9/bin/dnssec/dnssectool.h8
19 files changed, 2839 insertions, 255 deletions
diff --git a/contrib/bind9/bin/dnssec/Makefile.in b/contrib/bind9/bin/dnssec/Makefile.in
index b94dca7..d59a38fb 100644
--- a/contrib/bind9/bin/dnssec/Makefile.in
+++ b/contrib/bind9/bin/dnssec/Makefile.in
@@ -1,7 +1,7 @@
-# Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2002 Internet Software Consortium.
#
-# Permission to use, copy, modify, and distribute this software for any
+# 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.
#
@@ -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.26.18.4 2005/05/02 00:26:11 marka Exp $
+# $Id: Makefile.in,v 1.35 2008/11/07 02:28:49 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -39,20 +39,32 @@ DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
# Alphabetically
-TARGETS = dnssec-keygen@EXEEXT@ dnssec-signzone@EXEEXT@
+TARGETS = dnssec-keygen@EXEEXT@ dnssec-signzone@EXEEXT@ \
+ dnssec-keyfromlabel@EXEEXT@ dnssec-dsfromkey@EXEEXT@
OBJS = dnssectool.@O@
-SRCS = dnssec-keygen.c dnssec-signzone.c dnssectool.c
+SRCS = dnssec-dsfromkey.c dnssec-keyfromlabel.c dnssec-keygen.c \
+ dnssec-signzone.c dnssectool.c
-MANPAGES = dnssec-keygen.8 dnssec-signzone.8
+MANPAGES = dnssec-dsfromkey.8 dnssec-keyfromlabel.8 dnssec-keygen.8 \
+ dnssec-signzone.8
-HTMLPAGES = dnssec-keygen.html dnssec-signzone.html
+HTMLPAGES = dnssec-dsfromkey.html dnssec-keyfromlabel.html \
+ dnssec-keygen.html dnssec-signzone.html
MANOBJS = ${MANPAGES} ${HTMLPAGES}
@BIND9_MAKE_RULES@
+dnssec-dsfromkey@EXEEXT@: dnssec-dsfromkey.@O@ ${OBJS} ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ dnssec-dsfromkey.@O@ ${OBJS} ${LIBS}
+
+dnssec-keyfromlabel@EXEEXT@: dnssec-keyfromlabel.@O@ ${OBJS} ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ dnssec-keyfromlabel.@O@ ${OBJS} ${LIBS}
+
dnssec-keygen@EXEEXT@: dnssec-keygen.@O@ ${OBJS} ${DEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
dnssec-keygen.@O@ ${OBJS} ${LIBS}
diff --git a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.8 b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.8
new file mode 100644
index 0000000..4d4cbc9
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.8
@@ -0,0 +1,124 @@
+.\" Copyright (C) 2008 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: dnssec-dsfromkey.8,v 1.5 2008/11/08 01:11:47 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: dnssec\-dsfromkey
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\" Date: November 29, 2008
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "DNSSEC\-DSFROMKEY" "8" "November 29, 2008" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+dnssec\-dsfromkey \- DNSSEC DS RR generation tool
+.SH "SYNOPSIS"
+.HP 17
+\fBdnssec\-dsfromkey\fR [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-1\fR] [\fB\-2\fR] [\fB\-a\ \fR\fB\fIalg\fR\fR] {keyfile}
+.HP 17
+\fBdnssec\-dsfromkey\fR {\-s} [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-1\fR] [\fB\-2\fR] [\fB\-a\ \fR\fB\fIalg\fR\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdir\fR\fR] {dnsname}
+.SH "DESCRIPTION"
+.PP
+\fBdnssec\-dsfromkey\fR
+outputs the Delegation Signer (DS) resource record (RR), as defined in RFC 3658 and RFC 4509, for the given key(s).
+.SH "OPTIONS"
+.PP
+\-1
+.RS 4
+Use SHA\-1 as the digest algorithm (the default is to use both SHA\-1 and SHA\-256).
+.RE
+.PP
+\-2
+.RS 4
+Use SHA\-256 as the digest algorithm.
+.RE
+.PP
+\-a \fIalgorithm\fR
+.RS 4
+Select the digest algorithm. The value of
+\fBalgorithm\fR
+must be one of SHA\-1 (SHA1) or SHA\-256 (SHA256). These values are case insensitive.
+.RE
+.PP
+\-v \fIlevel\fR
+.RS 4
+Sets the debugging level.
+.RE
+.PP
+\-s
+.RS 4
+Keyset mode: in place of the keyfile name, the argument is the DNS domain name of a keyset file. Following options make sense only in this mode.
+.RE
+.PP
+\-c \fIclass\fR
+.RS 4
+Specifies the DNS class (default is IN), useful only in the keyset mode.
+.RE
+.PP
+\-d \fIdirectory\fR
+.RS 4
+Look for
+\fIkeyset\fR
+files in
+\fBdirectory\fR
+as the directory, ignored when not in the keyset mode.
+.RE
+.SH "EXAMPLE"
+.PP
+To build the SHA\-256 DS RR from the
+\fBKexample.com.+003+26160\fR
+keyfile name, the following command would be issued:
+.PP
+\fBdnssec\-dsfromkey \-2 Kexample.com.+003+26160\fR
+.PP
+The command would print something like:
+.PP
+\fBexample.com. IN DS 26160 5 2 3A1EADA7A74B8D0BA86726B0C227AA85AB8BBD2B2004F41A868A54F0 C5EA0B94\fR
+.SH "FILES"
+.PP
+The keyfile can be designed by the key identification
+\fIKnnnn.+aaa+iiiii\fR
+or the full file name
+\fIKnnnn.+aaa+iiiii.key\fR
+as generated by
+dnssec\-keygen(8).
+.PP
+The keyset file name is built from the
+\fBdirectory\fR, the string
+\fIkeyset\-\fR
+and the
+\fBdnsname\fR.
+.SH "CAVEAT"
+.PP
+A keyfile error can give a "file not found" even if the file exists.
+.SH "SEE ALSO"
+.PP
+\fBdnssec\-keygen\fR(8),
+\fBdnssec\-signzone\fR(8),
+BIND 9 Administrator Reference Manual,
+RFC 3658,
+RFC 4509.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2008 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c
new file mode 100644
index 0000000..653aa3e
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2008, 2009 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: dnssec-dsfromkey.c,v 1.2.14.3 2009/03/02 02:54:15 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <isc/buffer.h>
+#include <isc/commandline.h>
+#include <isc/entropy.h>
+#include <isc/hash.h>
+#include <isc/mem.h>
+#include <isc/print.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <dns/db.h>
+#include <dns/dbiterator.h>
+#include <dns/ds.h>
+#include <dns/fixedname.h>
+#include <dns/log.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
+#include <dns/rdataset.h>
+#include <dns/rdatasetiter.h>
+#include <dns/rdatatype.h>
+#include <dns/result.h>
+
+#include <dst/dst.h>
+
+#include "dnssectool.h"
+
+const char *program = "dnssec-dsfromkey";
+int verbose;
+
+static dns_rdataclass_t rdclass;
+static dns_fixedname_t fixed;
+static dns_name_t *name = NULL;
+static dns_db_t *db = NULL;
+static dns_dbnode_t *node = NULL;
+static dns_rdataset_t keyset;
+static isc_mem_t *mctx = NULL;
+
+static void
+loadkeys(char *dirname, char *setname)
+{
+ isc_result_t result;
+ char filename[1024];
+ isc_buffer_t buf;
+
+ dns_rdataset_init(&keyset);
+ dns_fixedname_init(&fixed);
+ name = dns_fixedname_name(&fixed);
+
+ isc_buffer_init(&buf, setname, strlen(setname));
+ isc_buffer_add(&buf, strlen(setname));
+ result = dns_name_fromtext(name, &buf, dns_rootname, ISC_FALSE, NULL);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't convert DNS name %s", setname);
+
+ isc_buffer_init(&buf, filename, sizeof(filename));
+ if (dirname != NULL) {
+ isc_buffer_putstr(&buf, dirname);
+ if (dirname[strlen(dirname) - 1] != '/')
+ isc_buffer_putstr(&buf, "/");
+ }
+ isc_buffer_putstr(&buf, "keyset-");
+ result = dns_name_tofilenametext(name, ISC_FALSE, &buf);
+ check_result(result, "dns_name_tofilenametext()");
+ if (isc_buffer_availablelength(&buf) == 0)
+ fatal("name %s too long", setname);
+ isc_buffer_putuint8(&buf, 0);
+
+ result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone,
+ rdclass, 0, NULL, &db);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't create database");
+
+ result = dns_db_load(db, filename);
+ if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE)
+ fatal("can't load %s: %s", filename, isc_result_totext(result));
+
+ result = dns_db_findnode(db, name, ISC_FALSE, &node);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't find %s node in %s", setname, filename);
+
+ result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey,
+ 0, 0, &keyset, NULL);
+ if (result == ISC_R_NOTFOUND)
+ fatal("no DNSKEY RR for %s in %s", setname, filename);
+ else if (result != ISC_R_SUCCESS)
+ fatal("dns_db_findrdataset");
+}
+
+static void
+loadkey(char *filename, unsigned char *key_buf, unsigned int key_buf_size,
+ dns_rdata_t *rdata)
+{
+ isc_result_t result;
+ dst_key_t *key = NULL;
+ isc_buffer_t keyb;
+ isc_region_t r;
+
+ dns_rdataset_init(&keyset);
+ dns_rdata_init(rdata);
+
+ isc_buffer_init(&keyb, key_buf, key_buf_size);
+
+ result = dst_key_fromnamedfile(filename, DST_TYPE_PUBLIC, mctx, &key);
+ if (result != ISC_R_SUCCESS)
+ fatal("invalid keyfile name %s: %s",
+ filename, isc_result_totext(result));
+
+ if (verbose > 2) {
+ char keystr[KEY_FORMATSIZE];
+
+ key_format(key, keystr, sizeof(keystr));
+ fprintf(stderr, "%s: %s\n", program, keystr);
+ }
+
+ result = dst_key_todns(key, &keyb);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't decode key");
+
+ isc_buffer_usedregion(&keyb, &r);
+ dns_rdata_fromregion(rdata, dst_key_class(key),
+ dns_rdatatype_dnskey, &r);
+
+ rdclass = dst_key_class(key);
+
+ dns_fixedname_init(&fixed);
+ name = dns_fixedname_name(&fixed);
+ result = dns_name_copy(dst_key_name(key), name, NULL);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't copy name");
+
+ dst_key_free(&key);
+}
+
+static void
+logkey(dns_rdata_t *rdata)
+{
+ isc_result_t result;
+ dst_key_t *key = NULL;
+ isc_buffer_t buf;
+ char keystr[KEY_FORMATSIZE];
+
+ isc_buffer_init(&buf, rdata->data, rdata->length);
+ isc_buffer_add(&buf, rdata->length);
+ result = dst_key_fromdns(name, rdclass, &buf, mctx, &key);
+ if (result != ISC_R_SUCCESS)
+ return;
+
+ key_format(key, keystr, sizeof(keystr));
+ fprintf(stderr, "%s: %s\n", program, keystr);
+
+ dst_key_free(&key);
+}
+
+static void
+emitds(unsigned int dtype, dns_rdata_t *rdata)
+{
+ isc_result_t result;
+ unsigned char buf[DNS_DS_BUFFERSIZE];
+ char text_buf[DST_KEY_MAXTEXTSIZE];
+ char class_buf[10];
+ isc_buffer_t textb, classb;
+ isc_region_t r;
+ dns_rdata_t ds;
+
+ isc_buffer_init(&textb, text_buf, sizeof(text_buf));
+ isc_buffer_init(&classb, class_buf, sizeof(class_buf));
+
+ dns_rdata_init(&ds);
+
+ result = dns_ds_buildrdata(name, rdata, dtype, buf, &ds);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't build DS");
+
+ result = dns_rdata_totext(&ds, (dns_name_t *) NULL, &textb);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't print DS rdata");
+
+ result = dns_rdataclass_totext(rdclass, &classb);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't print DS class");
+
+ result = dns_name_print(name, stdout);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't print DS name");
+
+ putchar(' ');
+
+ isc_buffer_usedregion(&classb, &r);
+ fwrite(r.base, 1, r.length, stdout);
+
+ printf(" DS ");
+
+ isc_buffer_usedregion(&textb, &r);
+ fwrite(r.base, 1, r.length, stdout);
+ putchar('\n');
+}
+
+static void
+usage(void) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s options keyfile\n\n", program);
+ fprintf(stderr, " %s options [-c class] [-d dir] -s dnsname\n\n",
+ program);
+ fprintf(stderr, "Version: %s\n", VERSION);
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -v <verbose level>\n");
+ fprintf(stderr, " -1: use SHA-1\n");
+ fprintf(stderr, " -2: use SHA-256\n");
+ fprintf(stderr, " -a algorithm: use algorithm\n");
+ fprintf(stderr, "Keyset options:\n");
+ fprintf(stderr, " -s: keyset mode\n");
+ fprintf(stderr, " -c class\n");
+ fprintf(stderr, " -d directory\n");
+ fprintf(stderr, "Output: DS RRs\n");
+
+ exit (-1);
+}
+
+int
+main(int argc, char **argv) {
+ char *algname = NULL, *classname = NULL, *dirname = NULL;
+ char *endp;
+ int ch;
+ unsigned int dtype = DNS_DSDIGEST_SHA1;
+ isc_boolean_t both = ISC_TRUE;
+ isc_boolean_t usekeyset = ISC_FALSE;
+ isc_result_t result;
+ isc_log_t *log = NULL;
+ isc_entropy_t *ectx = NULL;
+ dns_rdata_t rdata;
+
+ dns_rdata_init(&rdata);
+
+ if (argc == 1)
+ usage();
+
+ 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,
+ "12a:c:d:sv:h")) != -1) {
+ switch (ch) {
+ case '1':
+ dtype = DNS_DSDIGEST_SHA1;
+ both = ISC_FALSE;
+ break;
+ case '2':
+ dtype = DNS_DSDIGEST_SHA256;
+ both = ISC_FALSE;
+ break;
+ case 'a':
+ algname = isc_commandline_argument;
+ both = ISC_FALSE;
+ break;
+ case 'c':
+ classname = isc_commandline_argument;
+ break;
+ case 'd':
+ dirname = isc_commandline_argument;
+ break;
+ case 's':
+ usekeyset = ISC_TRUE;
+ break;
+ case 'v':
+ verbose = strtol(isc_commandline_argument, &endp, 0);
+ if (*endp != '\0')
+ fatal("-v must be followed by a number");
+ break;
+ case '?':
+ if (isc_commandline_option != '?')
+ fprintf(stderr, "%s: invalid argument -%c\n",
+ program, isc_commandline_option);
+ /* Falls into */
+ case 'h':
+ usage();
+
+ default:
+ fprintf(stderr, "%s: unhandled option -%c\n",
+ program, isc_commandline_option);
+ exit(1);
+ }
+ }
+
+ if (algname != NULL) {
+ if (strcasecmp(algname, "SHA1") == 0 ||
+ strcasecmp(algname, "SHA-1") == 0)
+ dtype = DNS_DSDIGEST_SHA1;
+ else if (strcasecmp(algname, "SHA256") == 0 ||
+ strcasecmp(algname, "SHA-256") == 0)
+ dtype = DNS_DSDIGEST_SHA256;
+ else
+ fatal("unknown algorithm %s", algname);
+ }
+
+ rdclass = strtoclass(classname);
+
+ if (argc < isc_commandline_index + 1)
+ fatal("the key file name was not specified");
+ if (argc > isc_commandline_index + 1)
+ fatal("extraneous arguments");
+
+ 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 initialize hash");
+ result = dst_lib_init(mctx, ectx,
+ ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
+ if (result != ISC_R_SUCCESS)
+ fatal("could not initialize dst");
+ isc_entropy_stopcallbacksources(ectx);
+
+ setup_logging(verbose, mctx, &log);
+
+ if (usekeyset) {
+ loadkeys(dirname, argv[isc_commandline_index]);
+
+ for (result = dns_rdataset_first(&keyset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&keyset)) {
+ dns_rdata_init(&rdata);
+ dns_rdataset_current(&keyset, &rdata);
+
+ if (verbose > 2)
+ logkey(&rdata);
+
+ if (both) {
+ emitds(DNS_DSDIGEST_SHA1, &rdata);
+ emitds(DNS_DSDIGEST_SHA256, &rdata);
+ } else
+ emitds(dtype, &rdata);
+ }
+ } else {
+ unsigned char key_buf[DST_KEY_MAXSIZE];
+
+ loadkey(argv[isc_commandline_index], key_buf,
+ DST_KEY_MAXSIZE, &rdata);
+
+ if (both) {
+ emitds(DNS_DSDIGEST_SHA1, &rdata);
+ emitds(DNS_DSDIGEST_SHA256, &rdata);
+ } else
+ emitds(dtype, &rdata);
+ }
+
+ if (dns_rdataset_isassociated(&keyset))
+ dns_rdataset_disassociate(&keyset);
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ if (db != NULL)
+ dns_db_detach(&db);
+ 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);
+
+ fflush(stdout);
+ if (ferror(stdout)) {
+ fprintf(stderr, "write error\n");
+ return (1);
+ } else
+ return (0);
+}
diff --git a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.docbook b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.docbook
new file mode 100644
index 0000000..c2c6b85
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.docbook
@@ -0,0 +1,214 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+ [<!ENTITY mdash "&#8212;">]>
+<!--
+ - Copyright (C) 2008 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: dnssec-dsfromkey.docbook,v 1.6 2008/11/07 13:54:11 jreed Exp $ -->
+<refentry id="man.dnssec-dsfromkey">
+ <refentryinfo>
+ <date>November 29, 2008</date>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle><application>dnssec-dsfromkey</application></refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo>BIND9</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname><application>dnssec-dsfromkey</application></refname>
+ <refpurpose>DNSSEC DS RR generation tool</refpurpose>
+ </refnamediv>
+
+ <docinfo>
+ <copyright>
+ <year>2008</year>
+ <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+ </copyright>
+ </docinfo>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>dnssec-dsfromkey</command>
+ <arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
+ <arg><option>-1</option></arg>
+ <arg><option>-2</option></arg>
+ <arg><option>-a <replaceable class="parameter">alg</replaceable></option></arg>
+ <arg choice="req">keyfile</arg>
+ </cmdsynopsis>
+ <cmdsynopsis>
+ <command>dnssec-dsfromkey</command>
+ <arg choice="req">-s</arg>
+ <arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
+ <arg><option>-1</option></arg>
+ <arg><option>-2</option></arg>
+ <arg><option>-a <replaceable class="parameter">alg</replaceable></option></arg>
+ <arg><option>-c <replaceable class="parameter">class</replaceable></option></arg>
+ <arg><option>-d <replaceable class="parameter">dir</replaceable></option></arg>
+ <arg choice="req">dnsname</arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para><command>dnssec-dsfromkey</command>
+ outputs the Delegation Signer (DS) resource record (RR), as defined in
+ RFC 3658 and RFC 4509, for the given key(s).
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-1</term>
+ <listitem>
+ <para>
+ Use SHA-1 as the digest algorithm (the default is to use
+ both SHA-1 and SHA-256).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-2</term>
+ <listitem>
+ <para>
+ Use SHA-256 as the digest algorithm.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-a <replaceable class="parameter">algorithm</replaceable></term>
+ <listitem>
+ <para>
+ Select the digest algorithm. The value of
+ <option>algorithm</option> must be one of SHA-1 (SHA1) or
+ SHA-256 (SHA256). These values are case insensitive.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-v <replaceable class="parameter">level</replaceable></term>
+ <listitem>
+ <para>
+ Sets the debugging level.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-s</term>
+ <listitem>
+ <para>
+ Keyset mode: in place of the keyfile name, the argument is
+ the DNS domain name of a keyset file. Following options make sense
+ only in this mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-c <replaceable class="parameter">class</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the DNS class (default is IN), useful only
+ in the keyset mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-d <replaceable class="parameter">directory</replaceable></term>
+ <listitem>
+ <para>
+ Look for <filename>keyset</filename> files in
+ <option>directory</option> as the directory, ignored when
+ not in the keyset mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>EXAMPLE</title>
+ <para>
+ To build the SHA-256 DS RR from the
+ <userinput>Kexample.com.+003+26160</userinput>
+ keyfile name, the following command would be issued:
+ </para>
+ <para><userinput>dnssec-dsfromkey -2 Kexample.com.+003+26160</userinput>
+ </para>
+ <para>
+ The command would print something like:
+ </para>
+ <para><userinput>example.com. IN DS 26160 5 2 3A1EADA7A74B8D0BA86726B0C227AA85AB8BBD2B2004F41A868A54F0 C5EA0B94</userinput>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>FILES</title>
+ <para>
+ The keyfile can be designed by the key identification
+ <filename>Knnnn.+aaa+iiiii</filename> or the full file name
+ <filename>Knnnn.+aaa+iiiii.key</filename> as generated by
+ <refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum>.
+ </para>
+ <para>
+ The keyset file name is built from the <option>directory</option>,
+ the string <filename>keyset-</filename> and the
+ <option>dnsname</option>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>CAVEAT</title>
+ <para>
+ A keyfile error can give a "file not found" even if the file exists.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para><citerefentry>
+ <refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>dnssec-signzone</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citetitle>BIND 9 Administrator Reference Manual</citetitle>,
+ <citetitle>RFC 3658</citetitle>,
+ <citetitle>RFC 4509</citetitle>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>AUTHOR</title>
+ <para><corpauthor>Internet Systems Consortium</corpauthor>
+ </para>
+ </refsect1>
+
+</refentry><!--
+ - Local variables:
+ - mode: sgml
+ - End:
+-->
diff --git a/contrib/bind9/bin/dnssec/dnssec-dsfromkey.html b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.html
new file mode 100644
index 0000000..72dfd3a
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-dsfromkey.html
@@ -0,0 +1,133 @@
+<!--
+ - Copyright (C) 2008 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: dnssec-dsfromkey.html,v 1.5 2008/11/08 01:11:47 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>dnssec-dsfromkey</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-dsfromkey"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">dnssec-dsfromkey</span> &#8212; DNSSEC DS RR generation tool</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] {keyfile}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> {-s} [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>dir</code></em></code>] {dnsname}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543424"></a><h2>DESCRIPTION</h2>
+<p><span><strong class="command">dnssec-dsfromkey</strong></span>
+ outputs the Delegation Signer (DS) resource record (RR), as defined in
+ RFC 3658 and RFC 4509, for the given key(s).
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543435"></a><h2>OPTIONS</h2>
+<div class="variablelist"><dl>
+<dt><span class="term">-1</span></dt>
+<dd><p>
+ Use SHA-1 as the digest algorithm (the default is to use
+ both SHA-1 and SHA-256).
+ </p></dd>
+<dt><span class="term">-2</span></dt>
+<dd><p>
+ Use SHA-256 as the digest algorithm.
+ </p></dd>
+<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
+<dd><p>
+ Select the digest algorithm. The value of
+ <code class="option">algorithm</code> must be one of SHA-1 (SHA1) or
+ SHA-256 (SHA256). These values are case insensitive.
+ </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">-s</span></dt>
+<dd><p>
+ Keyset mode: in place of the keyfile name, the argument is
+ the DNS domain name of a keyset file. Following options make sense
+ only in this mode.
+ </p></dd>
+<dt><span class="term">-c <em class="replaceable"><code>class</code></em></span></dt>
+<dd><p>
+ Specifies the DNS class (default is IN), useful only
+ in the keyset mode.
+ </p></dd>
+<dt><span class="term">-d <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Look for <code class="filename">keyset</code> files in
+ <code class="option">directory</code> as the directory, ignored when
+ not in the keyset mode.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543563"></a><h2>EXAMPLE</h2>
+<p>
+ To build the SHA-256 DS RR from the
+ <strong class="userinput"><code>Kexample.com.+003+26160</code></strong>
+ keyfile name, the following command would be issued:
+ </p>
+<p><strong class="userinput"><code>dnssec-dsfromkey -2 Kexample.com.+003+26160</code></strong>
+ </p>
+<p>
+ The command would print something like:
+ </p>
+<p><strong class="userinput"><code>example.com. IN DS 26160 5 2 3A1EADA7A74B8D0BA86726B0C227AA85AB8BBD2B2004F41A868A54F0 C5EA0B94</code></strong>
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543593"></a><h2>FILES</h2>
+<p>
+ The keyfile can be designed by the key identification
+ <code class="filename">Knnnn.+aaa+iiiii</code> or the full file name
+ <code class="filename">Knnnn.+aaa+iiiii.key</code> as generated by
+ <span class="refentrytitle">dnssec-keygen</span>(8).
+ </p>
+<p>
+ The keyset file name is built from the <code class="option">directory</code>,
+ the string <code class="filename">keyset-</code> and the
+ <code class="option">dnsname</code>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543628"></a><h2>CAVEAT</h2>
+<p>
+ A keyfile error can give a "file not found" even if the file exists.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543638"></a><h2>SEE ALSO</h2>
+<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
+ <span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>,
+ <em class="citetitle">RFC 3658</em>,
+ <em class="citetitle">RFC 4509</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543674"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div></body>
+</html>
diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8 b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8
new file mode 100644
index 0000000..6222058
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.8
@@ -0,0 +1,149 @@
+.\" Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND 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-keyfromlabel.8,v 1.6 2008/11/08 01:11:47 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: dnssec\-keyfromlabel
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\" Date: February 8, 2008
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "DNSSEC\-KEYFROMLABEL" "8" "February 8, 2008" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+dnssec\-keyfromlabel \- DNSSEC key generation tool
+.SH "SYNOPSIS"
+.HP 20
+\fBdnssec\-keyfromlabel\fR {\-a\ \fIalgorithm\fR} {\-l\ \fIlabel\fR} [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-k\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {name}
+.SH "DESCRIPTION"
+.PP
+\fBdnssec\-keyfromlabel\fR
+gets keys with the given label from a crypto hardware and builds key files for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034.
+.SH "OPTIONS"
+.PP
+\-a \fIalgorithm\fR
+.RS 4
+Selects the cryptographic algorithm. The value of
+\fBalgorithm\fR
+must be one of RSAMD5 (RSA) or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman). These values are case insensitive.
+.sp
+Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended.
+.sp
+Note 2: DH automatically sets the \-k flag.
+.RE
+.PP
+\-l \fIlabel\fR
+.RS 4
+Specifies the label of keys in the crypto hardware (PKCS#11 device).
+.RE
+.PP
+\-n \fInametype\fR
+.RS 4
+Specifies the owner type of the key. The value of
+\fBnametype\fR
+must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive.
+.RE
+.PP
+\-c \fIclass\fR
+.RS 4
+Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used.
+.RE
+.PP
+\-f \fIflag\fR
+.RS 4
+Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flag is KSK (Key Signing Key) DNSKEY.
+.RE
+.PP
+\-h
+.RS 4
+Prints a short summary of the options and arguments to
+\fBdnssec\-keygen\fR.
+.RE
+.PP
+\-k
+.RS 4
+Generate KEY records rather than DNSKEY records.
+.RE
+.PP
+\-p \fIprotocol\fR
+.RS 4
+Sets the protocol value for the generated key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors.
+.RE
+.PP
+\-t \fItype\fR
+.RS 4
+Indicates the use of the key.
+\fBtype\fR
+must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF. AUTH refers to the ability to authenticate data, and CONF the ability to encrypt data.
+.RE
+.PP
+\-v \fIlevel\fR
+.RS 4
+Sets the debugging level.
+.RE
+.SH "GENERATED KEY FILES"
+.PP
+When
+\fBdnssec\-keyfromlabel\fR
+completes successfully, it prints a string of the form
+\fIKnnnn.+aaa+iiiii\fR
+to the standard output. This is an identification string for the key files it has generated.
+.TP 4
+\(bu
+\fInnnn\fR
+is the key name.
+.TP 4
+\(bu
+\fIaaa\fR
+is the numeric representation of the algorithm.
+.TP 4
+\(bu
+\fIiiiii\fR
+is the key identifier (or footprint).
+.PP
+\fBdnssec\-keyfromlabel\fR
+creates two files, with names based on the printed string.
+\fIKnnnn.+aaa+iiiii.key\fR
+contains the public key, and
+\fIKnnnn.+aaa+iiiii.private\fR
+contains the private key.
+.PP
+The
+\fI.key\fR
+file contains a DNS KEY record that can be inserted into a zone file (directly or with a $INCLUDE statement).
+.PP
+The
+\fI.private\fR
+file contains algorithm specific fields. For obvious security reasons, this file does not have general read permission.
+.SH "SEE ALSO"
+.PP
+\fBdnssec\-keygen\fR(8),
+\fBdnssec\-signzone\fR(8),
+BIND 9 Administrator Reference Manual,
+RFC 2539,
+RFC 2845,
+RFC 4033.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2008 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c
new file mode 100644
index 0000000..e7587c3
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2007, 2008 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: dnssec-keyfromlabel.c,v 1.4 2008/09/24 02:46:21 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <isc/buffer.h>
+#include <isc/commandline.h>
+#include <isc/entropy.h>
+#include <isc/mem.h>
+#include <isc/region.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <dns/fixedname.h>
+#include <dns/keyvalues.h>
+#include <dns/log.h>
+#include <dns/name.h>
+#include <dns/rdataclass.h>
+#include <dns/result.h>
+#include <dns/secalg.h>
+
+#include <dst/dst.h>
+
+#include "dnssectool.h"
+
+#define MAX_RSA 4096 /* should be long enough... */
+
+const char *program = "dnssec-keyfromlabel";
+int verbose;
+
+static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 |"
+ " NSEC3DSA | NSEC3RSASHA1";
+
+static void
+usage(void) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s -a alg -l label [options] name\n\n",
+ program);
+ fprintf(stderr, "Version: %s\n", VERSION);
+ fprintf(stderr, "Required options:\n");
+ fprintf(stderr, " -a algorithm: %s\n", algs);
+ fprintf(stderr, " -l label: label of the key\n");
+ fprintf(stderr, " name: owner of the key\n");
+ fprintf(stderr, "Other options:\n");
+ fprintf(stderr, " -n nametype: ZONE | HOST | ENTITY | USER | OTHER\n");
+ fprintf(stderr, " (DNSKEY generation defaults to ZONE\n");
+ fprintf(stderr, " -c <class> (default: IN)\n");
+ fprintf(stderr, " -f keyflag: KSK\n");
+ fprintf(stderr, " -t <type>: "
+ "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF "
+ "(default: AUTHCONF)\n");
+ fprintf(stderr, " -p <protocol>: "
+ "default: 3 [dnssec]\n");
+ fprintf(stderr, " -v <verbose level>\n");
+ fprintf(stderr, " -k : generate a TYPE=KEY key\n");
+ fprintf(stderr, "Output:\n");
+ fprintf(stderr, " K<name>+<alg>+<id>.key, "
+ "K<name>+<alg>+<id>.private\n");
+
+ exit (-1);
+}
+
+int
+main(int argc, char **argv) {
+ char *algname = NULL, *nametype = NULL, *type = NULL;
+ char *classname = NULL;
+ char *endp;
+ dst_key_t *key = NULL, *oldkey;
+ dns_fixedname_t fname;
+ dns_name_t *name;
+ isc_uint16_t flags = 0, ksk = 0;
+ dns_secalg_t alg;
+ isc_boolean_t null_key = ISC_FALSE;
+ isc_mem_t *mctx = NULL;
+ int ch;
+ int protocol = -1, signatory = 0;
+ isc_result_t ret;
+ isc_textregion_t r;
+ char filename[255];
+ isc_buffer_t buf;
+ isc_log_t *log = NULL;
+ isc_entropy_t *ectx = NULL;
+ dns_rdataclass_t rdclass;
+ int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC;
+ char *label = NULL;
+
+ if (argc == 1)
+ usage();
+
+ RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
+
+ dns_result_register();
+
+ isc_commandline_errprint = ISC_FALSE;
+
+ while ((ch = isc_commandline_parse(argc, argv,
+ "a:c:f:kl:n:p:t:v:h")) != -1)
+ {
+ switch (ch) {
+ case 'a':
+ algname = isc_commandline_argument;
+ break;
+ case 'c':
+ classname = isc_commandline_argument;
+ break;
+ case 'f':
+ if (strcasecmp(isc_commandline_argument, "KSK") == 0)
+ ksk = DNS_KEYFLAG_KSK;
+ else
+ fatal("unknown flag '%s'",
+ isc_commandline_argument);
+ break;
+ case 'k':
+ options |= DST_TYPE_KEY;
+ break;
+ case 'l':
+ label = isc_commandline_argument;
+ break;
+ case 'n':
+ nametype = isc_commandline_argument;
+ break;
+ case 'p':
+ protocol = strtol(isc_commandline_argument, &endp, 10);
+ if (*endp != '\0' || protocol < 0 || protocol > 255)
+ fatal("-p must be followed by a number "
+ "[0..255]");
+ break;
+ case 't':
+ type = isc_commandline_argument;
+ break;
+ case 'v':
+ verbose = strtol(isc_commandline_argument, &endp, 0);
+ if (*endp != '\0')
+ fatal("-v must be followed by a number");
+ break;
+
+ case '?':
+ if (isc_commandline_option != '?')
+ fprintf(stderr, "%s: invalid argument -%c\n",
+ program, isc_commandline_option);
+ case 'h':
+ usage();
+
+ default:
+ fprintf(stderr, "%s: unhandled option -%c\n",
+ program, isc_commandline_option);
+ exit(1);
+ }
+ }
+
+ if (ectx == NULL)
+ setup_entropy(mctx, NULL, &ectx);
+ ret = dst_lib_init(mctx, ectx,
+ ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
+ if (ret != ISC_R_SUCCESS)
+ fatal("could not initialize dst");
+
+ setup_logging(verbose, mctx, &log);
+
+ if (label == NULL)
+ fatal("the key label was not specified");
+ if (argc < isc_commandline_index + 1)
+ fatal("the key name was not specified");
+ if (argc > isc_commandline_index + 1)
+ fatal("extraneous arguments");
+
+ if (algname == NULL)
+ fatal("no algorithm was specified");
+ if (strcasecmp(algname, "RSA") == 0) {
+ fprintf(stderr, "The use of RSA (RSAMD5) is not recommended.\n"
+ "If you still wish to use RSA (RSAMD5) please "
+ "specify \"-a RSAMD5\"\n");
+ return (1);
+ } else {
+ r.base = algname;
+ r.length = strlen(algname);
+ ret = dns_secalg_fromtext(&alg, &r);
+ if (ret != ISC_R_SUCCESS)
+ fatal("unknown algorithm %s", algname);
+ if (alg == DST_ALG_DH)
+ options |= DST_TYPE_KEY;
+ }
+
+ if (type != NULL && (options & DST_TYPE_KEY) != 0) {
+ if (strcasecmp(type, "NOAUTH") == 0)
+ flags |= DNS_KEYTYPE_NOAUTH;
+ else if (strcasecmp(type, "NOCONF") == 0)
+ flags |= DNS_KEYTYPE_NOCONF;
+ else if (strcasecmp(type, "NOAUTHCONF") == 0) {
+ flags |= (DNS_KEYTYPE_NOAUTH | DNS_KEYTYPE_NOCONF);
+ }
+ else if (strcasecmp(type, "AUTHCONF") == 0)
+ /* nothing */;
+ else
+ fatal("invalid type %s", type);
+ }
+
+ if (nametype == NULL) {
+ if ((options & DST_TYPE_KEY) != 0) /* KEY */
+ fatal("no nametype specified");
+ flags |= DNS_KEYOWNER_ZONE; /* DNSKEY */
+ } else if (strcasecmp(nametype, "zone") == 0)
+ flags |= DNS_KEYOWNER_ZONE;
+ else if ((options & DST_TYPE_KEY) != 0) { /* KEY */
+ if (strcasecmp(nametype, "host") == 0 ||
+ strcasecmp(nametype, "entity") == 0)
+ flags |= DNS_KEYOWNER_ENTITY;
+ else if (strcasecmp(nametype, "user") == 0)
+ flags |= DNS_KEYOWNER_USER;
+ else
+ fatal("invalid KEY nametype %s", nametype);
+ } else if (strcasecmp(nametype, "other") != 0) /* DNSKEY */
+ fatal("invalid DNSKEY nametype %s", nametype);
+
+ rdclass = strtoclass(classname);
+
+ if ((options & DST_TYPE_KEY) != 0) /* KEY */
+ flags |= signatory;
+ else if ((flags & DNS_KEYOWNER_ZONE) != 0) /* DNSKEY */
+ flags |= ksk;
+
+ if (protocol == -1)
+ protocol = DNS_KEYPROTO_DNSSEC;
+ else if ((options & DST_TYPE_KEY) == 0 &&
+ protocol != DNS_KEYPROTO_DNSSEC)
+ fatal("invalid DNSKEY protocol: %d", protocol);
+
+ if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) {
+ if ((flags & DNS_KEYFLAG_SIGNATORYMASK) != 0)
+ fatal("specified null key with signing authority");
+ }
+
+ if ((flags & DNS_KEYFLAG_OWNERMASK) == DNS_KEYOWNER_ZONE &&
+ alg == DNS_KEYALG_DH)
+ fatal("a key with algorithm '%s' cannot be a zone key",
+ algname);
+
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ isc_buffer_init(&buf, argv[isc_commandline_index],
+ strlen(argv[isc_commandline_index]));
+ isc_buffer_add(&buf, strlen(argv[isc_commandline_index]));
+ ret = dns_name_fromtext(name, &buf, dns_rootname, ISC_FALSE, NULL);
+ if (ret != ISC_R_SUCCESS)
+ fatal("invalid key name %s: %s", argv[isc_commandline_index],
+ isc_result_totext(ret));
+
+ if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY)
+ null_key = ISC_TRUE;
+
+ isc_buffer_init(&buf, filename, sizeof(filename) - 1);
+
+ /* associate the key */
+ ret = dst_key_fromlabel(name, alg, flags, protocol,
+ rdclass, "", label, NULL, mctx, &key);
+ isc_entropy_stopcallbacksources(ectx);
+
+ if (ret != ISC_R_SUCCESS) {
+ char namestr[DNS_NAME_FORMATSIZE];
+ char algstr[ALG_FORMATSIZE];
+ dns_name_format(name, namestr, sizeof(namestr));
+ alg_format(alg, algstr, sizeof(algstr));
+ fatal("failed to generate key %s/%s: %s\n",
+ namestr, algstr, isc_result_totext(ret));
+ exit(-1);
+ }
+
+ /*
+ * Try to read a key with the same name, alg and id from disk.
+ * If there is one we must continue generating a new one
+ * unless we were asked to generate a null key, in which
+ * case we return failure.
+ */
+ ret = dst_key_fromfile(name, dst_key_id(key), alg,
+ DST_TYPE_PRIVATE, NULL, mctx, &oldkey);
+ /* do not overwrite an existing key */
+ if (ret == ISC_R_SUCCESS) {
+ isc_buffer_clear(&buf);
+ ret = dst_key_buildfilename(key, 0, NULL, &buf);
+ fprintf(stderr, "%s: %s already exists\n",
+ program, filename);
+ dst_key_free(&key);
+ exit (1);
+ }
+
+ ret = dst_key_tofile(key, options, NULL);
+ if (ret != ISC_R_SUCCESS) {
+ char keystr[KEY_FORMATSIZE];
+ key_format(key, keystr, sizeof(keystr));
+ fatal("failed to write key %s: %s\n", keystr,
+ isc_result_totext(ret));
+ }
+
+ isc_buffer_clear(&buf);
+ ret = dst_key_buildfilename(key, 0, NULL, &buf);
+ printf("%s\n", filename);
+ dst_key_free(&key);
+
+ cleanup_logging(&log);
+ cleanup_entropy(&ectx);
+ dst_lib_destroy();
+ dns_name_destroy();
+ if (verbose > 10)
+ isc_mem_stats(mctx, stdout);
+ isc_mem_destroy(&mctx);
+
+ return (0);
+}
diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook
new file mode 100644
index 0000000..2bcf0a4
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.docbook
@@ -0,0 +1,265 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+ [<!ENTITY mdash "&#8212;">]>
+<!--
+ - Copyright (C) 2008 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: dnssec-keyfromlabel.docbook,v 1.6 2008/11/07 13:54:11 jreed Exp $ -->
+<refentry id="man.dnssec-keyfromlabel">
+ <refentryinfo>
+ <date>February 8, 2008</date>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle><application>dnssec-keyfromlabel</application></refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo>BIND9</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname><application>dnssec-keyfromlabel</application></refname>
+ <refpurpose>DNSSEC key generation tool</refpurpose>
+ </refnamediv>
+
+ <docinfo>
+ <copyright>
+ <year>2008</year>
+ <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+ </copyright>
+ </docinfo>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>dnssec-keyfromlabel</command>
+ <arg choice="req">-a <replaceable class="parameter">algorithm</replaceable></arg>
+ <arg choice="req">-l <replaceable class="parameter">label</replaceable></arg>
+ <arg><option>-c <replaceable class="parameter">class</replaceable></option></arg>
+ <arg><option>-f <replaceable class="parameter">flag</replaceable></option></arg>
+ <arg><option>-k</option></arg>
+ <arg><option>-n <replaceable class="parameter">nametype</replaceable></option></arg>
+ <arg><option>-p <replaceable class="parameter">protocol</replaceable></option></arg>
+ <arg><option>-t <replaceable class="parameter">type</replaceable></option></arg>
+ <arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
+ <arg choice="req">name</arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para><command>dnssec-keyfromlabel</command>
+ gets keys with the given label from a crypto hardware and builds
+ key files for DNSSEC (Secure DNS), as defined in RFC 2535
+ and RFC 4034.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-a <replaceable class="parameter">algorithm</replaceable></term>
+ <listitem>
+ <para>
+ Selects the cryptographic algorithm. The value of
+ <option>algorithm</option> must be one of RSAMD5 (RSA)
+ or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman).
+ These values are case insensitive.
+ </para>
+ <para>
+ Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
+ algorithm, and DSA is recommended.
+ </para>
+ <para>
+ Note 2: DH automatically sets the -k flag.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-l <replaceable class="parameter">label</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the label of keys in the crypto hardware
+ (PKCS#11 device).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-n <replaceable class="parameter">nametype</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the owner type of the key. The value of
+ <option>nametype</option> must either be ZONE (for a DNSSEC
+ zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with
+ a host (KEY)),
+ USER (for a key associated with a user(KEY)) or OTHER (DNSKEY).
+ These values are
+ case insensitive.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-c <replaceable class="parameter">class</replaceable></term>
+ <listitem>
+ <para>
+ Indicates that the DNS record containing the key should have
+ the specified class. If not specified, class IN is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-f <replaceable class="parameter">flag</replaceable></term>
+ <listitem>
+ <para>
+ Set the specified flag in the flag field of the KEY/DNSKEY record.
+ The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-h</term>
+ <listitem>
+ <para>
+ Prints a short summary of the options and arguments to
+ <command>dnssec-keygen</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-k</term>
+ <listitem>
+ <para>
+ Generate KEY records rather than DNSKEY records.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-p <replaceable class="parameter">protocol</replaceable></term>
+ <listitem>
+ <para>
+ Sets the protocol value for the generated key. The protocol
+ is a number between 0 and 255. The default is 3 (DNSSEC).
+ Other possible values for this argument are listed in
+ RFC 2535 and its successors.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-t <replaceable class="parameter">type</replaceable></term>
+ <listitem>
+ <para>
+ Indicates the use of the key. <option>type</option> must be
+ one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default
+ is AUTHCONF. AUTH refers to the ability to authenticate
+ data, and CONF the ability to encrypt data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-v <replaceable class="parameter">level</replaceable></term>
+ <listitem>
+ <para>
+ Sets the debugging level.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>GENERATED KEY FILES</title>
+ <para>
+ When <command>dnssec-keyfromlabel</command> completes
+ successfully,
+ it prints a string of the form <filename>Knnnn.+aaa+iiiii</filename>
+ to the standard output. This is an identification string for
+ the key files it has generated.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para><filename>nnnn</filename> is the key name.
+ </para>
+ </listitem>
+ <listitem>
+ <para><filename>aaa</filename> is the numeric representation
+ of the
+ algorithm.
+ </para>
+ </listitem>
+ <listitem>
+ <para><filename>iiiii</filename> is the key identifier (or
+ footprint).
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para><command>dnssec-keyfromlabel</command>
+ creates two files, with names based
+ on the printed string. <filename>Knnnn.+aaa+iiiii.key</filename>
+ contains the public key, and
+ <filename>Knnnn.+aaa+iiiii.private</filename> contains the
+ private
+ key.
+ </para>
+ <para>
+ The <filename>.key</filename> file contains a DNS KEY record
+ that
+ can be inserted into a zone file (directly or with a $INCLUDE
+ statement).
+ </para>
+ <para>
+ The <filename>.private</filename> file contains algorithm
+ specific
+ fields. For obvious security reasons, this file does not have
+ general read permission.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para><citerefentry>
+ <refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>dnssec-signzone</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citetitle>BIND 9 Administrator Reference Manual</citetitle>,
+ <citetitle>RFC 2539</citetitle>,
+ <citetitle>RFC 2845</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:
+-->
diff --git a/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html
new file mode 100644
index 0000000..cbea64b
--- /dev/null
+++ b/contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html
@@ -0,0 +1,171 @@
+<!--
+ - Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND 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-keyfromlabel.html,v 1.5 2008/10/15 01:11:35 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>dnssec-keyfromlabel</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-keyfromlabel"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">dnssec-keyfromlabel</span> &#8212; DNSSEC key generation tool</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">dnssec-keyfromlabel</code> {-a <em class="replaceable"><code>algorithm</code></em>} {-l <em class="replaceable"><code>label</code></em>} [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-k</code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {name}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543413"></a><h2>DESCRIPTION</h2>
+<p><span><strong class="command">dnssec-keyfromlabel</strong></span>
+ gets keys with the given label from a crypto hardware and builds
+ key files for DNSSEC (Secure DNS), as defined in RFC 2535
+ and RFC 4034.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543425"></a><h2>OPTIONS</h2>
+<div class="variablelist"><dl>
+<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
+<dd>
+<p>
+ Selects the cryptographic algorithm. The value of
+ <code class="option">algorithm</code> must be one of RSAMD5 (RSA)
+ or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA or DH (Diffie Hellman).
+ These values are case insensitive.
+ </p>
+<p>
+ Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
+ algorithm, and DSA is recommended.
+ </p>
+<p>
+ Note 2: DH automatically sets the -k flag.
+ </p>
+</dd>
+<dt><span class="term">-l <em class="replaceable"><code>label</code></em></span></dt>
+<dd><p>
+ Specifies the label of keys in the crypto hardware
+ (PKCS#11 device).
+ </p></dd>
+<dt><span class="term">-n <em class="replaceable"><code>nametype</code></em></span></dt>
+<dd><p>
+ Specifies the owner type of the key. The value of
+ <code class="option">nametype</code> must either be ZONE (for a DNSSEC
+ zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with
+ a host (KEY)),
+ USER (for a key associated with a user(KEY)) or OTHER (DNSKEY).
+ These values are
+ case insensitive.
+ </p></dd>
+<dt><span class="term">-c <em class="replaceable"><code>class</code></em></span></dt>
+<dd><p>
+ Indicates that the DNS record containing the key should have
+ the specified class. If not specified, class IN is used.
+ </p></dd>
+<dt><span class="term">-f <em class="replaceable"><code>flag</code></em></span></dt>
+<dd><p>
+ Set the specified flag in the flag field of the KEY/DNSKEY record.
+ The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ </p></dd>
+<dt><span class="term">-h</span></dt>
+<dd><p>
+ Prints a short summary of the options and arguments to
+ <span><strong class="command">dnssec-keygen</strong></span>.
+ </p></dd>
+<dt><span class="term">-k</span></dt>
+<dd><p>
+ Generate KEY records rather than DNSKEY records.
+ </p></dd>
+<dt><span class="term">-p <em class="replaceable"><code>protocol</code></em></span></dt>
+<dd><p>
+ Sets the protocol value for the generated key. The protocol
+ is a number between 0 and 255. The default is 3 (DNSSEC).
+ Other possible values for this argument are listed in
+ RFC 2535 and its successors.
+ </p></dd>
+<dt><span class="term">-t <em class="replaceable"><code>type</code></em></span></dt>
+<dd><p>
+ Indicates the use of the key. <code class="option">type</code> must be
+ one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default
+ is AUTHCONF. AUTH refers to the ability to authenticate
+ data, and CONF the ability to encrypt data.
+ </p></dd>
+<dt><span class="term">-v <em class="replaceable"><code>level</code></em></span></dt>
+<dd><p>
+ Sets the debugging level.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543619"></a><h2>GENERATED KEY FILES</h2>
+<p>
+ When <span><strong class="command">dnssec-keyfromlabel</strong></span> completes
+ successfully,
+ it prints a string of the form <code class="filename">Knnnn.+aaa+iiiii</code>
+ to the standard output. This is an identification string for
+ the key files it has generated.
+ </p>
+<div class="itemizedlist"><ul type="disc">
+<li><p><code class="filename">nnnn</code> is the key name.
+ </p></li>
+<li><p><code class="filename">aaa</code> is the numeric representation
+ of the
+ algorithm.
+ </p></li>
+<li><p><code class="filename">iiiii</code> is the key identifier (or
+ footprint).
+ </p></li>
+</ul></div>
+<p><span><strong class="command">dnssec-keyfromlabel</strong></span>
+ creates two files, with names based
+ on the printed string. <code class="filename">Knnnn.+aaa+iiiii.key</code>
+ contains the public key, and
+ <code class="filename">Knnnn.+aaa+iiiii.private</code> contains the
+ private
+ key.
+ </p>
+<p>
+ The <code class="filename">.key</code> file contains a DNS KEY record
+ that
+ can be inserted into a zone file (directly or with a $INCLUDE
+ statement).
+ </p>
+<p>
+ The <code class="filename">.private</code> file contains algorithm
+ specific
+ fields. For obvious security reasons, this file does not have
+ general read permission.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543691"></a><h2>SEE ALSO</h2>
+<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
+ <span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>,
+ <em class="citetitle">RFC 2539</em>,
+ <em class="citetitle">RFC 2845</em>,
+ <em class="citetitle">RFC 4033</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543731"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div></body>
+</html>
diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.8 b/contrib/bind9/bin/dnssec/dnssec-keygen.8
index e667ba9..13db3d9 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keygen.8
+++ b/contrib/bind9/bin/dnssec/dnssec-keygen.8
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-keygen.8,v 1.23.18.16 2008/10/16 01:29:40 tbox Exp $
+.\" $Id: dnssec-keygen.8,v 1.40 2008/10/15 01:11:35 tbox Exp $
.\"
.hy 0
.ad l
@@ -44,7 +44,7 @@ generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It
.RS 4
Selects the cryptographic algorithm. The value of
\fBalgorithm\fR
-must be one of RSAMD5 (RSA) or RSASHA1, DSA, DH (Diffie Hellman), or HMAC\-MD5. These values are case insensitive.
+must be one of RSAMD5 (RSA) or RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, DH (Diffie Hellman), or HMAC\-MD5. These values are case insensitive.
.sp
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. For TSIG, HMAC\-MD5 is mandatory.
.sp
@@ -60,7 +60,7 @@ Specifies the number of bits in the key. The choice of key size depends on the a
.RS 4
Specifies the owner type of the key. The value of
\fBnametype\fR
-must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive.
+must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive. Defaults to ZONE for DNSKEY generation.
.RE
.PP
\-c \fIclass\fR
diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.c b/contrib/bind9/bin/dnssec/dnssec-keygen.c
index 0b57f6d..614d388 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keygen.c
+++ b/contrib/bind9/bin/dnssec/dnssec-keygen.c
@@ -1,6 +1,19 @@
/*
- * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-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 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.
+ *
* Portions Copyright (C) 1995-2000 by Network Associates, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -16,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-keygen.c,v 1.66.18.10 2007/08/28 07:19:55 tbox Exp $ */
+/* $Id: dnssec-keygen.c,v 1.81 2008/09/25 04:02:38 tbox Exp $ */
/*! \file */
@@ -49,8 +62,9 @@
const char *program = "dnssec-keygen";
int verbose;
-static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 | HMAC-MD5 |"
- " HMAC-SHA1 | HMAC-SHA224 | HMAC-SHA256 | "
+static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 | NSEC3DSA |"
+ " NSEC3RSASHA1 | HMAC-MD5 |"
+ " HMAC-SHA1 | HMAC-SHA224 | HMAC-SHA256 |"
" HMAC-SHA384 | HMAC-SHA512";
static isc_boolean_t
@@ -61,7 +75,7 @@ dsa_size_ok(int size) {
static void
usage(void) {
fprintf(stderr, "Usage:\n");
- fprintf(stderr, " %s -a alg -b bits -n type [options] name\n\n",
+ fprintf(stderr, " %s -a alg -b bits [-n type] [options] name\n\n",
program);
fprintf(stderr, "Version: %s\n", VERSION);
fprintf(stderr, "Required options:\n");
@@ -69,8 +83,10 @@ usage(void) {
fprintf(stderr, " -b key size, in bits:\n");
fprintf(stderr, " RSAMD5:\t\t[512..%d]\n", MAX_RSA);
fprintf(stderr, " RSASHA1:\t\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " NSEC3RSASHA1:\t\t[512..%d]\n", MAX_RSA);
fprintf(stderr, " DH:\t\t[128..4096]\n");
fprintf(stderr, " DSA:\t\t[512..1024] and divisible by 64\n");
+ fprintf(stderr, " NSEC3DSA:\t\t[512..1024] and divisible by 64\n");
fprintf(stderr, " HMAC-MD5:\t[1..512]\n");
fprintf(stderr, " HMAC-SHA1:\t[1..160]\n");
fprintf(stderr, " HMAC-SHA224:\t[1..224]\n");
@@ -78,6 +94,7 @@ usage(void) {
fprintf(stderr, " HMAC-SHA384:\t[1..384]\n");
fprintf(stderr, " HMAC-SHA512:\t[1..512]\n");
fprintf(stderr, " -n nametype: ZONE | HOST | ENTITY | USER | OTHER\n");
+ fprintf(stderr, " (DNSKEY generation defaults to ZONE\n");
fprintf(stderr, " name: owner of the key\n");
fprintf(stderr, "Other options:\n");
fprintf(stderr, " -c <class> (default: IN)\n");
@@ -134,8 +151,10 @@ main(int argc, char **argv) {
dns_result_register();
+ isc_commandline_errprint = ISC_FALSE;
+
while ((ch = isc_commandline_parse(argc, argv,
- "a:b:c:d:ef:g:kn:t:p:s:r:v:h")) != -1)
+ "a:b:c:d:ef:g:kn:t:p:s:r:v:h")) != -1)
{
switch (ch) {
case 'a':
@@ -202,12 +221,17 @@ main(int argc, char **argv) {
fatal("-v must be followed by a number");
break;
+ case '?':
+ if (isc_commandline_option != '?')
+ fprintf(stderr, "%s: invalid argument -%c\n",
+ program, isc_commandline_option);
case 'h':
usage();
+
default:
- fprintf(stderr, "%s: invalid argument -%c\n",
- program, ch);
- usage();
+ fprintf(stderr, "%s: unhandled option -%c\n",
+ program, isc_commandline_option);
+ exit(1);
}
}
@@ -282,6 +306,7 @@ main(int argc, char **argv) {
switch (alg) {
case DNS_KEYALG_RSAMD5:
case DNS_KEYALG_RSASHA1:
+ case DNS_KEYALG_NSEC3RSASHA1:
if (size != 0 && (size < 512 || size > MAX_RSA))
fatal("RSA key size %d out of range", size);
break;
@@ -290,6 +315,7 @@ main(int argc, char **argv) {
fatal("DH key size %d out of range", size);
break;
case DNS_KEYALG_DSA:
+ case DNS_KEYALG_NSEC3DSA:
if (size != 0 && !dsa_size_ok(size))
fatal("invalid DSS key size: %d", size);
break;
@@ -349,18 +375,20 @@ main(int argc, char **argv) {
break;
}
- if (!(alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_RSASHA1) &&
- rsa_exp != 0)
+ if (!(alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_RSASHA1 ||
+ alg == DNS_KEYALG_NSEC3RSASHA1) && rsa_exp != 0)
fatal("specified RSA exponent for a non-RSA key");
if (alg != DNS_KEYALG_DH && generator != 0)
fatal("specified DH generator for a non-DH key");
- if (nametype == NULL)
- fatal("no nametype specified");
- if (strcasecmp(nametype, "zone") == 0)
+ if (nametype == NULL) {
+ if ((options & DST_TYPE_KEY) != 0) /* KEY / HMAC */
+ fatal("no nametype specified");
+ flags |= DNS_KEYOWNER_ZONE; /* DNSKEY */
+ } else if (strcasecmp(nametype, "zone") == 0)
flags |= DNS_KEYOWNER_ZONE;
- else if ((options & DST_TYPE_KEY) != 0) { /* KEY */
+ else if ((options & DST_TYPE_KEY) != 0) { /* KEY / HMAC */
if (strcasecmp(nametype, "host") == 0 ||
strcasecmp(nametype, "entity") == 0)
flags |= DNS_KEYOWNER_ENTITY;
@@ -373,7 +401,7 @@ main(int argc, char **argv) {
rdclass = strtoclass(classname);
- if ((options & DST_TYPE_KEY) != 0) /* KEY */
+ if ((options & DST_TYPE_KEY) != 0) /* KEY / HMAC */
flags |= signatory;
else if ((flags & DNS_KEYOWNER_ZONE) != 0) /* DNSKEY */
flags |= ksk;
diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.docbook b/contrib/bind9/bin/dnssec/dnssec-keygen.docbook
index ec7b69b..c267a1b 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keygen.docbook
+++ b/contrib/bind9/bin/dnssec/dnssec-keygen.docbook
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keygen.docbook,v 1.7.18.13 2008/10/15 23:46:06 tbox Exp $ -->
+<!-- $Id: dnssec-keygen.docbook,v 1.22 2008/10/14 14:32:50 jreed Exp $ -->
<refentry id="man.dnssec-keygen">
<refentryinfo>
<date>June 30, 2000</date>
@@ -92,13 +92,13 @@
<para>
Selects the cryptographic algorithm. The value of
<option>algorithm</option> must be one of RSAMD5 (RSA) or RSASHA1,
- DSA, DH (Diffie Hellman), or HMAC-MD5. These values
- are case insensitive.
+ DSA, NSEC3RSASHA1, NSEC3DSA, DH (Diffie Hellman), or HMAC-MD5.
+ These values are case insensitive.
</para>
<para>
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
- algorithm,
- and DSA is recommended. For TSIG, HMAC-MD5 is mandatory.
+ algorithm, and DSA is recommended. For TSIG, HMAC-MD5 is
+ mandatory.
</para>
<para>
Note 2: HMAC-MD5 and DH automatically set the -k flag.
@@ -130,8 +130,8 @@
zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with
a host (KEY)),
USER (for a key associated with a user(KEY)) or OTHER (DNSKEY).
- These values are
- case insensitive.
+ These values are case insensitive. Defaults to ZONE for DNSKEY
+ generation.
</para>
</listitem>
</varlistentry>
diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.html b/contrib/bind9/bin/dnssec/dnssec-keygen.html
index e0b0bfe..696ef88 100644
--- a/contrib/bind9/bin/dnssec/dnssec-keygen.html
+++ b/contrib/bind9/bin/dnssec/dnssec-keygen.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keygen.html,v 1.9.18.22 2008/10/16 01:29:40 tbox Exp $ -->
+<!-- $Id: dnssec-keygen.html,v 1.32 2008/10/15 01:11:35 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -47,13 +47,13 @@
<p>
Selects the cryptographic algorithm. The value of
<code class="option">algorithm</code> must be one of RSAMD5 (RSA) or RSASHA1,
- DSA, DH (Diffie Hellman), or HMAC-MD5. These values
- are case insensitive.
+ DSA, NSEC3RSASHA1, NSEC3DSA, DH (Diffie Hellman), or HMAC-MD5.
+ These values are case insensitive.
</p>
<p>
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
- algorithm,
- and DSA is recommended. For TSIG, HMAC-MD5 is mandatory.
+ algorithm, and DSA is recommended. For TSIG, HMAC-MD5 is
+ mandatory.
</p>
<p>
Note 2: HMAC-MD5 and DH automatically set the -k flag.
@@ -76,8 +76,8 @@
zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with
a host (KEY)),
USER (for a key associated with a user(KEY)) or OTHER (DNSKEY).
- These values are
- case insensitive.
+ These values are case insensitive. Defaults to ZONE for DNSKEY
+ generation.
</p></dd>
<dt><span class="term">-c <em class="replaceable"><code>class</code></em></span></dt>
<dd><p>
diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.8 b/contrib/bind9/bin/dnssec/dnssec-signzone.8
index 680960a..ca0ed36 100644
--- a/contrib/bind9/bin/dnssec/dnssec-signzone.8
+++ b/contrib/bind9/bin/dnssec/dnssec-signzone.8
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-signzone.8,v 1.28.18.19 2008/10/16 01:29:40 tbox Exp $
+.\" $Id: dnssec-signzone.8,v 1.47 2008/10/15 01:11:35 tbox Exp $
.\"
.hy 0
.ad l
@@ -33,7 +33,7 @@
dnssec\-signzone \- DNSSEC zone signing tool
.SH "SYNOPSIS"
.HP 16
-\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-p\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-t\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] {zonefile} [key...]
+\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-p\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-t\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] [\fB\-3\ \fR\fB\fIsalt\fR\fR] [\fB\-H\ \fR\fB\fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...]
.SH "DESCRIPTION"
.PP
\fBdnssec\-signzone\fR
@@ -212,6 +212,21 @@ Sets the debugging level.
Ignore KSK flag on key when determining what to sign.
.RE
.PP
+\-3 \fIsalt\fR
+.RS 4
+Generate a NSEC3 chain with the given hex encoded salt. A dash (\fIsalt\fR) can be used to indicate that no salt is to be used when generating the NSEC3 chain.
+.RE
+.PP
+\-H \fIiterations\fR
+.RS 4
+When generating a NSEC3 chain use this many interations. The default is 100.
+.RE
+.PP
+\-A
+.RS 4
+When generating a NSEC3 chain set the OPTOUT flag on all NSEC3 records and do not generate NSEC3 records for insecure delegations.
+.RE
+.PP
zonefile
.RS 4
The file containing the zone to be signed.
diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.c b/contrib/bind9/bin/dnssec/dnssec-signzone.c
index 9b49169..1da280f 100644
--- a/contrib/bind9/bin/dnssec/dnssec-signzone.c
+++ b/contrib/bind9/bin/dnssec/dnssec-signzone.c
@@ -1,6 +1,19 @@
/*
- * Portions Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-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 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.
+ *
* Portions Copyright (C) 1995-2000 by Network Associates, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -16,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-signzone.c,v 1.177.18.26 2008/06/02 23:46:01 tbox Exp $ */
+/* $Id: dnssec-signzone.c,v 1.209.12.3 2009/01/18 23:25:15 marka Exp $ */
/*! \file */
@@ -26,11 +39,13 @@
#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>
@@ -38,10 +53,11 @@
#include <isc/random.h>
#include <isc/serial.h>
#include <isc/stdio.h>
+#include <isc/stdlib.h>
#include <isc/string.h>
#include <isc/task.h>
-#include <isc/util.h>
#include <isc/time.h>
+#include <isc/util.h>
#include <dns/db.h>
#include <dns/dbiterator.h>
@@ -54,7 +70,9 @@
#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>
@@ -71,6 +89,13 @@
const char *program = "dnssec-signzone";
int verbose;
+typedef struct hashlist hashlist_t;
+
+static int nsec_datatype = dns_rdatatype_nsec;
+
+#define IS_NSEC3 (nsec_datatype == dns_rdatatype_nsec3)
+#define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
+
#define BUFSIZE 2048
#define MAXDSKEYS 8
@@ -125,6 +150,7 @@ static dns_dbversion_t *gversion; /* The database version */
static dns_dbiterator_t *gdbiter; /* The database iterator */
static dns_rdataclass_t gclass; /* The class */
static dns_name_t *gorigin; /* The database origin */
+static int nsec3flags = 0;
static isc_task_t *master = NULL;
static unsigned int ntasks = 0;
static isc_boolean_t shuttingdown = ISC_FALSE, finished = ISC_FALSE;
@@ -136,6 +162,8 @@ static dns_name_t *dlv = NULL;
static dns_fixedname_t dlv_fixed;
static dns_master_style_t *dsstyle = NULL;
static unsigned int serialformat = SOA_SERIAL_KEEP;
+static unsigned int hash_length = 0;
+static isc_boolean_t unknownalg = ISC_FALSE;
#define INCSTAT(counter) \
if (printstats) { \
@@ -147,19 +175,8 @@ static unsigned int serialformat = SOA_SERIAL_KEEP;
static void
sign(isc_task_t *task, isc_event_t *event);
-
-static inline 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 isc_boolean_t
+nsec3only(dns_dbnode_t *node);
static void
dumpnode(dns_name_t *name, dns_dbnode_t *node) {
@@ -549,6 +566,169 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
isc_mem_put(mctx, nowsignedby, arraysize * sizeof(isc_boolean_t));
}
+struct hashlist {
+ unsigned char *hashbuf;
+ size_t entries;
+ size_t size;
+ size_t length;
+};
+
+static void
+hashlist_init(hashlist_t *l, unsigned int nodes, unsigned int length) {
+
+ l->entries = 0;
+ l->length = length + 1;
+
+ if (nodes != 0) {
+ l->size = nodes;
+ l->hashbuf = malloc(l->size * l->length);
+ if (l->hashbuf == NULL)
+ l->size = 0;
+ } else {
+ l->size = 0;
+ l->hashbuf = NULL;
+ }
+}
+
+static void
+hashlist_add(hashlist_t *l, const unsigned char *hash, size_t len)
+{
+
+ REQUIRE(len <= l->length);
+
+ if (l->entries == l->size) {
+ l->size = l->size * 2 + 100;
+ l->hashbuf = realloc(l->hashbuf, l->size * l->length);
+ }
+ memset(l->hashbuf + l->entries * l->length, 0, l->length);
+ memcpy(l->hashbuf + l->entries * l->length, hash, len);
+ l->entries++;
+}
+
+static void
+hashlist_add_dns_name(hashlist_t *l, /*const*/ dns_name_t *name,
+ unsigned int hashalg, unsigned int iterations,
+ const unsigned char *salt, size_t salt_length,
+ isc_boolean_t speculative)
+{
+ char nametext[DNS_NAME_FORMATSIZE];
+ unsigned char hash[NSEC3_MAX_HASH_LENGTH + 1];
+ unsigned int len;
+ size_t i;
+
+ len = isc_iterated_hash(hash, hashalg, iterations, salt, salt_length,
+ name->ndata, name->length);
+ if (verbose) {
+ dns_name_format(name, nametext, sizeof nametext);
+ for (i = 0 ; i < len; i++)
+ fprintf(stderr, "%02x", hash[i]);
+ fprintf(stderr, " %s\n", nametext);
+ }
+ hash[len++] = speculative ? 1 : 0;
+ hashlist_add(l, hash, len);
+}
+
+static int
+hashlist_comp(const void *a, const void *b) {
+ return (memcmp(a, b, hash_length + 1));
+}
+
+static void
+hashlist_sort(hashlist_t *l) {
+ qsort(l->hashbuf, l->entries, l->length, hashlist_comp);
+}
+
+static isc_boolean_t
+hashlist_hasdup(hashlist_t *l) {
+ unsigned char *current;
+ unsigned char *next = l->hashbuf;
+ size_t entries = l->entries;
+
+ /*
+ * Skip initial speculative wild card hashs.
+ */
+ while (entries > 0U && next[l->length-1] != 0U) {
+ next += l->length;
+ entries--;
+ }
+
+ current = next;
+ while (entries-- > 1U) {
+ next += l->length;
+ if (next[l->length-1] != 0)
+ continue;
+ if (memcmp(current, next, l->length - 1) == 0)
+ return (ISC_TRUE);
+ current = next;
+ }
+ return (ISC_FALSE);
+}
+
+static const unsigned char *
+hashlist_findnext(const hashlist_t *l,
+ const unsigned char hash[NSEC3_MAX_HASH_LENGTH])
+{
+ unsigned int entries = l->entries;
+ const unsigned char *next = bsearch(hash, l->hashbuf, l->entries,
+ l->length, hashlist_comp);
+ INSIST(next != NULL);
+
+ do {
+ if (next < l->hashbuf + (l->entries - 1) * l->length)
+ next += l->length;
+ else
+ next = l->hashbuf;
+ if (next[l->length - 1] == 0)
+ break;
+ } while (entries-- > 1);
+ INSIST(entries != 0);
+ return (next);
+}
+
+static isc_boolean_t
+hashlist_exists(const hashlist_t *l,
+ const unsigned char hash[NSEC3_MAX_HASH_LENGTH])
+{
+ if (bsearch(hash, l->hashbuf, l->entries, l->length, hashlist_comp))
+ return (ISC_TRUE);
+ else
+ return (ISC_FALSE);
+}
+
+static void
+addnowildcardhash(hashlist_t *l, /*const*/ dns_name_t *name,
+ unsigned int hashalg, unsigned int iterations,
+ const unsigned char *salt, size_t salt_length)
+{
+ dns_fixedname_t fixed;
+ dns_name_t *wild;
+ dns_dbnode_t *node = NULL;
+ isc_result_t result;
+ char namestr[DNS_NAME_FORMATSIZE];
+
+ dns_fixedname_init(&fixed);
+ wild = dns_fixedname_name(&fixed);
+
+ result = dns_name_concatenate(dns_wildcardname, name, wild, NULL);
+ if (result == ISC_R_NOSPACE)
+ return;
+ check_result(result,"addnowildcardhash: dns_name_concatenate()");
+
+ result = dns_db_findnode(gdb, wild, ISC_FALSE, &node);
+ if (result == ISC_R_SUCCESS) {
+ dns_db_detachnode(gdb, &node);
+ return;
+ }
+
+ if (verbose) {
+ dns_name_format(wild, namestr, sizeof(namestr));
+ fprintf(stderr, "adding no-wildcardhash for %s\n", namestr);
+ }
+
+ hashlist_add_dns_name(l, wild, hashalg, iterations, salt, salt_length,
+ ISC_TRUE);
+}
+
static void
opendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass,
dns_db_t **dbp)
@@ -665,91 +845,6 @@ loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
}
static isc_boolean_t
-nsec_setbit(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdatatype_t type,
- unsigned int val)
-{
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_nsec_t nsec;
- unsigned int newlen;
- unsigned char bitmap[8192 + 512];
- unsigned char nsecdata[8192 + 512 + DNS_NAME_MAXWIRE];
- isc_boolean_t answer = ISC_FALSE;
- unsigned int i, len, window;
- int octet;
-
- result = dns_rdataset_first(rdataset);
- check_result(result, "dns_rdataset_first()");
- dns_rdataset_current(rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &nsec, NULL);
- check_result(result, "dns_rdata_tostruct");
-
- INSIST(nsec.len <= sizeof(bitmap));
-
- newlen = 0;
-
- memset(bitmap, 0, sizeof(bitmap));
- for (i = 0; i < nsec.len; i += len) {
- INSIST(i + 2 <= nsec.len);
- window = nsec.typebits[i];
- len = nsec.typebits[i+1];
- i += 2;
- INSIST(len > 0 && len <= 32);
- INSIST(i + len <= nsec.len);
- memmove(&bitmap[window * 32 + 512], &nsec.typebits[i], len);
- }
- set_bit(bitmap + 512, type, val);
- for (window = 0; window < 256; window++) {
- for (octet = 31; octet >= 0; octet--)
- if (bitmap[window * 32 + 512 + octet] != 0)
- break;
- if (octet < 0)
- continue;
- bitmap[newlen] = window;
- bitmap[newlen + 1] = octet + 1;
- newlen += 2;
- /*
- * Overlapping move.
- */
- memmove(&bitmap[newlen], &bitmap[window * 32 + 512], octet + 1);
- newlen += octet + 1;
- }
- if (newlen != nsec.len ||
- memcmp(nsec.typebits, bitmap, newlen) != 0) {
- dns_rdata_t newrdata = DNS_RDATA_INIT;
- isc_buffer_t b;
- dns_diff_t diff;
- dns_difftuple_t *tuple = NULL;
-
- dns_diff_init(mctx, &diff);
- result = dns_difftuple_create(mctx, DNS_DIFFOP_DEL, name,
- rdataset->ttl, &rdata, &tuple);
- check_result(result, "dns_difftuple_create");
- dns_diff_append(&diff, &tuple);
-
- nsec.typebits = bitmap;
- nsec.len = newlen;
- isc_buffer_init(&b, nsecdata, sizeof(nsecdata));
- result = dns_rdata_fromstruct(&newrdata, rdata.rdclass,
- dns_rdatatype_nsec, &nsec,
- &b);
- check_result(result, "dns_rdata_fromstruct");
-
- result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,
- name, rdataset->ttl,
- &newrdata, &tuple);
- check_result(result, "dns_difftuple_create");
- dns_diff_append(&diff, &tuple);
- result = dns_diff_apply(&diff, gdb, gversion);
- check_result(result, "dns_difftuple_apply");
- dns_diff_clear(&diff);
- answer = ISC_TRUE;
- }
- dns_rdata_freestruct(&nsec);
- return (answer);
-}
-
-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;
@@ -769,10 +864,25 @@ delegation(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t *ttlp) {
return (ISC_TF(result == ISC_R_SUCCESS));
}
+static isc_boolean_t
+secure(dns_name_t *name, dns_dbnode_t *node) {
+ dns_rdataset_t dsset;
+ isc_result_t result;
+
+ if (dns_name_equal(name, gorigin))
+ return (ISC_FALSE);
+
+ dns_rdataset_init(&dsset);
+ result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_ds,
+ 0, 0, &dsset, NULL);
+ if (dns_rdataset_isassociated(&dsset))
+ dns_rdataset_disassociate(&dsset);
+
+ return (ISC_TF(result == ISC_R_SUCCESS));
+}
+
/*%
- * Signs all records at a name. This mostly just signs each set individually,
- * but also adds the RRSIG bit to any NSECs generated earlier, deals with
- * parent/child KEY signatures, and handles other exceptional cases.
+ * Signs all records at a name.
*/
static void
signname(dns_dbnode_t *node, dns_name_t *name) {
@@ -780,89 +890,19 @@ signname(dns_dbnode_t *node, dns_name_t *name) {
dns_rdataset_t rdataset;
dns_rdatasetiter_t *rdsiter;
isc_boolean_t isdelegation = ISC_FALSE;
- isc_boolean_t hasds = ISC_FALSE;
- isc_boolean_t changed = ISC_FALSE;
dns_diff_t del, add;
char namestr[DNS_NAME_FORMATSIZE];
- isc_uint32_t nsttl = 0;
+ dns_rdataset_init(&rdataset);
dns_name_format(name, namestr, sizeof(namestr));
/*
* Determine if this is a delegation point.
*/
- if (delegation(name, node, &nsttl))
+ if (delegation(name, node, NULL))
isdelegation = ISC_TRUE;
/*
- * If this is a delegation point, look for a DS set.
- */
- if (isdelegation) {
- dns_rdataset_t dsset;
- dns_rdataset_t sigdsset;
-
- dns_rdataset_init(&dsset);
- dns_rdataset_init(&sigdsset);
- result = dns_db_findrdataset(gdb, node, gversion,
- dns_rdatatype_ds,
- 0, 0, &dsset, &sigdsset);
- if (result == ISC_R_SUCCESS) {
- dns_rdataset_disassociate(&dsset);
- if (generateds) {
- result = dns_db_deleterdataset(gdb, node,
- gversion,
- dns_rdatatype_ds,
- 0);
- check_result(result, "dns_db_deleterdataset");
- } else
- hasds = ISC_TRUE;
- }
- if (generateds) {
- result = loadds(name, nsttl, &dsset);
- if (result == ISC_R_SUCCESS) {
- result = dns_db_addrdataset(gdb, node,
- gversion, 0,
- &dsset, 0, NULL);
- check_result(result, "dns_db_addrdataset");
- hasds = ISC_TRUE;
- dns_rdataset_disassociate(&dsset);
- if (dns_rdataset_isassociated(&sigdsset))
- dns_rdataset_disassociate(&sigdsset);
- } else if (dns_rdataset_isassociated(&sigdsset)) {
- result = dns_db_deleterdataset(gdb, node,
- gversion,
- dns_rdatatype_rrsig,
- dns_rdatatype_ds);
- check_result(result, "dns_db_deleterdataset");
- dns_rdataset_disassociate(&sigdsset);
- }
- } else if (dns_rdataset_isassociated(&sigdsset))
- dns_rdataset_disassociate(&sigdsset);
- }
-
- /*
- * Make sure that NSEC bits are appropriately set.
- */
- dns_rdataset_init(&rdataset);
- RUNTIME_CHECK(dns_db_findrdataset(gdb, node, gversion,
- dns_rdatatype_nsec, 0, 0, &rdataset,
- NULL) == ISC_R_SUCCESS);
- if (!nokeys)
- changed = nsec_setbit(name, &rdataset, dns_rdatatype_rrsig, 1);
- if (changed) {
- dns_rdataset_disassociate(&rdataset);
- RUNTIME_CHECK(dns_db_findrdataset(gdb, node, gversion,
- dns_rdatatype_nsec, 0, 0,
- &rdataset,
- NULL) == ISC_R_SUCCESS);
- }
- if (hasds)
- (void)nsec_setbit(name, &rdataset, dns_rdatatype_ds, 1);
- else
- (void)nsec_setbit(name, &rdataset, dns_rdatatype_ds, 0);
- dns_rdataset_disassociate(&rdataset);
-
- /*
* Now iterate through the rdatasets.
*/
dns_diff_init(mctx, &del);
@@ -884,7 +924,7 @@ signname(dns_dbnode_t *node, dns_name_t *name) {
* isn't a DS record.
*/
if (isdelegation) {
- if (rdataset.type != dns_rdatatype_nsec &&
+ if (rdataset.type != nsec_datatype &&
rdataset.type != dns_rdatatype_ds)
goto skip;
} else if (rdataset.type == dns_rdatatype_ds) {
@@ -938,6 +978,7 @@ active_node(dns_dbnode_t *node) {
while (result == ISC_R_SUCCESS) {
dns_rdatasetiter_current(rdsiter, &rdataset);
if (rdataset.type != dns_rdatatype_nsec &&
+ rdataset.type != dns_rdatatype_nsec3 &&
rdataset.type != dns_rdatatype_rrsig)
active = ISC_TRUE;
dns_rdataset_disassociate(&rdataset);
@@ -950,7 +991,7 @@ active_node(dns_dbnode_t *node) {
fatal("rdataset iteration failed: %s",
isc_result_totext(result));
- if (!active) {
+ if (!active && nsec_datatype == dns_rdatatype_nsec) {
/*%
* The node is empty of everything but NSEC / RRSIG records.
*/
@@ -1009,6 +1050,32 @@ active_node(dns_dbnode_t *node) {
fatal("rdataset iteration failed: %s",
isc_result_totext(result));
dns_rdatasetiter_destroy(&rdsiter2);
+
+#if 0
+ /*
+ * Delete all NSEC records and RRSIG(NSEC) if we are in
+ * NSEC3 mode and vica versa.
+ */
+ for (result = dns_rdatasetiter_first(rdsiter2);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(rdsiter2)) {
+ dns_rdatasetiter_current(rdsiter, &rdataset);
+ type = rdataset.type;
+ covers = rdataset.covers;
+ if (type == dns_rdatatype_rrsig)
+ type = covers;
+ dns_rdataset_disassociate(&rdataset);
+ if (type == nsec_datatype ||
+ (type != dns_rdatatype_nsec &&
+ type != dns_rdatatype_nsec3))
+ continue;
+ if (covers != 0)
+ type = dns_rdatatype_rrsig;
+ result = dns_db_deleterdataset(gdb, node, gversion,
+ type, covers);
+ check_result(result, "dns_db_deleterdataset()");
+ }
+#endif
}
dns_rdatasetiter_destroy(&rdsiter);
@@ -1169,11 +1236,8 @@ presign(void) {
isc_result_t result;
gdbiter = NULL;
- result = dns_db_createiterator(gdb, ISC_FALSE, &gdbiter);
+ result = dns_db_createiterator(gdb, 0, &gdbiter);
check_result(result, "dns_db_createiterator()");
-
- result = dns_dbiterator_first(gdbiter);
- check_result(result, "dns_dbiterator_first()");
}
/*%
@@ -1186,6 +1250,8 @@ postsign(void) {
/*%
* Sign the apex of the zone.
+ * Note the origin may not be the first node if there are out of zone
+ * records.
*/
static void
signapex(void) {
@@ -1196,13 +1262,15 @@ signapex(void) {
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
+ result = dns_dbiterator_seek(gdbiter, gorigin);
+ check_result(result, "dns_dbiterator_seek()");
result = dns_dbiterator_current(gdbiter, &node, name);
check_result(result, "dns_dbiterator_current()");
signname(node, name);
dumpnode(name, node);
cleannode(gdb, gversion, node);
dns_db_detachnode(gdb, &node);
- result = dns_dbiterator_next(gdbiter);
+ result = dns_dbiterator_first(gdbiter);
if (result == ISC_R_NOMORE)
finished = ISC_TRUE;
else if (result != ISC_R_SUCCESS)
@@ -1223,6 +1291,8 @@ assignwork(isc_task_t *task, isc_task_t *worker) {
dns_rdataset_t nsec;
isc_boolean_t found;
isc_result_t result;
+ static dns_name_t *zonecut = NULL; /* Protected by namelock. */
+ static dns_fixedname_t fzonecut; /* Protected by namelock. */
static unsigned int ended = 0; /* Protected by namelock. */
if (shuttingdown)
@@ -1250,19 +1320,51 @@ assignwork(isc_task_t *task, isc_task_t *worker) {
if (result != ISC_R_SUCCESS)
fatal("failure iterating database: %s",
isc_result_totext(result));
+ /*
+ * The origin was handled by signapex().
+ */
+ if (dns_name_equal(name, gorigin)) {
+ dns_db_detachnode(gdb, &node);
+ goto next;
+ }
+ /*
+ * Sort the zone data from the glue and out-of-zone data.
+ * For NSEC zones nodes with zone data have NSEC records.
+ * For NSEC3 zones the NSEC3 nodes are zone data but
+ * outside of the zone name space. For the rest we need
+ * to track the bottom of zone cuts.
+ * Nodes which don't need to be signed are dumped here.
+ */
dns_rdataset_init(&nsec);
result = dns_db_findrdataset(gdb, node, gversion,
- dns_rdatatype_nsec, 0, 0,
+ nsec_datatype, 0, 0,
&nsec, NULL);
- if (result == ISC_R_SUCCESS)
- found = ISC_TRUE;
- else
- dumpnode(name, node);
if (dns_rdataset_isassociated(&nsec))
dns_rdataset_disassociate(&nsec);
- if (!found)
+ if (result == ISC_R_SUCCESS) {
+ found = ISC_TRUE;
+ } else if (nsec_datatype == dns_rdatatype_nsec3) {
+ if (dns_name_issubdomain(name, gorigin) &&
+ (zonecut == NULL ||
+ !dns_name_issubdomain(name, zonecut))) {
+ if (delegation(name, node, NULL)) {
+ dns_fixedname_init(&fzonecut);
+ zonecut = dns_fixedname_name(&fzonecut);
+ dns_name_copy(name, zonecut, NULL);
+ if (!OPTOUT(nsec3flags) ||
+ secure(name, node))
+ found = ISC_TRUE;
+ } else
+ found = ISC_TRUE;
+ }
+ }
+
+ if (!found) {
+ dumpnode(name, node);
dns_db_detachnode(gdb, &node);
+ }
+ next:
result = dns_dbiterator_next(gdbiter);
if (result == ISC_R_NOMORE) {
finished = ISC_TRUE;
@@ -1348,6 +1450,43 @@ sign(isc_task_t *task, isc_event_t *event) {
}
/*%
+ * Update / remove the DS RRset. Preserve RRSIG(DS) if possible.
+ */
+static void
+add_ds(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t nsttl) {
+ dns_rdataset_t dsset;
+ dns_rdataset_t sigdsset;
+ isc_result_t result;
+
+ dns_rdataset_init(&dsset);
+ dns_rdataset_init(&sigdsset);
+ result = dns_db_findrdataset(gdb, node, gversion,
+ dns_rdatatype_ds,
+ 0, 0, &dsset, &sigdsset);
+ if (result == ISC_R_SUCCESS) {
+ dns_rdataset_disassociate(&dsset);
+ result = dns_db_deleterdataset(gdb, node, gversion,
+ dns_rdatatype_ds, 0);
+ check_result(result, "dns_db_deleterdataset");
+ }
+ result = loadds(name, nsttl, &dsset);
+ if (result == ISC_R_SUCCESS) {
+ result = dns_db_addrdataset(gdb, node, gversion, 0,
+ &dsset, 0, NULL);
+ check_result(result, "dns_db_addrdataset");
+ dns_rdataset_disassociate(&dsset);
+ if (dns_rdataset_isassociated(&sigdsset))
+ dns_rdataset_disassociate(&sigdsset);
+ } else if (dns_rdataset_isassociated(&sigdsset)) {
+ result = dns_db_deleterdataset(gdb, node, gversion,
+ dns_rdatatype_rrsig,
+ dns_rdatatype_ds);
+ check_result(result, "dns_db_deleterdataset");
+ dns_rdataset_disassociate(&sigdsset);
+ }
+}
+
+/*%
* Generate NSEC records for the zone.
*/
static void
@@ -1358,6 +1497,7 @@ nsecify(void) {
dns_name_t *name, *nextname, *zonecut;
isc_boolean_t done = ISC_FALSE;
isc_result_t result;
+ isc_uint32_t nsttl = 0;
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
@@ -1366,7 +1506,7 @@ nsecify(void) {
dns_fixedname_init(&fzonecut);
zonecut = NULL;
- result = dns_db_createiterator(gdb, ISC_FALSE, &dbiter);
+ result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
check_result(result, "dns_db_createiterator()");
result = dns_dbiterator_first(dbiter);
@@ -1374,9 +1514,11 @@ nsecify(void) {
while (!done) {
dns_dbiterator_current(dbiter, &node, name);
- if (delegation(name, node, NULL)) {
+ if (delegation(name, node, &nsttl)) {
zonecut = dns_fixedname_name(&fzonecut);
dns_name_copy(name, zonecut, NULL);
+ if (generateds)
+ add_ds(name, node, nsttl);
}
result = dns_dbiterator_next(dbiter);
nextnode = NULL;
@@ -1419,6 +1561,451 @@ nsecify(void) {
}
/*%
+ * Does this node only contain NSEC3 records or RRSIG records or is empty.
+ */
+static isc_boolean_t
+nsec3only(dns_dbnode_t *node) {
+ dns_rdatasetiter_t *rdsiter = NULL;
+ isc_result_t result;
+ dns_rdataset_t rdataset;
+ isc_boolean_t answer = ISC_TRUE;
+
+ dns_rdataset_init(&rdataset);
+ result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
+ check_result(result, "dns_db_allrdatasets()");
+ result = dns_rdatasetiter_first(rdsiter);
+ while (result == ISC_R_SUCCESS) {
+ dns_rdatasetiter_current(rdsiter, &rdataset);
+ if (rdataset.type != dns_rdatatype_nsec3 &&
+ rdataset.type != dns_rdatatype_rrsig) {
+ answer = ISC_FALSE;
+ result = ISC_R_NOMORE;
+ } else
+ result = dns_rdatasetiter_next(rdsiter);
+ dns_rdataset_disassociate(&rdataset);
+ }
+ if (result != ISC_R_NOMORE)
+ fatal("rdataset iteration failed: %s",
+ isc_result_totext(result));
+ dns_rdatasetiter_destroy(&rdsiter);
+ return (answer);
+}
+
+static void
+addnsec3param(const unsigned char *salt, size_t salt_length,
+ unsigned int iterations)
+{
+ dns_dbnode_t *node = NULL;
+ dns_rdata_nsec3param_t nsec3param;
+ unsigned char nsec3parambuf[5 + 255];
+ dns_rdatalist_t rdatalist;
+ dns_rdataset_t rdataset;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ isc_buffer_t b;
+ isc_result_t result;
+
+ dns_rdataset_init(&rdataset);
+
+ nsec3param.common.rdclass = gclass;
+ nsec3param.common.rdtype = dns_rdatatype_nsec3param;
+ ISC_LINK_INIT(&nsec3param.common, link);
+ nsec3param.mctx = NULL;
+ nsec3param.flags = 0;
+ nsec3param.hash = unknownalg ? DNS_NSEC3_UNKNOWNALG : dns_hash_sha1;
+ nsec3param.iterations = iterations;
+ nsec3param.salt_length = salt_length;
+ DE_CONST(salt, nsec3param.salt);
+
+ isc_buffer_init(&b, nsec3parambuf, sizeof(nsec3parambuf));
+ result = dns_rdata_fromstruct(&rdata, gclass,
+ dns_rdatatype_nsec3param,
+ &nsec3param, &b);
+ rdatalist.rdclass = rdata.rdclass;
+ rdatalist.type = rdata.type;
+ rdatalist.covers = 0;
+ rdatalist.ttl = 0;
+ ISC_LIST_INIT(rdatalist.rdata);
+ ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
+ result = dns_rdatalist_tordataset(&rdatalist, &rdataset);
+ check_result(result, "dns_rdatalist_tordataset()");
+
+ result = dns_db_findnode(gdb, gorigin, ISC_TRUE, &node);
+ check_result(result, "dns_db_find(gorigin)");
+ result = dns_db_addrdataset(gdb, node, gversion, 0, &rdataset,
+ DNS_DBADD_MERGE, NULL);
+ if (result == DNS_R_UNCHANGED)
+ result = ISC_R_SUCCESS;
+ check_result(result, "addnsec3param: dns_db_addrdataset()");
+ dns_db_detachnode(gdb, &node);
+}
+
+static void
+addnsec3(dns_name_t *name, dns_dbnode_t *node,
+ const unsigned char *salt, size_t salt_length,
+ unsigned int iterations, hashlist_t *hashlist,
+ dns_ttl_t ttl)
+{
+ unsigned char hash[NSEC3_MAX_HASH_LENGTH];
+ const unsigned char *nexthash;
+ unsigned char nsec3buffer[DNS_NSEC3_BUFFERSIZE];
+ dns_fixedname_t hashname;
+ dns_rdatalist_t rdatalist;
+ dns_rdataset_t rdataset;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ isc_result_t result;
+ dns_dbnode_t *nsec3node = NULL;
+ char namebuf[DNS_NAME_FORMATSIZE];
+ size_t hash_length;
+
+ dns_name_format(name, namebuf, sizeof(namebuf));
+
+ dns_fixedname_init(&hashname);
+ dns_rdataset_init(&rdataset);
+
+ dns_name_downcase(name, name, NULL);
+ result = dns_nsec3_hashname(&hashname, hash, &hash_length,
+ name, gorigin, dns_hash_sha1, iterations,
+ salt, salt_length);
+ check_result(result, "addnsec3: dns_nsec3_hashname()");
+ nexthash = hashlist_findnext(hashlist, hash);
+ result = dns_nsec3_buildrdata(gdb, gversion, node,
+ unknownalg ?
+ DNS_NSEC3_UNKNOWNALG : dns_hash_sha1,
+ nsec3flags, iterations,
+ salt, salt_length,
+ nexthash, ISC_SHA1_DIGESTLENGTH,
+ nsec3buffer, &rdata);
+ check_result(result, "addnsec3: dns_nsec3_buildrdata()");
+ rdatalist.rdclass = rdata.rdclass;
+ rdatalist.type = rdata.type;
+ rdatalist.covers = 0;
+ rdatalist.ttl = ttl;
+ ISC_LIST_INIT(rdatalist.rdata);
+ ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
+ result = dns_rdatalist_tordataset(&rdatalist, &rdataset);
+ check_result(result, "dns_rdatalist_tordataset()");
+ result = dns_db_findnsec3node(gdb, dns_fixedname_name(&hashname),
+ ISC_TRUE, &nsec3node);
+ check_result(result, "addnsec3: dns_db_findnode()");
+ result = dns_db_addrdataset(gdb, nsec3node, gversion, 0, &rdataset,
+ 0, NULL);
+ if (result == DNS_R_UNCHANGED)
+ result = ISC_R_SUCCESS;
+ check_result(result, "addnsec3: dns_db_addrdataset()");
+ dns_db_detachnode(gdb, &nsec3node);
+}
+
+/*%
+ * Clean out NSEC3 record and RRSIG(NSEC3) that are not in the hash list.
+ *
+ * Extract the hash from the first label of 'name' then see if it
+ * is in hashlist. If 'name' is not in the hashlist then delete the
+ * any NSEC3 records which have the same parameters as the chain we
+ * are building.
+ *
+ * XXXMPA Should we also check that it of the form <hash>.<origin>?
+ */
+static void
+nsec3clean(dns_name_t *name, dns_dbnode_t *node,
+ unsigned int hashalg, unsigned int iterations,
+ const unsigned char *salt, size_t salt_length, hashlist_t *hashlist)
+{
+ dns_label_t label;
+ dns_rdata_nsec3_t nsec3;
+ dns_rdata_t rdata, delrdata;
+ dns_rdatalist_t rdatalist;
+ dns_rdataset_t rdataset, delrdataset;
+ isc_boolean_t delete_rrsigs = ISC_FALSE;
+ isc_buffer_t target;
+ isc_result_t result;
+ unsigned char hash[NSEC3_MAX_HASH_LENGTH + 1];
+
+ /*
+ * Get the first label.
+ */
+ dns_name_getlabel(name, 0, &label);
+
+ /*
+ * We want just the label contents.
+ */
+ isc_region_consume(&label, 1);
+
+ /*
+ * Decode base32hex string.
+ */
+ isc_buffer_init(&target, hash, sizeof(hash) - 1);
+ result = isc_base32hex_decoderegion(&label, &target);
+ if (result != ISC_R_SUCCESS)
+ return;
+
+ hash[isc_buffer_usedlength(&target)] = 0;
+
+ if (hashlist_exists(hashlist, hash))
+ return;
+
+ /*
+ * Verify that the NSEC3 parameters match the current ones
+ * otherwise we are dealing with a different NSEC3 chain.
+ */
+ dns_rdataset_init(&rdataset);
+ dns_rdataset_init(&delrdataset);
+
+ result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_nsec3,
+ 0, 0, &rdataset, NULL);
+ if (result != ISC_R_SUCCESS)
+ return;
+
+ /*
+ * Delete any matching NSEC3 records which have parameters that
+ * match the NSEC3 chain we are building.
+ */
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_init(&rdata);
+ dns_rdataset_current(&rdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &nsec3, NULL);
+ if (nsec3.hash == hashalg &&
+ nsec3.iterations == iterations &&
+ nsec3.salt_length == salt_length &&
+ !memcmp(nsec3.salt, salt, salt_length))
+ break;
+ rdatalist.rdclass = rdata.rdclass;
+ rdatalist.type = rdata.type;
+ rdatalist.covers = 0;
+ rdatalist.ttl = rdataset.ttl;
+ ISC_LIST_INIT(rdatalist.rdata);
+ dns_rdata_init(&delrdata);
+ dns_rdata_clone(&rdata, &delrdata);
+ ISC_LIST_APPEND(rdatalist.rdata, &delrdata, link);
+ result = dns_rdatalist_tordataset(&rdatalist, &delrdataset);
+ check_result(result, "dns_rdatalist_tordataset()");
+ result = dns_db_subtractrdataset(gdb, node, gversion,
+ &delrdataset, 0, NULL);
+ dns_rdataset_disassociate(&delrdataset);
+ if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED)
+ check_result(result, "dns_db_subtractrdataset(NSEC3)");
+ delete_rrsigs = ISC_TRUE;
+ }
+ dns_rdataset_disassociate(&rdataset);
+ if (result != ISC_R_NOMORE)
+ check_result(result, "dns_rdataset_first/next");
+
+ if (!delete_rrsigs)
+ return;
+ /*
+ * Delete the NSEC3 RRSIGs
+ */
+ result = dns_db_deleterdataset(gdb, node, gversion,
+ dns_rdatatype_rrsig,
+ dns_rdatatype_nsec3);
+ if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED)
+ check_result(result, "dns_db_deleterdataset(RRSIG(NSEC3))");
+}
+
+/*
+ * Generate NSEC3 records for the zone.
+ */
+static void
+nsec3ify(unsigned int hashalg, unsigned int iterations,
+ const unsigned char *salt, size_t salt_length, hashlist_t *hashlist)
+{
+ dns_dbiterator_t *dbiter = NULL;
+ dns_dbnode_t *node = NULL, *nextnode = NULL;
+ dns_fixedname_t fname, fnextname, fzonecut;
+ dns_name_t *name, *nextname, *zonecut;
+ isc_boolean_t done = ISC_FALSE;
+ isc_result_t result;
+ isc_boolean_t active;
+ isc_uint32_t nsttl = 0;
+ unsigned int count, nlabels;
+ int order;
+
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ dns_fixedname_init(&fnextname);
+ nextname = dns_fixedname_name(&fnextname);
+ dns_fixedname_init(&fzonecut);
+ zonecut = NULL;
+
+ /*
+ * Walk the zone generating the hash names.
+ */
+ 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) {
+ dns_dbiterator_current(dbiter, &node, name);
+ result = dns_dbiterator_next(dbiter);
+ nextnode = NULL;
+ while (result == ISC_R_SUCCESS) {
+ result = dns_dbiterator_current(dbiter, &nextnode,
+ nextname);
+ if (result != ISC_R_SUCCESS)
+ break;
+ active = active_node(nextnode);
+ if (!active) {
+ dns_db_detachnode(gdb, &nextnode);
+ result = dns_dbiterator_next(dbiter);
+ continue;
+ }
+ if (!dns_name_issubdomain(nextname, gorigin) ||
+ (zonecut != NULL &&
+ dns_name_issubdomain(nextname, zonecut))) {
+ dns_db_detachnode(gdb, &nextnode);
+ result = dns_dbiterator_next(dbiter);
+ continue;
+ }
+ if (delegation(nextname, nextnode, &nsttl)) {
+ zonecut = dns_fixedname_name(&fzonecut);
+ dns_name_copy(nextname, zonecut, NULL);
+ if (generateds)
+ add_ds(nextname, nextnode, nsttl);
+ if (OPTOUT(nsec3flags) &&
+ !secure(nextname, nextnode)) {
+ dns_db_detachnode(gdb, &nextnode);
+ result = dns_dbiterator_next(dbiter);
+ continue;
+ }
+ }
+ dns_db_detachnode(gdb, &nextnode);
+ break;
+ }
+ if (result == ISC_R_NOMORE) {
+ dns_name_copy(gorigin, nextname, NULL);
+ done = ISC_TRUE;
+ } else if (result != ISC_R_SUCCESS)
+ fatal("iterating through the database failed: %s",
+ isc_result_totext(result));
+ dns_name_downcase(name, name, NULL);
+ hashlist_add_dns_name(hashlist, name, hashalg, iterations,
+ salt, salt_length, ISC_FALSE);
+ dns_db_detachnode(gdb, &node);
+ /*
+ * Add hashs for empty nodes. Use closest encloser logic.
+ * The closest encloser either has data or is a empty
+ * node for another <name,nextname> span so we don't add
+ * it here. Empty labels on nextname are within the span.
+ */
+ dns_name_downcase(nextname, nextname, NULL);
+ dns_name_fullcompare(name, nextname, &order, &nlabels);
+ addnowildcardhash(hashlist, name, hashalg, iterations,
+ salt, salt_length);
+ count = dns_name_countlabels(nextname);
+ while (count > nlabels + 1) {
+ count--;
+ dns_name_split(nextname, count, NULL, nextname);
+ hashlist_add_dns_name(hashlist, nextname, hashalg,
+ iterations, salt, salt_length,
+ ISC_FALSE);
+ addnowildcardhash(hashlist, nextname, hashalg,
+ iterations, salt, salt_length);
+ }
+ }
+ dns_dbiterator_destroy(&dbiter);
+
+ /*
+ * We have all the hashes now so we can sort them.
+ */
+ hashlist_sort(hashlist);
+
+ /*
+ * Check for duplicate hashes. If found the salt needs to
+ * be changed.
+ */
+ if (hashlist_hasdup(hashlist))
+ fatal("Duplicate hash detected. Pick a different salt.");
+
+ /*
+ * Generate the nsec3 records.
+ */
+ zonecut = NULL;
+ done = ISC_FALSE;
+
+ addnsec3param(salt, salt_length, iterations);
+
+ 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) {
+ dns_dbiterator_current(dbiter, &node, name);
+ result = dns_dbiterator_next(dbiter);
+ nextnode = NULL;
+ while (result == ISC_R_SUCCESS) {
+ result = dns_dbiterator_current(dbiter, &nextnode,
+ nextname);
+ if (result != ISC_R_SUCCESS)
+ break;
+ /*
+ * Cleanout NSEC3 RRsets which don't exist in the
+ * hash table.
+ */
+ nsec3clean(nextname, nextnode, hashalg, iterations,
+ salt, salt_length, hashlist);
+ /*
+ * Skip NSEC3 only nodes when looking for the next
+ * node in the zone. Also skips now empty nodes.
+ */
+ if (nsec3only(nextnode)) {
+ dns_db_detachnode(gdb, &nextnode);
+ result = dns_dbiterator_next(dbiter);
+ continue;
+ }
+ if (!dns_name_issubdomain(nextname, gorigin) ||
+ (zonecut != NULL &&
+ dns_name_issubdomain(nextname, zonecut))) {
+ dns_db_detachnode(gdb, &nextnode);
+ result = dns_dbiterator_next(dbiter);
+ continue;
+ }
+ if (delegation(nextname, nextnode, NULL)) {
+ zonecut = dns_fixedname_name(&fzonecut);
+ dns_name_copy(nextname, zonecut, NULL);
+ if (OPTOUT(nsec3flags) &&
+ !secure(nextname, nextnode)) {
+ dns_db_detachnode(gdb, &nextnode);
+ result = dns_dbiterator_next(dbiter);
+ continue;
+ }
+ }
+ dns_db_detachnode(gdb, &nextnode);
+ break;
+ }
+ if (result == ISC_R_NOMORE) {
+ dns_name_copy(gorigin, nextname, NULL);
+ done = ISC_TRUE;
+ } else if (result != ISC_R_SUCCESS)
+ fatal("iterating through the database failed: %s",
+ isc_result_totext(result));
+ /*
+ * We need to pause here to release the lock on the database.
+ */
+ dns_dbiterator_pause(dbiter);
+ addnsec3(name, node, salt, salt_length, iterations,
+ hashlist, zonettl);
+ dns_db_detachnode(gdb, &node);
+ /*
+ * Add NSEC3's for empty nodes. Use closest encloser logic.
+ */
+ dns_name_fullcompare(name, nextname, &order, &nlabels);
+ count = dns_name_countlabels(nextname);
+ while (count > nlabels + 1) {
+ count--;
+ dns_name_split(nextname, count, NULL, nextname);
+ addnsec3(nextname, NULL, salt, salt_length,
+ iterations, hashlist, zonettl);
+ }
+ }
+ dns_dbiterator_destroy(&dbiter);
+}
+
+/*%
* Load the zone file from disk
*/
static void
@@ -1788,6 +2375,9 @@ usage(void) {
fprintf(stderr, "\t-n ncpus (number of cpus present)\n");
fprintf(stderr, "\t-k key_signing_key\n");
fprintf(stderr, "\t-l lookasidezone\n");
+ fprintf(stderr, "\t-3 salt (NSEC3 salt)\n");
+ fprintf(stderr, "\t-H iterations (NSEC3 iterations)\n");
+ fprintf(stderr, "\t-A (NSEC3 optout)\n");
fprintf(stderr, "\t-z:\t");
fprintf(stderr, "ignore KSK flag in DNSKEYs");
@@ -1852,6 +2442,36 @@ main(int argc, char *argv[]) {
isc_task_t **tasks = NULL;
isc_buffer_t b;
int len;
+ unsigned int iterations = 100U;
+ const unsigned char *salt = NULL;
+ size_t salt_length = 0;
+ unsigned char saltbuf[255];
+ hashlist_t hashlist;
+
+#define CMDLINE_FLAGS "3:aAc:d:e:f:ghH:i:I:j:k:l:m:n:N:o:O:pr:s:StUv:z"
+
+ /*
+ * 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;
masterstyle = &dns_master_style_explicitttl;
@@ -1863,10 +2483,34 @@ main(int argc, char *argv[]) {
dns_result_register();
- while ((ch = isc_commandline_parse(argc, argv,
- "ac:d:e:f:ghi:I:j:k:l:n:N:o:O:pr:s:Stv:z"))
- != -1) {
+ isc_commandline_errprint = ISC_FALSE;
+
+ while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
switch (ch) {
+ case '3':
+ if (strcmp(isc_commandline_argument, "-")) {
+ isc_buffer_t target;
+ char *sarg;
+
+ sarg = isc_commandline_argument;
+ isc_buffer_init(&target, saltbuf,
+ sizeof(saltbuf));
+ result = isc_hex_decodestring(sarg, &target);
+ check_result(result,
+ "isc_hex_decodestring(salt)");
+ salt = saltbuf;
+ salt_length = isc_buffer_usedlength(&target);
+ } else {
+ salt = saltbuf;
+ salt_length = 0;
+ }
+ nsec_datatype = dns_rdatatype_nsec3;
+ break;
+
+ case 'A':
+ nsec3flags |= DNS_NSEC3FLAG_OPTOUT;
+ break;
+
case 'a':
tryverify = ISC_TRUE;
break;
@@ -1891,11 +2535,19 @@ main(int argc, char *argv[]) {
generateds = ISC_TRUE;
break;
+ case '?':
+ if (isc_commandline_option != '?')
+ fprintf(stderr, "%s: invalid argument -%c\n",
+ program, isc_commandline_option);
case 'h':
- default:
usage();
break;
+ default:
+ fprintf(stderr, "%s: unhandled option -%c\n",
+ program, isc_commandline_option);
+ exit(1);
+
case 'i':
endp = NULL;
cycle = strtol(isc_commandline_argument, &endp, 0);
@@ -1934,6 +2586,9 @@ main(int argc, char *argv[]) {
dskeyfile[ndskeys++] = isc_commandline_argument;
break;
+ case 'm':
+ break;
+
case 'n':
endp = NULL;
ntasks = strtol(isc_commandline_argument, &endp, 0);
@@ -1945,6 +2600,15 @@ main(int argc, char *argv[]) {
serialformatstr = isc_commandline_argument;
break;
+ case 'H':
+ iterations = strtoul(isc_commandline_argument,
+ &endp, 0);
+ if (*endp != '\0')
+ fatal("iterations must be numeric");
+ if (iterations > 0xffffU)
+ fatal("iterations too big");
+ break;
+
case 'o':
origin = isc_commandline_argument;
break;
@@ -1975,6 +2639,10 @@ main(int argc, char *argv[]) {
printstats = ISC_TRUE;
break;
+ case 'U': /* Undocumented for testing only. */
+ unknownalg = ISC_TRUE;
+ break;
+
case 'v':
endp = NULL;
verbose = strtol(isc_commandline_argument, &endp, 0);
@@ -2018,7 +2686,7 @@ main(int argc, char *argv[]) {
cycle = (endtime - starttime) / 4;
if (ntasks == 0)
- ntasks = isc_os_ncpus();
+ ntasks = isc_os_ncpus() * 2;
vbprintf(4, "using %d cpus\n", ntasks);
rdclass = strtoclass(classname);
@@ -2082,7 +2750,6 @@ main(int argc, char *argv[]) {
0, 24, 0, 0, 0, 8, mctx);
check_result(result, "dns_master_stylecreate");
-
gdb = NULL;
TIME_NOW(&timer_start);
loadzone(file, origin, rdclass, &gdb);
@@ -2090,6 +2757,18 @@ main(int argc, char *argv[]) {
gclass = dns_db_class(gdb);
zonettl = soattl();
+ if (IS_NSEC3) {
+ isc_boolean_t answer;
+ hash_length = dns_nsec3_hashlength(dns_hash_sha1);
+ hashlist_init(&hashlist, dns_db_nodecount(gdb) * 2,
+ hash_length);
+ result = dns_nsec_nseconly(gdb, gversion, &answer);
+ check_result(result, "dns_nsec_nseconly");
+ if (answer)
+ fatal("NSEC3 generation requested with "
+ "NSEC only DNSKEY");
+ }
+
ISC_LIST_INIT(keylist);
if (argc == 0) {
@@ -2106,6 +2785,9 @@ main(int argc, char *argv[]) {
fatal("cannot load dnskey %s: %s", argv[i],
isc_result_totext(result));
+ if (!dns_name_equal(gorigin, dst_key_name(newkey)))
+ fatal("key %s not at origin\n", argv[i]);
+
key = ISC_LIST_HEAD(keylist);
while (key != NULL) {
dst_key_t *dkey = key->key;
@@ -2143,6 +2825,9 @@ main(int argc, char *argv[]) {
fatal("cannot load dnskey %s: %s", dskeyfile[i],
isc_result_totext(result));
+ if (!dns_name_equal(gorigin, dst_key_name(newkey)))
+ fatal("key %s not at origin\n", dskeyfile[i]);
+
key = ISC_LIST_HEAD(keylist);
while (key != NULL) {
dst_key_t *dkey = key->key;
@@ -2176,6 +2861,15 @@ main(int argc, char *argv[]) {
nokeys = ISC_TRUE;
}
+ if (IS_NSEC3) {
+ unsigned int max;
+ result = dns_nsec3_maxiterations(gdb, NULL, mctx, &max);
+ check_result(result, "dns_nsec3_maxiterations()");
+ if (iterations > max)
+ fatal("NSEC3 iterations too big for weakest DNSKEY "
+ "strength. Maximum iterations allowed %u.", max);
+ }
+
warnifallksk(gdb);
gversion = NULL;
@@ -2195,7 +2889,11 @@ main(int argc, char *argv[]) {
break;
}
- nsecify();
+ if (IS_NSEC3)
+ nsec3ify(dns_hash_sha1, iterations, salt, salt_length,
+ &hashlist);
+ else
+ nsecify();
if (!nokeys) {
writeset("keyset-", dns_rdatatype_dnskey);
diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.docbook b/contrib/bind9/bin/dnssec/dnssec-signzone.docbook
index 67eacc1..2f26ba4 100644
--- a/contrib/bind9/bin/dnssec/dnssec-signzone.docbook
+++ b/contrib/bind9/bin/dnssec/dnssec-signzone.docbook
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-signzone.docbook,v 1.10.18.19 2008/10/15 23:46:06 tbox Exp $ -->
+<!-- $Id: dnssec-signzone.docbook,v 1.31 2008/10/14 14:28:25 jreed Exp $ -->
<refentry id="man.dnssec-signzone">
<refentryinfo>
<date>June 30, 2000</date>
@@ -77,6 +77,9 @@
<arg><option>-t</option></arg>
<arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
<arg><option>-z</option></arg>
+ <arg><option>-3 <replaceable class="parameter">salt</replaceable></option></arg>
+ <arg><option>-H <replaceable class="parameter">iterations</replaceable></option></arg>
+ <arg><option>-A</option></arg>
<arg choice="req">zonefile</arg>
<arg rep="repeat">key</arg>
</cmdsynopsis>
@@ -400,6 +403,38 @@
</varlistentry>
<varlistentry>
+ <term>-3 <replaceable class="parameter">salt</replaceable></term>
+ <listitem>
+ <para>
+ Generate a NSEC3 chain with the given hex encoded salt.
+ A dash (<replaceable class="parameter">salt</replaceable>) can
+ be used to indicate that no salt is to be used when generating the NSEC3 chain.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-H <replaceable class="parameter">iterations</replaceable></term>
+ <listitem>
+ <para>
+ When generating a NSEC3 chain use this many interations. The
+ default is 100.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-A</term>
+ <listitem>
+ <para>
+ When generating a NSEC3 chain set the OPTOUT flag on all
+ NSEC3 records and do not generate NSEC3 records for insecure
+ delegations.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>zonefile</term>
<listitem>
<para>
diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.html b/contrib/bind9/bin/dnssec/dnssec-signzone.html
index 18d851d..6548d84 100644
--- a/contrib/bind9/bin/dnssec/dnssec-signzone.html
+++ b/contrib/bind9/bin/dnssec/dnssec-signzone.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-signzone.html,v 1.8.18.25 2008/10/16 01:29:40 tbox Exp $ -->
+<!-- $Id: dnssec-signzone.html,v 1.33 2008/10/15 01:11:35 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -29,10 +29,10 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-signzone</code> [<code class="option">-a</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-e <em class="replaceable"><code>end-time</code></em></code>] [<code class="option">-f <em class="replaceable"><code>output-file</code></em></code>] [<code class="option">-g</code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>key</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-i <em class="replaceable"><code>interval</code></em></code>] [<code class="option">-I <em class="replaceable"><code>input-format</code></em></code>] [<code class="option">-j <em class="replaceable"><code>jitter</code></em></code>] [<code class="option">-N <em class="replaceable"><code>soa-serial-format</code></em></code>] [<code class="option">-o <em class="replaceable"><code>origin</code></em></code>] [<code class="option">-O <em class="replaceable"><code>output-format</code></em></code>] [<code class="option">-p</code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-s <em class="replaceable"><code>start-time</code></em></code>] [<code class="option">-t</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-z</code>] {zonefile} [key...]</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-signzone</code> [<code class="option">-a</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-e <em class="replaceable"><code>end-time</code></em></code>] [<code class="option">-f <em class="replaceable"><code>output-file</code></em></code>] [<code class="option">-g</code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>key</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-i <em class="replaceable"><code>interval</code></em></code>] [<code class="option">-I <em class="replaceable"><code>input-format</code></em></code>] [<code class="option">-j <em class="replaceable"><code>jitter</code></em></code>] [<code class="option">-N <em class="replaceable"><code>soa-serial-format</code></em></code>] [<code class="option">-o <em class="replaceable"><code>origin</code></em></code>] [<code class="option">-O <em class="replaceable"><code>output-format</code></em></code>] [<code class="option">-p</code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-s <em class="replaceable"><code>start-time</code></em></code>] [<code class="option">-t</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-z</code>] [<code class="option">-3 <em class="replaceable"><code>salt</code></em></code>] [<code class="option">-H <em class="replaceable"><code>iterations</code></em></code>] [<code class="option">-A</code>] {zonefile} [key...]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543529"></a><h2>DESCRIPTION</h2>
+<a name="id2543550"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-signzone</strong></span>
signs a zone. It generates
NSEC and RRSIG records and produces a signed version of the
@@ -43,7 +43,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543544"></a><h2>OPTIONS</h2>
+<a name="id2543565"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a</span></dt>
<dd><p>
@@ -226,6 +226,23 @@
<dd><p>
Ignore KSK flag on key when determining what to sign.
</p></dd>
+<dt><span class="term">-3 <em class="replaceable"><code>salt</code></em></span></dt>
+<dd><p>
+ Generate a NSEC3 chain with the given hex encoded salt.
+ A dash (<em class="replaceable"><code>salt</code></em>) can
+ be used to indicate that no salt is to be used when generating the NSEC3 chain.
+ </p></dd>
+<dt><span class="term">-H <em class="replaceable"><code>iterations</code></em></span></dt>
+<dd><p>
+ When generating a NSEC3 chain use this many interations. The
+ default is 100.
+ </p></dd>
+<dt><span class="term">-A</span></dt>
+<dd><p>
+ When generating a NSEC3 chain set the OPTOUT flag on all
+ NSEC3 records and do not generate NSEC3 records for insecure
+ delegations.
+ </p></dd>
<dt><span class="term">zonefile</span></dt>
<dd><p>
The file containing the zone to be signed.
@@ -241,7 +258,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544330"></a><h2>EXAMPLE</h2>
+<a name="id2544404"></a><h2>EXAMPLE</h2>
<p>
The following command signs the <strong class="userinput"><code>example.com</code></strong>
zone with the DSA key generated by <span><strong class="command">dnssec-keygen</strong></span>
@@ -270,14 +287,14 @@ db.example.com.signed
%</pre>
</div>
<div class="refsect1" lang="en">
-<a name="id2544381"></a><h2>SEE ALSO</h2>
+<a name="id2544523"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</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="id2544406"></a><h2>AUTHOR</h2>
+<a name="id2544548"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/bin/dnssec/dnssectool.c b/contrib/bind9/bin/dnssec/dnssectool.c
index 4f95540..e933a06 100644
--- a/contrib/bind9/bin/dnssec/dnssectool.c
+++ b/contrib/bind9/bin/dnssec/dnssectool.c
@@ -1,8 +1,8 @@
/*
- * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * 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.
*
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssectool.c,v 1.40.18.3 2005/07/01 03:55:28 marka Exp $ */
+/* $Id: dnssectool.c,v 1.45 2007/06/19 23:46:59 tbox Exp $ */
/*! \file */
diff --git a/contrib/bind9/bin/dnssec/dnssectool.h b/contrib/bind9/bin/dnssec/dnssectool.h
index c5f3648..ee476f4 100644
--- a/contrib/bind9/bin/dnssec/dnssectool.h
+++ b/contrib/bind9/bin/dnssec/dnssectool.h
@@ -1,8 +1,8 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * 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.
*
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssectool.h,v 1.18 2004/03/05 04:57:41 marka Exp $ */
+/* $Id: dnssectool.h,v 1.22 2008/09/25 04:02:38 tbox Exp $ */
#ifndef DNSSECTOOL_H
#define DNSSECTOOL_H 1
@@ -41,7 +41,7 @@ vbprintf(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
void
type_format(const dns_rdatatype_t type, char *cp, unsigned int size);
-#define TYPE_FORMATSIZE 10
+#define TYPE_FORMATSIZE 20
void
alg_format(const dns_secalg_t alg, char *cp, unsigned int size);
OpenPOWER on IntegriCloud